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.


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