Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel' of palacios@newskysaw.cs.northwestern.edu:/home/palacios/palacio...
[palacios.git] / palacios / src / devices / vga.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2011, Peter Dinda <pdinda@northwestern.edu> 
11  * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Peter Dinda <pdinda@northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <palacios/vmm_types.h>
23 #include <palacios/vm_guest_mem.h>
24 #include <palacios/vmm_io.h>
25 #include <interfaces/vmm_graphics_console.h>
26
27 #include "vga_regs.h"
28
29 #define MEM_REGION_START 0xa0000
30 #define MEM_REGION_END   0xc0000
31 #define MEM_REGION_NUM_PAGES (((MEM_REGION_END)-(MEM_REGION_START))/4096)
32
33 #define MAP_SIZE 65536
34 #define MAP_NUM  4
35
36 #define UPDATES_PER_RENDER 100
37
38 typedef uint8_t *vga_map; // points to MAP_SIZE data
39
40 #define VGA_MAXX 1024
41 #define VGA_MAXY 768
42
43
44 #define VGA_MISC_OUT_READ 0x3cc
45 #define VGA_MISC_OUT_WRITE 0x3c2
46
47 #define VGA_INPUT_STAT0_READ 0x3c2
48
49 #define VGA_INPUT_STAT1_READ_MONO 0x3ba
50 #define VGA_INPUT_STAT1_READ_COLOR 0x3da
51
52 #define VGA_FEATURE_CONTROL_READ 0x3ca
53 #define VGA_FEATURE_CONTROL_WRITE_MONO 0x3ba
54 #define VGA_FEATURE_CONTROL_WRITE_COLOR 0x3da
55
56 #define VGA_VIDEO_SUBSYS_ENABLE 0x3c3
57
58 #define VGA_SEQUENCER_ADDRESS 0x3c4
59 #define VGA_SEQUENCER_DATA 0x3c5
60 #define VGA_SEQUENCER_NUM 5
61
62
63 #define VGA_CRT_CONTROLLER_ADDRESS_MONO 0x3b4
64 #define VGA_CRT_CONTROLLER_ADDRESS_COLOR 0x3d4
65 #define VGA_CRT_CONTROLLER_DATA_MONO 0x3b5
66 #define VGA_CRT_CONTROLLER_DATA_COLOR 0x3d5
67 #define VGA_CRT_CONTROLLER_NUM 25
68
69
70 #define VGA_GRAPHICS_CONTROLLER_ADDRESS 0x3ce
71 #define VGA_GRAPHICS_CONTROLLER_DATA 0x3cf
72 #define VGA_GRAPHICS_CONTROLLER_NUM 9
73
74 #define VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE 0x3c0
75 #define VGA_ATTRIBUTE_CONTROLLER_READ 0x3c1
76 #define VGA_ATTRIBUTE_CONTROLLER_NUM 21
77
78 #define VGA_DAC_WRITE_ADDR 0x3c8
79 #define VGA_DAC_READ_ADDR 0x3c7
80 #define VGA_DAC_DATA 0x3c9
81 #define VGA_DAC_PIXEL_MASK 0x3c6
82
83 #define VGA_DAC_NUM_ENTRIES 256
84
85 struct vga_misc_regs {
86     /* Read: 0x3cc; Write: 0x3c2 */
87     struct vga_misc_out_reg        vga_misc_out;
88     /* Read: 0x3c2 */
89     struct vga_input_stat0_reg     vga_input_stat0;
90     /* Read: 0x3?a  3ba for mono; 3da for cga set by misc.io_addr_sel */
91     struct vga_input_stat1_reg     vga_input_stat1; 
92     /* Read: 0x3ca; Write: 0x3?a 3ba for mono 3da for color - set by misc.io_addr_sel*/
93     struct vga_feature_control_reg vga_feature_control;
94     /* Read: 0x3c3; Write: 0x3c3 */
95     struct vga_video_subsys_enable_reg vga_video_subsys_enable;
96 } __attribute__((packed));
97
98 struct vga_sequencer_regs {
99     /*   Address register is 0x3c4, data register is 0x3c5 */
100     /* 0x3c4 */
101     struct vga_sequencer_addr_reg vga_sequencer_addr;
102
103     /* these can be accessed via the index, offset on start 
104        or via the specific regs.   For this reason, it is essential
105        that this is all packed and that the order does not change */
106     
107     uint8_t  vga_sequencer_regs[0];
108
109     /* Index 0 */
110     struct vga_reset_reg   vga_reset;
111     /* Index 1 */
112     struct vga_clocking_mode_reg vga_clocking_mode;
113     /* Index 2 */
114     struct vga_map_mask_reg vga_map_mask;
115     /* Index 3 */
116     struct vga_char_map_select_reg vga_char_map_select;
117     /* Index 4 */
118     struct vga_mem_mode_reg  vga_mem_mode;
119 } __attribute__((packed));
120
121 struct vga_crt_controller_regs {
122     /* Address Register is 0x3b4 or 0x3d4 */
123     /* Data register is 0x3b5 or 0x3d5 based on mono versus color */
124     struct vga_crt_addr_reg vga_crt_addr;
125
126     /* these can be accessed via the index, offset on start 
127        or via the specific regs.   For this reason, it is essential
128        that this is all packed and that the order does not change */
129     
130     uint8_t  vga_crt_controller_regs[0];
131
132     /* index 0 */
133     vga_horizontal_total_reg vga_horizontal_total;
134     /* index 1 */
135     vga_horizontal_display_enable_end_reg vga_horizontal_display_enable_end;
136     /* index 2 */
137     vga_start_horizontal_blanking_reg vga_start_horizontal_blanking;
138     /* index 3 */
139     struct vga_end_horizontal_blanking_reg vga_end_horizontal_blanking;
140     /* index 4 */
141     vga_start_horizontal_retrace_pulse_reg vga_start_horizontal_retrace_pulse;
142     /* index 5 */
143     struct vga_end_horizontal_retrace_reg vga_end_horizontal_retrace;
144     /* index 6 */
145     vga_vertical_total_reg vga_vertical_total;
146     /* index 7 */
147     struct vga_overflow_reg vga_overflow;
148     /* index 8 */
149     struct vga_preset_row_scan_reg vga_preset_row_scan;
150     /* index 9 */
151     struct vga_max_row_scan_reg vga_row_scan;
152     /* index 10 */
153     struct vga_cursor_start_reg vga_cursor_start;
154     /* index 11 */
155     struct vga_cursor_end_reg vga_cursor_end;
156     /* index 12 */
157     vga_start_address_high_reg vga_start_address_high;
158     /* index 13 */
159     vga_start_address_low_reg vga_start_address_low;
160     /* index 14 */
161     vga_cursor_location_high_reg vga_cursor_location_high;
162     /* index 15 */
163     vga_cursor_location_low_reg vga_cursor_location_low;
164     /* index 16 */
165     vga_vertical_retrace_start_reg vga_vertical_retrace_start;
166     /* index 17 */
167     struct vga_vertical_retrace_end_reg vga_vertical_retrace_end;
168     /* index 18 */
169     vga_vertical_display_enable_end_reg vga_vertical_display_enable;
170     /* index 19 */
171     vga_offset_reg vga_offset;
172     /* index 20 */
173     struct vga_underline_location_reg vga_underline_location;
174     /* index 21 */
175     vga_start_vertical_blanking_reg vga_start_vertical_blanking;
176     /* index 22 */
177     vga_end_vertical_blanking_reg vga_end_vertical_blanking;
178     /* index 23 */
179     struct vga_crt_mode_control_reg vga_crt_mode_control;
180     /* index 24 */
181     vga_line_compare_reg vga_line_compare;
182 } __attribute__((packed));
183
184 struct vga_graphics_controller_regs {
185     /*   Address: 0x3ce    Data: 0x3cf */
186
187     /* 0x3ce */
188     struct vga_graphics_ctrl_addr_reg vga_graphics_ctrl_addr;
189
190     /* these can be accessed via the index, offset on start 
191        or via the specific regs.   For this reason, it is essential
192        that this is all packed and that the order does not change */
193     
194     uint8_t  vga_graphics_controller_regs[0];
195
196     /* Index 0 */
197     struct vga_set_reset_reg vga_set_reset;
198     /* Index 1 */
199     struct vga_enable_set_reset_reg vga_enable_set_reset;
200     /* Index 2 */
201     struct vga_color_compare_reg vga_color_compare;
202     /* Index 3 */
203     struct vga_data_rotate_reg vga_data_rotate;
204     /* Index 4 */
205     struct vga_read_map_select_reg vga_read_map_select;
206     /* Index 5 */
207     struct vga_graphics_mode_reg vga_graphics_mode;
208     /* Index 6 */
209     struct vga_misc_reg vga_misc;
210     /* Index 7 */
211     struct vga_color_dont_care_reg vga_color_dont_care;
212     /* Index 8 */
213     vga_bit_mask_reg vga_bit_mask;
214 } __attribute__((packed));
215
216
217 struct vga_attribute_contoller_regs {
218     /*
219       Address AND WRITE: 0x3c0
220       Read: 0x3c1
221
222       The write protocol is to write the index to 0x3c0 followed by 
223       the data.  The read protocol is to write the index to 0x3c0
224       and then read from 0x3c1
225   
226       IMPORTANT: write address, write data flips state back to write address
227       write address, read data DOES NOT
228
229       To reset to write address state, read input status register 1
230 */
231     enum { ATTR_ADDR, ATTR_DATA }  state;  //state of the flip flop
232
233     /* 0x3c0 */
234     struct vga_attribute_controller_address_reg vga_attribute_controller_addr;
235
236
237     
238     /* these can be accessed via the index, offset on start 
239        or via the specific regs.   For this reason, it is essential
240        that this is all packed and that the order does not change */
241     
242     uint8_t  vga_attribute_controller_regs[0];
243
244     /* Indices 0..15 */
245     vga_internal_palette_regs   vga_internal_palette;
246     /* Index 16 */
247     struct vga_attribute_mode_control_reg vga_attribute_mode_control;
248     /* Index 17 */
249     vga_overscan_color_reg vga_overscan_color;
250     /* Index 18 */
251     struct vga_color_plane_enable_reg vga_color_plane_enable;
252     /* Index 19 */
253     struct vga_horizontal_pixel_pan_reg vga_horizontal_pixel_pan;
254     /* Index 20 */
255     struct vga_color_select_reg vga_color_select;
256 } __attribute__((packed));
257
258 struct vga_dac_regs {
259     enum {DAC_READ=0, DAC_WRITE} state;
260     enum {RED=0,GREEN,BLUE} channel;
261     vga_dac_pixel_mask_reg vga_pixel_mask;
262     vga_dac_write_addr_reg vga_dac_write_addr;
263     vga_dac_read_addr_reg vga_dac_read_addr;
264     // the dac_data register is used only to access the registers
265     // and thus has no representation here
266     vga_palette_reg vga_dac_palette[VGA_DAC_NUM_ENTRIES];
267 } __attribute__((packed));
268     
269
270 struct vga_internal {
271     struct vm_device *dev;  
272     
273     bool passthrough;
274     bool skip_next_passthrough_out; // for word access 
275
276     struct v3_frame_buffer_spec  target_spec;
277     v3_graphics_console_t host_cons;
278
279     uint32_t updates_since_render;
280
281     struct frame_buf *framebuf; // we render to this
282     
283     //    void *mem_store;     // This is the region where the memory hooks will go
284
285     vga_map  map[MAP_NUM];  // the maps that the host writes to
286
287     uint8_t  latch[MAP_NUM];  // written to in any read, used during writes
288
289     /* Range of I/O ports here for backward compat with MDA and CGA */
290     struct vga_misc_regs  vga_misc;
291
292     /* Address Register is 0x3b4 or 0x3d4 */
293     /* Data register is 0x3b5 or 0x3d5 based on MDA/CGA/VGA (backward compat) */
294     struct vga_crt_controller_regs vga_crt_controller;
295
296     /*   Address register is 0x3c4, data register is 0x3c5 */
297     struct vga_sequencer_regs vga_sequencer;
298
299     /*   Address: 0x3ce    Data: 0x3cf */
300     struct vga_graphics_controller_regs vga_graphics_controller;
301
302     /*
303       Address AND WRITE: 0x3c0
304       Read: 0x3c1
305       Flip-Flop
306     */
307     struct vga_attribute_contoller_regs vga_attribute_controller;
308
309     /*
310       address for reads: 0x3c7 (also resets state machine for access to 18 bit regs 
311       address for writes: 0x3c8 ("")
312       data: 0x3c9
313       pixel mask: 0x3c6 - do not write (init to 0xff)
314     */
315     struct vga_dac_regs vga_dac;
316 };
317
318
319
320 static int render(struct vga_internal *vga)
321 {
322     vga->updates_since_render++;
323
324     if (vga->host_cons && v3_graphics_console_inform_update(vga->host_cons)>0) { 
325         // Draw some crap for testing for now
326
327         void *fb;
328         struct v3_frame_buffer_spec *s;
329
330         fb = v3_graphics_console_get_frame_buffer_data_rw(vga->host_cons,&(vga->target_spec));
331
332         s=&(vga->target_spec);
333
334         if (0 && fb && s->height>=480 && s->width>=640 ) { 
335             uint8_t color = (uint8_t)(vga->updates_since_render);
336
337             uint32_t x, y;
338
339             for (y=0;y<480;y++) {
340                 for (x=0;x<640;x++) { 
341                     void *pixel = fb + ((x + (y*s->width)) * s->bytes_per_pixel);
342                     uint8_t *red = pixel + s->red_offset;
343                     uint8_t *green = pixel + s->green_offset;
344                     uint8_t *blue = pixel + s->blue_offset;
345
346                     if (y<(480/4)) { 
347                         *red=color+x;
348                         *green=0;
349                         *blue=0;
350                     } else if (y<(480/2)) { 
351                         *red=0;
352                         *green=color+x;
353                         *blue=0;
354                     } else if (y<(3*(480/4))) { 
355                         *red=0;
356                         *green=0;
357                         *blue=color+x;
358                     } else {
359                         *red=*green=*blue=color+x;
360                     }
361                 }
362             }
363         }
364
365         if (1 && fb && s->height>=768 && s->width>=1024 && !(vga->updates_since_render % 100)) { 
366             // we draw the maps next, each being a 256x256 block appearing 32 pixels below the display block
367             uint8_t m;
368             uint32_t x,y;
369             uint8_t *b;
370
371             for (m=0;m<4;m++) { 
372                 b=(vga->map[m]);
373                 for (y=480+32;y<768;y++) { 
374                     for (x=m*256;x<(m+1)*256;x++,b++) { 
375                         void *pixel = fb + ((x + (y*s->width)) * s->bytes_per_pixel);
376                         uint8_t *red = pixel + s->red_offset;
377                         uint8_t *green = pixel + s->green_offset;
378                         uint8_t *blue = pixel + s->blue_offset;
379
380                         *red=*green=*blue=*b;
381                     }
382                 }
383             }
384         }
385         v3_graphics_console_release_frame_buffer_data_rw(vga->host_cons);
386     }
387
388     return 0;
389 }
390
391
392 static void get_mem_region(struct vga_internal *vga, uint64_t *mem_start, uint64_t *mem_end) 
393 {
394     switch (vga->vga_graphics_controller.vga_misc.memory_map) { 
395         case 0: 
396             *mem_start=0xa0000;
397             *mem_end=0xc0000;
398             break;
399         case 1:
400             *mem_start=0xa0000;
401             *mem_end=0xb0000;
402             break;
403         case 2:
404             *mem_start=0xb0000;
405             *mem_end=0xb8000;
406             break;
407         case 3:
408             *mem_start=0xb8000;
409             *mem_end=0xc0000;
410             break;
411     }
412 }
413
414 static uint64_t find_offset(struct vga_internal *vga, addr_t guest_addr)
415 {
416     uint64_t mem_start, mem_end;
417     
418     mem_start=mem_end=0;
419     
420     get_mem_region(vga, &mem_start, &mem_end);
421
422     return (guest_addr-mem_start) % (mem_end-mem_start > 65536 ? 65536 : (mem_end-mem_start)); 
423
424 }
425
426     
427
428
429 static int vga_write(struct guest_info * core, 
430                      addr_t guest_addr, 
431                      void * src, 
432                      uint_t length, 
433                      void * priv_data)
434 {
435     struct vm_device *dev = (struct vm_device *)priv_data;
436     struct vga_internal *vga = (struct vga_internal *) dev->private_data;
437
438     PrintDebug("vga: memory write: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
439
440     if (vga->passthrough) { 
441         PrintDebug("vga: passthrough write to 0x%p\n", V3_VAddr((void*)guest_addr));
442         memcpy(V3_VAddr((void*)guest_addr),src,length);
443     }
444     
445 #if 0
446     int i;
447     PrintDebug("vga: data written was 0x");
448     for (i=0;i<length;i++) {
449         uint8_t c= ((char*)src)[i];
450         PrintDebug("%.2x", c);
451     }
452     PrintDebug(" \"");
453     for (i=0;i<length;i++) {
454         char c= ((char*)src)[i];
455         PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || (c==' ') ? c : '.');
456     }
457     PrintDebug("\"\n");
458 #endif
459
460     /* Write mode determine by Graphics Mode Register (Index 05h).writemode */
461     
462     switch (vga->vga_graphics_controller.vga_graphics_mode.write_mode) {
463         case 0: {
464             
465             /* 
466                00b -- Write Mode 0: In this mode, the host data is first rotated 
467                as per the Rotate Count field, then the Enable Set/Reset mechanism 
468                selects data from this or the Set/Reset field. Then the selected 
469                Logical Operation is performed on the resulting data and the data 
470                in the latch register. Then the Bit Mask field is used to select 
471                which bits come from the resulting data and which come 
472                from the latch register. Finally, only the bit planes enabled by 
473                the Memory Plane Write Enable field are written to memory.
474             */
475
476             int i;
477
478             uint8_t  mapnum;
479             uint64_t offset;
480
481             uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
482             uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
483             
484             offset = find_offset(vga, guest_addr);
485
486             PrintDebug("vga: mode 0 write, offset=0x%llx, ror=%u, func=%u\n", offset,ror,func);
487
488             for (i=0;i<length;i++,offset++) { 
489                 // now for each map
490                 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
491                 uint8_t esr = vga->vga_graphics_controller.vga_enable_set_reset.val &0xf;
492                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
493                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
494
495                 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, esr>>=1, bm>>=1, mm>>=1) { 
496                     vga_map map = vga->map[mapnum];
497                     uint8_t data = ((uint8_t *)src)[i];
498                     uint8_t latchval = vga->latch[mapnum];
499                         
500                     // rotate data right
501                     data = (data>>ror) | data<<(8-ror);
502
503                     // use SR bit if ESR is on for this map
504                     if (esr & 0x1) { 
505                         data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7);  // expand sr bit
506                     }
507                     
508                     // Apply function
509                     switch (func) { 
510                         case 0: // NOP
511                             break;
512                         case 1: // AND
513                             data &= latchval;
514                             break;
515                         case 2: // OR
516                             data |= latchval;
517                             break;
518                         case 3: // XOR
519                             data ^= latchval;
520                             break;
521                     }
522                             
523                     // mux between latch and alu output
524                     if (bm & 0x1) { 
525                         // use alu output, which is in data
526                     } else {
527                         // use latch value
528                         data=latchval;
529                     }
530                     
531                     // selective write
532                     if (mm & 0x1) { 
533                         // write to this map
534                         //PrintDebug("vga: write map %u offset 0x%p map=0x%p pointer=0x%p\n",mapnum,(void*)offset,map,&(map[offset]));
535                         map[offset] = data;
536                     } else {
537                         // skip this map
538                     }
539                 }
540             }
541         }
542             break;
543
544
545             
546         case 1: {
547             /* 
548                01b -- Write Mode 1: In this mode, data is transferred directly 
549                from the 32 bit latch register to display memory, affected only by 
550                the Memory Plane Write Enable field. The host data is not used in this mode.
551             */
552
553             int i;
554
555             uint64_t offset = find_offset(vga,guest_addr);
556
557             PrintDebug("vga: mode 1 write, offset=0x%llx\n", offset);
558
559             for (i=0;i<length;i++,offset++) { 
560
561                 uint8_t mapnum;
562                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
563
564                 for (mapnum=0;mapnum<4;mapnum++,  mm>>=1) { 
565                     vga_map map = vga->map[mapnum];
566                     uint8_t latchval = vga->latch[mapnum];
567                         
568                     // selective write
569                     if (mm & 0x1) { 
570                         // write to this map
571                         map[offset] = latchval;
572                     } else {
573                         // skip this map
574                     }
575                 }
576             }
577         }
578             break;
579
580         case 2: {
581             /*
582               10b -- Write Mode 2: In this mode, the bits 3-0 of the host data 
583               are replicated across all 8 bits of their respective planes. 
584               Then the selected Logical Operation is performed on the resulting 
585               data and the data in the latch register. Then the Bit Mask field is used to 
586               select which bits come from the resulting data and which come from 
587               the latch register. Finally, only the bit planes enabled by the 
588               Memory Plane Write Enable field are written to memory.
589             */
590             int i;
591             uint8_t  mapnum;
592             uint64_t offset;
593
594             uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
595             
596             offset = find_offset(vga, guest_addr);
597
598             PrintDebug("vga: mode 2 write, offset=0x%llx, func=%u\n", offset,func);
599
600             for (i=0;i<length;i++,offset++) { 
601                 // now for each map
602                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
603                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
604
605                 for (mapnum=0;mapnum<4;mapnum++,  bm>>=1, mm>>=1) { 
606                     vga_map map = vga->map[mapnum];
607                     uint8_t data = ((uint8_t *)src)[i];
608                     uint8_t latchval = vga->latch[mapnum];
609                         
610                     // expand relevant bit to 8 bit
611                     // it's basically esr=1, sr=bit from write
612                     data = (uint8_t)(((sint8_t)(((data>>mapnum)&0x1)<<7))>>7);
613                     
614                     // Apply function
615                     switch (func) { 
616                         case 0: // NOP
617                             break;
618                         case 1: // AND
619                             data &= latchval;
620                             break;
621                         case 2: // OR
622                             data |= latchval;
623                             break;
624                         case 3: // XOR
625                             data ^= latchval;
626                             break;
627                     }
628                             
629                     // mux between latch and alu output
630                     if (bm & 0x1) { 
631                         // use alu output, which is in data
632                     } else {
633                         // use latch value
634                         data=latchval;
635                     }
636                     
637                     // selective write
638                     if (mm & 0x1) { 
639                         // write to this map
640                         map[offset] = data;
641                     } else {
642                         // skip this map
643                     }
644                 }
645             }
646         }
647             break;
648
649         case 3: {
650             /* 11b -- Write Mode 3: In this mode, the data in the Set/Reset field is used 
651                as if the Enable Set/Reset field were set to 1111b. Then the host data is 
652                first rotated as per the Rotate Count field, then logical ANDed with the 
653                value of the Bit Mask field. The resulting value is used on the data 
654                obtained from the Set/Reset field in the same way that the Bit Mask field 
655                would ordinarily be used. to select which bits come from the expansion 
656                of the Set/Reset field and which come from the latch register. Finally, 
657                only the bit planes enabled by the Memory Plane Write Enable field 
658                are written to memory.
659             */
660             int i;
661
662             uint8_t  mapnum;
663             uint64_t offset;
664
665             uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
666             
667             offset = find_offset(vga, guest_addr);
668
669             PrintDebug("vga: mode 3 write, offset=0x%llx, ror=%u\n", offset,ror);
670
671             for (i=0;i<length;i++,offset++) { 
672                 // now for each map
673                 uint8_t data = ((uint8_t *)src)[i];
674
675                 data = (data>>ror) | data<<(8-ror);
676
677                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask & data;
678                 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
679                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
680
681                 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, bm>>=1, mm>>=1) { 
682                     vga_map map = vga->map[mapnum];
683                     uint8_t latchval = vga->latch[mapnum];
684                         
685                     data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7);  // expand sr bit
686                     
687                     
688                     // mux between latch and alu output
689                     if (bm & 0x1) { 
690                         // use alu output, which is in data
691                     } else {
692                         // use latch value
693                         data=latchval;
694                     }
695                     
696                     // selective write
697                     if (mm & 0x1) { 
698                         // write to this map
699                         map[offset] = data;
700                     } else {
701                         // skip this map
702                     }
703                 }
704             }
705
706         }
707             break;
708
709             // There is no default
710     }
711
712     render(vga);
713     
714     return length;
715 }
716
717
718 /*
719 up to 256K mapped through a window of 32 to 128K
720
721 most cards support linear mode as well
722
723 Need to implement readability too
724
725 Write extended memory bit to enable all 256K: 
726
727    Sequencer Memory Mode Register (Index 04h) . extended memory
728
729 Must enable writes before effects happen:
730   
731   Miscellaneous Output Register (Read at 3CCh, Write at 3C2h).ram enable
732
733 Choose which addresses are supported for CPU writes:
734
735 Miscellaneous Graphics Register (Index 06h).memory map select
736  
737 00b -- A0000h-BFFFFh (128K region)
738 01b -- A0000h-AFFFFh (64K region)
739 10b -- B0000h-B7FFFh (32K region)
740 11b -- B8000h-BFFFFh (32K region)
741
742 There are three addressing modes: Chain 4, Odd/Even mode, and normal mode:
743
744 Chain 4: This mode is used for MCGA emulation in the 320x200 256-color mode. The address is mapped to memory MOD 4 (shifted right 2 places.)
745
746 Memory model: 64K 32 bit locations; divided into 4 64K bit planes
747
748
749    
750
751
752 Assume linear framebuffer, starting at address buf:
753
754 */
755
756
757
758 static int vga_read(struct guest_info * core, 
759                     addr_t guest_addr, 
760                     void * dst, 
761                     uint_t length, 
762                     void * priv_data)
763 {
764     struct vm_device *dev = (struct vm_device *)priv_data;
765     struct vga_internal *vga = (struct vga_internal *) dev->private_data;
766     
767
768     PrintDebug("vga: memory read: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
769
770
771                 
772    
773     /*
774       Reading, 2 modes, set via Graphics Mode Register (index 05h).Read Mode:
775     */
776     switch (vga->vga_graphics_controller.vga_graphics_mode.read_mode) { 
777         case 0: {
778             /*      0 - a byte from ONE of the 4 planes is returned; 
779                     which plane is determined by Read Map Select (Read Map Select Register (Index 04h)) */
780             uint8_t  mapnum;
781             uint64_t offset;
782             
783             mapnum = vga->vga_graphics_controller.vga_read_map_select.map_select;
784             offset = find_offset(vga,guest_addr);
785             
786             if (offset>=65536) { 
787                 PrintError("vga: read to offset=%llu map=%u (%u bytes)\n",offset,mapnum,length);
788             }
789
790             memcpy(dst,(vga->map[mapnum])+offset,length);
791
792             // load the latches with the last item read
793             for (mapnum=0;mapnum<4;mapnum++) { 
794                 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
795             }
796             
797         
798         }
799             break;
800         case 1: {
801             /*      1 - Compare video memory and reference color 
802                     (in Color Compare, except those not set in Color Don't Care), 
803                     each bit in returned result is one comparison between the reference color 
804
805                     Ref color is *4* bits, and thus a one byte read returns a comparison 
806                     with 8 pixels
807
808             */
809             int i;
810
811             uint8_t cc=vga->vga_graphics_controller.vga_color_compare.val & 0xf ;
812             uint8_t dc=vga->vga_graphics_controller.vga_color_dont_care.val & 0xf;
813
814             uint8_t  mapnum;
815             uint64_t offset;
816             uint8_t  byte;
817             uint8_t  bits;
818             
819             offset = find_offset(vga,guest_addr);
820             
821             for (i=0;i<length;i++,offset++) { 
822                 vga_map map;
823                 byte=0;
824                 for (mapnum=0;mapnum<4;mapnum++) { 
825                     map = vga->map[mapnum];
826                     if ( (dc>>mapnum)&0x1 ) { // don't care
827                         bits=0;
828                     } else {
829                         // lower 4 bits
830                         bits = (map[offset]&0xf) == cc;
831                         bits <<= 1;
832                         // upper 4 bits
833                         bits |= (((map[offset]>>4))&0xf) == cc;
834                     }
835                     // not clear whether it is 0..k or k..0
836                     byte<<=2;
837                     byte|=bits;
838                 }
839             }
840
841             // load the latches with the last item read
842             for (mapnum=0;mapnum<4;mapnum++) { 
843                 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
844             }
845
846         }
847             break;
848             // there is no default
849     }
850
851     if (vga->passthrough) { 
852         PrintDebug("vga: passthrough read from 0x%p\n",V3_VAddr((void*)guest_addr));
853         memcpy(dst,V3_VAddr((void*)guest_addr),length);
854     }
855
856
857 #if 0
858     int i;
859     PrintDebug("vga: data read is 0x");
860     for (i=0;i<length;i++) {
861         uint8_t c= ((char*)dst)[i];
862         PrintDebug("%.2x", c);
863     }
864     PrintDebug(" \"");
865     for (i=0;i<length;i++) {
866         char c= ((char*)dst)[i];
867         PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || (c==' ') ? c : '.');
868     }
869     PrintDebug("\"\n");
870 #endif
871
872     return length;
873
874 }
875
876
877
878
879
880 #define ERR_WRONG_SIZE(op,reg,len,min,max)      \
881     if (((len)<(min)) || ((len)>(max))) {       \
882         PrintError("vga: %s of %s wrong size (%d bytes, but only %d to %d allowed)\n",(op),(reg),(len),(min),(max)); \
883         return -1; \
884 }
885         
886 static inline void passthrough_io_in(uint16_t port, void * dest, uint_t length) {
887     switch (length) {
888         case 1:
889             *(uint8_t *)dest = v3_inb(port);
890             break;
891         case 2:
892             *(uint16_t *)dest = v3_inw(port);
893             break;
894         case 4:
895             *(uint32_t *)dest = v3_indw(port);
896             break;
897         default:
898             PrintError("vga: unsupported passthrough io in size %u\n",length);
899             break;
900     }
901 }
902
903
904 static inline void passthrough_io_out(uint16_t port, const void * src, uint_t length) {
905     switch (length) {
906         case 1:
907             v3_outb(port, *(uint8_t *)src);
908             break;
909         case 2:
910             v3_outw(port, *(uint16_t *)src);
911             break;
912         case 4:
913             v3_outdw(port, *(uint32_t *)src);
914             break;
915         default:
916             PrintError("vga: unsupported passthrough io out size %u\n",length);
917             break;
918     }
919 }
920
921 #define PASSTHROUGH_IO_IN(vga,port,dest,len)                            \
922     do { if ((vga)->passthrough) { passthrough_io_in(port,dest,len); } } while (0)
923
924 #define PASSTHROUGH_IO_OUT(vga,port,src,len)                            \
925     do { if ((vga)->passthrough && (!(vga)->skip_next_passthrough_out)) { passthrough_io_out(port,src,len); } (vga)->skip_next_passthrough_out=false; } while (0)
926
927 #define PASSTHROUGH_IO_SKIP_NEXT_OUT(vga)                                       \
928     do { if ((vga)->passthrough) { (vga)->skip_next_passthrough_out=true; } } while (0)
929                 
930 #define PASSTHROUGH_READ_CHECK(vga,inter,pass) \
931     do { if ((vga)->passthrough) { if ((inter)!=(pass)) { PrintError("vga: passthrough error: passthrough value read is 0x%x, but internal value read is 0x%x\n",(pass),(inter)); } } } while (0)
932
933 static int misc_out_read(struct guest_info *core, 
934                          uint16_t port, 
935                          void *dest,
936                          uint_t len,
937                          void *priv_data)
938 {
939     struct vga_internal *vga = (struct vga_internal *) priv_data;
940
941     PrintDebug("vga: misc out read data=0x%x\n", vga->vga_misc.vga_misc_out.val);
942
943     ERR_WRONG_SIZE("read","misc out",len,1,1);
944    
945     *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
946
947     PASSTHROUGH_IO_IN(vga,port,dest,len);
948
949     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_misc_out.val,*((uint8_t*)dest));
950
951     return len;
952 }
953
954 static int misc_out_write(struct guest_info *core, 
955                           uint16_t port, 
956                           void *src,
957                           uint_t len,
958                           void *priv_data)
959 {
960     struct vga_internal *vga = (struct vga_internal *) priv_data;
961     
962     PrintDebug("vga: misc out write data=0x%x\n", *((uint8_t*)src));
963         
964     ERR_WRONG_SIZE("write","misc out",len,1,1);
965
966     PASSTHROUGH_IO_OUT(vga,port,src,len);
967
968     vga->vga_misc.vga_misc_out.val =  *((uint8_t*)src) ;
969     
970     render(vga);
971     
972     return len;
973 }
974
975
976
977 static int input_stat0_read(struct guest_info *core, 
978                             uint16_t port, 
979                             void *dest,
980                             uint_t len,
981                             void *priv_data)
982 {
983     struct vga_internal *vga = (struct vga_internal *) priv_data;
984
985     PrintDebug("vga: input stat0  read data=0x%x\n", vga->vga_misc.vga_input_stat0.val);
986
987     ERR_WRONG_SIZE("read","input stat0",len,1,1);
988
989     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
990
991     PASSTHROUGH_IO_IN(vga,port,dest,len);
992
993     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat0.val,*(uint8_t*)dest);
994
995     return len;
996 }
997
998
999 static int input_stat1_read(struct guest_info *core, 
1000                             uint16_t port, 
1001                             void *dest,
1002                             uint_t len,
1003                             void *priv_data)
1004 {
1005     struct vga_internal *vga = (struct vga_internal *) priv_data;
1006
1007     PrintDebug("vga: input stat0 (%s) read data=0x%x\n", 
1008                port==0x3ba ? "mono" : "color",
1009                vga->vga_misc.vga_input_stat1.val);
1010
1011     ERR_WRONG_SIZE("read","input stat1",len,1,1);
1012
1013
1014     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val;
1015
1016     // Stunningly, reading stat1 is also a way to reset
1017     // the state of attribute controller address/data flipflop
1018     // That is some mighty fine crack the designers were smoking.
1019     
1020     vga->vga_attribute_controller.state=ATTR_ADDR;
1021
1022     PASSTHROUGH_IO_IN(vga,port,dest,len);
1023
1024     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat1.val,*(uint8_t*)dest);
1025
1026     return len;
1027 }
1028                          
1029
1030 static int feature_control_read(struct guest_info *core, 
1031                                 uint16_t port, 
1032                                 void *dest,
1033                                 uint_t len,
1034                                 void *priv_data)
1035 {
1036     struct vga_internal *vga = (struct vga_internal *) priv_data;
1037
1038     PrintDebug("vga: feature control  read data=0x%x\n", 
1039                vga->vga_misc.vga_feature_control.val);
1040
1041     ERR_WRONG_SIZE("read","feature control",len,1,1);
1042
1043
1044     *((uint8_t*)dest) = vga->vga_misc.vga_feature_control.val;
1045
1046     PASSTHROUGH_IO_IN(vga,port,dest,len);
1047
1048     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_feature_control.val,*(uint8_t*)dest);
1049
1050     return len;
1051 }
1052
1053 static int feature_control_write(struct guest_info *core, 
1054                                  uint16_t port, 
1055                                  void *src,
1056                                  uint_t len,
1057                                  void *priv_data)
1058 {
1059     struct vga_internal *vga = (struct vga_internal *) priv_data;
1060     
1061     PrintDebug("vga: feature control (%s) write data=0x%x\n", 
1062                port==0x3ba ? "mono" : "color",
1063                *((uint8_t*)src));
1064         
1065     ERR_WRONG_SIZE("write","feature control",len,1,1);
1066     
1067     PASSTHROUGH_IO_OUT(vga,port,src,len);
1068
1069     vga->vga_misc.vga_feature_control.val =  *((uint8_t*)src) ;
1070     
1071     render(vga);
1072     
1073     return len;
1074 }
1075
1076
1077 static int video_subsys_enable_read(struct guest_info *core, 
1078                                     uint16_t port, 
1079                                     void *dest,
1080                                     uint_t len,
1081                                     void *priv_data)
1082 {
1083     struct vga_internal *vga = (struct vga_internal *) priv_data;
1084
1085     PrintDebug("vga: video subsys enable read data=0x%x\n", 
1086                vga->vga_misc.vga_video_subsys_enable.val);
1087
1088     ERR_WRONG_SIZE("read","video subsys enable",len,1,1);
1089
1090     *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
1091
1092     PASSTHROUGH_IO_IN(vga,port,dest,len);
1093
1094     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_video_subsys_enable.val,*(uint8_t*)dest);
1095
1096     return len;
1097 }
1098
1099 static int video_subsys_enable_write(struct guest_info *core, 
1100                                      uint16_t port, 
1101                                      void *src,
1102                                      uint_t len,
1103                                      void *priv_data)
1104 {
1105     struct vga_internal *vga = (struct vga_internal *) priv_data;
1106     
1107     PrintDebug("vga: video subsys enable write data=0x%x\n", *((uint8_t*)src));
1108         
1109     ERR_WRONG_SIZE("write","video subsys enable",len,1,1);
1110     
1111     PASSTHROUGH_IO_OUT(vga,port,src,len);
1112
1113     vga->vga_misc.vga_video_subsys_enable.val =  *((uint8_t*)src) ;
1114     
1115     render(vga);
1116     
1117     return len;
1118 }
1119
1120 static int sequencer_address_read(struct guest_info *core, 
1121                                   uint16_t port, 
1122                                   void *dest,
1123                                   uint_t len,
1124                                   void *priv_data)
1125 {
1126     struct vga_internal *vga = (struct vga_internal *) priv_data;
1127
1128     PrintDebug("vga: sequencer address read data=0x%x\n", 
1129                vga->vga_sequencer.vga_sequencer_addr.val);
1130
1131     ERR_WRONG_SIZE("read","vga sequencer addr",len,1,1);
1132
1133     *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
1134
1135     PASSTHROUGH_IO_IN(vga,port,dest,len);
1136
1137     PASSTHROUGH_READ_CHECK(vga,vga->vga_sequencer.vga_sequencer_addr.val,*(uint8_t*)dest);
1138
1139     return len;
1140 }
1141
1142 static int sequencer_data_write(struct guest_info *core, 
1143                                uint16_t port, 
1144                                void *src,
1145                                uint_t len,
1146                                void *priv_data)
1147 {
1148     struct vga_internal *vga = (struct vga_internal *) priv_data;
1149     uint8_t index;
1150     uint8_t data;
1151     
1152     data=*((uint8_t*)src);
1153     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
1154     
1155     PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n", 
1156                index, data);
1157     
1158     ERR_WRONG_SIZE("write","vga sequencer data",len,1,1);
1159     
1160     PASSTHROUGH_IO_OUT(vga,port,src,len);
1161
1162
1163     if (index>=VGA_SEQUENCER_NUM) { 
1164         PrintError("vga: sequencer data write is for invalid index %d, ignoring\n",index);
1165     } else {
1166         vga->vga_sequencer.vga_sequencer_regs[index] = data;
1167     }
1168
1169     render(vga);
1170     
1171     return len;
1172 }
1173
1174 static int sequencer_address_write(struct guest_info *core, 
1175                                   uint16_t port, 
1176                                   void *src,
1177                                   uint_t len,
1178                                   void *priv_data)
1179 {
1180     struct vga_internal *vga = (struct vga_internal *) priv_data;
1181     uint8_t new_addr;
1182
1183     new_addr=*((uint8_t*)src);
1184
1185     PrintDebug("vga: sequencer address write data=0x%x len=%u\n", len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1186
1187     ERR_WRONG_SIZE("write","vga sequencer addr",len,1,2);
1188
1189     PASSTHROUGH_IO_OUT(vga,port,src,len);
1190     
1191     vga->vga_sequencer.vga_sequencer_addr.val =  *((uint8_t*)src) ;
1192     
1193     if (len==2) { 
1194         PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1195         // second byte is the data
1196         if (sequencer_data_write(core,port,src+1,1,vga)!=1) { 
1197             PrintError("vga: write of data failed\n");
1198             return -1;
1199         }
1200     }
1201
1202     return len;
1203 }
1204
1205 static int sequencer_data_read(struct guest_info *core, 
1206                               uint16_t port, 
1207                               void *dest,
1208                               uint_t len,
1209                               void *priv_data)
1210 {
1211     struct vga_internal *vga = (struct vga_internal *) priv_data;
1212     uint8_t index;
1213     uint8_t data;
1214
1215     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
1216
1217     if (index>=VGA_SEQUENCER_NUM) { 
1218         data=0;
1219         PrintError("vga: sequencer data read at invalid index %d, returning zero\n",index);
1220     } else {
1221         data=vga->vga_sequencer.vga_sequencer_regs[index];
1222     }
1223
1224     PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n", 
1225                    index, data);
1226     
1227     ERR_WRONG_SIZE("read","vga sequencer data",len,1,1);
1228
1229     *((uint8_t*)dest) = data;
1230
1231     PASSTHROUGH_IO_IN(vga,port,dest,len);
1232
1233     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1234
1235     return len;
1236 }
1237
1238  
1239  
1240
1241
1242 static int crt_controller_address_read(struct guest_info *core, 
1243                                         uint16_t port, 
1244                                         void *dest,
1245                                         uint_t len,
1246                                         void *priv_data)
1247 {
1248     struct vga_internal *vga = (struct vga_internal *) priv_data;
1249
1250     PrintDebug("vga: crt controller (%s) address read data=0x%x\n", 
1251                port==0x3b4 ? "mono" : "color",
1252                vga->vga_crt_controller.vga_crt_addr.val);
1253
1254     ERR_WRONG_SIZE("read","vga crt controller addr",len,1,1);
1255
1256     *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
1257
1258     PASSTHROUGH_IO_IN(vga,port,dest,len);
1259
1260     PASSTHROUGH_READ_CHECK(vga,vga->vga_crt_controller.vga_crt_addr.val,*(uint8_t*)dest);
1261
1262     return len;
1263 }
1264
1265 static int crt_controller_data_write(struct guest_info *core, 
1266                                      uint16_t port, 
1267                                      void *src,
1268                                      uint_t len,
1269                                      void *priv_data)
1270 {
1271     struct vga_internal *vga = (struct vga_internal *) priv_data;
1272     uint8_t index;
1273     uint8_t data;
1274
1275     data=*((uint8_t*)src);
1276
1277     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
1278     
1279     PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n", 
1280                port==0x3b5 ? "mono" : "color",
1281                index, data);
1282
1283     ERR_WRONG_SIZE("write","vga crt controller data",len,1,1);
1284
1285     PASSTHROUGH_IO_OUT(vga,port,src,len);
1286
1287     if (index>=VGA_CRT_CONTROLLER_NUM) { 
1288         PrintError("vga; crt controller write is for illegal index %d, ignoring\n",index);
1289     } else {
1290         vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
1291     }
1292
1293     render(vga);
1294
1295     return len;
1296 }
1297
1298 static int crt_controller_address_write(struct guest_info *core, 
1299                                         uint16_t port, 
1300                                         void *src,
1301                                         uint_t len,
1302                                         void *priv_data)
1303 {
1304     struct vga_internal *vga = (struct vga_internal *) priv_data;
1305     uint8_t new_addr;
1306
1307     new_addr=*((uint8_t*)src);
1308
1309     PrintDebug("vga: crt controller (%s) address write data=0x%x len=%u\n", 
1310                port==0x3b4 ? "mono" : "color",
1311                len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1312
1313     ERR_WRONG_SIZE("write","vga crt controller addr",len,1,2);
1314
1315     PASSTHROUGH_IO_OUT(vga,port,src,len);
1316
1317     vga->vga_crt_controller.vga_crt_addr.val =  *((uint8_t*)src) ;
1318         
1319     if (len==2) { 
1320         PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1321         // second byte is the data
1322         if (crt_controller_data_write(core,port,src+1,1,vga)!=1) { 
1323             PrintError("vga: write of data failed\n");
1324             return -1;
1325         }
1326     }
1327     
1328     return len;
1329 }
1330
1331 static int crt_controller_data_read(struct guest_info *core, 
1332                                     uint16_t port, 
1333                                     void *dest,
1334                                     uint_t len,
1335                                     void *priv_data)
1336 {
1337     struct vga_internal *vga = (struct vga_internal *) priv_data;
1338     uint8_t index;
1339     uint8_t data;
1340
1341     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
1342     
1343     if (index>=VGA_CRT_CONTROLLER_NUM) { 
1344         data=0;
1345         PrintError("vga: crt controller data read for illegal index %d, returning zero\n",index);
1346     } else {
1347         data=vga->vga_crt_controller.vga_crt_controller_regs[index];
1348     }
1349
1350     PrintDebug("vga: crt controller data (index=%d) = 0x%x\n",index,data);
1351     
1352     ERR_WRONG_SIZE("read","vga crt controller data",len,1,1);
1353
1354     *((uint8_t*)dest) = data;
1355
1356     PASSTHROUGH_IO_IN(vga,port,dest,len);
1357
1358     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t *)dest);
1359
1360     return len;
1361 }
1362
1363
1364
1365 static int graphics_controller_address_read(struct guest_info *core, 
1366                                             uint16_t port, 
1367                                             void *dest,
1368                                             uint_t len,
1369                                             void *priv_data)
1370 {
1371     struct vga_internal *vga = (struct vga_internal *) priv_data;
1372     
1373     PrintDebug("vga: graphics controller address read data=0x%x\n", 
1374                vga->vga_graphics_controller.vga_graphics_ctrl_addr.val);
1375
1376     ERR_WRONG_SIZE("read","vga graphics controller addr",len,1,1);
1377
1378     *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
1379
1380     PASSTHROUGH_IO_IN(vga,port,dest,len);
1381
1382     PASSTHROUGH_READ_CHECK(vga,vga->vga_graphics_controller.vga_graphics_ctrl_addr.val,*(uint8_t*)dest);
1383
1384     return len;
1385 }
1386
1387 static int graphics_controller_data_write(struct guest_info *core, 
1388                                           uint16_t port, 
1389                                           void *src,
1390                                           uint_t len,
1391                                           void *priv_data)
1392 {
1393     struct vga_internal *vga = (struct vga_internal *) priv_data;
1394     uint8_t index;
1395     uint8_t data;
1396     
1397     data=*((uint8_t*)src);
1398     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
1399     
1400
1401     PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n", 
1402                index, data);
1403     
1404     ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
1405     
1406     PASSTHROUGH_IO_OUT(vga,port,src,len);
1407
1408     if (index>=VGA_GRAPHICS_CONTROLLER_NUM) { 
1409         PrintError("vga: graphics controller write for illegal index %d ignored\n",index);
1410     } else {
1411         vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
1412     }
1413
1414     render(vga);
1415     
1416     return len;
1417 }
1418
1419 static int graphics_controller_address_write(struct guest_info *core, 
1420                                              uint16_t port, 
1421                                              void *src,
1422                                              uint_t len,
1423                                              void *priv_data)
1424 {
1425     struct vga_internal *vga = (struct vga_internal *) priv_data;
1426     uint8_t new_addr;
1427
1428     new_addr=*((uint8_t*)src);
1429
1430     PrintDebug("vga: graphics controller address write data=0x%x len=%u\n", 
1431                len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1432
1433     ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,2);
1434
1435     PASSTHROUGH_IO_OUT(vga,port,src,len);
1436
1437     vga->vga_graphics_controller.vga_graphics_ctrl_addr.val =  *((uint8_t*)src) ;
1438
1439     if (len==2) { 
1440         PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1441         // second byte is the data
1442         if (graphics_controller_data_write(core,port,src+1,1,vga)!=1) { 
1443             PrintError("vga: write of data failed\n");
1444             return -1;
1445         }
1446     }
1447
1448     return len;
1449 }
1450
1451 static int graphics_controller_data_read(struct guest_info *core, 
1452                                          uint16_t port, 
1453                                          void *dest,
1454                                          uint_t len,
1455                                          void *priv_data)
1456 {
1457     struct vga_internal *vga = (struct vga_internal *) priv_data;
1458     uint8_t index;
1459     uint8_t data;
1460
1461     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
1462
1463
1464     if (index>=VGA_GRAPHICS_CONTROLLER_NUM) { 
1465         data=0;
1466         PrintError("vga: graphics controller data read from illegal index %d, returning zero\n",index);
1467     } else {
1468         data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
1469     }
1470     
1471     PrintDebug("vga: graphics controller data read data (index=%d) = 0x%x\n", 
1472                index, data);
1473
1474     ERR_WRONG_SIZE("read","vga graphics controller data",len,1,1);
1475
1476     *((uint8_t*)dest) = data;
1477
1478     PASSTHROUGH_IO_IN(vga,port,dest,len);
1479
1480     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1481     
1482     return len;
1483 }
1484
1485
1486
1487
1488 /* Note that these guys have a bizarre protocol*/
1489
1490 static int attribute_controller_address_read(struct guest_info *core, 
1491                                              uint16_t port, 
1492                                              void *dest,
1493                                              uint_t len,
1494                                              void *priv_data)
1495 {
1496     struct vga_internal *vga = (struct vga_internal *) priv_data;
1497     
1498     PrintDebug("vga: attribute controller address read data=0x%x\n", 
1499                vga->vga_attribute_controller.vga_attribute_controller_addr.val);
1500
1501     ERR_WRONG_SIZE("read","vga attribute  controller addr",len,1,1);
1502
1503     *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
1504
1505     PASSTHROUGH_IO_IN(vga,port,dest,len);
1506
1507     PASSTHROUGH_READ_CHECK(vga,vga->vga_attribute_controller.vga_attribute_controller_addr.val,*(uint8_t*)dest);
1508
1509     // Reading the attribute controller does not change the state
1510
1511     return len;
1512 }
1513
1514 static int attribute_controller_address_and_data_write(struct guest_info *core, 
1515                                                        uint16_t port, 
1516                                                        void *src,
1517                                                        uint_t len,
1518                                                        void *priv_data)
1519 {
1520     struct vga_internal *vga = (struct vga_internal *) priv_data;
1521
1522
1523     if (vga->vga_attribute_controller.state==ATTR_ADDR) { 
1524         uint8_t new_addr = *((uint8_t*)src);
1525         // We are to treat this as an address write, and flip state
1526         // to expect data ON THIS SAME PORT
1527         PrintDebug("vga: attribute controller address write data=0x%x\n", new_addr);
1528         
1529         ERR_WRONG_SIZE("write","vga attribute controller addr",len,1,1);
1530
1531         PASSTHROUGH_IO_OUT(vga,port,src,len);
1532
1533         vga->vga_attribute_controller.vga_attribute_controller_addr.val =  new_addr;
1534
1535         vga->vga_attribute_controller.state=ATTR_DATA;
1536         return len;
1537
1538     } else if (vga->vga_attribute_controller.state==ATTR_DATA) { 
1539
1540         uint8_t data = *((uint8_t*)src);
1541         uint8_t index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
1542
1543         PrintDebug("vga: attribute controller data write index %d with data=0x%x\n", index,data);
1544         
1545         ERR_WRONG_SIZE("write","vga attribute controller data",len,1,1);
1546
1547         PASSTHROUGH_IO_OUT(vga,port,src,len);
1548         
1549         if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) { 
1550             PrintError("vga: attribute controller write to illegal index %d ignored\n",index);
1551         } else {
1552             vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
1553         }
1554         
1555         vga->vga_attribute_controller.state=ATTR_ADDR;
1556         
1557         return len;
1558     }
1559     
1560     return -1;
1561         
1562 }
1563
1564 static int attribute_controller_data_read(struct guest_info *core, 
1565                                           uint16_t port, 
1566                                           void *dest,
1567                                           uint_t len,
1568                                           void *priv_data)
1569 {
1570     struct vga_internal *vga = (struct vga_internal *) priv_data;
1571     uint8_t index;
1572     uint8_t data;
1573
1574     index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
1575
1576     if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) { 
1577         data=0;
1578         PrintError("vga: attribute controller read of illegal index %d, returning zero\n",index);
1579     } else {
1580         data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
1581     }
1582     
1583     PrintDebug("vga: attribute controller data read data (index=%d) = 0x%x\n", 
1584                index, data);
1585
1586     ERR_WRONG_SIZE("read","vga attribute controller data",len,1,1);
1587
1588     *((uint8_t*)dest) = data;
1589
1590     PASSTHROUGH_IO_IN(vga,port,dest,len);
1591
1592     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1593
1594     return len;
1595 }
1596
1597
1598 /*
1599    Note that these guys also have a strange protocol
1600    since they need to squeeze 18 bits of data through
1601    an 8 bit port 
1602 */
1603 static int dac_write_address_read(struct guest_info *core, 
1604                                   uint16_t port, 
1605                                   void *dest,
1606                                   uint_t len,
1607                                   void *priv_data)
1608 {
1609     struct vga_internal *vga = (struct vga_internal *) priv_data;
1610     
1611     PrintDebug("vga: dac write address read data=0x%x\n", 
1612                vga->vga_dac.vga_dac_write_addr);
1613
1614     ERR_WRONG_SIZE("read","vga dac write addr",len,1,1);
1615
1616
1617     *((uint8_t*)dest) = vga->vga_dac.vga_dac_write_addr;
1618
1619     PASSTHROUGH_IO_IN(vga,port,dest,len);
1620     
1621     PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_write_addr,*(uint8_t*)dest);
1622
1623     // This read does not reset the state machine
1624
1625     return len;
1626 }
1627
1628 static int dac_write_address_write(struct guest_info *core, 
1629                                    uint16_t port, 
1630                                    void *src,
1631                                    uint_t len,
1632                                    void *priv_data)
1633 {
1634     struct vga_internal *vga = (struct vga_internal *) priv_data;
1635     uint8_t new_addr;
1636
1637     new_addr=*((uint8_t*)src);
1638
1639     PrintDebug("vga: dac write address write data=0x%x\n", new_addr);
1640
1641     ERR_WRONG_SIZE("write","vga dac write addr",len,1,1);
1642
1643     PASSTHROUGH_IO_OUT(vga,port,src,len);
1644
1645     // cannot be out of bounds since there are 256 regs
1646
1647     vga->vga_dac.vga_dac_write_addr =  *((uint8_t*)src) ;
1648
1649     // Now we also need to reset the state machine
1650     
1651     vga->vga_dac.state=DAC_WRITE;
1652     vga->vga_dac.channel=RED;
1653
1654     return len;
1655 }
1656
1657
1658 static int dac_read_address_read(struct guest_info *core, 
1659                                  uint16_t port, 
1660                                  void *dest,
1661                                  uint_t len,
1662                                  void *priv_data)
1663 {
1664     struct vga_internal *vga = (struct vga_internal *) priv_data;
1665     
1666     PrintDebug("vga: dac read address read data=0x%x\n", 
1667                vga->vga_dac.vga_dac_read_addr);
1668
1669     ERR_WRONG_SIZE("read","vga dac read addr",len,1,1);
1670
1671     *((uint8_t*)dest) = vga->vga_dac.vga_dac_read_addr;
1672
1673     PASSTHROUGH_IO_IN(vga,port,dest,len);
1674
1675     PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_read_addr,*(uint8_t*)dest);
1676     
1677     // This read does not reset the state machine
1678
1679     return len;
1680 }
1681
1682 static int dac_read_address_write(struct guest_info *core, 
1683                                   uint16_t port, 
1684                                   void *src,
1685                                   uint_t len,
1686                                   void *priv_data)
1687 {
1688     struct vga_internal *vga = (struct vga_internal *) priv_data;
1689     uint8_t new_addr;
1690
1691     new_addr=*((uint8_t*)src);
1692
1693     PrintDebug("vga: dac read address write data=0x%x\n", new_addr);
1694
1695     ERR_WRONG_SIZE("write","vga dac read addr",len,1,1);
1696
1697     PASSTHROUGH_IO_OUT(vga,port,src,len);
1698
1699     // cannot be out of bounds since there are 256 regs
1700
1701     vga->vga_dac.vga_dac_read_addr =  *((uint8_t*)src) ;
1702
1703     // Now we also need to reset the state machine
1704     
1705     vga->vga_dac.state=DAC_READ;
1706     vga->vga_dac.channel=RED;
1707
1708     return len;
1709 }
1710
1711
1712 static int dac_data_read(struct guest_info *core, 
1713                          uint16_t port, 
1714                          void *dest,
1715                          uint_t len,
1716                          void *priv_data)
1717 {
1718     struct vga_internal *vga = (struct vga_internal *) priv_data;
1719     uint8_t curreg;
1720     uint8_t curchannel;
1721     uint8_t data;
1722     
1723     if (vga->vga_dac.state!=DAC_READ) { 
1724         PrintError("vga: dac data read while in other state\n");
1725         // results undefined, so we continue
1726     }
1727
1728     ERR_WRONG_SIZE("read","vga dac read data",len,1,1);
1729
1730     curreg = vga->vga_dac.vga_dac_read_addr;
1731     curchannel = vga->vga_dac.channel;
1732     data = (vga->vga_dac.vga_dac_palette[curreg] >> curchannel*8) & 0x3f;
1733
1734     PrintDebug("vga: dac reg %u [%s] = 0x%x\n",
1735                curreg, 
1736                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1737                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1738                data);
1739
1740     *((uint8_t*)dest) = data;
1741
1742     PASSTHROUGH_IO_IN(vga,port,dest,len);
1743
1744     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1745     
1746     curchannel = (curchannel+1)%3;
1747     vga->vga_dac.channel=curchannel;
1748     if (curchannel==0) { 
1749         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1750     } 
1751     vga->vga_dac.vga_dac_read_addr = curreg;
1752     vga->vga_dac.state=DAC_READ;
1753
1754     return len;
1755 }
1756
1757
1758
1759 static int dac_data_write(struct guest_info *core, 
1760                           uint16_t port, 
1761                           void *src,
1762                           uint_t len,
1763                           void *priv_data)
1764 {
1765     struct vga_internal *vga = (struct vga_internal *) priv_data;
1766     uint8_t curreg;
1767     uint8_t curchannel;
1768     uint8_t data;
1769     vga_palette_reg data32;
1770     vga_palette_reg mask32;
1771     
1772     if (vga->vga_dac.state!=DAC_WRITE) { 
1773         PrintError("vga: dac data write while in other state\n");
1774         // results undefined, so we continue
1775     }
1776
1777     ERR_WRONG_SIZE("read","vga dac write data",len,1,1);
1778
1779     PASSTHROUGH_IO_OUT(vga,port,src,len);
1780
1781     curreg = vga->vga_dac.vga_dac_write_addr;
1782     curchannel = vga->vga_dac.channel;
1783     data = *((uint8_t *)src);
1784
1785     PrintDebug("vga: dac reg %u [%s] write with 0x%x\n",
1786                curreg, 
1787                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1788                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1789                data);
1790
1791     data32 = data & 0x3f ;
1792     data32 <<= curchannel*8;
1793     mask32 = ~(0xff << (curchannel * 8));
1794
1795     vga->vga_dac.vga_dac_palette[curreg] &= mask32;
1796     vga->vga_dac.vga_dac_palette[curreg] |= data32;
1797
1798     curchannel = (curchannel+1)%3;
1799     vga->vga_dac.channel=curchannel;
1800     if (curchannel==0) { 
1801         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1802     } 
1803     vga->vga_dac.vga_dac_write_addr = curreg;
1804     vga->vga_dac.state=DAC_WRITE;
1805
1806     render(vga);
1807
1808     return len;
1809 }
1810
1811  
1812
1813 static int dac_pixel_mask_read(struct guest_info *core, 
1814                                uint16_t port, 
1815                                void *dest,
1816                                uint_t len,
1817                                void *priv_data)
1818 {
1819     struct vga_internal *vga = (struct vga_internal *) priv_data;
1820     
1821     PrintDebug("vga: dac pixel mask read data=0x%x\n", 
1822                vga->vga_dac.vga_pixel_mask);
1823
1824     ERR_WRONG_SIZE("read","vga pixel mask",len,1,1);
1825
1826     *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
1827
1828     PASSTHROUGH_IO_IN(vga,port,dest,len);
1829
1830     PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_pixel_mask,*(uint8_t*)dest);
1831
1832     return len;
1833 }
1834
1835 static int dac_pixel_mask_write(struct guest_info *core, 
1836                                 uint16_t port, 
1837                                 void *src,
1838                                 uint_t len,
1839                                 void *priv_data)
1840 {
1841     struct vga_internal *vga = (struct vga_internal *) priv_data;
1842     uint8_t new_data;
1843
1844     new_data=*((uint8_t*)src);
1845
1846     PrintDebug("vga: dac pixel mask write data=0x%x\n", new_data);
1847
1848     ERR_WRONG_SIZE("write","pixel mask",len,1,1);
1849
1850     PASSTHROUGH_IO_OUT(vga,port,src,len);
1851
1852     vga->vga_dac.vga_pixel_mask =  new_data;
1853
1854     return len;
1855 }
1856
1857 static int init_vga(struct vga_internal *vga)
1858 {
1859     // TODO: startup spec of register contents, if any
1860     PrintError("vga: init_vga is UNIMPLEMTED\n");
1861     return 0;
1862 }
1863
1864 static int free_vga(struct vga_internal *vga) 
1865 {
1866     int i;
1867     int ret;
1868     struct vm_device *dev = vga->dev;
1869
1870     // Framebuffer deletion is user's responsibility
1871
1872     //    if (vga->mem_store) {
1873     //  V3_FreePages(v3_hva_to_hpa(vga->mem_store),MEM_REGION_NUM_PAGES);
1874     //  vga->mem_store=0;
1875     //}
1876     
1877     for (i=0;i<MAP_NUM;i++) { 
1878         if (vga->map[i]) { 
1879             V3_FreePages(V3_PAddr(vga->map[i]),MAP_SIZE/4096);
1880             vga->map[i]=0;
1881         }
1882     }
1883
1884     v3_unhook_mem(vga->dev->vm, V3_MEM_CORE_ANY, MEM_REGION_START);
1885
1886     ret = 0;
1887
1888     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_READ);
1889     // The following also covers VGA_INPUT_STAT0_READ
1890     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_WRITE);
1891     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1892     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_MONO);
1893     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1894     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_COLOR);
1895     ret |= v3_dev_unhook_io(dev, VGA_FEATURE_CONTROL_READ);
1896     
1897     ret |= v3_dev_unhook_io(dev, VGA_VIDEO_SUBSYS_ENABLE);
1898
1899     /* Sequencer registers */
1900     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_ADDRESS);
1901     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_DATA);
1902
1903     /* CRT controller registers */
1904     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO);
1905     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR);
1906     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO);
1907     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR);
1908
1909     /* graphics controller registers */
1910     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS);
1911     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA);
1912
1913     /* attribute controller registers */
1914     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE);
1915     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ);
1916
1917     /* video DAC palette registers */
1918     ret |= v3_dev_unhook_io(dev, VGA_DAC_WRITE_ADDR);
1919     ret |= v3_dev_unhook_io(dev, VGA_DAC_READ_ADDR);
1920     ret |= v3_dev_unhook_io(dev, VGA_DAC_DATA);
1921     ret |= v3_dev_unhook_io(dev, VGA_DAC_PIXEL_MASK);
1922
1923
1924     if (vga->host_cons) { 
1925         v3_graphics_console_close(vga->host_cons);
1926     }
1927
1928     V3_Free(vga);
1929
1930     return 0;
1931 }
1932
1933 static struct v3_device_ops dev_ops = {
1934     .free = (int (*)(void *))free_vga,
1935 };
1936
1937
1938 static int vga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1939     struct vga_internal *vga;
1940     int i;
1941     int ret;
1942
1943     char * dev_id = v3_cfg_val(cfg, "ID");
1944     char * passthrough = v3_cfg_val(cfg, "passthrough");
1945     char * hostframebuf = v3_cfg_val(cfg, "hostframebuf");
1946
1947     PrintDebug("vga: init_device\n");
1948
1949     vga = (struct vga_internal *)V3_Malloc(sizeof(struct vga_internal));
1950
1951     if (!vga) { 
1952         PrintError("vga: cannot allocate\n");
1953         return -1;
1954     }
1955
1956     memset(vga, 0, sizeof(struct vga_internal));
1957
1958     if (passthrough && strcasecmp(passthrough,"enable")==0) {
1959         PrintDebug("vga: enabling passthrough\n");
1960         vga->passthrough=true;
1961         vga->skip_next_passthrough_out=false;
1962     }
1963
1964
1965     if (hostframebuf && strcasecmp(hostframebuf,"enable")==0) { 
1966         struct v3_frame_buffer_spec req;
1967
1968         PrintDebug("vga: enabling host frame buffer console (GRAPHICS_CONSOLE)\n");
1969
1970         memset(&req,0,sizeof(struct v3_frame_buffer_spec));
1971         memset(&(vga->target_spec),0,sizeof(struct v3_frame_buffer_spec));
1972
1973         req.height=VGA_MAXY;
1974         req.width=VGA_MAXX;
1975         req.bytes_per_pixel=4;
1976         req.bits_per_channel=8;
1977         req.red_offset=0;
1978         req.green_offset=1;
1979         req.blue_offset=2;
1980         
1981
1982         vga->host_cons = v3_graphics_console_open(vm,&req,&(vga->target_spec));
1983
1984         if (!vga->host_cons) { 
1985             PrintError("vga: unable to open host OS's graphics console\n");
1986             free_vga(vga);
1987             return -1;
1988         }
1989
1990         if (memcmp(&req,&(vga->target_spec),sizeof(req))) {
1991             PrintDebug("vga: warning: target spec differs from requested spec\n");
1992             PrintDebug("vga: request: %u by %u by %u with %u bpc and r,g,b at %u, %u, %u\n", req.width, req.height, req.bytes_per_pixel, req.bits_per_channel, req.red_offset, req.green_offset, req.blue_offset);
1993             PrintDebug("vga: response: %u by %u by %u with %u bpc and r,g,b at %u, %u, %u\n", vga->target_spec.width, vga->target_spec.height, vga->target_spec.bytes_per_pixel, vga->target_spec.bits_per_channel, vga->target_spec.red_offset, vga->target_spec.green_offset, vga->target_spec.blue_offset);
1994
1995         }
1996     }
1997
1998     if (!vga->passthrough && !vga->host_cons) { 
1999         V3_Print("vga: neither passthrough nor host console are enabled - no way to display anything!\n");
2000     }
2001
2002
2003     // No memory store is allocated since we will use a full memory hook
2004     // The VGA maps can be read as well as written
2005     // Reads also affect writes, since they are how you fill the latches
2006
2007     // Now allocate the maps
2008     for (i=0;i<MAP_NUM;i++) { 
2009         vga->map[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
2010         if (!(vga->map[i])) {
2011             PrintError("vga: cannot allocate maps\n");
2012             free_vga(vga);
2013             return -1;
2014         }
2015         memset(vga->map[i],0,MAP_SIZE);
2016     }
2017     
2018     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vga);
2019     
2020     if (dev == NULL) {
2021         PrintError("Could not attach device %s\n", dev_id);
2022         free_vga(vga);
2023         return -1;
2024     }
2025     
2026     vga->dev = dev;
2027     
2028     if (v3_hook_full_mem(vm, V3_MEM_CORE_ANY, 
2029                          MEM_REGION_START, MEM_REGION_END,
2030                          &vga_read, 
2031                          &vga_write,
2032                          dev) == -1) {
2033         PrintError("vga: memory book failed\n");
2034         v3_remove_device(dev);
2035         return -1;
2036     }
2037
2038     ret = 0;
2039     
2040     /* Miscelaneous registers */
2041     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_READ, &misc_out_read, NULL);
2042     // The following also covers VGA_INPUT_STAT0_READ
2043     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_WRITE, &input_stat0_read, &misc_out_write);
2044     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
2045     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_MONO, &input_stat1_read, &feature_control_write);
2046     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
2047     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_COLOR, &input_stat1_read, &feature_control_write);
2048     ret |= v3_dev_hook_io(dev, VGA_FEATURE_CONTROL_READ, &feature_control_read, NULL);
2049     
2050     ret |= v3_dev_hook_io(dev, VGA_VIDEO_SUBSYS_ENABLE, &video_subsys_enable_read, &video_subsys_enable_write);
2051
2052     /* Sequencer registers */
2053     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_ADDRESS, &sequencer_address_read, &sequencer_address_write);
2054     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_DATA, &sequencer_data_read, &sequencer_data_write);
2055
2056     /* CRT controller registers */
2057     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO, &crt_controller_address_read,&crt_controller_address_write);
2058     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR, &crt_controller_address_read,&crt_controller_address_write);
2059     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO, &crt_controller_data_read,&crt_controller_data_write);
2060     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR, &crt_controller_data_read,&crt_controller_data_write);
2061
2062     /* graphics controller registers */
2063     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS, &graphics_controller_address_read,&graphics_controller_address_write);
2064     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA, &graphics_controller_data_read,&graphics_controller_data_write);
2065
2066     /* attribute controller registers */
2067     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE, &attribute_controller_address_read,&attribute_controller_address_and_data_write);
2068     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ, &attribute_controller_data_read,NULL);
2069
2070     /* video DAC palette registers */
2071     ret |= v3_dev_hook_io(dev, VGA_DAC_WRITE_ADDR, &dac_write_address_read,&dac_write_address_write);
2072     ret |= v3_dev_hook_io(dev, VGA_DAC_READ_ADDR, &dac_read_address_read,&dac_read_address_write);
2073     ret |= v3_dev_hook_io(dev, VGA_DAC_DATA, &dac_data_read, &dac_data_write);
2074     ret |= v3_dev_hook_io(dev, VGA_DAC_PIXEL_MASK, &dac_pixel_mask_read, &dac_pixel_mask_write);
2075
2076     if (ret != 0) {
2077         PrintError("vga: Error allocating VGA I/O ports\n");
2078         v3_remove_device(dev);
2079         return -1;
2080     }
2081
2082     init_vga(vga);
2083
2084     PrintDebug("vga: successfully added and initialized.\n");
2085
2086     return 0;
2087
2088 }
2089
2090 device_register("VGA", vga_init);