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.


Updated VGA to support the graphics console host interface
[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 <palacios/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 (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
366     return 0;
367 }
368
369
370 static void get_mem_region(struct vga_internal *vga, uint64_t *mem_start, uint64_t *mem_end) 
371 {
372     switch (vga->vga_graphics_controller.vga_misc.memory_map) { 
373         case 0: 
374             *mem_start=0xa0000;
375             *mem_end=0xc0000;
376             break;
377         case 1:
378             *mem_start=0xa0000;
379             *mem_end=0xb0000;
380             break;
381         case 2:
382             *mem_start=0xb0000;
383             *mem_end=0xb8000;
384             break;
385         case 3:
386             *mem_start=0xb8000;
387             *mem_end=0xc0000;
388             break;
389     }
390 }
391
392 static uint64_t find_offset(struct vga_internal *vga, addr_t guest_addr)
393 {
394     uint64_t mem_start, mem_end;
395     
396     mem_start=mem_end=0;
397     
398     get_mem_region(vga, &mem_start, &mem_end);
399
400     return (guest_addr-mem_start) % (mem_end-mem_start > 65536 ? 65536 : (mem_end-mem_start)); 
401
402 }
403
404     
405
406
407 static int vga_write(struct guest_info * core, 
408                      addr_t guest_addr, 
409                      void * src, 
410                      uint_t length, 
411                      void * priv_data)
412 {
413     int i;
414     struct vm_device *dev = (struct vm_device *)priv_data;
415     struct vga_internal *vga = (struct vga_internal *) dev->private_data;
416
417     PrintDebug("vga: memory write: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
418
419     if (vga->passthrough) { 
420         PrintDebug("vga: passthrough write to 0x%p\n", V3_VAddr((void*)guest_addr));
421         memcpy(V3_VAddr((void*)guest_addr),src,length);
422     }
423     
424     PrintDebug("vga: data written was \"");
425     for (i=0;i<length;i++) {
426         char c= ((char*)src)[i];
427         PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
428     }
429     PrintDebug("\"\n");
430
431     /* Write mode determine by Graphics Mode Register (Index 05h).writemode */
432     
433     switch (vga->vga_graphics_controller.vga_graphics_mode.write_mode) {
434         case 0: {
435             
436             /* 
437                00b -- Write Mode 0: In this mode, the host data is first rotated 
438                as per the Rotate Count field, then the Enable Set/Reset mechanism 
439                selects data from this or the Set/Reset field. Then the selected 
440                Logical Operation is performed on the resulting data and the data 
441                in the latch register. Then the Bit Mask field is used to select 
442                which bits come from the resulting data and which come 
443                from the latch register. Finally, only the bit planes enabled by 
444                the Memory Plane Write Enable field are written to memory.
445             */
446
447             int i;
448
449             uint8_t  mapnum;
450             uint64_t offset;
451
452             uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
453             uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
454             
455             offset = find_offset(vga, guest_addr);
456
457             PrintDebug("vga: mode 0 write, offset=0x%llx, ror=%u, func=%u\n", offset,ror,func);
458
459             for (i=0;i<length;i++,offset++) { 
460                 // now for each map
461                 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
462                 uint8_t esr = vga->vga_graphics_controller.vga_enable_set_reset.val &0xf;
463                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
464                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
465
466                 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, esr>>=1, bm>>=1, mm>>=1) { 
467                     vga_map map = vga->map[mapnum];
468                     uint8_t data = ((uint8_t *)src)[i];
469                     uint8_t latchval = vga->latch[mapnum];
470                         
471                     // rotate data right
472                     data = (data>>ror) | data<<(8-ror);
473
474                     // use SR bit if ESR is on for this map
475                     if (esr & 0x1) { 
476                         data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7);  // expand sr bit
477                     }
478                     
479                     // Apply function
480                     switch (func) { 
481                         case 0: // NOP
482                             break;
483                         case 1: // AND
484                             data &= latchval;
485                             break;
486                         case 2: // OR
487                             data |= latchval;
488                             break;
489                         case 3: // XOR
490                             data ^= latchval;
491                             break;
492                     }
493                             
494                     // mux between latch and alu output
495                     if (bm & 0x1) { 
496                         // use alu output, which is in data
497                     } else {
498                         // use latch value
499                         data=latchval;
500                     }
501                     
502                     // selective write
503                     if (mm & 0x1) { 
504                         // write to this map
505                         //PrintDebug("vga: write map %u offset 0x%p map=0x%p pointer=0x%p\n",mapnum,(void*)offset,map,&(map[offset]));
506                         map[offset] = data;
507                     } else {
508                         // skip this map
509                     }
510                 }
511             }
512         }
513             break;
514
515
516             
517         case 1: {
518             /* 
519                01b -- Write Mode 1: In this mode, data is transferred directly 
520                from the 32 bit latch register to display memory, affected only by 
521                the Memory Plane Write Enable field. The host data is not used in this mode.
522             */
523
524             int i;
525
526             uint64_t offset = find_offset(vga,guest_addr);
527
528             PrintDebug("vga: mode 1 write, offset=0x%llx\n", offset);
529
530             for (i=0;i<length;i++,offset++) { 
531
532                 uint8_t mapnum;
533                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
534
535                 for (mapnum=0;mapnum<4;mapnum++,  mm>>=1) { 
536                     vga_map map = vga->map[mapnum];
537                     uint8_t latchval = vga->latch[mapnum];
538                         
539                     // selective write
540                     if (mm & 0x1) { 
541                         // write to this map
542                         map[offset] = latchval;
543                     } else {
544                         // skip this map
545                     }
546                 }
547             }
548         }
549             break;
550
551         case 2: {
552             /*
553               10b -- Write Mode 2: In this mode, the bits 3-0 of the host data 
554               are replicated across all 8 bits of their respective planes. 
555               Then the selected Logical Operation is performed on the resulting 
556               data and the data in the latch register. Then the Bit Mask field is used to 
557               select which bits come from the resulting data and which come from 
558               the latch register. Finally, only the bit planes enabled by the 
559               Memory Plane Write Enable field are written to memory.
560             */
561             int i;
562             uint8_t  mapnum;
563             uint64_t offset;
564
565             uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
566             
567             offset = find_offset(vga, guest_addr);
568
569             PrintDebug("vga: mode 2 write, offset=0x%llx, func=%u\n", offset,func);
570
571             for (i=0;i<length;i++,offset++) { 
572                 // now for each map
573                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
574                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
575
576                 for (mapnum=0;mapnum<4;mapnum++,  bm>>=1, mm>>=1) { 
577                     vga_map map = vga->map[mapnum];
578                     uint8_t data = ((uint8_t *)src)[i];
579                     uint8_t latchval = vga->latch[mapnum];
580                         
581                     // expand relevant bit to 8 bit
582                     // it's basically esr=1, sr=bit from write
583                     data = (uint8_t)(((sint8_t)(((data>>mapnum)&0x1)<<7))>>7);
584                     
585                     // Apply function
586                     switch (func) { 
587                         case 0: // NOP
588                             break;
589                         case 1: // AND
590                             data &= latchval;
591                             break;
592                         case 2: // OR
593                             data |= latchval;
594                             break;
595                         case 3: // XOR
596                             data ^= latchval;
597                             break;
598                     }
599                             
600                     // mux between latch and alu output
601                     if (bm & 0x1) { 
602                         // use alu output, which is in data
603                     } else {
604                         // use latch value
605                         data=latchval;
606                     }
607                     
608                     // selective write
609                     if (mm & 0x1) { 
610                         // write to this map
611                         map[offset] = data;
612                     } else {
613                         // skip this map
614                     }
615                 }
616             }
617         }
618             break;
619
620         case 3: {
621             /* 11b -- Write Mode 3: In this mode, the data in the Set/Reset field is used 
622                as if the Enable Set/Reset field were set to 1111b. Then the host data is 
623                first rotated as per the Rotate Count field, then logical ANDed with the 
624                value of the Bit Mask field. The resulting value is used on the data 
625                obtained from the Set/Reset field in the same way that the Bit Mask field 
626                would ordinarily be used. to select which bits come from the expansion 
627                of the Set/Reset field and which come from the latch register. Finally, 
628                only the bit planes enabled by the Memory Plane Write Enable field 
629                are written to memory.
630             */
631             int i;
632
633             uint8_t  mapnum;
634             uint64_t offset;
635
636             uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
637             
638             offset = find_offset(vga, guest_addr);
639
640             PrintDebug("vga: mode 3 write, offset=0x%llx, ror=%u\n", offset,ror);
641
642             for (i=0;i<length;i++,offset++) { 
643                 // now for each map
644                 uint8_t data = ((uint8_t *)src)[i];
645
646                 data = (data>>ror) | data<<(8-ror);
647
648                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask & data;
649                 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
650                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
651
652                 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, bm>>=1, mm>>=1) { 
653                     vga_map map = vga->map[mapnum];
654                     uint8_t latchval = vga->latch[mapnum];
655                         
656                     data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7);  // expand sr bit
657                     
658                     
659                     // mux between latch and alu output
660                     if (bm & 0x1) { 
661                         // use alu output, which is in data
662                     } else {
663                         // use latch value
664                         data=latchval;
665                     }
666                     
667                     // selective write
668                     if (mm & 0x1) { 
669                         // write to this map
670                         map[offset] = data;
671                     } else {
672                         // skip this map
673                     }
674                 }
675             }
676
677         }
678             break;
679
680             // There is no default
681     }
682
683     render(vga);
684     
685     return length;
686 }
687
688
689 /*
690 up to 256K mapped through a window of 32 to 128K
691
692 most cards support linear mode as well
693
694 Need to implement readability too
695
696 Write extended memory bit to enable all 256K: 
697
698    Sequencer Memory Mode Register (Index 04h) . extended memory
699
700 Must enable writes before effects happen:
701   
702   Miscellaneous Output Register (Read at 3CCh, Write at 3C2h).ram enable
703
704 Choose which addresses are supported for CPU writes:
705
706 Miscellaneous Graphics Register (Index 06h).memory map select
707  
708 00b -- A0000h-BFFFFh (128K region)
709 01b -- A0000h-AFFFFh (64K region)
710 10b -- B0000h-B7FFFh (32K region)
711 11b -- B8000h-BFFFFh (32K region)
712
713 There are three addressing modes: Chain 4, Odd/Even mode, and normal mode:
714
715 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.)
716
717 Memory model: 64K 32 bit locations; divided into 4 64K bit planes
718
719
720    
721
722
723 Assume linear framebuffer, starting at address buf:
724
725 */
726
727
728
729 static int vga_read(struct guest_info * core, 
730                     addr_t guest_addr, 
731                     void * dst, 
732                     uint_t length, 
733                     void * priv_data)
734 {
735     int i;
736     struct vm_device *dev = (struct vm_device *)priv_data;
737     struct vga_internal *vga = (struct vga_internal *) dev->private_data;
738     
739
740     PrintDebug("vga: memory read: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
741
742
743                 
744    
745     /*
746       Reading, 2 modes, set via Graphics Mode Register (index 05h).Read Mode:
747     */
748     switch (vga->vga_graphics_controller.vga_graphics_mode.read_mode) { 
749         case 0: {
750             /*      0 - a byte from ONE of the 4 planes is returned; 
751                     which plane is determined by Read Map Select (Read Map Select Register (Index 04h)) */
752             uint8_t  mapnum;
753             uint64_t offset;
754             
755             mapnum = vga->vga_graphics_controller.vga_read_map_select.map_select;
756             offset = find_offset(vga,guest_addr);
757             
758             if (offset>=65536) { 
759                 PrintError("vga: read to offset=%llu map=%u (%u bytes)\n",offset,mapnum,length);
760             }
761
762             memcpy(dst,(vga->map[mapnum])+offset,length);
763
764             // load the latches with the last item read
765             for (mapnum=0;mapnum<4;mapnum++) { 
766                 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
767             }
768             
769         
770         }
771             break;
772         case 1: {
773             /*      1 - Compare video memory and reference color 
774                     (in Color Compare, except those not set in Color Don't Care), 
775                     each bit in returned result is one comparison between the reference color 
776
777                     Ref color is *4* bits, and thus a one byte read returns a comparison 
778                     with 8 pixels
779
780             */
781             int i;
782
783             uint8_t cc=vga->vga_graphics_controller.vga_color_compare.val & 0xf ;
784             uint8_t dc=vga->vga_graphics_controller.vga_color_dont_care.val & 0xf;
785
786             uint8_t  mapnum;
787             uint64_t offset;
788             uint8_t  byte;
789             uint8_t  bits;
790             
791             offset = find_offset(vga,guest_addr);
792             
793             for (i=0;i<length;i++,offset++) { 
794                 vga_map map;
795                 byte=0;
796                 for (mapnum=0;mapnum<4;mapnum++) { 
797                     map = vga->map[mapnum];
798                     if ( (dc>>mapnum)&0x1 ) { // don't care
799                         bits=0;
800                     } else {
801                         // lower 4 bits
802                         bits = (map[offset]&0xf) == cc;
803                         bits <<= 1;
804                         // upper 4 bits
805                         bits |= (((map[offset]>>4))&0xf) == cc;
806                     }
807                     // not clear whether it is 0..k or k..0
808                     byte<<=2;
809                     byte|=bits;
810                 }
811             }
812
813             // load the latches with the last item read
814             for (mapnum=0;mapnum<4;mapnum++) { 
815                 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
816             }
817
818         }
819             break;
820             // there is no default
821     }
822
823     if (vga->passthrough) { 
824         PrintDebug("vga: passthrough read from 0x%p\n",V3_VAddr((void*)guest_addr));
825         memcpy(dst,V3_VAddr((void*)guest_addr),length);
826     }
827
828
829     PrintDebug("vga: data read is \"");
830     for (i=0;i<length;i++) {
831         char c= ((char*)dst)[i];
832         PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
833     }
834     PrintDebug("\"\n");
835
836     return length;
837
838 }
839
840
841
842
843
844 #define ERR_WRONG_SIZE(op,reg,len,min,max)      \
845     if (((len)<(min)) || ((len)>(max))) {       \
846         PrintError("vga: %s of %s wrong size (%d bytes, but only %d to %d allowed)\n",(op),(reg),(len),(min),(max)); \
847         return -1; \
848 }
849         
850 static inline void passthrough_io_in(uint16_t port, void * dest, uint_t length) {
851     switch (length) {
852         case 1:
853             *(uint8_t *)dest = v3_inb(port);
854             break;
855         case 2:
856             *(uint16_t *)dest = v3_inw(port);
857             break;
858         case 4:
859             *(uint32_t *)dest = v3_indw(port);
860             break;
861         default:
862             PrintError("vga: unsupported passthrough io in size %u\n",length);
863             break;
864     }
865 }
866
867
868 static inline void passthrough_io_out(uint16_t port, const void * src, uint_t length) {
869     switch (length) {
870         case 1:
871             v3_outb(port, *(uint8_t *)src);
872             break;
873         case 2:
874             v3_outw(port, *(uint16_t *)src);
875             break;
876         case 4:
877             v3_outdw(port, *(uint32_t *)src);
878             break;
879         default:
880             PrintError("vga: unsupported passthrough io out size %u\n",length);
881             break;
882     }
883 }
884
885 #define PASSTHROUGH_IO_IN(vga,port,dest,len)                            \
886     do { if ((vga)->passthrough) { passthrough_io_in(port,dest,len); } } while (0)
887
888 #define PASSTHROUGH_IO_OUT(vga,port,src,len)                            \
889     do { if ((vga)->passthrough && (!(vga)->skip_next_passthrough_out)) { passthrough_io_out(port,src,len); } (vga)->skip_next_passthrough_out=false; } while (0)
890
891 #define PASSTHROUGH_IO_SKIP_NEXT_OUT(vga)                                       \
892     do { if ((vga)->passthrough) { (vga)->skip_next_passthrough_out=true; } } while (0)
893                 
894 #define PASSTHROUGH_READ_CHECK(vga,inter,pass) \
895     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)
896
897 static int misc_out_read(struct guest_info *core, 
898                          uint16_t port, 
899                          void *dest,
900                          uint_t len,
901                          void *priv_data)
902 {
903     struct vga_internal *vga = (struct vga_internal *) priv_data;
904
905     PrintDebug("vga: misc out read data=0x%x\n", vga->vga_misc.vga_misc_out.val);
906
907     ERR_WRONG_SIZE("read","misc out",len,1,1);
908    
909     *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
910
911     PASSTHROUGH_IO_IN(vga,port,dest,len);
912
913     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_misc_out.val,*((uint8_t*)dest));
914
915     return len;
916 }
917
918 static int misc_out_write(struct guest_info *core, 
919                           uint16_t port, 
920                           void *src,
921                           uint_t len,
922                           void *priv_data)
923 {
924     struct vga_internal *vga = (struct vga_internal *) priv_data;
925     
926     PrintDebug("vga: misc out write data=0x%x\n", *((uint8_t*)src));
927         
928     ERR_WRONG_SIZE("write","misc out",len,1,1);
929
930     PASSTHROUGH_IO_OUT(vga,port,src,len);
931
932     vga->vga_misc.vga_misc_out.val =  *((uint8_t*)src) ;
933     
934     render(vga);
935     
936     return len;
937 }
938
939
940
941 static int input_stat0_read(struct guest_info *core, 
942                             uint16_t port, 
943                             void *dest,
944                             uint_t len,
945                             void *priv_data)
946 {
947     struct vga_internal *vga = (struct vga_internal *) priv_data;
948
949     PrintDebug("vga: input stat0  read data=0x%x\n", vga->vga_misc.vga_input_stat0.val);
950
951     ERR_WRONG_SIZE("read","input stat0",len,1,1);
952
953     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
954
955     PASSTHROUGH_IO_IN(vga,port,dest,len);
956
957     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat0.val,*(uint8_t*)dest);
958
959     return len;
960 }
961
962
963 static int input_stat1_read(struct guest_info *core, 
964                             uint16_t port, 
965                             void *dest,
966                             uint_t len,
967                             void *priv_data)
968 {
969     struct vga_internal *vga = (struct vga_internal *) priv_data;
970
971     PrintDebug("vga: input stat0 (%s) read data=0x%x\n", 
972                port==0x3ba ? "mono" : "color",
973                vga->vga_misc.vga_input_stat1.val);
974
975     ERR_WRONG_SIZE("read","input stat1",len,1,1);
976
977
978     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val;
979
980     // Stunningly, reading stat1 is also a way to reset
981     // the state of attribute controller address/data flipflop
982     // That is some mighty fine crack the designers were smoking.
983     
984     vga->vga_attribute_controller.state=ATTR_ADDR;
985
986     PASSTHROUGH_IO_IN(vga,port,dest,len);
987
988     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat1.val,*(uint8_t*)dest);
989
990     return len;
991 }
992                          
993
994 static int feature_control_read(struct guest_info *core, 
995                                 uint16_t port, 
996                                 void *dest,
997                                 uint_t len,
998                                 void *priv_data)
999 {
1000     struct vga_internal *vga = (struct vga_internal *) priv_data;
1001
1002     PrintDebug("vga: feature control  read data=0x%x\n", 
1003                vga->vga_misc.vga_feature_control.val);
1004
1005     ERR_WRONG_SIZE("read","feature control",len,1,1);
1006
1007
1008     *((uint8_t*)dest) = vga->vga_misc.vga_feature_control.val;
1009
1010     PASSTHROUGH_IO_IN(vga,port,dest,len);
1011
1012     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_feature_control.val,*(uint8_t*)dest);
1013
1014     return len;
1015 }
1016
1017 static int feature_control_write(struct guest_info *core, 
1018                                  uint16_t port, 
1019                                  void *src,
1020                                  uint_t len,
1021                                  void *priv_data)
1022 {
1023     struct vga_internal *vga = (struct vga_internal *) priv_data;
1024     
1025     PrintDebug("vga: feature control (%s) write data=0x%x\n", 
1026                port==0x3ba ? "mono" : "color",
1027                *((uint8_t*)src));
1028         
1029     ERR_WRONG_SIZE("write","feature control",len,1,1);
1030     
1031     PASSTHROUGH_IO_OUT(vga,port,src,len);
1032
1033     vga->vga_misc.vga_feature_control.val =  *((uint8_t*)src) ;
1034     
1035     render(vga);
1036     
1037     return len;
1038 }
1039
1040
1041 static int video_subsys_enable_read(struct guest_info *core, 
1042                                     uint16_t port, 
1043                                     void *dest,
1044                                     uint_t len,
1045                                     void *priv_data)
1046 {
1047     struct vga_internal *vga = (struct vga_internal *) priv_data;
1048
1049     PrintDebug("vga: video subsys enable read data=0x%x\n", 
1050                vga->vga_misc.vga_video_subsys_enable.val);
1051
1052     ERR_WRONG_SIZE("read","video subsys enable",len,1,1);
1053
1054     *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
1055
1056     PASSTHROUGH_IO_IN(vga,port,dest,len);
1057
1058     PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_video_subsys_enable.val,*(uint8_t*)dest);
1059
1060     return len;
1061 }
1062
1063 static int video_subsys_enable_write(struct guest_info *core, 
1064                                      uint16_t port, 
1065                                      void *src,
1066                                      uint_t len,
1067                                      void *priv_data)
1068 {
1069     struct vga_internal *vga = (struct vga_internal *) priv_data;
1070     
1071     PrintDebug("vga: video subsys enable write data=0x%x\n", *((uint8_t*)src));
1072         
1073     ERR_WRONG_SIZE("write","video subsys enable",len,1,1);
1074     
1075     PASSTHROUGH_IO_OUT(vga,port,src,len);
1076
1077     vga->vga_misc.vga_video_subsys_enable.val =  *((uint8_t*)src) ;
1078     
1079     render(vga);
1080     
1081     return len;
1082 }
1083
1084 static int sequencer_address_read(struct guest_info *core, 
1085                                   uint16_t port, 
1086                                   void *dest,
1087                                   uint_t len,
1088                                   void *priv_data)
1089 {
1090     struct vga_internal *vga = (struct vga_internal *) priv_data;
1091
1092     PrintDebug("vga: sequencer address read data=0x%x\n", 
1093                vga->vga_sequencer.vga_sequencer_addr.val);
1094
1095     ERR_WRONG_SIZE("read","vga sequencer addr",len,1,1);
1096
1097     *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
1098
1099     PASSTHROUGH_IO_IN(vga,port,dest,len);
1100
1101     PASSTHROUGH_READ_CHECK(vga,vga->vga_sequencer.vga_sequencer_addr.val,*(uint8_t*)dest);
1102
1103     return len;
1104 }
1105
1106 static int sequencer_data_write(struct guest_info *core, 
1107                                uint16_t port, 
1108                                void *src,
1109                                uint_t len,
1110                                void *priv_data)
1111 {
1112     struct vga_internal *vga = (struct vga_internal *) priv_data;
1113     uint8_t index;
1114     uint8_t data;
1115     
1116     data=*((uint8_t*)src);
1117     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
1118     
1119     PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n", 
1120                index, data);
1121     
1122     ERR_WRONG_SIZE("write","vga sequencer data",len,1,1);
1123     
1124     PASSTHROUGH_IO_OUT(vga,port,src,len);
1125
1126
1127     if (index>=VGA_SEQUENCER_NUM) { 
1128         PrintError("vga: sequencer data write is for invalid index %d, ignoring\n",index);
1129     } else {
1130         vga->vga_sequencer.vga_sequencer_regs[index] = data;
1131     }
1132
1133     render(vga);
1134     
1135     return len;
1136 }
1137
1138 static int sequencer_address_write(struct guest_info *core, 
1139                                   uint16_t port, 
1140                                   void *src,
1141                                   uint_t len,
1142                                   void *priv_data)
1143 {
1144     struct vga_internal *vga = (struct vga_internal *) priv_data;
1145     uint8_t new_addr;
1146
1147     new_addr=*((uint8_t*)src);
1148
1149     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);
1150
1151     ERR_WRONG_SIZE("write","vga sequencer addr",len,1,2);
1152
1153     PASSTHROUGH_IO_OUT(vga,port,src,len);
1154     
1155     vga->vga_sequencer.vga_sequencer_addr.val =  *((uint8_t*)src) ;
1156     
1157     if (len==2) { 
1158         PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1159         // second byte is the data
1160         if (sequencer_data_write(core,port,src+1,1,vga)!=1) { 
1161             PrintError("vga: write of data failed\n");
1162             return -1;
1163         }
1164     }
1165
1166     return len;
1167 }
1168
1169 static int sequencer_data_read(struct guest_info *core, 
1170                               uint16_t port, 
1171                               void *dest,
1172                               uint_t len,
1173                               void *priv_data)
1174 {
1175     struct vga_internal *vga = (struct vga_internal *) priv_data;
1176     uint8_t index;
1177     uint8_t data;
1178
1179     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
1180
1181     if (index>=VGA_SEQUENCER_NUM) { 
1182         data=0;
1183         PrintError("vga: sequencer data read at invalid index %d, returning zero\n",index);
1184     } else {
1185         data=vga->vga_sequencer.vga_sequencer_regs[index];
1186     }
1187
1188     PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n", 
1189                    index, data);
1190     
1191     ERR_WRONG_SIZE("read","vga sequencer data",len,1,1);
1192
1193     *((uint8_t*)dest) = data;
1194
1195     PASSTHROUGH_IO_IN(vga,port,dest,len);
1196
1197     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1198
1199     return len;
1200 }
1201
1202  
1203  
1204
1205
1206 static int crt_controller_address_read(struct guest_info *core, 
1207                                         uint16_t port, 
1208                                         void *dest,
1209                                         uint_t len,
1210                                         void *priv_data)
1211 {
1212     struct vga_internal *vga = (struct vga_internal *) priv_data;
1213
1214     PrintDebug("vga: crt controller (%s) address read data=0x%x\n", 
1215                port==0x3b4 ? "mono" : "color",
1216                vga->vga_crt_controller.vga_crt_addr.val);
1217
1218     ERR_WRONG_SIZE("read","vga crt controller addr",len,1,1);
1219
1220     *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
1221
1222     PASSTHROUGH_IO_IN(vga,port,dest,len);
1223
1224     PASSTHROUGH_READ_CHECK(vga,vga->vga_crt_controller.vga_crt_addr.val,*(uint8_t*)dest);
1225
1226     return len;
1227 }
1228
1229 static int crt_controller_data_write(struct guest_info *core, 
1230                                      uint16_t port, 
1231                                      void *src,
1232                                      uint_t len,
1233                                      void *priv_data)
1234 {
1235     struct vga_internal *vga = (struct vga_internal *) priv_data;
1236     uint8_t index;
1237     uint8_t data;
1238
1239     data=*((uint8_t*)src);
1240
1241     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
1242     
1243     PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n", 
1244                port==0x3b5 ? "mono" : "color",
1245                index, data);
1246
1247     ERR_WRONG_SIZE("write","vga crt controller data",len,1,1);
1248
1249     PASSTHROUGH_IO_OUT(vga,port,src,len);
1250
1251     if (index>=VGA_CRT_CONTROLLER_NUM) { 
1252         PrintError("vga; crt controller write is for illegal index %d, ignoring\n",index);
1253     } else {
1254         vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
1255     }
1256
1257     render(vga);
1258
1259     return len;
1260 }
1261
1262 static int crt_controller_address_write(struct guest_info *core, 
1263                                         uint16_t port, 
1264                                         void *src,
1265                                         uint_t len,
1266                                         void *priv_data)
1267 {
1268     struct vga_internal *vga = (struct vga_internal *) priv_data;
1269     uint8_t new_addr;
1270
1271     new_addr=*((uint8_t*)src);
1272
1273     PrintDebug("vga: crt controller (%s) address write data=0x%x len=%u\n", 
1274                port==0x3b4 ? "mono" : "color",
1275                len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1276
1277     ERR_WRONG_SIZE("write","vga crt controller addr",len,1,2);
1278
1279     PASSTHROUGH_IO_OUT(vga,port,src,len);
1280
1281     vga->vga_crt_controller.vga_crt_addr.val =  *((uint8_t*)src) ;
1282         
1283     if (len==2) { 
1284         PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1285         // second byte is the data
1286         if (crt_controller_data_write(core,port,src+1,1,vga)!=1) { 
1287             PrintError("vga: write of data failed\n");
1288             return -1;
1289         }
1290     }
1291     
1292     return len;
1293 }
1294
1295 static int crt_controller_data_read(struct guest_info *core, 
1296                                     uint16_t port, 
1297                                     void *dest,
1298                                     uint_t len,
1299                                     void *priv_data)
1300 {
1301     struct vga_internal *vga = (struct vga_internal *) priv_data;
1302     uint8_t index;
1303     uint8_t data;
1304
1305     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
1306     
1307     if (index>=VGA_CRT_CONTROLLER_NUM) { 
1308         data=0;
1309         PrintError("vga: crt controller data read for illegal index %d, returning zero\n",index);
1310     } else {
1311         data=vga->vga_crt_controller.vga_crt_controller_regs[index];
1312     }
1313
1314     PrintDebug("vga: crt controller data (index=%d) = 0x%x\n",index,data);
1315     
1316     ERR_WRONG_SIZE("read","vga crt controller data",len,1,1);
1317
1318     *((uint8_t*)dest) = data;
1319
1320     PASSTHROUGH_IO_IN(vga,port,dest,len);
1321
1322     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t *)dest);
1323
1324     return len;
1325 }
1326
1327
1328
1329 static int graphics_controller_address_read(struct guest_info *core, 
1330                                             uint16_t port, 
1331                                             void *dest,
1332                                             uint_t len,
1333                                             void *priv_data)
1334 {
1335     struct vga_internal *vga = (struct vga_internal *) priv_data;
1336     
1337     PrintDebug("vga: graphics controller address read data=0x%x\n", 
1338                vga->vga_graphics_controller.vga_graphics_ctrl_addr.val);
1339
1340     ERR_WRONG_SIZE("read","vga graphics controller addr",len,1,1);
1341
1342     *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
1343
1344     PASSTHROUGH_IO_IN(vga,port,dest,len);
1345
1346     PASSTHROUGH_READ_CHECK(vga,vga->vga_graphics_controller.vga_graphics_ctrl_addr.val,*(uint8_t*)dest);
1347
1348     return len;
1349 }
1350
1351 static int graphics_controller_data_write(struct guest_info *core, 
1352                                           uint16_t port, 
1353                                           void *src,
1354                                           uint_t len,
1355                                           void *priv_data)
1356 {
1357     struct vga_internal *vga = (struct vga_internal *) priv_data;
1358     uint8_t index;
1359     uint8_t data;
1360     
1361     data=*((uint8_t*)src);
1362     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
1363     
1364
1365     PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n", 
1366                index, data);
1367     
1368     ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
1369     
1370     PASSTHROUGH_IO_OUT(vga,port,src,len);
1371
1372     if (index>=VGA_GRAPHICS_CONTROLLER_NUM) { 
1373         PrintError("vga: graphics controller write for illegal index %d ignored\n",index);
1374     } else {
1375         vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
1376     }
1377
1378     render(vga);
1379     
1380     return len;
1381 }
1382
1383 static int graphics_controller_address_write(struct guest_info *core, 
1384                                              uint16_t port, 
1385                                              void *src,
1386                                              uint_t len,
1387                                              void *priv_data)
1388 {
1389     struct vga_internal *vga = (struct vga_internal *) priv_data;
1390     uint8_t new_addr;
1391
1392     new_addr=*((uint8_t*)src);
1393
1394     PrintDebug("vga: graphics controller address write data=0x%x len=%u\n", 
1395                len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1396
1397     ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,2);
1398
1399     PASSTHROUGH_IO_OUT(vga,port,src,len);
1400
1401     vga->vga_graphics_controller.vga_graphics_ctrl_addr.val =  *((uint8_t*)src) ;
1402
1403     if (len==2) { 
1404         PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1405         // second byte is the data
1406         if (graphics_controller_data_write(core,port,src+1,1,vga)!=1) { 
1407             PrintError("vga: write of data failed\n");
1408             return -1;
1409         }
1410     }
1411
1412     return len;
1413 }
1414
1415 static int graphics_controller_data_read(struct guest_info *core, 
1416                                          uint16_t port, 
1417                                          void *dest,
1418                                          uint_t len,
1419                                          void *priv_data)
1420 {
1421     struct vga_internal *vga = (struct vga_internal *) priv_data;
1422     uint8_t index;
1423     uint8_t data;
1424
1425     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
1426
1427
1428     if (index>=VGA_GRAPHICS_CONTROLLER_NUM) { 
1429         data=0;
1430         PrintError("vga: graphics controller data read from illegal index %d, returning zero\n",index);
1431     } else {
1432         data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
1433     }
1434     
1435     PrintDebug("vga: graphics controller data read data (index=%d) = 0x%x\n", 
1436                index, data);
1437
1438     ERR_WRONG_SIZE("read","vga graphics controller data",len,1,1);
1439
1440     *((uint8_t*)dest) = data;
1441
1442     PASSTHROUGH_IO_IN(vga,port,dest,len);
1443
1444     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1445     
1446     return len;
1447 }
1448
1449
1450
1451
1452 /* Note that these guys have a bizarre protocol*/
1453
1454 static int attribute_controller_address_read(struct guest_info *core, 
1455                                              uint16_t port, 
1456                                              void *dest,
1457                                              uint_t len,
1458                                              void *priv_data)
1459 {
1460     struct vga_internal *vga = (struct vga_internal *) priv_data;
1461     
1462     PrintDebug("vga: attribute controller address read data=0x%x\n", 
1463                vga->vga_attribute_controller.vga_attribute_controller_addr.val);
1464
1465     ERR_WRONG_SIZE("read","vga attribute  controller addr",len,1,1);
1466
1467     *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
1468
1469     PASSTHROUGH_IO_IN(vga,port,dest,len);
1470
1471     PASSTHROUGH_READ_CHECK(vga,vga->vga_attribute_controller.vga_attribute_controller_addr.val,*(uint8_t*)dest);
1472
1473     // Reading the attribute controller does not change the state
1474
1475     return len;
1476 }
1477
1478 static int attribute_controller_address_and_data_write(struct guest_info *core, 
1479                                                        uint16_t port, 
1480                                                        void *src,
1481                                                        uint_t len,
1482                                                        void *priv_data)
1483 {
1484     struct vga_internal *vga = (struct vga_internal *) priv_data;
1485
1486
1487     if (vga->vga_attribute_controller.state==ATTR_ADDR) { 
1488         uint8_t new_addr = *((uint8_t*)src);
1489         // We are to treat this as an address write, and flip state
1490         // to expect data ON THIS SAME PORT
1491         PrintDebug("vga: attribute controller address write data=0x%x\n", new_addr);
1492         
1493         ERR_WRONG_SIZE("write","vga attribute controller addr",len,1,1);
1494
1495         PASSTHROUGH_IO_OUT(vga,port,src,len);
1496
1497         vga->vga_attribute_controller.vga_attribute_controller_addr.val =  new_addr;
1498
1499         vga->vga_attribute_controller.state=ATTR_DATA;
1500         return len;
1501
1502     } else if (vga->vga_attribute_controller.state==ATTR_DATA) { 
1503
1504         uint8_t data = *((uint8_t*)src);
1505         uint8_t index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
1506
1507         PrintDebug("vga: attribute controller data write index %d with data=0x%x\n", index,data);
1508         
1509         ERR_WRONG_SIZE("write","vga attribute controller data",len,1,1);
1510
1511         PASSTHROUGH_IO_OUT(vga,port,src,len);
1512         
1513         if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) { 
1514             PrintError("vga: attribute controller write to illegal index %d ignored\n",index);
1515         } else {
1516             vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
1517         }
1518         
1519         vga->vga_attribute_controller.state=ATTR_ADDR;
1520         
1521         return len;
1522     }
1523     
1524     return -1;
1525         
1526 }
1527
1528 static int attribute_controller_data_read(struct guest_info *core, 
1529                                           uint16_t port, 
1530                                           void *dest,
1531                                           uint_t len,
1532                                           void *priv_data)
1533 {
1534     struct vga_internal *vga = (struct vga_internal *) priv_data;
1535     uint8_t index;
1536     uint8_t data;
1537
1538     index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
1539
1540     if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) { 
1541         data=0;
1542         PrintError("vga: attribute controller read of illegal index %d, returning zero\n",index);
1543     } else {
1544         data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
1545     }
1546     
1547     PrintDebug("vga: attribute controller data read data (index=%d) = 0x%x\n", 
1548                index, data);
1549
1550     ERR_WRONG_SIZE("read","vga attribute controller data",len,1,1);
1551
1552     *((uint8_t*)dest) = data;
1553
1554     PASSTHROUGH_IO_IN(vga,port,dest,len);
1555
1556     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1557
1558     return len;
1559 }
1560
1561
1562 /*
1563    Note that these guys also have a strange protocol
1564    since they need to squeeze 18 bits of data through
1565    an 8 bit port 
1566 */
1567 static int dac_write_address_read(struct guest_info *core, 
1568                                   uint16_t port, 
1569                                   void *dest,
1570                                   uint_t len,
1571                                   void *priv_data)
1572 {
1573     struct vga_internal *vga = (struct vga_internal *) priv_data;
1574     
1575     PrintDebug("vga: dac write address read data=0x%x\n", 
1576                vga->vga_dac.vga_dac_write_addr);
1577
1578     ERR_WRONG_SIZE("read","vga dac write addr",len,1,1);
1579
1580
1581     *((uint8_t*)dest) = vga->vga_dac.vga_dac_write_addr;
1582
1583     PASSTHROUGH_IO_IN(vga,port,dest,len);
1584     
1585     PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_write_addr,*(uint8_t*)dest);
1586
1587     // This read does not reset the state machine
1588
1589     return len;
1590 }
1591
1592 static int dac_write_address_write(struct guest_info *core, 
1593                                    uint16_t port, 
1594                                    void *src,
1595                                    uint_t len,
1596                                    void *priv_data)
1597 {
1598     struct vga_internal *vga = (struct vga_internal *) priv_data;
1599     uint8_t new_addr;
1600
1601     new_addr=*((uint8_t*)src);
1602
1603     PrintDebug("vga: dac write address write data=0x%x\n", new_addr);
1604
1605     ERR_WRONG_SIZE("write","vga dac write addr",len,1,1);
1606
1607     PASSTHROUGH_IO_OUT(vga,port,src,len);
1608
1609     // cannot be out of bounds since there are 256 regs
1610
1611     vga->vga_dac.vga_dac_write_addr =  *((uint8_t*)src) ;
1612
1613     // Now we also need to reset the state machine
1614     
1615     vga->vga_dac.state=DAC_WRITE;
1616     vga->vga_dac.channel=RED;
1617
1618     return len;
1619 }
1620
1621
1622 static int dac_read_address_read(struct guest_info *core, 
1623                                  uint16_t port, 
1624                                  void *dest,
1625                                  uint_t len,
1626                                  void *priv_data)
1627 {
1628     struct vga_internal *vga = (struct vga_internal *) priv_data;
1629     
1630     PrintDebug("vga: dac read address read data=0x%x\n", 
1631                vga->vga_dac.vga_dac_read_addr);
1632
1633     ERR_WRONG_SIZE("read","vga dac read addr",len,1,1);
1634
1635     *((uint8_t*)dest) = vga->vga_dac.vga_dac_read_addr;
1636
1637     PASSTHROUGH_IO_IN(vga,port,dest,len);
1638
1639     PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_read_addr,*(uint8_t*)dest);
1640     
1641     // This read does not reset the state machine
1642
1643     return len;
1644 }
1645
1646 static int dac_read_address_write(struct guest_info *core, 
1647                                   uint16_t port, 
1648                                   void *src,
1649                                   uint_t len,
1650                                   void *priv_data)
1651 {
1652     struct vga_internal *vga = (struct vga_internal *) priv_data;
1653     uint8_t new_addr;
1654
1655     new_addr=*((uint8_t*)src);
1656
1657     PrintDebug("vga: dac read address write data=0x%x\n", new_addr);
1658
1659     ERR_WRONG_SIZE("write","vga dac read addr",len,1,1);
1660
1661     PASSTHROUGH_IO_OUT(vga,port,src,len);
1662
1663     // cannot be out of bounds since there are 256 regs
1664
1665     vga->vga_dac.vga_dac_read_addr =  *((uint8_t*)src) ;
1666
1667     // Now we also need to reset the state machine
1668     
1669     vga->vga_dac.state=DAC_READ;
1670     vga->vga_dac.channel=RED;
1671
1672     return len;
1673 }
1674
1675
1676 static int dac_data_read(struct guest_info *core, 
1677                          uint16_t port, 
1678                          void *dest,
1679                          uint_t len,
1680                          void *priv_data)
1681 {
1682     struct vga_internal *vga = (struct vga_internal *) priv_data;
1683     uint8_t curreg;
1684     uint8_t curchannel;
1685     uint8_t data;
1686     
1687     if (vga->vga_dac.state!=DAC_READ) { 
1688         PrintError("vga: dac data read while in other state\n");
1689         // results undefined, so we continue
1690     }
1691
1692     ERR_WRONG_SIZE("read","vga dac read data",len,1,1);
1693
1694     curreg = vga->vga_dac.vga_dac_read_addr;
1695     curchannel = vga->vga_dac.channel;
1696     data = (vga->vga_dac.vga_dac_palette[curreg] >> curchannel*8) & 0x3f;
1697
1698     PrintDebug("vga: dac reg %u [%s] = 0x%x\n",
1699                curreg, 
1700                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1701                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1702                data);
1703
1704     *((uint8_t*)dest) = data;
1705
1706     PASSTHROUGH_IO_IN(vga,port,dest,len);
1707
1708     PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1709     
1710     curchannel = (curchannel+1)%3;
1711     vga->vga_dac.channel=curchannel;
1712     if (curchannel==0) { 
1713         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1714     } 
1715     vga->vga_dac.vga_dac_read_addr = curreg;
1716     vga->vga_dac.state=DAC_READ;
1717
1718     return len;
1719 }
1720
1721
1722
1723 static int dac_data_write(struct guest_info *core, 
1724                           uint16_t port, 
1725                           void *src,
1726                           uint_t len,
1727                           void *priv_data)
1728 {
1729     struct vga_internal *vga = (struct vga_internal *) priv_data;
1730     uint8_t curreg;
1731     uint8_t curchannel;
1732     uint8_t data;
1733     vga_palette_reg data32;
1734     vga_palette_reg mask32;
1735     
1736     if (vga->vga_dac.state!=DAC_WRITE) { 
1737         PrintError("vga: dac data write while in other state\n");
1738         // results undefined, so we continue
1739     }
1740
1741     ERR_WRONG_SIZE("read","vga dac write data",len,1,1);
1742
1743     PASSTHROUGH_IO_OUT(vga,port,src,len);
1744
1745     curreg = vga->vga_dac.vga_dac_write_addr;
1746     curchannel = vga->vga_dac.channel;
1747     data = *((uint8_t *)src);
1748
1749     PrintDebug("vga: dac reg %u [%s] write with 0x%x\n",
1750                curreg, 
1751                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1752                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1753                data);
1754
1755     data32 = data & 0x3f ;
1756     data32 <<= curchannel*8;
1757     mask32 = ~(0xff << (curchannel * 8));
1758
1759     vga->vga_dac.vga_dac_palette[curreg] &= mask32;
1760     vga->vga_dac.vga_dac_palette[curreg] |= data32;
1761
1762     curchannel = (curchannel+1)%3;
1763     vga->vga_dac.channel=curchannel;
1764     if (curchannel==0) { 
1765         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1766     } 
1767     vga->vga_dac.vga_dac_write_addr = curreg;
1768     vga->vga_dac.state=DAC_WRITE;
1769
1770     render(vga);
1771
1772     return len;
1773 }
1774
1775  
1776
1777 static int dac_pixel_mask_read(struct guest_info *core, 
1778                                uint16_t port, 
1779                                void *dest,
1780                                uint_t len,
1781                                void *priv_data)
1782 {
1783     struct vga_internal *vga = (struct vga_internal *) priv_data;
1784     
1785     PrintDebug("vga: dac pixel mask read data=0x%x\n", 
1786                vga->vga_dac.vga_pixel_mask);
1787
1788     ERR_WRONG_SIZE("read","vga pixel mask",len,1,1);
1789
1790     *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
1791
1792     PASSTHROUGH_IO_IN(vga,port,dest,len);
1793
1794     PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_pixel_mask,*(uint8_t*)dest);
1795
1796     return len;
1797 }
1798
1799 static int dac_pixel_mask_write(struct guest_info *core, 
1800                                 uint16_t port, 
1801                                 void *src,
1802                                 uint_t len,
1803                                 void *priv_data)
1804 {
1805     struct vga_internal *vga = (struct vga_internal *) priv_data;
1806     uint8_t new_data;
1807
1808     new_data=*((uint8_t*)src);
1809
1810     PrintDebug("vga: dac pixel mask write data=0x%x\n", new_data);
1811
1812     ERR_WRONG_SIZE("write","pixel mask",len,1,1);
1813
1814     PASSTHROUGH_IO_OUT(vga,port,src,len);
1815
1816     vga->vga_dac.vga_pixel_mask =  new_data;
1817
1818     return len;
1819 }
1820
1821 static int init_vga(struct vga_internal *vga)
1822 {
1823     // TODO: startup spec of register contents, if any
1824     PrintError("vga: init_vga is UNIMPLEMTED\n");
1825     return 0;
1826 }
1827
1828 static int free_vga(struct vga_internal *vga) 
1829 {
1830     int i;
1831     int ret;
1832     struct vm_device *dev = vga->dev;
1833
1834     // Framebuffer deletion is user's responsibility
1835
1836     //    if (vga->mem_store) {
1837     //  V3_FreePages(v3_hva_to_hpa(vga->mem_store),MEM_REGION_NUM_PAGES);
1838     //  vga->mem_store=0;
1839     //}
1840     
1841     for (i=0;i<MAP_NUM;i++) { 
1842         if (vga->map[i]) { 
1843             V3_FreePages(V3_PAddr(vga->map[i]),MAP_SIZE/4096);
1844             vga->map[i]=0;
1845         }
1846     }
1847
1848     v3_unhook_mem(vga->dev->vm, V3_MEM_CORE_ANY, MEM_REGION_START);
1849
1850     ret = 0;
1851
1852     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_READ);
1853     // The following also covers VGA_INPUT_STAT0_READ
1854     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_WRITE);
1855     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1856     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_MONO);
1857     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1858     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_COLOR);
1859     ret |= v3_dev_unhook_io(dev, VGA_FEATURE_CONTROL_READ);
1860     
1861     ret |= v3_dev_unhook_io(dev, VGA_VIDEO_SUBSYS_ENABLE);
1862
1863     /* Sequencer registers */
1864     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_ADDRESS);
1865     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_DATA);
1866
1867     /* CRT controller registers */
1868     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO);
1869     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR);
1870     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO);
1871     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR);
1872
1873     /* graphics controller registers */
1874     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS);
1875     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA);
1876
1877     /* attribute controller registers */
1878     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE);
1879     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ);
1880
1881     /* video DAC palette registers */
1882     ret |= v3_dev_unhook_io(dev, VGA_DAC_WRITE_ADDR);
1883     ret |= v3_dev_unhook_io(dev, VGA_DAC_READ_ADDR);
1884     ret |= v3_dev_unhook_io(dev, VGA_DAC_DATA);
1885     ret |= v3_dev_unhook_io(dev, VGA_DAC_PIXEL_MASK);
1886
1887
1888     if (vga->host_cons) { 
1889         v3_graphics_console_close(vga->host_cons);
1890     }
1891
1892     V3_Free(vga);
1893
1894     return 0;
1895 }
1896
1897 static struct v3_device_ops dev_ops = {
1898     .free = (int (*)(void *))free_vga,
1899 };
1900
1901
1902 static int vga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1903     struct vga_internal *vga;
1904     int i;
1905     int ret;
1906
1907     char * dev_id = v3_cfg_val(cfg, "ID");
1908     char * passthrough = v3_cfg_val(cfg, "passthrough");
1909     char * hostframebuf = v3_cfg_val(cfg, "hostframebuf");
1910
1911     PrintDebug("vga: init_device\n");
1912
1913     vga = (struct vga_internal *)V3_Malloc(sizeof(struct vga_internal));
1914
1915     if (!vga) { 
1916         PrintError("vga: cannot allocate\n");
1917         return -1;
1918     }
1919
1920     memset(vga, 0, sizeof(struct vga_internal));
1921
1922     if (passthrough && strcasecmp(passthrough,"enable")==0) {
1923         PrintDebug("vga: enabling passthrough\n");
1924         vga->passthrough=true;
1925         vga->skip_next_passthrough_out=false;
1926     }
1927
1928
1929     if (hostframebuf && strcasecmp(hostframebuf,"enable")==0) { 
1930         struct v3_frame_buffer_spec req;
1931
1932         PrintDebug("vga: enabling host frame buffer console (GRAPHICS_CONSOLE)\n");
1933
1934         memset(&req,0,sizeof(struct v3_frame_buffer_spec));
1935         memset(&(vga->target_spec),0,sizeof(struct v3_frame_buffer_spec));
1936
1937         req.height=VGA_MAXY;
1938         req.width=VGA_MAXX;
1939         req.bytes_per_pixel=4;
1940         req.bits_per_channel=8;
1941         req.red_offset=0;
1942         req.green_offset=1;
1943         req.blue_offset=2;
1944         
1945
1946         vga->host_cons = v3_graphics_console_open(vm,&req,&(vga->target_spec));
1947
1948         if (!vga->host_cons) { 
1949             PrintError("vga: unable to open host OS's graphics console\n");
1950             free_vga(vga);
1951             return -1;
1952         }
1953
1954         if (memcmp(&req,&(vga->target_spec),sizeof(req))) {
1955             PrintDebug("vga: warning: target spec differs from requested spec\n");
1956             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);
1957             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);
1958
1959         }
1960     }
1961
1962     if (!vga->passthrough && !vga->host_cons) { 
1963         V3_Print("vga: neither passthrough nor host console are enabled - no way to display anything!\n");
1964     }
1965
1966
1967     // No memory store is allocated since we will use a full memory hook
1968     // The VGA maps can be read as well as written
1969     // Reads also affect writes, since they are how you fill the latches
1970
1971     // Now allocate the maps
1972     for (i=0;i<MAP_NUM;i++) { 
1973         vga->map[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
1974         if (!(vga->map[i])) {
1975             PrintError("vga: cannot allocate maps\n");
1976             free_vga(vga);
1977             return -1;
1978         }
1979         memset(vga->map[i],0,MAP_SIZE);
1980     }
1981     
1982     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vga);
1983     
1984     if (dev == NULL) {
1985         PrintError("Could not attach device %s\n", dev_id);
1986         free_vga(vga);
1987         return -1;
1988     }
1989     
1990     vga->dev = dev;
1991     
1992     if (v3_hook_full_mem(vm, V3_MEM_CORE_ANY, 
1993                          MEM_REGION_START, MEM_REGION_END,
1994                          &vga_read, 
1995                          &vga_write,
1996                          dev) == -1) {
1997         PrintError("vga: memory book failed\n");
1998         v3_remove_device(dev);
1999         return -1;
2000     }
2001
2002     ret = 0;
2003     
2004     /* Miscelaneous registers */
2005     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_READ, &misc_out_read, NULL);
2006     // The following also covers VGA_INPUT_STAT0_READ
2007     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_WRITE, &input_stat0_read, &misc_out_write);
2008     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
2009     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_MONO, &input_stat1_read, &feature_control_write);
2010     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
2011     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_COLOR, &input_stat1_read, &feature_control_write);
2012     ret |= v3_dev_hook_io(dev, VGA_FEATURE_CONTROL_READ, &feature_control_read, NULL);
2013     
2014     ret |= v3_dev_hook_io(dev, VGA_VIDEO_SUBSYS_ENABLE, &video_subsys_enable_read, &video_subsys_enable_write);
2015
2016     /* Sequencer registers */
2017     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_ADDRESS, &sequencer_address_read, &sequencer_address_write);
2018     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_DATA, &sequencer_data_read, &sequencer_data_write);
2019
2020     /* CRT controller registers */
2021     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO, &crt_controller_address_read,&crt_controller_address_write);
2022     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR, &crt_controller_address_read,&crt_controller_address_write);
2023     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO, &crt_controller_data_read,&crt_controller_data_write);
2024     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR, &crt_controller_data_read,&crt_controller_data_write);
2025
2026     /* graphics controller registers */
2027     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS, &graphics_controller_address_read,&graphics_controller_address_write);
2028     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA, &graphics_controller_data_read,&graphics_controller_data_write);
2029
2030     /* attribute controller registers */
2031     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE, &attribute_controller_address_read,&attribute_controller_address_and_data_write);
2032     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ, &attribute_controller_data_read,NULL);
2033
2034     /* video DAC palette registers */
2035     ret |= v3_dev_hook_io(dev, VGA_DAC_WRITE_ADDR, &dac_write_address_read,&dac_write_address_write);
2036     ret |= v3_dev_hook_io(dev, VGA_DAC_READ_ADDR, &dac_read_address_read,&dac_read_address_write);
2037     ret |= v3_dev_hook_io(dev, VGA_DAC_DATA, &dac_data_read, &dac_data_write);
2038     ret |= v3_dev_hook_io(dev, VGA_DAC_PIXEL_MASK, &dac_pixel_mask_read, &dac_pixel_mask_write);
2039
2040     if (ret != 0) {
2041         PrintError("vga: Error allocating VGA I/O ports\n");
2042         v3_remove_device(dev);
2043         return -1;
2044     }
2045
2046     init_vga(vga);
2047
2048     PrintDebug("vga: successfully added and initialized.\n");
2049
2050     return 0;
2051
2052 }
2053
2054 device_register("VGA", vga_init);