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