/[gxemul]/trunk/src/devices/dev_vga.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_vga.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 6 by dpavlin, Mon Oct 8 16:18:11 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_vga.c,v 1.74 2005/05/29 16:04:28 debug Exp $   *  $Id: dev_vga.c,v 1.104 2007/06/15 19:57:34 debug Exp $
29   *   *
30   *  VGA charcell and graphics device.   *  COMMENT: VGA framebuffer device (charcell and graphics modes)
31   *   *
32   *  It should work with 80x25 and 40x25 text modes, and with a few graphics   *  It should work with 80x25 and 40x25 text modes, and with a few graphics
33   *  modes as long as no fancy VGA features are used.   *  modes as long as no fancy VGA features are used.
# Line 52  Line 52 
52  #include "fonts/font8x16.c"  #include "fonts/font8x16.c"
53    
54    
55  /*  For bintranslated videomem -> framebuffer updates:  */  /*  For videomem -> framebuffer updates:  */
56  #define VGA_TICK_SHIFT          16  #define VGA_TICK_SHIFT          18
57    
58  #define MAX_RETRACE_SCANLINES   420  #define MAX_RETRACE_SCANLINES   420
59  #define N_IS1_READ_THRESHOLD    50  #define N_IS1_READ_THRESHOLD    50
60    
 #define VGA_MEM_MAXY            60  
 #define VGA_MEM_ALLOCY          60  
61  #define GFX_ADDR_WINDOW         0x18000  #define GFX_ADDR_WINDOW         0x18000
62    
63  #define VGA_FB_ADDR     0x1c00000000ULL  #define VGA_FB_ADDR     0x1c00000000ULL
# Line 75  struct vga_data { Line 73  struct vga_data {
73          uint64_t        control_base;          uint64_t        control_base;
74    
75          struct vfb_data *fb;          struct vfb_data *fb;
76          size_t          fb_size;          uint32_t        fb_size;
77    
78          int             fb_max_x;               /*  pixels  */          int             fb_max_x;               /*  pixels  */
79          int             fb_max_y;               /*  pixels  */          int             fb_max_y;               /*  pixels  */
# Line 94  struct vga_data { Line 92  struct vga_data {
92          unsigned char   *font;          unsigned char   *font;
93          size_t          charcells_size;          size_t          charcells_size;
94          unsigned char   *charcells;             /*  2 bytes per char  */          unsigned char   *charcells;             /*  2 bytes per char  */
95          unsigned char   *charcells_outputed;          unsigned char   *charcells_outputed;    /*  text  */
96            unsigned char   *charcells_drawn;       /*  framebuffer  */
97    
98          /*  Graphics:  */          /*  Graphics:  */
99          int             graphics_mode;          int             graphics_mode;
100          int             bits_per_pixel;          int             bits_per_pixel;
101          unsigned char   *gfx_mem;          unsigned char   *gfx_mem;
102          size_t          gfx_mem_size;          uint32_t        gfx_mem_size;
103    
104          /*  Registers:  */          /*  Registers:  */
105          int             attribute_state;        /*  0 or 1  */          int             attribute_state;        /*  0 or 1  */
# Line 138  struct vga_data { Line 137  struct vga_data {
137          int             cursor_y;          int             cursor_y;
138    
139          int             modified;          int             modified;
140            int             palette_modified;
141          int             update_x1;          int             update_x1;
142          int             update_y1;          int             update_y1;
143          int             update_x2;          int             update_x2;
# Line 146  struct vga_data { Line 146  struct vga_data {
146    
147    
148  /*  /*
149     *  recalc_cursor_position():
150     *
151     *  Should be called whenever the cursor location _or_ the display
152     *  base has been changed.
153     */
154    static void recalc_cursor_position(struct vga_data *d)
155    {
156            int base = (d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
157                + d->crtc_reg[VGA_CRTC_START_ADDR_LOW];
158            int ofs = d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_HIGH] * 256 +
159                d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_LOW];
160            ofs -= base;
161            d->cursor_x = ofs % d->max_x;
162            d->cursor_y = ofs / d->max_x;
163    }
164    
165    
166    /*
167   *  register_reset():   *  register_reset():
168   *   *
169   *  Resets many registers to sane values.   *  Resets many registers to sane values.
170   */   */
171  static void register_reset(struct vga_data *d)  static void register_reset(struct vga_data *d)
172  {  {
173          /*  Home cursor:  */          /*  Home cursor and start at the top:  */
         d->cursor_x = d->cursor_y = 0;  
174          d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_HIGH] =          d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_HIGH] =
175              d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_LOW] = 0;              d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_LOW] = 0;
   
176          d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] =          d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] =
177              d->crtc_reg[VGA_CRTC_START_ADDR_LOW] = 0;              d->crtc_reg[VGA_CRTC_START_ADDR_LOW] = 0;
178    
179            recalc_cursor_position(d);
180    
181          /*  Reset cursor scanline stuff:  */          /*  Reset cursor scanline stuff:  */
182          d->crtc_reg[VGA_CRTC_CURSOR_SCANLINE_START] = d->font_height - 4;          d->crtc_reg[VGA_CRTC_CURSOR_SCANLINE_START] = d->font_height - 2;
183          d->crtc_reg[VGA_CRTC_CURSOR_SCANLINE_END] = d->font_height - 2;          d->crtc_reg[VGA_CRTC_CURSOR_SCANLINE_END] = d->font_height - 1;
184    
185          d->sequencer_reg[VGA_SEQ_MAP_MASK] = 0x0f;          d->sequencer_reg[VGA_SEQ_MAP_MASK] = 0x0f;
186          d->graphcontr_reg[VGA_GRAPHCONTR_MASK] = 0xff;          d->graphcontr_reg[VGA_GRAPHCONTR_MASK] = 0xff;
# Line 190  static void reset_palette(struct vga_dat Line 208  static void reset_palette(struct vga_dat
208          for (i=16; i<256; i++)          for (i=16; i<256; i++)
209                  d->fb->rgb_palette[i*3 + 0] = d->fb->rgb_palette[i*3 + 1] =                  d->fb->rgb_palette[i*3 + 0] = d->fb->rgb_palette[i*3 + 1] =
210                      d->fb->rgb_palette[i*3 + 2] = (i & 15) * 4;                      d->fb->rgb_palette[i*3 + 2] = (i & 15) * 4;
211            d->palette_modified = 1;
212          i = 0;          i = 0;
213    
214          if (grayscale) {          if (grayscale) {
# Line 232  static void reset_palette(struct vga_dat Line 250  static void reset_palette(struct vga_dat
250  /*  /*
251   *  vga_update_textmode():   *  vga_update_textmode():
252   *   *
253   *  Called from vga_update() when use_x11 is false. This causes modified   *  Called from vga_update() when x11 in_use is false. This causes modified
254   *  character cells to be "simulated" by outputing ANSI escape sequences   *  character cells to be "simulated" by outputing ANSI escape sequences
255   *  that draw the characters in a terminal window instead.   *  that draw the characters in a terminal window instead.
256   */   */
# Line 260  static void vga_update_textmode(struct m Line 278  static void vga_update_textmode(struct m
278                  d->charcells_outputed[i+1] = d->charcells[base+i+1];                  d->charcells_outputed[i+1] = d->charcells[base+i+1];
279    
280                  if (!printed_last || x == 0) {                  if (!printed_last || x == 0) {
281                          sprintf(s, "\033[%i;%iH", y + 1, x + 1);                          snprintf(s, sizeof(s), "\033[%i;%iH", y + 1, x + 1);
282                          c_putstr(d, s);                          c_putstr(d, s);
283                  }                  }
284                  if (oldcolor < 0 || (bg<<4)+fg != oldcolor || !printed_last) {                  if (oldcolor < 0 || (bg<<4)+fg != oldcolor || !printed_last) {
285                          sprintf(s, "\033[0;"); c_putstr(d, s);                          snprintf(s, sizeof(s), "\033[0;"); c_putstr(d, s);
286    
287                          switch (fg & 7) {                          switch (fg & 7) {
288                          case 0: c_putstr(d, "30"); break;                          case 0: c_putstr(d, "30"); break;
# Line 301  static void vga_update_textmode(struct m Line 319  static void vga_update_textmode(struct m
319          }          }
320    
321          /*  Restore the terminal's cursor position:  */          /*  Restore the terminal's cursor position:  */
322          sprintf(s, "\033[%i;%iH", d->cursor_y + 1, d->cursor_x + 1);          snprintf(s, sizeof(s), "\033[%i;%iH", d->cursor_y + 1, d->cursor_x + 1);
323          c_putstr(d, s);          c_putstr(d, s);
324  }  }
325    
# Line 343  static void vga_update_graphics(struct m Line 361  static void vga_update_graphics(struct m
361                          }                          }
362                          for (iy=y*ry; iy<(y+1)*ry; iy++)                          for (iy=y*ry; iy<(y+1)*ry; iy++)
363                                  for (ix=x*rx; ix<(x+1)*rx; ix++) {                                  for (ix=x*rx; ix<(x+1)*rx; ix++) {
364                                          int addr2 = (d->fb_max_x * iy + ix) * 3;                                          uint32_t addr2 = (d->fb_max_x * iy
365                                                + ix) * 3;
366                                          if (addr2 < d->fb_size)                                          if (addr2 < d->fb_size)
367                                                  dev_fb_access(machine->cpus[0],                                                  dev_fb_access(machine->cpus[0],
368                                                      machine->memory, addr2,                                                      machine->memory, addr2,
# Line 364  static void vga_update_graphics(struct m Line 383  static void vga_update_graphics(struct m
383  static void vga_update_text(struct machine *machine, struct vga_data *d,  static void vga_update_text(struct machine *machine, struct vga_data *d,
384          int x1, int y1, int x2, int y2)          int x1, int y1, int x2, int y2)
385  {  {
386          int fg, bg, i, x,y, subx, line, start, end, base;          int fg, bg, x,y, subx, line;
387            size_t i, start, end, base;
388          int font_size = d->font_height;          int font_size = d->font_height;
389          int font_width = d->font_width;          int font_width = d->font_width;
390          unsigned char *pal = d->fb->rgb_palette;          unsigned char *pal = d->fb->rgb_palette;
391    
392            if (d->pixel_repx * font_width > 8*8) {
393                    fatal("[ too large font ]\n");
394                    return;
395            }
396    
397          /*  Hm... I'm still using the old start..end code:  */          /*  Hm... I'm still using the old start..end code:  */
398          start = (d->max_x * y1 + x1) * 2;          start = (d->max_x * y1 + x1) * 2;
399          end   = (d->max_x * y2 + x2) * 2;          end   = (d->max_x * y2 + x2) * 2;
# Line 382  static void vga_update_text(struct machi Line 407  static void vga_update_text(struct machi
407          base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)          base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
408              + d->crtc_reg[VGA_CRTC_START_ADDR_LOW]) * 2;              + d->crtc_reg[VGA_CRTC_START_ADDR_LOW]) * 2;
409    
410          if (!machine->use_x11)          if (!machine->x11_md.in_use)
411                  vga_update_textmode(machine, d, base, start, end);                  vga_update_textmode(machine, d, base, start, end);
412    
413          for (i=start; i<=end; i+=2) {          for (i=start; i<=end; i+=2) {
414                  unsigned char ch = d->charcells[i + base];                  unsigned char ch = d->charcells[i + base];
415    
416                    if (!d->palette_modified && d->charcells_drawn[i] == ch &&
417                        d->charcells_drawn[i+1] == d->charcells[i+base+1])
418                            continue;
419    
420                    d->charcells_drawn[i] = ch;
421                    d->charcells_drawn[i+1] = d->charcells[i + base + 1];
422    
423                  fg = d->charcells[i+base + 1] & 15;                  fg = d->charcells[i+base + 1] & 15;
424                  bg = (d->charcells[i+base + 1] >> 4) & 7;                  bg = (d->charcells[i+base + 1] >> 4) & 7;
425    
# Line 400  static void vga_update_text(struct machi Line 433  static void vga_update_text(struct machi
433    
434                  /*  Draw the character:  */                  /*  Draw the character:  */
435                  for (line = 0; line < font_size; line++) {                  for (line = 0; line < font_size; line++) {
436                            /*  hardcoded for max 8 scaleup... :-)  */
437                            unsigned char rgb_line[3 * 8 * 8];
438                            int iy;
439    
440                          for (subx = 0; subx < font_width; subx++) {                          for (subx = 0; subx < font_width; subx++) {
441                                  int ix, iy, color_index;                                  int ix, color_index;
442    
443                                  if (d->use_palette_per_line) {                                  if (d->use_palette_per_line) {
444                                          int sline = d->pixel_repy * (line+y);                                          int sline = d->pixel_repy * (line+y);
# Line 418  static void vga_update_text(struct machi Line 455  static void vga_update_text(struct machi
455                                  else                                  else
456                                          color_index = bg;                                          color_index = bg;
457    
458                                  for (iy=0; iy<d->pixel_repy; iy++)                                  for (ix=0; ix<d->pixel_repx; ix++)
459                                      for (ix=0; ix<d->pixel_repx; ix++) {                                          memcpy(rgb_line + (subx*d->pixel_repx +
460                                          int addr = (d->fb_max_x* (d->pixel_repy                                              ix) * 3, &pal[color_index * 3], 3);
461                                              * (line+y) + iy) + (x+subx) *                          }
                                             d->pixel_repx + ix) * 3;  
462    
463                                          if (addr >= d->fb_size)                          for (iy=0; iy<d->pixel_repy; iy++) {
464                                                  continue;                                  uint32_t addr = (d->fb_max_x * (d->pixel_repy *
465                                          dev_fb_access(machine->cpus[0],                                      (line+y) + iy) + x * d->pixel_repx) * 3;
466                                              machine->memory, addr,                                  if (addr >= d->fb_size)
467                                              &pal[color_index * 3], 3,                                          continue;
468                                              MEM_WRITE, d->fb);                                  dev_fb_access(machine->cpus[0],
469                                      }                                      machine->memory, addr, rgb_line,
470                                        3 * machine->x11_md.scaleup * font_width,
471                                        MEM_WRITE, d->fb);
472                          }                          }
473                  }                  }
474          }          }
# Line 465  static void vga_update_cursor(struct mac Line 503  static void vga_update_cursor(struct mac
503  }  }
504    
505    
506  /*  DEVICE_TICK(vga)
  *  dev_vga_tick():  
  */  
 void dev_vga_tick(struct cpu *cpu, void *extra)  
507  {  {
508          struct vga_data *d = extra;          struct vga_data *d = extra;
509          uint64_t low = (uint64_t)-1, high;          int64_t low = -1, high;
510    
511          vga_update_cursor(cpu->machine, d);          vga_update_cursor(cpu->machine, d);
512    
513          /*  TODO: text vs graphics tick?  */          /*  TODO: text vs graphics tick?  */
514          memory_device_bintrans_access(cpu, cpu->mem, extra, &low, &high);          memory_device_dyntrans_access(cpu, cpu->mem, extra,
515                (uint64_t *) &low, (uint64_t *) &high);
516    
517          if ((int64_t)low != -1) {          if (low != -1) {
518                  debug("[ dev_vga_tick: bintrans access, %llx .. %llx ]\n",                  int base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
519                      (long long)low, (long long)high);                      + d->crtc_reg[VGA_CRTC_START_ADDR_LOW]) * 2;
520                    int new_u_y1, new_u_y2;
521                    debug("[ dev_vga_tick: dyntrans access, %"PRIx64" .. %"
522                        PRIx64" ]\n", (uint64_t) low, (uint64_t) high);
523                    low -= base;
524                    high -= base;
525                  d->update_x1 = 0;                  d->update_x1 = 0;
526                  d->update_x2 = d->max_x - 1;                  d->update_x2 = d->max_x - 1;
527                  d->update_y1 = (low/2) / d->max_x;                  new_u_y1 = (low/2) / d->max_x;
528                  d->update_y2 = ((high/2) / d->max_x) + 1;                  new_u_y2 = ((high/2) / d->max_x) + 1;
529                    if (new_u_y1 < d->update_y1)
530                            d->update_y1 = new_u_y1;
531                    if (new_u_y2 > d->update_y2)
532                            d->update_y2 = new_u_y2;
533                    if (d->update_y1 < 0)
534                            d->update_y1 = 0;
535                  if (d->update_y2 >= d->max_y)                  if (d->update_y2 >= d->max_y)
536                          d->update_y2 = d->max_y - 1;                          d->update_y2 = d->max_y - 1;
537                  d->modified = 1;                  d->modified = 1;
# Line 509  void dev_vga_tick(struct cpu *cpu, void Line 556  void dev_vga_tick(struct cpu *cpu, void
556                  }                  }
557          }          }
558    
559          if (!cpu->machine->use_x11) {          if (!cpu->machine->x11_md.in_use) {
560                  /*  NOTE: 2 > 0, so this only updates the cursor, no                  /*  NOTE: 2 > 0, so this only updates the cursor, no
561                      character cells.  */                      character cells.  */
562                  vga_update_textmode(cpu->machine, d, 0, 2, 0);                  vga_update_textmode(cpu->machine, d, 0, 2, 0);
# Line 523  void dev_vga_tick(struct cpu *cpu, void Line 570  void dev_vga_tick(struct cpu *cpu, void
570                          vga_update_graphics(cpu->machine, d, d->update_x1,                          vga_update_graphics(cpu->machine, d, d->update_x1,
571                              d->update_y1, d->update_x2, d->update_y2);                              d->update_y1, d->update_x2, d->update_y2);
572    
573                    d->palette_modified = 0;
574                  d->modified = 0;                  d->modified = 0;
575                  d->update_x1 = 999999;                  d->update_x1 = 999999;
576                  d->update_x2 = -1;                  d->update_x2 = -1;
# Line 536  void dev_vga_tick(struct cpu *cpu, void Line 584  void dev_vga_tick(struct cpu *cpu, void
584    
585    
586  /*  /*
  *  vga_graphics_access():  
  *  
587   *  Reads and writes to the VGA video memory (pixels).   *  Reads and writes to the VGA video memory (pixels).
588   */   */
589  int dev_vga_graphics_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(vga_graphics)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
590  {  {
591          struct vga_data *d = extra;          struct vga_data *d = extra;
592          int i,j, x=0, y=0, x2=0, y2=0, modified = 0;          int j, x=0, y=0, x2=0, y2=0, modified = 0;
593            size_t i;
594    
595          if (relative_addr + len >= GFX_ADDR_WINDOW)          if (relative_addr + len >= GFX_ADDR_WINDOW)
596                  return 0;                  return 0;
# Line 582  int dev_vga_graphics_access(struct cpu * Line 627  int dev_vga_graphics_access(struct cpu *
627                                          int b = data[i] & pixelmask;                                          int b = data[i] & pixelmask;
628                                          int m = d->sequencer_reg[                                          int m = d->sequencer_reg[
629                                              VGA_SEQ_MAP_MASK] & 0x0f;                                              VGA_SEQ_MAP_MASK] & 0x0f;
630                                          int addr = (y * d->max_x + x + i*8 + j)                                          uint32_t addr = (y * d->max_x + x +
631                                              * d->bits_per_pixel / 8;                                              i*8 + j) * d->bits_per_pixel / 8;
632                                          unsigned char byte;                                          unsigned char byte;
633                                          if (!(d->graphcontr_reg[                                          if (!(d->graphcontr_reg[
634                                              VGA_GRAPHCONTR_MASK] & pixelmask))                                              VGA_GRAPHCONTR_MASK] & pixelmask))
# Line 634  int dev_vga_graphics_access(struct cpu * Line 679  int dev_vga_graphics_access(struct cpu *
679    
680    
681  /*  /*
682   *  dev_vga_access():   *  Reads and writes the VGA video memory (charcells).
  *  
  *  Reads and writes to the VGA video memory (charcells).  
683   */   */
684  int dev_vga_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr,  DEVICE_ACCESS(vga)
         unsigned char *data, size_t len, int writeflag, void *extra)  
685  {  {
686          struct vga_data *d = extra;          struct vga_data *d = extra;
687          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
688          int i, x, y, x2, y2, r, base;          int x, y, x2, y2, r, base;
689            size_t i;
690    
691          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
692                    idata = memory_readmax64(cpu, data, len);
693    
694          base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)          base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
695              + d->crtc_reg[VGA_CRTC_START_ADDR_LOW]) * 2;              + d->crtc_reg[VGA_CRTC_START_ADDR_LOW]) * 2;
# Line 655  int dev_vga_access(struct cpu *cpu, stru Line 699  int dev_vga_access(struct cpu *cpu, stru
699          y2 = (r+len-1) / (d->max_x * 2);          y2 = (r+len-1) / (d->max_x * 2);
700          x2 = ((r+len-1)/2) % d->max_x;          x2 = ((r+len-1)/2) % d->max_x;
701    
702          if (relative_addr < d->charcells_size) {          if (relative_addr + len - 1 < d->charcells_size) {
703                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
704                          for (i=0; i<len; i++) {                          for (i=0; i<len; i++) {
705                                  int old = d->charcells[relative_addr + i];                                  int old = d->charcells[relative_addr + i];
# Line 712  int dev_vga_access(struct cpu *cpu, stru Line 756  int dev_vga_access(struct cpu *cpu, stru
756  static void vga_crtc_reg_write(struct machine *machine, struct vga_data *d,  static void vga_crtc_reg_write(struct machine *machine, struct vga_data *d,
757          int regnr, int idata)          int regnr, int idata)
758  {  {
759          int ofs, grayscale;          int i, grayscale;
760    
761          switch (regnr) {          switch (regnr) {
762          case VGA_CRTC_CURSOR_SCANLINE_START:            /*  0x0a  */          case VGA_CRTC_CURSOR_SCANLINE_START:            /*  0x0a  */
# Line 725  static void vga_crtc_reg_write(struct ma Line 769  static void vga_crtc_reg_write(struct ma
769                  d->update_y1 = 0;                  d->update_y1 = 0;
770                  d->update_y2 = d->max_y - 1;                  d->update_y2 = d->max_y - 1;
771                  d->modified = 1;                  d->modified = 1;
772                    recalc_cursor_position(d);
773                  break;                  break;
774          case VGA_CRTC_CURSOR_LOCATION_HIGH:             /*  0x0e  */          case VGA_CRTC_CURSOR_LOCATION_HIGH:             /*  0x0e  */
775          case VGA_CRTC_CURSOR_LOCATION_LOW:              /*  0x0f  */          case VGA_CRTC_CURSOR_LOCATION_LOW:              /*  0x0f  */
776                  ofs = d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_HIGH] * 256 +                  recalc_cursor_position(d);
                     d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_LOW];  
                 d->cursor_x = ofs % d->max_x;  
                 d->cursor_y = ofs / d->max_x;  
777                  break;                  break;
778          case 0xff:          case 0xff:
779                  grayscale = 0;                  grayscale = 0;
# Line 741  static void vga_crtc_reg_write(struct ma Line 783  static void vga_crtc_reg_write(struct ma
783                  case 0x01:                  case 0x01:
784                          d->cur_mode = MODE_CHARCELL;                          d->cur_mode = MODE_CHARCELL;
785                          d->max_x = 40; d->max_y = 25;                          d->max_x = 40; d->max_y = 25;
786                          d->pixel_repx = 2; d->pixel_repy = 1;                          d->pixel_repx = machine->x11_md.scaleup * 2;
787                            d->pixel_repy = machine->x11_md.scaleup;
788                          d->font_width = 8;                          d->font_width = 8;
789                          d->font_height = 16;                          d->font_height = 16;
790                          d->font = font8x16;                          d->font = font8x16;
# Line 751  static void vga_crtc_reg_write(struct ma Line 794  static void vga_crtc_reg_write(struct ma
794                  case 0x03:                  case 0x03:
795                          d->cur_mode = MODE_CHARCELL;                          d->cur_mode = MODE_CHARCELL;
796                          d->max_x = 80; d->max_y = 25;                          d->max_x = 80; d->max_y = 25;
797                          d->pixel_repx = d->pixel_repy = 1;                          d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
798                          d->font_width = 8;                          d->font_width = 8;
799                          d->font_height = 16;                          d->font_height = 16;
800                          d->font = font8x16;                          d->font = font8x16;
# Line 761  static void vga_crtc_reg_write(struct ma Line 804  static void vga_crtc_reg_write(struct ma
804                          d->max_x = 160; d->max_y = 200;                          d->max_x = 160; d->max_y = 200;
805                          d->graphics_mode = GRAPHICS_MODE_4BIT;                          d->graphics_mode = GRAPHICS_MODE_4BIT;
806                          d->bits_per_pixel = 4;                          d->bits_per_pixel = 4;
807                          d->pixel_repx = 4;                          d->pixel_repx = 4 * machine->x11_md.scaleup;
808                          d->pixel_repy = 2;                          d->pixel_repy = 2 * machine->x11_md.scaleup;
809                          break;                          break;
810                  case 0x09:                  case 0x09:
811                  case 0x0d:                  case 0x0d:
# Line 770  static void vga_crtc_reg_write(struct ma Line 813  static void vga_crtc_reg_write(struct ma
813                          d->max_x = 320; d->max_y = 200;                          d->max_x = 320; d->max_y = 200;
814                          d->graphics_mode = GRAPHICS_MODE_4BIT;                          d->graphics_mode = GRAPHICS_MODE_4BIT;
815                          d->bits_per_pixel = 4;                          d->bits_per_pixel = 4;
816                          d->pixel_repx = d->pixel_repy = 2;                          d->pixel_repx = d->pixel_repy =
817                                2 * machine->x11_md.scaleup;
818                          break;                          break;
819                  case 0x0e:                  case 0x0e:
820                          d->cur_mode = MODE_GRAPHICS;                          d->cur_mode = MODE_GRAPHICS;
821                          d->max_x = 640; d->max_y = 200;                          d->max_x = 640; d->max_y = 200;
822                          d->graphics_mode = GRAPHICS_MODE_4BIT;                          d->graphics_mode = GRAPHICS_MODE_4BIT;
823                          d->bits_per_pixel = 4;                          d->bits_per_pixel = 4;
824                          d->pixel_repx = 1;                          d->pixel_repx = machine->x11_md.scaleup;
825                          d->pixel_repy = 2;                          d->pixel_repy = machine->x11_md.scaleup * 2;
826                          break;                          break;
827                  case 0x10:                  case 0x10:
828                          d->cur_mode = MODE_GRAPHICS;                          d->cur_mode = MODE_GRAPHICS;
829                          d->max_x = 640; d->max_y = 350;                          d->max_x = 640; d->max_y = 350;
830                          d->graphics_mode = GRAPHICS_MODE_4BIT;                          d->graphics_mode = GRAPHICS_MODE_4BIT;
831                          d->bits_per_pixel = 4;                          d->bits_per_pixel = 4;
832                          d->pixel_repx = d->pixel_repy = 1;                          d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
833                          break;                          break;
834                  case 0x12:                  case 0x12:
835                          d->cur_mode = MODE_GRAPHICS;                          d->cur_mode = MODE_GRAPHICS;
836                          d->max_x = 640; d->max_y = 480;                          d->max_x = 640; d->max_y = 480;
837                          d->graphics_mode = GRAPHICS_MODE_4BIT;                          d->graphics_mode = GRAPHICS_MODE_4BIT;
838                          d->bits_per_pixel = 4;                          d->bits_per_pixel = 4;
839                          d->pixel_repx = d->pixel_repy = 1;                          d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
840                          break;                          break;
841                  case 0x13:                  case 0x13:
842                          d->cur_mode = MODE_GRAPHICS;                          d->cur_mode = MODE_GRAPHICS;
843                          d->max_x = 320; d->max_y = 200;                          d->max_x = 320; d->max_y = 200;
844                          d->graphics_mode = GRAPHICS_MODE_8BIT;                          d->graphics_mode = GRAPHICS_MODE_8BIT;
845                          d->bits_per_pixel = 8;                          d->bits_per_pixel = 8;
846                          d->pixel_repx = d->pixel_repy = 2;                          d->pixel_repx = d->pixel_repy =
847                                2 * machine->x11_md.scaleup;
848                          break;                          break;
849                  default:                  default:
850                          fatal("TODO! video mode change hack (mode 0x%02x)\n",                          fatal("TODO! video mode change hack (mode 0x%02x)\n",
# Line 820  static void vga_crtc_reg_write(struct ma Line 865  static void vga_crtc_reg_write(struct ma
865                               d->max_y * d->pixel_repy * 3;                               d->max_y * d->pixel_repy * 3;
866                  }                  }
867    
868                    for (i=0; i<machine->ncpus; i++)
869                            machine->cpus[i]->invalidate_translation_caches(
870                                machine->cpus[i], 0, INVALIDATE_ALL);
871    
872                  if (d->gfx_mem != NULL)                  if (d->gfx_mem != NULL)
873                          free(d->gfx_mem);                          free(d->gfx_mem);
874                  d->gfx_mem_size = 1;                  d->gfx_mem_size = 1;
875                  if (d->cur_mode == MODE_GRAPHICS)                  if (d->cur_mode == MODE_GRAPHICS)
876                          d->gfx_mem_size = d->max_x * d->max_y /                          d->gfx_mem_size = d->max_x * d->max_y /
877                              (d->graphics_mode == GRAPHICS_MODE_8BIT? 1 : 2);                              (d->graphics_mode == GRAPHICS_MODE_8BIT? 1 : 2);
878                  d->gfx_mem = malloc(d->gfx_mem_size);  
879                    CHECK_ALLOCATION(d->gfx_mem = malloc(d->gfx_mem_size));
880    
881                  /*  Clear screen and reset the palette:  */                  /*  Clear screen and reset the palette:  */
882                  memset(d->charcells_outputed, 0, d->charcells_size);                  memset(d->charcells_outputed, 0, d->charcells_size);
883                    memset(d->charcells_drawn, 0, d->charcells_size);
884                  memset(d->gfx_mem, 0, d->gfx_mem_size);                  memset(d->gfx_mem, 0, d->gfx_mem_size);
885                  d->update_x1 = 0;                  d->update_x1 = 0;
886                  d->update_x2 = d->max_x - 1;                  d->update_x2 = d->max_x - 1;
# Line 854  static void vga_sequencer_reg_write(stru Line 905  static void vga_sequencer_reg_write(stru
905          int regnr, int idata)          int regnr, int idata)
906  {  {
907          switch (regnr) {          switch (regnr) {
908          case VGA_SEQ_MAP_MASK:          /*  0x02  */          case VGA_SEQ_RESET:
909            case VGA_SEQ_MAP_MASK:
910            case VGA_SEQ_SEQUENCER_MEMORY_MODE:
911                    debug("[ vga_sequencer_reg_write: select %i: TODO ]\n", regnr);
912                  break;                  break;
913          default:fatal("[ vga_sequencer_reg_write: select %i ]\n", regnr);          default:fatal("[ vga_sequencer_reg_write: select %i ]\n", regnr);
914                  /*  cpu->running = 0;  */                  /*  cpu->running = 0;  */
# Line 871  static void vga_graphcontr_reg_write(str Line 925  static void vga_graphcontr_reg_write(str
925          struct vga_data *d, int regnr, int idata)          struct vga_data *d, int regnr, int idata)
926  {  {
927          switch (regnr) {          switch (regnr) {
928          case VGA_GRAPHCONTR_MASK:               /*  0x08  */          case VGA_GRAPHCONTR_READMAPSELECT:
929            case VGA_GRAPHCONTR_GRAPHICSMODE:
930            case VGA_GRAPHCONTR_MISC:
931            case VGA_GRAPHCONTR_MASK:
932                    debug("[ vga_graphcontr_reg_write: select %i: TODO ]\n", regnr);
933                  break;                  break;
934          default:fatal("[ vga_graphcontr_reg_write: select %i ]\n", regnr);          default:fatal("[ vga_graphcontr_reg_write: select %i ]\n", regnr);
935                  /*  cpu->running = 0;  */                  /*  cpu->running = 0;  */
# Line 887  static void vga_graphcontr_reg_write(str Line 945  static void vga_graphcontr_reg_write(str
945  static void vga_attribute_reg_write(struct machine *machine, struct vga_data *d,  static void vga_attribute_reg_write(struct machine *machine, struct vga_data *d,
946          int regnr, int idata)          int regnr, int idata)
947  {  {
948            /*  0-15 are palette registers: TODO  */
949            if (regnr >= 0 && regnr <= 0xf)
950                    return;
951    
952          switch (regnr) {          switch (regnr) {
953          default:fatal("[ vga_attribute_reg_write: select %i ]\n", regnr);          default:fatal("[ vga_attribute_reg_write: select %i ]\n", regnr);
954                  /*  cpu->running = 0;  */                  /*  cpu->running = 0;  */
# Line 899  static void vga_attribute_reg_write(stru Line 961  static void vga_attribute_reg_write(stru
961   *   *
962   *  Reads and writes of the VGA control registers.   *  Reads and writes of the VGA control registers.
963   */   */
964  int dev_vga_ctrl_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(vga_ctrl)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
965  {  {
966          struct vga_data *d = extra;          struct vga_data *d = extra;
967          int i;          size_t i;
968          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
969    
970          for (i=0; i<len; i++) {          for (i=0; i<len; i++) {
# Line 978  int dev_vga_ctrl_access(struct cpu *cpu, Line 1038  int dev_vga_ctrl_access(struct cpu *cpu,
1038                                  d->palette_read_index = idata;                                  d->palette_read_index = idata;
1039                                  d->palette_read_subindex = 0;                                  d->palette_read_subindex = 0;
1040                          } else {                          } else {
1041                                  fatal("[ dev_vga: WARNING: Read from "                                  debug("[ dev_vga: WARNING: Read from "
1042                                      "VGA_DAC_ADDR_READ? TODO ]\n");                                      "VGA_DAC_ADDR_READ? TODO ]\n");
1043                                  /*  TODO  */                                  /*  TODO  */
1044                          }                          }
# Line 1009  int dev_vga_ctrl_access(struct cpu *cpu, Line 1069  int dev_vga_ctrl_access(struct cpu *cpu,
1069                                      palette changed:  */                                      palette changed:  */
1070                                  if (new != old) {                                  if (new != old) {
1071                                          d->modified = 1;                                          d->modified = 1;
1072                                            d->palette_modified = 1;
1073                                          d->update_x1 = d->update_y1 = 0;                                          d->update_x1 = d->update_y1 = 0;
1074                                          d->update_x2 = d->max_x - 1;                                          d->update_x2 = d->max_x - 1;
1075                                          d->update_y2 = d->max_y - 1;                                          d->update_y2 = d->max_y - 1;
# Line 1078  int dev_vga_ctrl_access(struct cpu *cpu, Line 1139  int dev_vga_ctrl_access(struct cpu *cpu,
1139                          if ((d->current_retrace_line & 7) == 7) {                          if ((d->current_retrace_line & 7) == 7) {
1140                                  if (d->retrace_palette == NULL &&                                  if (d->retrace_palette == NULL &&
1141                                      d->n_is1_reads > N_IS1_READ_THRESHOLD) {                                      d->n_is1_reads > N_IS1_READ_THRESHOLD) {
1142                                          d->retrace_palette = malloc(                                          CHECK_ALLOCATION(d->retrace_palette =
1143                                              MAX_RETRACE_SCANLINES * 256*3);                                              malloc(
1144                                          if (d->retrace_palette == NULL) {                                              MAX_RETRACE_SCANLINES * 256*3));
                                                 fatal("out of memory\n");  
                                                 exit(1);  
                                         }  
1145                                  }                                  }
1146                                  if (d->retrace_palette != NULL)                                  if (d->retrace_palette != NULL)
1147                                          memcpy(d->retrace_palette + (d->                                          memcpy(d->retrace_palette + (d->
# Line 1103  int dev_vga_ctrl_access(struct cpu *cpu, Line 1161  int dev_vga_ctrl_access(struct cpu *cpu,
1161    
1162                  default:                  default:
1163                          if (writeflag==MEM_READ) {                          if (writeflag==MEM_READ) {
1164                                  fatal("[ vga_ctrl: read from 0x%08lx ]\n",                                  debug("[ vga_ctrl: read from 0x%08lx ]\n",
1165                                      (long)relative_addr);                                      (long)relative_addr);
1166                          } else {                          } else {
1167                                  fatal("[ vga_ctrl: write to  0x%08lx: 0x%08x"                                  debug("[ vga_ctrl: write to  0x%08lx: 0x%08x"
1168                                      " ]\n", (long)relative_addr, (int)idata);                                      " ]\n", (long)relative_addr, (int)idata);
1169                          }                          }
1170                  }                  }
# Line 1132  void dev_vga_init(struct machine *machin Line 1190  void dev_vga_init(struct machine *machin
1190          uint64_t videomem_base, uint64_t control_base, char *name)          uint64_t videomem_base, uint64_t control_base, char *name)
1191  {  {
1192          struct vga_data *d;          struct vga_data *d;
1193          int i, x,y, tmpi;          size_t allocsize, i;
         size_t allocsize;  
1194    
1195          d = malloc(sizeof(struct vga_data));          CHECK_ALLOCATION(d = malloc(sizeof(struct vga_data)));
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
1196          memset(d, 0, sizeof(struct vga_data));          memset(d, 0, sizeof(struct vga_data));
1197    
1198          d->console_handle = console_start_slave(machine, name);          d->console_handle = console_start_slave(machine, "vga",
1199                CONSOLE_OUTPUT_ONLY);
1200    
1201          d->videomem_base  = videomem_base;          d->videomem_base  = videomem_base;
1202          d->control_base   = control_base;          d->control_base   = control_base;
1203          d->max_x          = 80;          d->max_x          = 80;
1204          d->max_y          = 25;          d->max_y          = 25;
         d->pixel_repx     = 1;  
         d->pixel_repy     = 1;  
1205          d->cur_mode       = MODE_CHARCELL;          d->cur_mode       = MODE_CHARCELL;
1206          d->crtc_reg[0xff] = 0x03;          d->crtc_reg[0xff] = 0x03;
1207          d->charcells_size = d->max_x * VGA_MEM_MAXY * 2;          d->charcells_size = 0x8000;
1208          d->gfx_mem_size   = 1;  /*  Nothing, as we start in text mode  */          d->gfx_mem_size   = 1;  /*  Nothing, as we start in text mode  */
1209            d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
1210    
1211          /*  Allocate in 4KB pages, to make it possible to use bintrans:  */          /*  Allocate in full pages, to make it possible to use dyntrans:  */
1212          allocsize = ((d->charcells_size - 1) | 0xfff) + 1;          allocsize = ((d->charcells_size-1) | (machine->arch_pagesize-1)) + 1;
1213          d->charcells = malloc(d->charcells_size);          CHECK_ALLOCATION(d->charcells = malloc(d->charcells_size));
1214          d->charcells_outputed = malloc(d->charcells_size);          CHECK_ALLOCATION(d->charcells_outputed = malloc(d->charcells_size));
1215          d->gfx_mem = malloc(d->gfx_mem_size);          CHECK_ALLOCATION(d->charcells_drawn = malloc(d->charcells_size));
1216          if (d->charcells == NULL || d->charcells_outputed == NULL ||          CHECK_ALLOCATION(d->gfx_mem = malloc(d->gfx_mem_size));
1217              d->gfx_mem == NULL) {  
1218                  fprintf(stderr, "out of memory in dev_vga_init()\n");          memset(d->charcells_drawn, 0, d->charcells_size);
1219                  exit(1);  
1220          }          for (i=0; i<d->charcells_size; i+=2) {
1221                    d->charcells[i] = ' ';
1222          for (y=0; y<VGA_MEM_MAXY; y++) {                  d->charcells[i+1] = 0x07;  /*  Default color  */
1223                  for (x=0; x<d->max_x; x++) {                  d->charcells_drawn[i] = ' ';
1224                          char ch = ' ';                  d->charcells_drawn[i+1] = 0x07;
                         i = (x + d->max_x * y) * 2;  
                         d->charcells[i] = ch;  
                         d->charcells[i+1] = 0x07;  /*  Default color  */  
                 }  
1225          }          }
1226    
1227          memset(d->charcells_outputed, 0, d->charcells_size);          memset(d->charcells_outputed, 0, d->charcells_size);
# Line 1189  void dev_vga_init(struct machine *machin Line 1238  void dev_vga_init(struct machine *machin
1238                  d->fb_max_y *= d->font_height;                  d->fb_max_y *= d->font_height;
1239          }          }
1240    
1241            memory_device_register(mem, "vga_charcells", videomem_base + 0x18000,
1242                allocsize, dev_vga_access, d, DM_DYNTRANS_OK |
1243                DM_DYNTRANS_WRITE_OK | DM_READS_HAVE_NO_SIDE_EFFECTS,
1244                d->charcells);
1245            memory_device_register(mem, "vga_gfx", videomem_base, GFX_ADDR_WINDOW,
1246                dev_vga_graphics_access, d, DM_DEFAULT |
1247                DM_READS_HAVE_NO_SIDE_EFFECTS, d->gfx_mem);
1248            memory_device_register(mem, "vga_ctrl", control_base,
1249                32, dev_vga_ctrl_access, d, DM_DEFAULT, NULL);
1250    
1251          d->fb = dev_fb_init(machine, mem, VGA_FB_ADDR, VFB_GENERIC,          d->fb = dev_fb_init(machine, mem, VGA_FB_ADDR, VFB_GENERIC,
1252              d->fb_max_x, d->fb_max_y, d->fb_max_x, d->fb_max_y, 24, "VGA", 0);              d->fb_max_x, d->fb_max_y, d->fb_max_x, d->fb_max_y, 24, "VGA");
1253          d->fb_size = d->fb_max_x * d->fb_max_y * 3;          d->fb_size = d->fb_max_x * d->fb_max_y * 3;
1254    
1255          reset_palette(d, 0);          reset_palette(d, 0);
1256    
         /*  MEM_BINTRANS_WRITE_OK  <-- This works with OpenBSD/arc, but not  
             with Windows NT yet. Why? */  
         memory_device_register(mem, "vga_charcells", videomem_base + 0x18000,  
             allocsize, dev_vga_access, d, MEM_BINTRANS_OK |  
             MEM_READING_HAS_NO_SIDE_EFFECTS, d->charcells);  
         memory_device_register(mem, "vga_gfx", videomem_base, GFX_ADDR_WINDOW,  
             dev_vga_graphics_access, d, MEM_DEFAULT |  
             MEM_READING_HAS_NO_SIDE_EFFECTS, d->gfx_mem);  
         memory_device_register(mem, "vga_ctrl", control_base,  
             32, dev_vga_ctrl_access, d, MEM_DEFAULT, NULL);  
   
1257          /*  This will force an initial redraw/resynch:  */          /*  This will force an initial redraw/resynch:  */
1258          d->update_x1 = 0;          d->update_x1 = 0;
1259          d->update_x2 = d->max_x - 1;          d->update_x2 = d->max_x - 1;
# Line 1215  void dev_vga_init(struct machine *machin Line 1263  void dev_vga_init(struct machine *machin
1263    
1264          machine_add_tickfunction(machine, dev_vga_tick, d, VGA_TICK_SHIFT);          machine_add_tickfunction(machine, dev_vga_tick, d, VGA_TICK_SHIFT);
1265    
         vga_update_cursor(machine, d);  
   
         tmpi = d->cursor_y * d->max_x + d->cursor_x;  
   
1266          register_reset(d);          register_reset(d);
1267    
1268            vga_update_cursor(machine, d);
1269  }  }
1270    

Legend:
Removed from v.6  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26