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.


fd4a0686e179ea5841cfe967668887740a836fe0
[palacios.git] / palacios / src / devices / vga_regs.h
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 #ifndef _VGA_REGS
20 #define _VGA_REGS
21
22 /*
23     General Purpose Registers 
24   
25     These have well-known io ports for backward compatibility with
26     monochrome and cga controllers.   Note that the ioports of 
27     some of these vary depending on vga_misc_out_reg.io_addr_sel.  
28     If this is zero, then they are mapped as expected for a mono card
29     If one, then as for a cga card
30
31 */
32
33 /* Read: 0x3cc; Write: 0x3c2 */
34 struct vga_misc_out_reg {
35     union {
36         uint8_t val;
37         struct {
38             uint8_t io_addr_sel:1; // 0=>CRT at 0x3bx, input1 at 0x3ba (mono)
39                                    // 1=>CRT at 0x3dx, input1 at 0x3da (cga)
40             uint8_t en_ram:1;      // allow FB writes
41             uint8_t clock_sel:2;   // 00=>25.175/640 wide; 01=>28.322/720 wide
42             uint8_t reserved:2;
43             uint8_t horiz_sync_pol:1; // VH=01 => 400 lines; 10 => 350 lines
44             uint8_t vert_sync_pol:1;  // VH=11 => 480 lines
45             uint8_t reserved2:1;
46         } __attribute__((packed));
47     } __attribute__((packed));
48 } __attribute__((packed));
49
50
51 /* Read: 0x3c2 */
52 struct vga_input_stat0_reg {
53     union {
54         uint8_t val;
55         struct {
56             uint8_t reserved:4;
57             uint8_t switch_sense:1; // type of display attached (mono/color)
58             uint8_t reserved2:2;
59             uint8_t crt_inter:1;   // vertical retrace interrupt pending;
60         } __attribute__((packed));
61     } __attribute__((packed));
62 } __attribute__((packed));
63
64
65 /* Read: 0x3?a  3ba for mono; 3da for cga set by misc.io_addr_sel */
66 struct vga_input_stat1_reg {
67     union {
68         uint8_t val;
69         struct {
70             uint8_t disp_en:1; // in horizontal or vertical retrace (drawing)
71             uint8_t reserved:2;
72             uint8_t vert_retrace:1; // in vertical retrace interval
73             uint8_t reserved2:4;
74         } __attribute__((packed));
75     } __attribute__((packed));
76 } __attribute__((packed));
77
78
79 /* Read: 0x3ca; Write: 0x3?a 3ba for mono 3da for color - set by misc.io_addr_sel*/
80 struct vga_feature_control_reg {
81     union {
82         uint8_t val;
83         struct {
84             uint8_t reserved:8; // per IBM spec
85         } __attribute__((packed));
86     } __attribute__((packed));
87 } __attribute__((packed));
88
89 /* Read: 0x3c3; Write: 0x3c3 */
90 struct vga_video_subsys_enable_reg {
91     union {
92         uint8_t val;
93         struct {
94             uint8_t reserved:8; // per IBM spec
95         } __attribute__((packed));
96     } __attribute__((packed));
97 } __attribute__((packed));
98
99 /* 
100    Sequencer Registers 
101   
102    These are all accessed via address and data registers.  
103   
104    Address register is 0x3c4, data register is 0x3c5
105 */
106
107 /* 0x3c4 */
108 struct vga_sequencer_addr_reg {
109     union {
110         uint8_t val;
111         struct {
112             uint8_t seq_address:3; 
113             uint8_t reserved:5; 
114         } __attribute__((packed));
115     } __attribute__((packed));
116 } __attribute__((packed))
117 ;
118
119 /* Index 0 */
120 struct vga_reset_reg {
121     union {
122         uint8_t val;
123         struct {
124             uint8_t async_reset:1; // write zero to async clear and halt
125             uint8_t sync_reset:1;  // write zero to sync clear and halt
126                                    // write 11 to run
127             uint8_t reserved:6; 
128         } __attribute__((packed));
129     } __attribute__((packed));
130 } __attribute__((packed));
131
132 /* Index 1 */
133 struct vga_clocking_mode_reg {
134     union {
135         uint8_t val;
136         struct {
137             uint8_t dot8:1;        // 0=>9 dot clocks per char clock; 1=>8
138             uint8_t reserved:1;    // must be one
139             uint8_t shift_load:1;  //
140             uint8_t dot_clock:1;   // 0=> dc=master clock; 1=> dc=0.5*master
141                                    // e.g. 0 for 640 wide, 1 for 320 wide
142             uint8_t shift_4:1;     // shift_4 shift_load  Load video serializer
143                                    //    0       0          every char clock
144                                    //    0       1          every 2nd
145                                    //    1       0          every 4th 
146             uint8_t screen_off:1;  // turn off display
147             uint8_t reserved2:2;   
148         } __attribute__((packed));
149     } __attribute__((packed));
150 } __attribute__((packed));
151
152 /* Index 2 */
153 struct vga_map_mask_reg {
154     union {
155         uint8_t val;
156         struct {
157             uint8_t map0_en:1;  // enable map 0 (write to bank zero of mem)
158             uint8_t map1_en:1;  // enable map 1
159             uint8_t map2_en:1;  // enable map 2  All enabled=>chain4 mode
160             uint8_t map3_en:1;  // enable map 3
161             uint8_t reserved:4; 
162         } __attribute__((packed));
163     } __attribute__((packed));
164 } __attribute__((packed));
165
166 /* Index 3 */
167 struct vga_char_map_select_reg {
168     union {
169         uint8_t val;
170         struct {
171             uint8_t char_map_b_sel_lsb:2;  // low 2 bits of char map b sel
172             uint8_t char_map_a_sel_lsb:2;  // low 2 bits of char map a sel
173             uint8_t char_map_b_sel_msb:1;  // high bit of char map b sel
174             uint8_t char_map_a_sel_msb:1;  // high bit of char map a sel
175             uint8_t reserved:2; 
176             /*
177                For A: the map bits give the char sets at:
178                   000  1st 8K of map (bank) 2
179                   001  3rd 8K
180                   010  5th 8K
181                   011  7th 8K
182                   100  2nd 8K
183                   101  4th 8K
184                   110  6th 8K
185                   111  8th 8K
186  
187                Identical for B
188             */
189         } __attribute__((packed));
190     } __attribute__((packed));
191 } __attribute__((packed));
192
193 /* Index 4 */
194 struct vga_mem_mode_reg {
195     union {
196         uint8_t val;
197         struct {
198             uint8_t reserved:1;
199             uint8_t extended_memory:1; // 1=>256K RAM, 0=>64K
200             uint8_t odd_even:1;
201                 // 0 => even addresses go to BOTH banks 0 and 2, odd 1 and 3
202                 //      or flip between 0/1 for CGA compat
203                 // 1 => address bank sequentially, map mask selects bank
204             uint8_t chain4:1;  
205                 // 0 => map mask register used to select bank
206                 // 1 => lower 2 bits of address used to select bank
207             uint8_t reserved2:4; 
208         } __attribute__((packed));
209     } __attribute__((packed));
210 } __attribute__((packed));
211
212 /*
213   CRT Controller Registers
214
215   These registers control the rendering of the framebuffer (the maps)
216   to the monitor.   This includes text/graphics mode, and which kind of mode
217   
218   It's important to understand that while the vertical resolution works
219   as you would expect, using scan lines, the horizontal resolution is
220   in terms of characters (char clocks), EVEN IF YOU ARE IN A GRAPHICS MODE
221
222   Another important thing to understand is that the modes defined in he
223   VGA/VESA bios are just convenient names for particular settings of 
224   the CRT controller registers.   Other options are also possible.
225
226   Address register is 0x3d4 or 0x3b4 depending on misc.ioaddr_sel
227   Data register is 0x3d5 or 0x3b5 depending on misc.ioaddr_sel
228   b4/5 is for mono compatability
229 */
230
231 /* 0x3b4 or 0x3d4 */
232 struct vga_crt_addr_reg {
233     union {
234         uint8_t val;
235         struct {
236             uint8_t crt_address:5; 
237             uint8_t reserved:3; 
238         } __attribute__((packed));
239     } __attribute__((packed));
240 } __attribute__((packed))
241 ;
242
243
244 /* index 0 */
245 // Total number of chars in horizontal interval, including retrace
246 typedef uint8_t vga_horizontal_total_reg;
247
248 /* index 1 */
249 // text: number of displayed characters minus 1 (columns-1)
250 // graphic: horizontal resolution is cols*#dotclocks_per_charclock
251 typedef uint8_t vga_horizontal_display_enable_end_reg;
252
253 /* index 2 */
254 // horizontal characer count at which blanking starts
255 typedef uint8_t vga_start_horizontal_blanking_reg;
256
257 /* index 3 */
258 struct vga_end_horizontal_blanking_reg {
259     union {
260         uint8_t val;
261         struct {
262             uint8_t end_blanking:5; // when blanking ends, in char clocks 
263                                     // top bit in horizontal retrace
264             uint8_t display_enable_skew:2; // skew in character clocks
265             uint8_t reserved:1;     // must be 1 
266         } __attribute__((packed));
267     } __attribute__((packed));
268 } __attribute__((packed))
269 ;
270
271 /* index 4 */
272 // screen centering:  char position where horizontal retrace is active
273 typedef uint8_t vga_start_horizontal_retrace_pulse_reg;
274
275 /* index 5 */
276 struct vga_end_horizontal_retrace_reg {
277     union {
278         uint8_t val;
279         struct {
280             uint8_t end_horizontal_retrace:5; 
281             // horizontal char count where retrace inactive
282             uint8_t horizontal_retrace_delay:2; 
283             // skew of retace signal in char clocks
284             uint8_t end_horizontal_blanking5:1;
285             // top bit in horizontal blanking
286         } __attribute__((packed));
287     } __attribute__((packed));
288 } __attribute__((packed))
289 ;
290
291 /* index 6 */
292 // lower 8 bits of total number of scan lines minus 2
293 // There are 10 bits total, 2 of which are on the overflow reg
294 typedef uint8_t vga_vertical_total_reg;
295
296 /* index 7 */
297 struct vga_overflow_reg {
298     union {
299         uint8_t val;
300         struct {
301             uint8_t vertical_total8:1; // vert total, bit 8
302             uint8_t vertical_disp_enable_end8:1; // bit 8
303             uint8_t vertical_retrace_start8:1; // bit 8
304             uint8_t vertical_blanking_start8:1; //bit 8
305             uint8_t line_compare8:1; // bit 8;
306             uint8_t vertical_total9:1; // vert total, bit 9
307             uint8_t vertical_disp_enable_end9:1; // bit 9
308             uint8_t vertical_retrace_start9:1; // bit 9
309         } __attribute__((packed));
310     } __attribute__((packed));
311 } __attribute__((packed))
312 ;
313
314 /* index 8 */
315 struct vga_preset_row_scan_reg {
316     union {
317         uint8_t val;
318         struct {
319             uint8_t start_row_scan_count:5; 
320             // what the row counter begins at?
321             uint8_t byte_panning:2; 
322             // ?
323             uint8_t reserved:1;
324         } __attribute__((packed));
325     } __attribute__((packed));
326 } __attribute__((packed))
327 ;
328
329 /* index 9 */
330 struct vga_max_row_scan_reg {
331     union {
332         uint8_t val;
333         struct {
334             uint8_t max_scan_line:5; 
335             // scan lines per character row minus 1
336             uint8_t start_vertical_blanking9:1; 
337             // bit 9 of this field
338             uint8_t line_compare9:1;
339             // bit 9 of this field
340             uint8_t double_scan:1; // 1=> 200 scan lines double to 400
341         } __attribute__((packed));
342     } __attribute__((packed));
343 } __attribute__((packed))
344 ;
345
346 /* index 10 */
347 struct vga_cursor_start_reg {
348     union {
349         uint8_t val;
350         struct {
351             uint8_t row_scan_cursor_begin:5; 
352             // row at which the cursor begins
353             uint8_t cursor_off:1; 
354             // bit 9 of this field
355             uint8_t reserved:2;
356         } __attribute__((packed));
357     } __attribute__((packed));
358 } __attribute__((packed))
359 ;
360
361 /* index 11 */
362 struct vga_cursor_end_reg {
363     union {
364         uint8_t val;
365         struct {
366             uint8_t row_scan_cursor_end:5; 
367             // row at which the cursor ends
368             uint8_t cursor_skew:2; 
369             // skew in cursor clocks
370             uint8_t reserved:1;
371         } __attribute__((packed));
372     } __attribute__((packed));
373 } __attribute__((packed))
374 ;
375
376
377 /* index 12 */
378 // starting address of regenerative buffer (?)
379 typedef uint8_t vga_start_address_high_reg;
380 /* index 13 */
381 // starting address of regenerative buffer (?)
382 typedef uint8_t vga_start_address_low_reg;
383
384 /* index 14 */
385 // cursor location
386 typedef uint8_t vga_cursor_location_high_reg;
387 /* index 15 */
388 // cursor location
389 typedef uint8_t vga_cursor_location_low_reg;
390
391 /* index 16 */
392 // vertical retrace start - low 8 bits, 9th is on overflow register
393 typedef uint8_t vga_vertical_retrace_start_reg;
394
395
396 /* index 17 */
397 struct vga_vertical_retrace_end_reg {
398     union {
399         uint8_t val;
400         struct {
401             uint8_t vertical_retrace_end:4;
402             uint8_t clear_vertical_interrupt:1; // 0 to clear interrupt
403             uint8_t enable_vertical_interrupt:1; // IRQ2 on vert retrace
404             uint8_t select_5_refresh_cycles:1; // Slower displays
405             uint8_t protect_regs:1; // 1=> indices 0..7 disabled
406         } __attribute__((packed));
407     } __attribute__((packed));
408 } __attribute__((packed))
409 ;
410
411 /* index 18 */
412 // lower 8 bits of 10 bit value (rest on overflow reg)
413 // this is the total number of scan lines minus one
414 typedef uint8_t vga_vertical_display_enable_end_reg;
415
416 /* index 19 */
417 // logical line width of the screen (including attrs)
418 // starting memory address of next character row is 2 or 4 times
419 // this value
420 typedef uint8_t vga_offset_reg;
421
422
423 /* index 20 */
424 struct vga_underline_location_reg {
425     union {
426         uint8_t val;
427         struct {
428             uint8_t start_underline:5; // scan line in char where UL starts
429             uint8_t count_by_four:1;   // memory addresses count by 4 (for dw)
430             uint8_t doubleword:1;      // memory addresses are 32 bits
431             uint8_t reserved:1;
432         } __attribute__((packed));
433     } __attribute__((packed));
434 } __attribute__((packed))
435 ;
436
437 /* index 21 */
438 // 8 bits of 10 bit quanity, rest are on overflow and maximum scan line reg
439 // scan line count at which vertical blanking goes on, minus one
440 typedef uint8_t vga_start_vertical_blanking_reg;
441
442 /* index 22 */
443 // scan line count at which vertical blanking goes off
444 typedef uint8_t vga_end_vertical_blanking_reg;
445
446
447 /* index 23 */
448 struct vga_crt_mode_control_reg {
449     union {
450         uint8_t val;
451         struct {
452             uint8_t cms0:1; 
453             // bit 13 of output mux come from rowscan, bit zero if zero
454             // otherwise from bit 13 of address counter
455             // ?? compatability with CGA
456    
457             uint8_t select_row_scan_ctr:1;
458             // bit 14 of output mux comes from bit 1 of rowscan if zero
459             // otherwise from bit 14 of addres counter
460             // ? CGA ?
461
462             uint8_t horizontal_retrace_select:1;
463             // select clock of vertical timing counter
464             // 0 = horiz retrace clock, 1=same / 2
465
466             uint8_t count_by_two:1;
467             // address counter source
468             // 0 = character clock
469             // 1 = character clock / 2 (word)
470
471             uint8_t reserved:1;
472
473             uint8_t address_wrap:1;
474             // is MA 13 or MA 15 output in MA 0 when in word address mode
475
476             uint8_t word_byte_mode:1;
477             // 0 = word mode memory access , 1= byte
478             
479             uint8_t reset:1;
480             // 0 = stop horizontal and vertical retrace
481         } __attribute__((packed));
482     } __attribute__((packed));
483 } __attribute__((packed))
484 ;
485
486 /* index 24 */
487 // lower 8 bits of 10 bit counter; rest are on overflow and max scan line regs
488 // line counter is zeroed when it hits this value
489 typedef uint8_t vga_line_compare_reg;
490
491 /*
492    Graphics Controller Registers
493
494    These registers control how the framebuffer / banks are accessed 
495    from the host computer.   How a memory write is translated is 
496    determined by these settings.
497
498    Address: 0x3ce
499    Data: 0x3cf
500
501 */
502
503 /* 0x3ce */
504 struct vga_graphics_ctrl_addr_reg {
505     union {
506         uint8_t val;
507         struct {
508             uint8_t graphics_address:4; 
509             uint8_t reserved:4; 
510         } __attribute__((packed));
511     } __attribute__((packed));
512 } __attribute__((packed))
513 ;
514
515 /* Index 0 */
516 // these are the values written to each map given memory write
517 // mode 0.   While they are single bits, they are extended to full 
518 // bytes
519 struct vga_set_reset_reg {
520     union {
521         uint8_t val;
522         struct {
523             uint8_t sr0:1; //  bank 0
524             uint8_t sr1:1; //  bank 1
525             uint8_t sr2:1; //  bank 2
526             uint8_t sr3:1; //  bank 3
527             uint8_t reserved:4; 
528         } __attribute__((packed));
529     } __attribute__((packed));
530 } __attribute__((packed))
531 ;
532
533 /* Index 1 */
534 // these flags enable the use of the set/reset register values
535 // in writing the map when write mode 0 is used
536 struct vga_enable_set_reset_reg {
537     union {
538         uint8_t val;
539         struct {
540             uint8_t esr0:1; //  bank 0
541             uint8_t esr1:1; //  bank 1
542             uint8_t esr2:1; //  bank 2
543             uint8_t esr3:1; //  bank 3
544             uint8_t reserved:4; 
545         } __attribute__((packed));
546     } __attribute__((packed));
547 } __attribute__((packed))
548 ;
549
550 /* Index 2 */
551 // Color comparison values for one of the read modes
552 struct vga_color_compare_reg {
553     union {
554         uint8_t val;
555         struct {
556             uint8_t cc0:1; //  bank 0
557             uint8_t cc1:1; //  bank 1
558             uint8_t cc2:1; //  bank 2
559             uint8_t cc3:1; //  bank 3
560             uint8_t reserved:4; 
561         } __attribute__((packed));
562     } __attribute__((packed));
563 } __attribute__((packed))
564 ;
565
566 /* Index 3 */
567 // rotation amount and function for write mode 0 and others
568 struct vga_data_rotate_reg {
569     union {
570         uint8_t val;
571         struct {
572             uint8_t rotate_count:3; //  amount to ROR bits being written
573             uint8_t function:2;     // function to use
574             // 00 : NOP
575             // 01 : AND
576             // 10 : OR
577             // 11 : XOR
578             uint8_t reserved:3; 
579         } __attribute__((packed));
580     } __attribute__((packed));
581 } __attribute__((packed))
582 ;
583
584 /* Index 4 */
585 // which of the maps (banks) will be read from when a system read occurs
586 // Does not affect color compare reads
587 struct vga_read_map_select_reg {
588     union {
589         uint8_t val;
590         struct {
591             uint8_t map_select:2; //  which one you want to read
592             uint8_t reserved:6; 
593         } __attribute__((packed));
594     } __attribute__((packed));
595 } __attribute__((packed))
596 ;
597
598 /* Index 5 */
599 // Graphics Mode DOES NOT MEAN graphics mode - it means
600 // the modes in which framebuffer reads/writes are done
601 struct vga_graphics_mode_reg {
602     union {
603         uint8_t val;
604         struct {
605             uint8_t write_mode:2; 
606             /* 
607               
608 From the IBM docmentation:
609
610 0 0 Each memory map is written with the system data rotated by the count
611 in the Data Rotate register. If the set/reset function is enabled for a
612 specific map, that map receives the 8-bit value contained in the
613 Set/Reset register.
614
615 0 1 Each memory map is written with the contents of the system latches.
616 These latches are loaded by a system read operation.
617
618 1 0 Memory map n (0 through 3) is filled with 8 bits of the value of data
619 bit n.
620
621 1 1 Each memory map is written with the 8-bit value contained in the
622 Set/Reset register for that map (the Enable Set/Reset register has no
623 effect). Rotated system data is ANDed with the Bit Mask register to
624 form an 8-bit value that performs the same function as the Bit Mask
625 register in write modes 0 and 2 (see also Bit Mask register on
626 page 2-88).
627             */
628             uint8_t reserved:1;
629             uint8_t read_mode:1;
630             // 1 = read gets comparison of all maps and color compare
631             // 0 = read gets bits from selected map
632             uint8_t odd_even:1;
633             // 1 = odd/even addressing as in CGMA
634             // 0 = NOT odd/even
635             // notice that this is the OPPOSITE of the bit in the sequencer!
636             uint8_t shift_reg_mode:1;
637             // 1 = shift regs get odd bits from odd maps and even/even
638             uint8_t c256:1;                 // 1 = 256 color mode
639             // 0 = shift_reg_mode controls shift regs
640             uint8_t reserved2:1; 
641         } __attribute__((packed));
642     } __attribute__((packed));
643 } __attribute__((packed))
644 ;
645
646 /* Index 6 */
647 // Misc
648 struct vga_misc_reg {
649     union {
650         uint8_t val;
651         struct {
652             uint8_t graphics_mode:1;
653             // if on, then we are in a graphics mode
654             // if off, we are in a text mode
655             uint8_t odd_even:1;
656             // if on, then low order bit of system address
657             // selects odd or even map
658             uint8_t memory_map:2;
659             // Controls mapping of regenerative buffer into address space
660             // 00 => A0000 for 128K
661             // 01 => A0000 for 64K
662             // 10 => B0000 for 32K
663             // 11 => B8000 for 32K
664             uint8_t reserved:4; 
665         } __attribute__((packed));
666     } __attribute__((packed));
667 } __attribute__((packed))
668 ;
669
670 /* Index 7 */
671 // Color don't care
672 struct vga_color_dont_care_reg {
673     union {
674         uint8_t val;
675         struct {
676             uint8_t dc_map0:1;
677             uint8_t dc_map1:1;
678             uint8_t dc_map2:1;
679             uint8_t dc_map3:1;
680             // if off then the corresponding map is not
681             // considered in color comparison
682             uint8_t reserved:4; 
683         } __attribute__((packed));
684     } __attribute__((packed));
685 } __attribute__((packed))
686 ;
687
688 /* Index 8 */
689 typedef uint8_t vga_bit_mask_reg;
690 // bit high means corresponding bit in each mask
691 // can be changed  (used for write modes 0 and 2)
692
693 /* 
694   Attribute Controller Registers
695
696   The attribute controller essentially handles
697   attributes in text mode and palletes in graphics mode
698
699   Address AND WRITE: 0x3c0
700   Read: 0x3c1
701
702   The write protocol is to write the index to 0x3c0 followed by 
703   the data.  The read protocol is to write the index to 0x3c0
704   and then read from 0x3c1
705
706   IMPORTANT: write address, write data flips state back to write address
707   write address, read data DOES NOT
708
709   To reset to write address state, read input status register 1
710 */
711
712 /* 0x3c0 */
713 struct vga_attribute_controller_address_reg {
714     union {
715         uint8_t val;
716         struct {
717             uint8_t index:5;    // actual address
718             uint8_t internal_palette_address_source:1; 
719             // 0 => use the internal color palette (load the regs)
720             // 1 => use the external color palette
721             uint8_t reserved:2; 
722         } __attribute__((packed));
723     } __attribute__((packed));
724 } __attribute__((packed))
725 ;
726
727 /* 
728    Internal Palette Registers
729
730    Index 0..15
731
732    Register k maps attribute k to the palette entry loaded in register k
733 */
734 struct vga_internal_palette_reg {
735     union {
736         uint8_t val;
737         struct {
738             uint8_t palette_data:6;    // which palette entry to use
739             uint8_t reserved:2; 
740         } __attribute__((packed));
741     } __attribute__((packed));
742 } __attribute__((packed))
743 ;
744
745 typedef struct vga_internal_palette_reg vga_internal_palette_regs[16];
746
747 /* Index 16 */
748 struct vga_attribute_mode_control_reg {
749     union {
750         uint8_t val;
751         struct {
752             uint8_t graphics:1;  // graphics versus text mode
753             uint8_t mono_emul:1; // emulate an MDA
754             uint8_t enable_line_graphics_char_code:1;
755             // 1 => enable special line graphics characters
756             //      and force 9th dot to be same as 8th dot of char
757             uint8_t enable_blink;
758             // 1 => MSB of the attribute means blink (8 colors + blink)
759             // 0 => MSB of the attribute means intensity (16 colors)
760             uint8_t reserved:1;
761             uint8_t pixel_panning:1;
762             // if 1, pixel panning reg set to 0 when line compare succeeds
763             uint8_t pixel_width:1;
764             // 1 => 8 bit color (256 colors)
765             uint8_t p54_select:1;
766             // select source of p5 and p6 inputs to DAC
767             // 0 => use internal palette regs
768             // 1 => use color select reg
769         } __attribute__((packed));
770     } __attribute__((packed));
771 } __attribute__((packed))
772 ;
773
774 /* Index 17 */
775 // this is the screen border color
776 typedef uint8_t vga_overscan_color_reg;
777
778 /* Index 18 */
779 // Enable the corresponding display memory color plane
780 struct vga_color_plane_enable_reg {
781     union {
782         uint8_t val;
783         struct {
784             uint8_t enable_color_plane:4;
785             uint8_t reserved:4; 
786         } __attribute__((packed));
787     } __attribute__((packed));
788 } __attribute__((packed))
789     ;
790
791 /* Index 19 */
792 // number of pixels to shift the display to the left
793 struct vga_horizontal_pixel_pan_reg {
794     union {
795         uint8_t val;
796         struct {
797             uint8_t horizontal_pixel_pan:4;
798             uint8_t reserved:4; 
799         } __attribute__((packed));
800     } __attribute__((packed));
801 } __attribute__((packed))
802     ;
803
804 /* Index 20 */
805 // color select
806 // These allow for quick switching back and forth between
807 // color palletes
808 struct vga_color_select_reg {
809     union {
810         uint8_t val;
811         struct {
812             uint8_t sc4:1;
813             uint8_t sc5:1;
814             uint8_t sc6:1;
815             uint8_t sc7:1;
816             uint8_t reserved:4; 
817         } __attribute__((packed));
818     } __attribute__((packed));
819 } __attribute__((packed))
820     ;
821
822 /*
823   DAC registers
824
825   Used to derive the ultimate pixel colors that are rendered on the display
826   
827   There are 256 palette registers
828   We can change any one or read any one
829 */
830
831 //
832 // The palette register that will returned on a data write
833 // 0x3c8
834 typedef uint8_t vga_dac_write_addr_reg;
835
836 //
837 // The palette register that will returned on a data read
838 // 0x3c7
839 typedef uint8_t vga_dac_read_addr_reg;
840
841 //
842 // Read or write of a palette register
843 // 0x3c9
844 // Successive references to this register increment
845 // the palette register index (for reads and writes separately)
846 // Three SUCCESSIVE WRITES ARE EXPECTED to set the 18 bit register
847 // Three SUCCESSIVE READS ARE EXPECTED to read out the register
848 // reads or writes are in order RED GREEN BLUE
849 // ADDRESS REG WRITE always resets
850 typedef uint8_t vga_dac_data_reg;
851
852 //
853 // Pixel Mask
854 // 0x3c6
855 typedef uint8_t vga_dac_pixel_mask_reg;
856
857 // Palette register (256 of these)
858 // strictly speaking, each of these is 18 bits wide, 6 bits per channel
859 // We will provide reg&0x3f, reg>>8 & 0x3f, etc
860 // This is red, green, blue
861 typedef uint32_t vga_palette_reg; 
862
863
864 //
865 //  What attribute bytes mean in text mode
866 //
867 struct vga_attribute_byte {
868     union {
869         uint8_t val;
870         struct {
871             uint8_t fore:3;   //foreground color
872             uint8_t foreground_intensity_or_font_select:1; // depends on char map select reg
873             // character map selection is effected
874             // when memory_mode.extended meomory=1
875             // and the two character map enteries on character_map_select are 
876             // different
877             uint8_t back:3;   //background color
878             uint8_t blinking_or_bg_intensity:1; 
879             // attribute mode control.enableblink = 1 => blink
880             // =0 => intensity (16 colors of bg)
881         } __attribute__((packed));
882     } __attribute__((packed));
883 } __attribute__((packed));
884
885 #endif