dev_vga.cc Source File

Back to the index.

dev_vga.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2009 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: VGA framebuffer device (charcell and graphics modes)
29  *
30  * It should work with 80x25 and 40x25 text modes, and with a few graphics
31  * modes as long as no fancy VGA features are used.
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #include "console.h"
39 #include "cpu.h"
40 #include "devices.h"
41 #include "machine.h"
42 #include "memory.h"
43 #include "misc.h"
44 
45 #include "../include/vga.h"
46 
47 /* These are generated from binary font files: */
48 #include "fonts/font8x8.cc"
49 #include "fonts/font8x10.cc"
50 #include "fonts/font8x16.cc"
51 
52 
53 /* For videomem -> framebuffer updates: */
54 #define VGA_TICK_SHIFT 18
55 
56 #define MAX_RETRACE_SCANLINES 420
57 #define N_IS1_READ_THRESHOLD 50
58 
59 #define GFX_ADDR_WINDOW 0x18000
60 
61 #define VGA_FB_ADDR 0x1c00000000ULL
62 
63 #define MODE_CHARCELL 1
64 #define MODE_GRAPHICS 2
65 
66 #define GRAPHICS_MODE_8BIT 1
67 #define GRAPHICS_MODE_4BIT 2
68 
69 struct vga_data {
70  uint64_t videomem_base;
71  uint64_t control_base;
72 
73  struct vfb_data *fb;
74  uint32_t fb_size;
75 
76  int fb_max_x; /* pixels */
77  int fb_max_y; /* pixels */
78  int max_x; /* charcells or pixels */
79  int max_y; /* charcells or pixels */
80 
81  /* Selects charcell mode or graphics mode: */
82  int cur_mode;
83 
84  /* Common for text and graphics modes: */
86 
87  /* Textmode: */
90  unsigned char *font;
92  unsigned char *charcells; /* 2 bytes per char */
93  unsigned char *charcells_outputed; /* text */
94  unsigned char *charcells_drawn; /* framebuffer */
95 
96  /* Graphics: */
99  unsigned char *gfx_mem;
100  uint32_t gfx_mem_size;
101 
102  /* Registers: */
103  int attribute_state; /* 0 or 1 */
104  unsigned char attribute_reg_select;
105  unsigned char attribute_reg[256];
106 
107  unsigned char misc_output_reg;
108 
109  unsigned char sequencer_reg_select;
110  unsigned char sequencer_reg[256];
111 
112  unsigned char graphcontr_reg_select;
113  unsigned char graphcontr_reg[256];
114 
115  unsigned char crtc_reg_select;
116  unsigned char crtc_reg[256];
117 
118  unsigned char palette_read_index;
120  unsigned char palette_write_index;
122 
125 
126  /* Palette per scanline during retrace: */
127  unsigned char *retrace_palette;
129  int64_t n_is1_reads;
130 
131  /* Misc.: */
133 
134  int cursor_x;
135  int cursor_y;
136 
137  int modified;
143 };
144 
145 
146 /*
147  * recalc_cursor_position():
148  *
149  * Should be called whenever the cursor location _or_ the display
150  * base has been changed.
151  */
152 static void recalc_cursor_position(struct vga_data *d)
153 {
154  int base = (d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
156  int ofs = d->crtc_reg[VGA_CRTC_CURSOR_LOCATION_HIGH] * 256 +
158  ofs -= base;
159  d->cursor_x = ofs % d->max_x;
160  d->cursor_y = ofs / d->max_x;
161 }
162 
163 
164 /*
165  * register_reset():
166  *
167  * Resets many registers to sane values.
168  */
169 static void register_reset(struct vga_data *d)
170 {
171  /* Home cursor and start at the top: */
176 
177  recalc_cursor_position(d);
178 
179  /* Reset cursor scanline stuff: */
182 
183  d->sequencer_reg[VGA_SEQ_MAP_MASK] = 0x0f;
185 
187  d->n_is1_reads = 0;
188 }
189 
190 
191 static void c_putstr(struct vga_data *d, const char *s)
192 {
193  while (*s)
195 }
196 
197 
198 /*
199  * reset_palette():
200  */
201 static void reset_palette(struct vga_data *d, int grayscale)
202 {
203  int i, r, g, b;
204 
205  /* TODO: default values for entry 16..255? */
206  for (i=16; i<256; i++)
207  d->fb->rgb_palette[i*3 + 0] = d->fb->rgb_palette[i*3 + 1] =
208  d->fb->rgb_palette[i*3 + 2] = (i & 15) * 4;
209  d->palette_modified = 1;
210  i = 0;
211 
212  if (grayscale) {
213  for (r=0; r<2; r++)
214  for (g=0; g<2; g++)
215  for (b=0; b<2; b++) {
216  d->fb->rgb_palette[i + 0] =
217  d->fb->rgb_palette[i + 1] =
218  d->fb->rgb_palette[i + 2] =
219  (r+g+b) * 0xaa / 3;
220  d->fb->rgb_palette[i + 8*3 + 0] =
221  d->fb->rgb_palette[i + 8*3 + 1] =
222  d->fb->rgb_palette[i + 8*3 + 2] =
223  (r+g+b) * 0xaa / 3 + 0x55;
224  i+=3;
225  }
226  return;
227  }
228 
229  for (r=0; r<2; r++)
230  for (g=0; g<2; g++)
231  for (b=0; b<2; b++) {
232  d->fb->rgb_palette[i + 0] = r * 0xaa;
233  d->fb->rgb_palette[i + 1] = g * 0xaa;
234  d->fb->rgb_palette[i + 2] = b * 0xaa;
235  i+=3;
236  }
237  for (r=0; r<2; r++)
238  for (g=0; g<2; g++)
239  for (b=0; b<2; b++) {
240  d->fb->rgb_palette[i + 0] = r * 0xaa + 0x55;
241  d->fb->rgb_palette[i + 1] = g * 0xaa + 0x55;
242  d->fb->rgb_palette[i + 2] = b * 0xaa + 0x55;
243  i+=3;
244  }
245 }
246 
247 
248 /*
249  * vga_update_textmode():
250  *
251  * Called from vga_update() when x11 in_use is false. This causes modified
252  * character cells to be "simulated" by outputing ANSI escape sequences
253  * that draw the characters in a terminal window instead.
254  */
255 static void vga_update_textmode(struct machine *machine,
256  struct vga_data *d, int base, int start, int end)
257 {
258  char s[50];
259  int i, oldcolor = -1, printed_last = 0;
260 
261  for (i=start; i<=end; i+=2) {
262  unsigned char ch = d->charcells[base+i];
263  int fg = d->charcells[base+i+1] & 15;
264  int bg = (d->charcells[base+i+1] >> 4) & 15;
265  /* top bit of bg = blink */
266  int x = (i/2) % d->max_x;
267  int y = (i/2) / d->max_x;
268 
269  if (d->charcells[base+i] == d->charcells_outputed[i] &&
270  d->charcells[base+i+1] == d->charcells_outputed[i+1]) {
271  printed_last = 0;
272  continue;
273  }
274 
275  d->charcells_outputed[i] = d->charcells[base+i];
276  d->charcells_outputed[i+1] = d->charcells[base+i+1];
277 
278  if (!printed_last || x == 0) {
279  snprintf(s, sizeof(s), "\033[%i;%iH", y + 1, x + 1);
280  c_putstr(d, s);
281  }
282  if (oldcolor < 0 || (bg<<4)+fg != oldcolor || !printed_last) {
283  snprintf(s, sizeof(s), "\033[0;"); c_putstr(d, s);
284 
285  switch (fg & 7) {
286  case 0: c_putstr(d, "30"); break;
287  case 1: c_putstr(d, "34"); break;
288  case 2: c_putstr(d, "32"); break;
289  case 3: c_putstr(d, "36"); break;
290  case 4: c_putstr(d, "31"); break;
291  case 5: c_putstr(d, "35"); break;
292  case 6: c_putstr(d, "33"); break;
293  case 7: c_putstr(d, "37"); break;
294  }
295  if (fg & 8)
296  c_putstr(d, ";1");
297  c_putstr(d, ";");
298  switch (bg & 7) {
299  case 0: c_putstr(d, "40"); break;
300  case 1: c_putstr(d, "44"); break;
301  case 2: c_putstr(d, "42"); break;
302  case 3: c_putstr(d, "46"); break;
303  case 4: c_putstr(d, "41"); break;
304  case 5: c_putstr(d, "45"); break;
305  case 6: c_putstr(d, "43"); break;
306  case 7: c_putstr(d, "47"); break;
307  }
308  /* TODO: blink */
309  c_putstr(d, "m");
310  }
311 
312  if (ch >= 0x20 && ch != 127)
314 
315  oldcolor = (bg << 4) + fg;
316  printed_last = 1;
317  }
318 
319  /* Restore the terminal's cursor position: */
320  snprintf(s, sizeof(s), "\033[%i;%iH", d->cursor_y + 1, d->cursor_x + 1);
321  c_putstr(d, s);
322 }
323 
324 
325 /*
326  * vga_update_graphics():
327  *
328  * This function should be called whenever any part of d->gfx_mem[] has
329  * been written to. It will redraw all pixels within the range x1,y1
330  * .. x2,y2 using the right palette.
331  */
332 static void vga_update_graphics(struct machine *machine, struct vga_data *d,
333  int x1, int y1, int x2, int y2)
334 {
335  int x, y, ix, iy, c, rx = d->pixel_repx, ry = d->pixel_repy;
336  unsigned char pixel[3];
337 
338  for (y=y1; y<=y2; y++)
339  for (x=x1; x<=x2; x++) {
340  /* addr is where to read from VGA memory, addr2 is
341  where to write on the 24-bit framebuffer device */
342  int addr = (y * d->max_x + x) * d->bits_per_pixel;
343  switch (d->bits_per_pixel) {
344  case 8: addr >>= 3;
345  c = d->gfx_mem[addr];
346  pixel[0] = d->fb->rgb_palette[c*3+0];
347  pixel[1] = d->fb->rgb_palette[c*3+1];
348  pixel[2] = d->fb->rgb_palette[c*3+2];
349  break;
350  case 4: addr >>= 2;
351  if (addr & 1)
352  c = d->gfx_mem[addr >> 1] >> 4;
353  else
354  c = d->gfx_mem[addr >> 1] & 0xf;
355  pixel[0] = d->fb->rgb_palette[c*3+0];
356  pixel[1] = d->fb->rgb_palette[c*3+1];
357  pixel[2] = d->fb->rgb_palette[c*3+2];
358  break;
359  }
360  for (iy=y*ry; iy<(y+1)*ry; iy++)
361  for (ix=x*rx; ix<(x+1)*rx; ix++) {
362  uint32_t addr2 = (d->fb_max_x * iy
363  + ix) * 3;
364  if (addr2 < d->fb_size)
365  dev_fb_access(machine->cpus[0],
366  machine->memory, addr2,
367  pixel, sizeof(pixel),
368  MEM_WRITE, d->fb);
369  }
370  }
371 }
372 
373 
374 /*
375  * vga_update_text():
376  *
377  * This function should be called whenever any part of d->charcells[] has
378  * been written to. It will redraw all characters within the range x1,y1
379  * .. x2,y2 using the right palette.
380  */
381 static void vga_update_text(struct machine *machine, struct vga_data *d,
382  int x1, int y1, int x2, int y2)
383 {
384  int fg, bg, x,y, subx, line;
385  size_t i, start, end, base;
386  int font_size = d->font_height;
387  int font_width = d->font_width;
388  unsigned char *pal = d->fb->rgb_palette;
389 
390  if (d->pixel_repx * font_width > 8*8) {
391  fatal("[ too large font ]\n");
392  return;
393  }
394 
395  /* Hm... I'm still using the old start..end code: */
396  start = (d->max_x * y1 + x1) * 2;
397  end = (d->max_x * y2 + x2) * 2;
398 
399  start &= ~1;
400  end |= 1;
401 
402  if (end >= d->charcells_size)
403  end = d->charcells_size - 1;
404 
405  base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
407 
408  if (!machine->x11_md.in_use)
409  vga_update_textmode(machine, d, base, start, end);
410 
411  for (i=start; i<=end; i+=2) {
412  unsigned char ch = d->charcells[i + base];
413 
414  if (!d->palette_modified && d->charcells_drawn[i] == ch &&
415  d->charcells_drawn[i+1] == d->charcells[i+base+1])
416  continue;
417 
418  d->charcells_drawn[i] = ch;
419  d->charcells_drawn[i+1] = d->charcells[i + base + 1];
420 
421  fg = d->charcells[i+base + 1] & 15;
422  bg = (d->charcells[i+base + 1] >> 4) & 7;
423 
424  /* Blink is hard to do :-), but inversion might be ok too: */
425  if (d->charcells[i+base + 1] & 128) {
426  int tmp = fg; fg = bg; bg = tmp;
427  }
428 
429  x = (i/2) % d->max_x; x *= font_width;
430  y = (i/2) / d->max_x; y *= font_size;
431 
432  /* Draw the character: */
433  for (line = 0; line < font_size; line++) {
434  /* hardcoded for max 8 scaleup... :-) */
435  unsigned char rgb_line[3 * 8 * 8];
436  int iy;
437 
438  for (subx = 0; subx < font_width; subx++) {
439  int ix, color_index;
440 
441  if (d->use_palette_per_line) {
442  int sline = d->pixel_repy * (line+y);
443  if (sline < MAX_RETRACE_SCANLINES)
444  pal = d->retrace_palette
445  + sline * 256*3;
446  else
447  pal = d->fb->rgb_palette;
448  }
449 
450  if (d->font[ch * font_size + line] &
451  (128 >> subx))
452  color_index = fg;
453  else
454  color_index = bg;
455 
456  for (ix=0; ix<d->pixel_repx; ix++)
457  memcpy(rgb_line + (subx*d->pixel_repx +
458  ix) * 3, &pal[color_index * 3], 3);
459  }
460 
461  for (iy=0; iy<d->pixel_repy; iy++) {
462  uint32_t addr = (d->fb_max_x * (d->pixel_repy *
463  (line+y) + iy) + x * d->pixel_repx) * 3;
464  if (addr >= d->fb_size)
465  continue;
466  dev_fb_access(machine->cpus[0],
467  machine->memory, addr, rgb_line,
468  3 * machine->x11_md.scaleup * font_width,
469  MEM_WRITE, d->fb);
470  }
471  }
472  }
473 }
474 
475 
476 /*
477  * vga_update_cursor():
478  */
479 static void vga_update_cursor(struct machine *machine, struct vga_data *d)
480 {
481  int onoff = 1, height = d->crtc_reg[VGA_CRTC_CURSOR_SCANLINE_END]
483 
484  if (d->cur_mode != MODE_CHARCELL)
485  onoff = 0;
486 
489  onoff = 0;
490  height = 1;
491  }
492 
494  onoff = 0;
495 
496  dev_fb_setcursor(d->fb,
497  d->cursor_x * d->font_width * d->pixel_repx, (d->cursor_y *
499  d->pixel_repy, onoff, d->font_width * d->pixel_repx, height *
500  d->pixel_repy);
501 }
502 
503 
505 {
506  struct vga_data *d = (struct vga_data *) extra;
507  int64_t low = -1, high;
508 
509  vga_update_cursor(cpu->machine, d);
510 
511  /* TODO: text vs graphics tick? */
513  (uint64_t *) &low, (uint64_t *) &high);
514 
515  if (low != -1) {
516  int base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
518  int new_u_y1, new_u_y2;
519  debug("[ dev_vga_tick: dyntrans access, %" PRIx64" .. %"
520  PRIx64" ]\n", (uint64_t) low, (uint64_t) high);
521  low -= base;
522  high -= base;
523  d->update_x1 = 0;
524  d->update_x2 = d->max_x - 1;
525  new_u_y1 = (low/2) / d->max_x;
526  new_u_y2 = ((high/2) / d->max_x) + 1;
527  if (new_u_y1 < d->update_y1)
528  d->update_y1 = new_u_y1;
529  if (new_u_y2 > d->update_y2)
530  d->update_y2 = new_u_y2;
531  if (d->update_y1 < 0)
532  d->update_y1 = 0;
533  if (d->update_y2 >= d->max_y)
534  d->update_y2 = d->max_y - 1;
535  d->modified = 1;
536  }
537 
539  d->retrace_palette != NULL) {
540  d->use_palette_per_line = 1;
541  d->update_x1 = 0;
542  d->update_x2 = d->max_x - 1;
543  d->update_y1 = 0;
544  d->update_y2 = d->max_y - 1;
545  d->modified = 1;
546  } else {
547  if (d->use_palette_per_line) {
548  d->use_palette_per_line = 0;
549  d->update_x1 = 0;
550  d->update_x2 = d->max_x - 1;
551  d->update_y1 = 0;
552  d->update_y2 = d->max_y - 1;
553  d->modified = 1;
554  }
555  }
556 
557  if (!cpu->machine->x11_md.in_use) {
558  /* NOTE: 2 > 0, so this only updates the cursor, no
559  character cells. */
560  vga_update_textmode(cpu->machine, d, 0, 2, 0);
561  }
562 
563  if (d->modified) {
564  if (d->cur_mode == MODE_CHARCELL)
565  vga_update_text(cpu->machine, d, d->update_x1,
566  d->update_y1, d->update_x2, d->update_y2);
567  else
568  vga_update_graphics(cpu->machine, d, d->update_x1,
569  d->update_y1, d->update_x2, d->update_y2);
570 
571  d->palette_modified = 0;
572  d->modified = 0;
573  d->update_x1 = 999999;
574  d->update_x2 = -1;
575  d->update_y1 = 999999;
576  d->update_y2 = -1;
577  }
578 
580  d->n_is1_reads = 0;
581 }
582 
583 
584 /*
585  * Reads and writes to the VGA video memory (pixels).
586  */
587 DEVICE_ACCESS(vga_graphics)
588 {
589  struct vga_data *d = (struct vga_data *) extra;
590  int j, x=0, y=0, x2=0, y2=0, modified = 0;
591  size_t i;
592 
593  if (relative_addr + len >= GFX_ADDR_WINDOW)
594  return 0;
595 
596  if (d->cur_mode != MODE_GRAPHICS)
597  return 1;
598 
599  switch (d->graphics_mode) {
600  case GRAPHICS_MODE_8BIT:
601  y = relative_addr / d->max_x;
602  x = relative_addr % d->max_x;
603  y2 = (relative_addr+len-1) / d->max_x;
604  x2 = (relative_addr+len-1) % d->max_x;
605 
606  if (writeflag == MEM_WRITE) {
607  memcpy(d->gfx_mem + relative_addr, data, len);
608  modified = 1;
609  } else
610  memcpy(data, d->gfx_mem + relative_addr, len);
611  break;
612  case GRAPHICS_MODE_4BIT:
613  y = relative_addr * 8 / d->max_x;
614  x = relative_addr * 8 % d->max_x;
615  y2 = ((relative_addr+len)*8-1) / d->max_x;
616  x2 = ((relative_addr+len)*8-1) % d->max_x;
617  /* TODO: color stuff */
618 
619  /* Read/write d->gfx_mem in 4-bit color: */
620  if (writeflag == MEM_WRITE) {
621  /* i is byte index to write, j is bit index */
622  for (i=0; i<len; i++)
623  for (j=0; j<8; j++) {
624  int pixelmask = 1 << (7-j);
625  int b = data[i] & pixelmask;
626  int m = d->sequencer_reg[
627  VGA_SEQ_MAP_MASK] & 0x0f;
628  uint32_t addr = (y * d->max_x + x +
629  i*8 + j) * d->bits_per_pixel / 8;
630  unsigned char byte;
631  if (!(d->graphcontr_reg[
632  VGA_GRAPHCONTR_MASK] & pixelmask))
633  continue;
634  if (addr >= d->gfx_mem_size)
635  continue;
636  byte = d->gfx_mem[addr];
637  if (b && j&1)
638  byte |= m << 4;
639  if (b && !(j&1))
640  byte |= m;
641  if (!b && j&1)
642  byte &= ~(m << 4);
643  if (!b && !(j&1))
644  byte &= ~m;
645  d->gfx_mem[addr] = byte;
646  }
647  modified = 1;
648  } else {
649  fatal("TODO: 4 bit graphics read, mask=0x%02x\n",
651  for (i=0; i<len; i++)
652  data[i] = random();
653  }
654  break;
655  default:fatal("dev_vga: Unimplemented graphics mode %i\n",
656  d->graphics_mode);
657  cpu->running = 0;
658  }
659 
660  if (modified) {
661  d->modified = 1;
662  if (x < d->update_x1) d->update_x1 = x;
663  if (x > d->update_x2) d->update_x2 = x;
664  if (y < d->update_y1) d->update_y1 = y;
665  if (y > d->update_y2) d->update_y2 = y;
666  if (x2 < d->update_x1) d->update_x1 = x2;
667  if (x2 > d->update_x2) d->update_x2 = x2;
668  if (y2 < d->update_y1) d->update_y1 = y2;
669  if (y2 > d->update_y2) d->update_y2 = y2;
670  if (y != y2) {
671  d->update_x1 = 0;
672  d->update_x2 = d->max_x - 1;
673  }
674  }
675  return 1;
676 }
677 
678 
679 /*
680  * Reads and writes the VGA video memory (charcells).
681  */
683 {
684  struct vga_data *d = (struct vga_data *) extra;
685  uint64_t idata = 0, odata = 0;
686  int x, y, x2, y2, r, base;
687  size_t i;
688 
689  if (writeflag == MEM_WRITE)
690  idata = memory_readmax64(cpu, data, len);
691 
692  base = ((d->crtc_reg[VGA_CRTC_START_ADDR_HIGH] << 8)
694  r = relative_addr - base;
695  y = r / (d->max_x * 2);
696  x = (r/2) % d->max_x;
697  y2 = (r+len-1) / (d->max_x * 2);
698  x2 = ((r+len-1)/2) % d->max_x;
699 
700  if (relative_addr + len - 1 < d->charcells_size) {
701  if (writeflag == MEM_WRITE) {
702  for (i=0; i<len; i++) {
703  int old = d->charcells[relative_addr + i];
704  if (old != data[i]) {
705  d->charcells[relative_addr + i] =
706  data[i];
707  d->modified = 1;
708  }
709  }
710 
711  if (d->modified) {
712  if (x < d->update_x1) d->update_x1 = x;
713  if (x > d->update_x2) d->update_x2 = x;
714  if (y < d->update_y1) d->update_y1 = y;
715  if (y > d->update_y2) d->update_y2 = y;
716  if (x2 < d->update_x1) d->update_x1 = x2;
717  if (x2 > d->update_x2) d->update_x2 = x2;
718  if (y2 < d->update_y1) d->update_y1 = y2;
719  if (y2 > d->update_y2) d->update_y2 = y2;
720 
721  if (y != y2) {
722  d->update_x1 = 0;
723  d->update_x2 = d->max_x - 1;
724  }
725  }
726  } else
727  memcpy(data, d->charcells + relative_addr, len);
728  return 1;
729  }
730 
731  switch (relative_addr) {
732  default:
733  if (writeflag==MEM_READ) {
734  debug("[ vga: read from 0x%08lx ]\n",
735  (long)relative_addr);
736  } else {
737  debug("[ vga: write to 0x%08lx: 0x%08x ]\n",
738  (long)relative_addr, idata);
739  }
740  }
741 
742  if (writeflag == MEM_READ)
743  memory_writemax64(cpu, data, len, odata);
744 
745  return 1;
746 }
747 
748 
749 /*
750  * vga_crtc_reg_write():
751  *
752  * Writes to VGA CRTC registers.
753  */
754 static void vga_crtc_reg_write(struct machine *machine, struct vga_data *d,
755  int regnr, int idata)
756 {
757  int i, grayscale;
758 
759  switch (regnr) {
760  case VGA_CRTC_CURSOR_SCANLINE_START: /* 0x0a */
761  case VGA_CRTC_CURSOR_SCANLINE_END: /* 0x0b */
762  break;
763  case VGA_CRTC_START_ADDR_HIGH: /* 0x0c */
764  case VGA_CRTC_START_ADDR_LOW: /* 0x0d */
765  d->update_x1 = 0;
766  d->update_x2 = d->max_x - 1;
767  d->update_y1 = 0;
768  d->update_y2 = d->max_y - 1;
769  d->modified = 1;
770  recalc_cursor_position(d);
771  break;
772  case VGA_CRTC_CURSOR_LOCATION_HIGH: /* 0x0e */
773  case VGA_CRTC_CURSOR_LOCATION_LOW: /* 0x0f */
774  recalc_cursor_position(d);
775  break;
776  case 0xff:
777  grayscale = 0;
778  switch (d->crtc_reg[0xff]) {
779  case 0x00:
780  grayscale = 1;
781  case 0x01:
782  d->cur_mode = MODE_CHARCELL;
783  d->max_x = 40; d->max_y = 25;
784  d->pixel_repx = machine->x11_md.scaleup * 2;
785  d->pixel_repy = machine->x11_md.scaleup;
786  d->font_width = 8;
787  d->font_height = 16;
788  d->font = font8x16;
789  break;
790  case 0x02:
791  grayscale = 1;
792  case 0x03:
793  d->cur_mode = MODE_CHARCELL;
794  d->max_x = 80; d->max_y = 25;
795  d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
796  d->font_width = 8;
797  d->font_height = 16;
798  d->font = font8x16;
799  break;
800  case 0x08:
801  d->cur_mode = MODE_GRAPHICS;
802  d->max_x = 160; d->max_y = 200;
804  d->bits_per_pixel = 4;
805  d->pixel_repx = 4 * machine->x11_md.scaleup;
806  d->pixel_repy = 2 * machine->x11_md.scaleup;
807  break;
808  case 0x09:
809  case 0x0d:
810  d->cur_mode = MODE_GRAPHICS;
811  d->max_x = 320; d->max_y = 200;
813  d->bits_per_pixel = 4;
814  d->pixel_repx = d->pixel_repy =
815  2 * machine->x11_md.scaleup;
816  break;
817  case 0x0e:
818  d->cur_mode = MODE_GRAPHICS;
819  d->max_x = 640; d->max_y = 200;
821  d->bits_per_pixel = 4;
822  d->pixel_repx = machine->x11_md.scaleup;
823  d->pixel_repy = machine->x11_md.scaleup * 2;
824  break;
825  case 0x10:
826  d->cur_mode = MODE_GRAPHICS;
827  d->max_x = 640; d->max_y = 350;
829  d->bits_per_pixel = 4;
830  d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
831  break;
832  case 0x12:
833  d->cur_mode = MODE_GRAPHICS;
834  d->max_x = 640; d->max_y = 480;
836  d->bits_per_pixel = 4;
837  d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
838  break;
839  case 0x13:
840  d->cur_mode = MODE_GRAPHICS;
841  d->max_x = 320; d->max_y = 200;
843  d->bits_per_pixel = 8;
844  d->pixel_repx = d->pixel_repy =
845  2 * machine->x11_md.scaleup;
846  break;
847  default:
848  fatal("TODO! video mode change hack (mode 0x%02x)\n",
849  d->crtc_reg[0xff]);
850  exit(1);
851  }
852 
853  if (d->cur_mode == MODE_CHARCELL) {
854  dev_fb_resize(d->fb, d->max_x * d->font_width *
855  d->pixel_repx, d->max_y * d->font_height *
856  d->pixel_repy);
857  d->fb_size = d->max_x * d->pixel_repx * d->font_width *
858  d->max_y * d->pixel_repy * d->font_height * 3;
859  } else {
860  dev_fb_resize(d->fb, d->max_x * d->pixel_repx,
861  d->max_y * d->pixel_repy);
862  d->fb_size = d->max_x * d->pixel_repx *
863  d->max_y * d->pixel_repy * 3;
864  }
865 
866  for (i=0; i<machine->ncpus; i++)
867  machine->cpus[i]->invalidate_translation_caches(
868  machine->cpus[i], 0, INVALIDATE_ALL);
869 
870  if (d->gfx_mem != NULL)
871  free(d->gfx_mem);
872  d->gfx_mem_size = 1;
873  if (d->cur_mode == MODE_GRAPHICS)
874  d->gfx_mem_size = d->max_x * d->max_y /
875  (d->graphics_mode == GRAPHICS_MODE_8BIT? 1 : 2);
876 
877  CHECK_ALLOCATION(d->gfx_mem = (unsigned char *) malloc(d->gfx_mem_size));
878 
879  /* Clear screen and reset the palette: */
880  memset(d->charcells_outputed, 0, d->charcells_size);
881  memset(d->charcells_drawn, 0, d->charcells_size);
882  memset(d->gfx_mem, 0, d->gfx_mem_size);
883  d->update_x1 = 0;
884  d->update_x2 = d->max_x - 1;
885  d->update_y1 = 0;
886  d->update_y2 = d->max_y - 1;
887  d->modified = 1;
888  reset_palette(d, grayscale);
889  register_reset(d);
890  break;
891  default:fatal("[ vga_crtc_reg_write: regnr=0x%02x idata=0x%02x ]\n",
892  regnr, idata);
893  }
894 }
895 
896 
897 /*
898  * vga_sequencer_reg_write():
899  *
900  * Writes to VGA Sequencer registers.
901  */
902 static void vga_sequencer_reg_write(struct machine *machine, struct vga_data *d,
903  int regnr, int idata)
904 {
905  switch (regnr) {
906  case VGA_SEQ_RESET:
907  case VGA_SEQ_MAP_MASK:
909  debug("[ vga_sequencer_reg_write: select %i: TODO ]\n", regnr);
910  break;
911  default:fatal("[ vga_sequencer_reg_write: select %i ]\n", regnr);
912  /* cpu->running = 0; */
913  }
914 }
915 
916 
917 /*
918  * vga_graphcontr_reg_write():
919  *
920  * Writes to VGA Graphics Controller registers.
921  */
922 static void vga_graphcontr_reg_write(struct machine *machine,
923  struct vga_data *d, int regnr, int idata)
924 {
925  switch (regnr) {
928  case VGA_GRAPHCONTR_MISC:
929  case VGA_GRAPHCONTR_MASK:
930  debug("[ vga_graphcontr_reg_write: select %i: TODO ]\n", regnr);
931  break;
932  default:fatal("[ vga_graphcontr_reg_write: select %i ]\n", regnr);
933  /* cpu->running = 0; */
934  }
935 }
936 
937 
938 /*
939  * vga_attribute_reg_write():
940  *
941  * Writes to VGA Attribute registers.
942  */
943 static void vga_attribute_reg_write(struct machine *machine, struct vga_data *d,
944  int regnr, int idata)
945 {
946  /* 0-15 are palette registers: TODO */
947  if (regnr >= 0 && regnr <= 0xf)
948  return;
949 
950  switch (regnr) {
951  default:fatal("[ vga_attribute_reg_write: select %i ]\n", regnr);
952  /* cpu->running = 0; */
953  }
954 }
955 
956 
957 /*
958  * dev_vga_ctrl_access():
959  *
960  * Reads and writes of the VGA control registers.
961  */
962 DEVICE_ACCESS(vga_ctrl)
963 {
964  struct vga_data *d = (struct vga_data *) extra;
965  size_t i;
966  uint64_t idata = 0, odata = 0;
967 
968  for (i=0; i<len; i++) {
969  idata = data[i];
970 
971  /* 0x3C0 + relative_addr... */
972 
973  switch (relative_addr) {
974 
975  case VGA_ATTRIBUTE_ADDR: /* 0x00 */
976  switch (d->attribute_state) {
977  case 0: if (writeflag == MEM_READ)
978  odata = d->attribute_reg_select;
979  else {
980  d->attribute_reg_select = 1;
981  d->attribute_state = 1;
982  }
983  break;
984  case 1: d->attribute_state = 0;
986  idata;
987  vga_attribute_reg_write(cpu->machine, d,
988  d->attribute_reg_select, idata);
989  break;
990  }
991  break;
992  case VGA_ATTRIBUTE_DATA_READ: /* 0x01 */
993  if (writeflag == MEM_WRITE)
994  fatal("[ dev_vga: WARNING: Write to "
995  "VGA_ATTRIBUTE_DATA_READ? ]\n");
996  else {
997  if (d->attribute_state == 0)
998  fatal("[ dev_vga: WARNING: Read from "
999  "VGA_ATTRIBUTE_DATA_READ, but no"
1000  " register selected? ]\n");
1001  else
1002  odata = d->attribute_reg[
1004  }
1005  break;
1006 
1007  case VGA_MISC_OUTPUT_W: /* 0x02 */
1008  if (writeflag == MEM_WRITE)
1009  d->misc_output_reg = idata;
1010  else {
1011  /* Reads: Input Status 0 */
1012  odata = 0x00;
1013  }
1014  break;
1015 
1016  case VGA_SEQUENCER_ADDR: /* 0x04 */
1017  if (writeflag == MEM_READ)
1018  odata = d->sequencer_reg_select;
1019  else
1020  d->sequencer_reg_select = idata;
1021  break;
1022  case VGA_SEQUENCER_DATA: /* 0x05 */
1023  if (writeflag == MEM_READ)
1024  odata = d->sequencer_reg[
1026  else {
1027  d->sequencer_reg[d->
1028  sequencer_reg_select] = idata;
1029  vga_sequencer_reg_write(cpu->machine, d,
1030  d->sequencer_reg_select, idata);
1031  }
1032  break;
1033 
1034  case VGA_DAC_ADDR_READ: /* 0x07 */
1035  if (writeflag == MEM_WRITE) {
1036  d->palette_read_index = idata;
1037  d->palette_read_subindex = 0;
1038  } else {
1039  debug("[ dev_vga: WARNING: Read from "
1040  "VGA_DAC_ADDR_READ? TODO ]\n");
1041  /* TODO */
1042  }
1043  break;
1044  case VGA_DAC_ADDR_WRITE: /* 0x08 */
1045  if (writeflag == MEM_WRITE) {
1046  d->palette_write_index = idata;
1047  d->palette_write_subindex = 0;
1048 
1049  /* TODO: Is this correct? */
1050  d->palette_read_index = idata;
1051  d->palette_read_subindex = 0;
1052  } else {
1053  fatal("[ dev_vga: WARNING: Read from "
1054  "VGA_DAC_ADDR_WRITE? ]\n");
1055  odata = d->palette_write_index;
1056  }
1057  break;
1058  case VGA_DAC_DATA: /* 0x09 */
1059  if (writeflag == MEM_WRITE) {
1060  int new_ = (idata & 63) << 2;
1061  int old = d->fb->rgb_palette[d->
1062  palette_write_index*3+d->
1064  d->fb->rgb_palette[d->palette_write_index * 3 +
1065  d->palette_write_subindex] = new_;
1066  /* Redraw whole screen, if the
1067  palette changed: */
1068  if (new_ != old) {
1069  d->modified = 1;
1070  d->palette_modified = 1;
1071  d->update_x1 = d->update_y1 = 0;
1072  d->update_x2 = d->max_x - 1;
1073  d->update_y2 = d->max_y - 1;
1074  }
1075  d->palette_write_subindex ++;
1076  if (d->palette_write_subindex == 3) {
1077  d->palette_write_index ++;
1078  d->palette_write_subindex = 0;
1079  }
1080  } else {
1081  odata = (d->fb->rgb_palette[d->
1082  palette_read_index * 3 +
1083  d->palette_read_subindex] >> 2) & 63;
1084  d->palette_read_subindex ++;
1085  if (d->palette_read_subindex == 3) {
1086  d->palette_read_index ++;
1087  d->palette_read_subindex = 0;
1088  }
1089  }
1090  break;
1091 
1092  case VGA_MISC_OUTPUT_R:
1093  odata = d->misc_output_reg;
1094  break;
1095 
1096  case VGA_GRAPHCONTR_ADDR: /* 0x0e */
1097  if (writeflag == MEM_READ)
1098  odata = d->graphcontr_reg_select;
1099  else
1100  d->graphcontr_reg_select = idata;
1101  break;
1102  case VGA_GRAPHCONTR_DATA: /* 0x0f */
1103  if (writeflag == MEM_READ)
1104  odata = d->graphcontr_reg[
1106  else {
1107  d->graphcontr_reg[d->
1108  graphcontr_reg_select] = idata;
1109  vga_graphcontr_reg_write(cpu->machine, d,
1110  d->graphcontr_reg_select, idata);
1111  }
1112  break;
1113 
1114  case VGA_CRTC_ADDR: /* 0x14 */
1115  if (writeflag == MEM_READ)
1116  odata = d->crtc_reg_select;
1117  else
1118  d->crtc_reg_select = idata;
1119  break;
1120  case VGA_CRTC_DATA: /* 0x15 */
1121  if (writeflag == MEM_READ)
1122  odata = d->crtc_reg[d->crtc_reg_select];
1123  else {
1124  d->crtc_reg[d->crtc_reg_select] = idata;
1125  vga_crtc_reg_write(cpu->machine, d,
1126  d->crtc_reg_select, idata);
1127  }
1128  break;
1129 
1130  case VGA_INPUT_STATUS_1: /* 0x1A */
1131  odata = 0;
1132  d->n_is1_reads ++;
1133  d->current_retrace_line ++;
1135  /* Whenever we are "inside" a scan line, copy the
1136  current palette into retrace_palette[][]: */
1137  if ((d->current_retrace_line & 7) == 7) {
1138  if (d->retrace_palette == NULL &&
1141  (unsigned char *) malloc(
1142  MAX_RETRACE_SCANLINES * 256*3));
1143  }
1144  if (d->retrace_palette != NULL)
1145  memcpy(d->retrace_palette + (d->
1146  current_retrace_line >> 3) * 256*3,
1147  d->fb->rgb_palette, d->cur_mode ==
1148  MODE_CHARCELL? (16*3) : (256*3));
1149  }
1150  /* These need to go on and off, to fake the
1151  real vertical and horizontal retrace info. */
1152  if (d->current_retrace_line < 20*8)
1153  odata |= VGA_IS1_DISPLAY_VRETRACE;
1154  else {
1155  if ((d->current_retrace_line & 7) == 0)
1157  }
1158  break;
1159 
1160  default:
1161  if (writeflag==MEM_READ) {
1162  debug("[ vga_ctrl: read from 0x%08lx ]\n",
1163  (long)relative_addr);
1164  } else {
1165  debug("[ vga_ctrl: write to 0x%08lx: 0x%08x"
1166  " ]\n", (long)relative_addr, (int)idata);
1167  }
1168  }
1169 
1170  if (writeflag == MEM_READ)
1171  data[i] = odata;
1172 
1173  /* For multi-byte accesses: */
1174  relative_addr ++;
1175  }
1176 
1177  return 1;
1178 }
1179 
1180 
1181 /*
1182  * dev_vga_init():
1183  *
1184  * Register a VGA text console device. max_x and max_y could be something
1185  * like 80 and 25, respectively.
1186  */
1187 void dev_vga_init(struct machine *machine, struct memory *mem,
1188  uint64_t videomem_base, uint64_t control_base, const char *name)
1189 {
1190  struct vga_data *d;
1191  size_t allocsize, i;
1192 
1193  CHECK_ALLOCATION(d = (struct vga_data *) malloc(sizeof(struct vga_data)));
1194  memset(d, 0, sizeof(struct vga_data));
1195 
1196  d->console_handle = console_start_slave(machine, "vga",
1198 
1201  d->max_x = 80;
1202  d->max_y = 25;
1203  d->cur_mode = MODE_CHARCELL;
1204  d->crtc_reg[0xff] = 0x03;
1205  d->charcells_size = 0x8000;
1206  d->gfx_mem_size = 64; /* Nothing, as we start in text mode,
1207  but size large enough to make gfx_mem aligned. */
1208  d->pixel_repx = d->pixel_repy = machine->x11_md.scaleup;
1209 
1210  /* Allocate in full pages, to make it possible to use dyntrans: */
1211  allocsize = ((d->charcells_size-1) | (machine->arch_pagesize-1)) + 1;
1212  CHECK_ALLOCATION(d->charcells = (unsigned char *) malloc(d->charcells_size));
1213  CHECK_ALLOCATION(d->charcells_outputed = (unsigned char *) malloc(d->charcells_size));
1214  CHECK_ALLOCATION(d->charcells_drawn = (unsigned char *) malloc(d->charcells_size));
1215  CHECK_ALLOCATION(d->gfx_mem = (unsigned char *) malloc(d->gfx_mem_size));
1216 
1217  memset(d->charcells_drawn, 0, d->charcells_size);
1218 
1219  for (i=0; i<d->charcells_size; i+=2) {
1220  d->charcells[i] = ' ';
1221  d->charcells[i+1] = 0x07; /* Default color */
1222  d->charcells_drawn[i] = ' ';
1223  d->charcells_drawn[i+1] = 0x07;
1224  }
1225 
1226  memset(d->charcells_outputed, 0, d->charcells_size);
1227  memset(d->gfx_mem, 0, d->gfx_mem_size);
1228 
1229  d->font = font8x16;
1230  d->font_width = 8;
1231  d->font_height = 16;
1232 
1233  d->fb_max_x = d->pixel_repx * d->max_x;
1234  d->fb_max_y = d->pixel_repy * d->max_y;
1235  if (d->cur_mode == MODE_CHARCELL) {
1236  d->fb_max_x *= d->font_width;
1237  d->fb_max_y *= d->font_height;
1238  }
1239 
1240  memory_device_register(mem, "vga_charcells", videomem_base + 0x18000,
1241  allocsize, dev_vga_access, d, DM_DYNTRANS_OK |
1243  d->charcells);
1244  memory_device_register(mem, "vga_gfx", videomem_base, GFX_ADDR_WINDOW,
1245  dev_vga_graphics_access, d, DM_DEFAULT |
1247  memory_device_register(mem, "vga_ctrl", control_base,
1248  32, dev_vga_ctrl_access, d, DM_DEFAULT, NULL);
1249 
1250  d->fb = dev_fb_init(machine, mem, VGA_FB_ADDR, VFB_GENERIC,
1251  d->fb_max_x, d->fb_max_y, d->fb_max_x, d->fb_max_y, 24, "VGA");
1252  d->fb_size = d->fb_max_x * d->fb_max_y * 3;
1253 
1254  reset_palette(d, 0);
1255 
1256  /* This will force an initial redraw/resynch: */
1257  d->update_x1 = 0;
1258  d->update_x2 = d->max_x - 1;
1259  d->update_y1 = 0;
1260  d->update_y2 = d->max_y - 1;
1261  d->modified = 1;
1262 
1263  machine_add_tickfunction(machine, dev_vga_tick, d, VGA_TICK_SHIFT);
1264 
1265  register_reset(d);
1266 
1267  vga_update_cursor(machine, d);
1268 }
1269 
unsigned char * font
Definition: dev_vga.cc:90
#define VGA_INPUT_STATUS_1
Definition: vga.h:88
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
int palette_modified
Definition: dev_vga.cc:138
void fatal(const char *fmt,...)
Definition: main.cc:152
int update_y2
Definition: dev_vga.cc:142
struct vfb_data * fb
Definition: dev_vga.cc:73
#define DM_DEFAULT
Definition: memory.h:130
unsigned char * charcells
Definition: dev_vga.cc:92
int bits_per_pixel
Definition: dev_vga.cc:98
#define VGA_SEQ_MAP_MASK
Definition: vga.h:54
int arch_pagesize
Definition: machine.h:151
char palette_write_subindex
Definition: dev_vga.cc:121
int current_retrace_line
Definition: dev_vga.cc:123
int graphics_mode
Definition: dev_vga.cc:97
unsigned char * gfx_mem
Definition: dev_vga.cc:99
#define VGA_SEQUENCER_ADDR
Definition: vga.h:50
#define VGA_FB_ADDR
Definition: dev_vga.cc:61
#define VGA_CRTC_ADDR
Definition: vga.h:79
int update_x1
Definition: dev_vga.cc:139
#define INVALIDATE_ALL
Definition: cpu.h:478
#define VGA_MISC_OUTPUT_IOAS
Definition: vga.h:48
#define VGA_CRTC_CURSOR_LOCATION_HIGH
Definition: vga.h:85
int cursor_x
Definition: dev_vga.cc:134
struct vfb_data * dev_fb_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, int vfb_type, int visible_xsize, int visible_ysize, int xsize, int ysize, int bit_depth, const char *name)
Definition: dev_fb.cc:834
unsigned char crtc_reg[256]
Definition: dev_vga.cc:116
void dev_vga_init(struct machine *machine, struct memory *mem, uint64_t videomem_base, uint64_t control_base, const char *name)
Definition: dev_vga.cc:1187
#define VFB_GENERIC
Definition: devices.h:190
struct memory * mem
Definition: cpu.h:362
int fb_max_y
Definition: dev_vga.cc:77
DEVICE_TICK(vga)
Definition: dev_vga.cc:504
size_t charcells_size
Definition: dev_vga.cc:91
unsigned char crtc_reg_select
Definition: dev_vga.cc:115
struct machine * machine
Definition: cpu.h:328
int64_t n_is1_reads
Definition: dev_vga.cc:129
unsigned char graphcontr_reg[256]
Definition: dev_vga.cc:113
int scaleup
Definition: machine.h:84
#define MEM_READ
Definition: memory.h:116
struct memory * memory
Definition: machine.h:126
#define VGA_GRAPHCONTR_MISC
Definition: vga.h:75
unsigned char * charcells_drawn
Definition: dev_vga.cc:94
uint64_t videomem_base
Definition: dev_vga.cc:70
#define VGA_MISC_OUTPUT_W
Definition: vga.h:45
int fb_max_x
Definition: dev_vga.cc:76
#define VGA_CRTC_DATA
Definition: vga.h:80
uint32_t fb_size
Definition: dev_vga.cc:74
void console_putchar(int handle, int ch)
Definition: console.cc:405
unsigned char attribute_reg[256]
Definition: dev_vga.cc:105
int font_height
Definition: dev_vga.cc:89
struct cpu ** cpus
Definition: machine.h:140
#define VGA_GRAPHCONTR_MASK
Definition: vga.h:77
int update_x2
Definition: dev_vga.cc:141
int console_handle
Definition: dev_vga.cc:132
int ncpus
Definition: machine.h:139
int pixel_repx
Definition: dev_vga.cc:85
#define VGA_SEQ_RESET
Definition: vga.h:52
#define VGA_ATTRIBUTE_DATA_READ
Definition: vga.h:41
#define VGA_DAC_ADDR_WRITE
Definition: vga.h:60
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
#define VGA_GRAPHCONTR_READMAPSELECT
Definition: vga.h:73
DEVICE_ACCESS(vga_graphics)
Definition: dev_vga.cc:587
int modified
Definition: dev_vga.cc:137
#define MAX_RETRACE_SCANLINES
Definition: dev_vga.cc:56
#define VGA_GRAPHCONTR_GRAPHICSMODE
Definition: vga.h:74
unsigned char * retrace_palette
Definition: dev_vga.cc:127
#define VGA_CRTC_START_ADDR_LOW
Definition: vga.h:84
#define DM_READS_HAVE_NO_SIDE_EFFECTS
Definition: memory.h:133
u_short data
Definition: siireg.h:79
int pixel_repy
Definition: dev_vga.cc:85
#define VGA_ATTRIBUTE_ADDR
Definition: vga.h:38
#define GRAPHICS_MODE_8BIT
Definition: dev_vga.cc:66
unsigned char font8x16[]
Definition: font8x16.cc:1
unsigned char graphcontr_reg_select
Definition: dev_vga.cc:112
#define DM_DYNTRANS_WRITE_OK
Definition: memory.h:132
unsigned char sequencer_reg[256]
Definition: dev_vga.cc:110
uint8_t running
Definition: cpu.h:353
#define VGA_GRAPHCONTR_DATA
Definition: vga.h:68
#define VGA_CRTC_CURSOR_SCANLINE_END
Definition: vga.h:82
#define MEM_WRITE
Definition: memory.h:117
unsigned char sequencer_reg_select
Definition: dev_vga.cc:109
#define VGA_CRTC_START_ADDR_HIGH
Definition: vga.h:83
#define VGA_DAC_DATA
Definition: vga.h:61
#define VGA_IS1_DISPLAY_DISPLAY_DISABLE
Definition: vga.h:90
#define VGA_MISC_OUTPUT_R
Definition: vga.h:65
#define GFX_ADDR_WINDOW
Definition: dev_vga.cc:59
int attribute_state
Definition: dev_vga.cc:103
struct x11_md x11_md
Definition: machine.h:179
#define VGA_SEQ_SEQUENCER_MEMORY_MODE
Definition: vga.h:56
uint32_t addr
unsigned char attribute_reg_select
Definition: dev_vga.cc:104
#define debug
Definition: dev_adb.cc:57
Definition: cpu.h:326
char palette_read_subindex
Definition: dev_vga.cc:119
#define VGA_CRTC_CURSOR_LOCATION_LOW
Definition: vga.h:86
int cur_mode
Definition: dev_vga.cc:82
uint64_t control_base
Definition: dev_vga.cc:71
unsigned char * charcells_outputed
Definition: dev_vga.cc:93
int input_status_1
Definition: dev_vga.cc:124
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
#define VGA_IS1_DISPLAY_VRETRACE
Definition: vga.h:89
int dev_vga_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
int dev_fb_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
void dev_fb_resize(struct vfb_data *d, int new_xsize, int new_ysize)
Definition: dev_fb.cc:123
#define VGA_GRAPHCONTR_ADDR
Definition: vga.h:67
int console_start_slave(struct machine *machine, const char *consolename, int use_for_input)
Definition: console.cc:668
int cursor_y
Definition: dev_vga.cc:135
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition: memory.cc:339
#define GRAPHICS_MODE_4BIT
Definition: dev_vga.cc:67
#define DM_DYNTRANS_OK
Definition: memory.h:131
int in_use
Definition: machine.h:82
int max_y
Definition: dev_vga.cc:79
#define N_IS1_READ_THRESHOLD
Definition: dev_vga.cc:57
#define VGA_SEQUENCER_DATA
Definition: vga.h:51
void memory_device_dyntrans_access(struct cpu *, struct memory *mem, void *extra, uint64_t *low, uint64_t *high)
Definition: memory.cc:264
int update_y1
Definition: dev_vga.cc:140
Definition: memory.h:75
addr & if(addr >=0x24 &&page !=NULL)
uint32_t gfx_mem_size
Definition: dev_vga.cc:100
#define MODE_GRAPHICS
Definition: dev_vga.cc:64
int font_width
Definition: dev_vga.cc:88
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
Definition: machine.cc:280
#define MODE_CHARCELL
Definition: dev_vga.cc:63
#define VGA_TICK_SHIFT
Definition: dev_vga.cc:54
unsigned char palette_write_index
Definition: dev_vga.cc:120
int max_x
Definition: dev_vga.cc:78
int use_palette_per_line
Definition: dev_vga.cc:128
unsigned char misc_output_reg
Definition: dev_vga.cc:107
unsigned char rgb_palette[256 *3]
Definition: devices.h:223
#define VGA_CRTC_CURSOR_SCANLINE_START
Definition: vga.h:81
#define CONSOLE_OUTPUT_ONLY
Definition: console.h:39
unsigned char palette_read_index
Definition: dev_vga.cc:118
void dev_fb_setcursor(struct vfb_data *d, int cursor_x, int cursor_y, int on, int cursor_xsize, int cursor_ysize)
Definition: dev_fb.cc:193
#define VGA_DAC_ADDR_READ
Definition: vga.h:59
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
Definition: cpu.h:374

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13