Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / seabios / vgasrc / stdvgamodes.c
1 // Standard VGA mode information.
2 //
3 // Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2001-2008 the LGPL VGABios developers Team
5 //
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
7
8 #include "biosvar.h" // GET_GLOBAL
9 #include "output.h" // warn_internalerror
10 #include "stdvga.h" // stdvga_find_mode
11 #include "string.h" // memcpy_far
12 #include "vgabios.h" // video_param_table
13
14
15 /****************************************************************
16  * Video mode register definitions
17  ****************************************************************/
18
19 /* Mono */
20 static u8 palette0[] VAR16 = {
21   0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
22   0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
23   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
24   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
25   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
26   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
27   0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
28   0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
29   0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
30   0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
31   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
32   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
33   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
34   0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
35   0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
36   0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f
37 };
38
39 static u8 palette1[] VAR16 = {
40   0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
41   0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
42   0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
43   0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
44   0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
45   0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
46   0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
47   0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
48   0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
49   0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
50   0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
51   0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
52   0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
53   0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
54   0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
55   0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
56 };
57
58 static u8 palette2[] VAR16 = {
59   0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
60   0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a,
61   0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f,
62   0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f,
63   0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a,
64   0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a,
65   0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f,
66   0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f,
67   0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a,
68   0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a,
69   0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f,
70   0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f,
71   0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a,
72   0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a,
73   0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
74   0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
75 };
76
77 static u8 palette3[] VAR16 = {
78   0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
79   0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
80   0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
81   0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
82   0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b,
83   0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18,
84   0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28,
85   0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f,
86   0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f,
87   0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10,
88   0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00,
89   0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00,
90   0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f,
91   0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f,
92   0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f,
93   0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27,
94
95   0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f,
96   0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f,
97   0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37,
98   0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f,
99   0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f,
100   0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31,
101   0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d,
102   0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d,
103   0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a,
104   0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f,
105   0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c,
106   0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07,
107   0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00,
108   0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00,
109   0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15,
110   0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c,
111
112   0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c,
113   0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11,
114   0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e,
115   0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e,
116   0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18,
117   0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c,
118   0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c,
119   0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16,
120   0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14,
121   0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14,
122   0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a,
123   0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c,
124   0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10,
125   0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04,
126   0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00,
127   0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00,
128
129   0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c,
130   0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10,
131   0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10,
132   0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a,
133   0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08,
134   0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08,
135   0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e,
136   0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10,
137   0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10,
138   0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c,
139   0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b,
140   0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b,
141   0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f,
142   0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10,
143   0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
144   0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
145 };
146
147 static u8 sequ_01[] VAR16 = { 0x08, 0x03, 0x00, 0x02 };
148 static u8 crtc_01[] VAR16 = {
149     0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
150     0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
151     0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
152     0xff };
153 static u8 actl_01[] VAR16 = {
154     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
155     0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
156     0x0c, 0x00, 0x0f, 0x08 };
157 static u8 grdc_01[] VAR16 = {
158     0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff };
159 static u8 sequ_03[] VAR16 = { 0x00, 0x03, 0x00, 0x02 };
160 static u8 crtc_03[] VAR16 = {
161     0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
162     0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
163     0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
164     0xff };
165 static u8 sequ_04[] VAR16 = { 0x09, 0x03, 0x00, 0x02 };
166 static u8 crtc_04[] VAR16 = {
167     0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
168     0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169     0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
170     0xff };
171 static u8 actl_04[] VAR16 = {
172     0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
173     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
174     0x01, 0x00, 0x03, 0x00 };
175 static u8 grdc_04[] VAR16 = {
176     0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff };
177 static u8 sequ_06[] VAR16 = { 0x01, 0x01, 0x00, 0x06 };
178 static u8 crtc_06[] VAR16 = {
179     0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
180     0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181     0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
182     0xff };
183 static u8 actl_06[] VAR16 = {
184     0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
185     0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
186     0x01, 0x00, 0x01, 0x00 };
187 static u8 grdc_06[] VAR16 = {
188     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff };
189 static u8 crtc_07[] VAR16 = {
190     0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
191     0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
192     0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
193     0xff };
194 static u8 actl_07[] VAR16 = {
195     0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
196     0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
197     0x0e, 0x00, 0x0f, 0x08 };
198 static u8 grdc_07[] VAR16 = {
199     0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff };
200 static u8 sequ_0d[] VAR16 = { 0x09, 0x0f, 0x00, 0x06 };
201 static u8 crtc_0d[] VAR16 = {
202     0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
203     0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204     0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
205     0xff };
206 static u8 actl_0d[] VAR16 = {
207     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
208     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
209     0x01, 0x00, 0x0f, 0x00 };
210 static u8 grdc_0d[] VAR16 = {
211     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff };
212 static u8 sequ_0e[] VAR16 = { 0x01, 0x0f, 0x00, 0x06 };
213 static u8 crtc_0e[] VAR16 = {
214     0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
215     0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216     0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
217     0xff };
218 static u8 crtc_0f[] VAR16 = {
219     0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
220     0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221     0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
222     0xff };
223 static u8 actl_0f[] VAR16 = {
224     0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
225     0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
226     0x01, 0x00, 0x01, 0x00 };
227 static u8 actl_10[] VAR16 = {
228     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
229     0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
230     0x01, 0x00, 0x0f, 0x00 };
231 static u8 crtc_11[] VAR16 = {
232     0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
233     0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234     0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
235     0xff };
236 static u8 actl_11[] VAR16 = {
237     0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
238     0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
239     0x01, 0x00, 0x0f, 0x00 };
240 static u8 sequ_13[] VAR16 = { 0x01, 0x0f, 0x00, 0x0e };
241 static u8 crtc_13[] VAR16 = {
242     0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
243     0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244     0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
245     0xff };
246 static u8 actl_13[] VAR16 = {
247     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
248     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
249     0x41, 0x00, 0x0f, 0x00 };
250 static u8 grdc_13[] VAR16 = {
251     0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff };
252 static u8 crtc_6A[] VAR16 = {
253     0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
254     0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255     0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3,
256     0xff };
257
258 #define PAL(x) x, sizeof(x)
259
260 struct stdvga_mode_s {
261     u16 mode;
262     struct vgamode_s info;
263
264     u8 pelmask;
265     u8 *dac;
266     u16 dacsize;
267     u8 *sequ_regs;
268     u8 miscreg;
269     u8 *crtc_regs;
270     u8 *actl_regs;
271     u8 *grdc_regs;
272 };
273
274 static struct stdvga_mode_s vga_modes[] VAR16 = {
275     //mode { model       tx   ty bpp cw ch  sstart    }
276     // pelm  dac            sequ     misc  crtc     actl     grdc
277     {0x00, { MM_TEXT,    40,  25, 4, 9, 16, SEG_CTEXT }
278      , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01},
279     {0x01, { MM_TEXT,    40,  25, 4, 9, 16, SEG_CTEXT }
280      , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01},
281     {0x02, { MM_TEXT,    80,  25, 4, 9, 16, SEG_CTEXT }
282      , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01},
283     {0x03, { MM_TEXT,    80,  25, 4, 9, 16, SEG_CTEXT }
284      , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01},
285     {0x04, { MM_CGA,    320, 200, 2, 8,  8, SEG_CTEXT }
286      , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04},
287     {0x05, { MM_CGA,    320, 200, 2, 8,  8, SEG_CTEXT }
288      , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04},
289     {0x06, { MM_CGA,    640, 200, 1, 8,  8, SEG_CTEXT }
290      , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06},
291     {0x07, { MM_TEXT,    80,  25, 4, 9, 16, SEG_MTEXT }
292      , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07},
293     {0x0D, { MM_PLANAR, 320, 200, 4, 8,  8, SEG_GRAPH }
294      , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d},
295     {0x0E, { MM_PLANAR, 640, 200, 4, 8,  8, SEG_GRAPH }
296      , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d},
297     {0x0F, { MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH }
298      , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d},
299     {0x10, { MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH }
300      , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d},
301     {0x11, { MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH }
302      , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d},
303     {0x12, { MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH }
304      , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d},
305     {0x13, { MM_PACKED, 320, 200, 8, 8,  8, SEG_GRAPH }
306      , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13},
307     {0x6A, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH }
308      , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d},
309 };
310
311
312 /****************************************************************
313  * Mode functions
314  ****************************************************************/
315
316 static int
317 is_stdvga_mode(struct vgamode_s *vmode_g)
318 {
319     return (vmode_g >= &vga_modes[0].info
320             && vmode_g <= &vga_modes[ARRAY_SIZE(vga_modes)-1].info);
321 }
322
323 struct vgamode_s *
324 stdvga_find_mode(int mode)
325 {
326     int i;
327     for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
328         struct stdvga_mode_s *stdmode_g = &vga_modes[i];
329         if (GET_GLOBAL(stdmode_g->mode) == mode)
330             return &stdmode_g->info;
331     }
332     return NULL;
333 }
334
335 void
336 stdvga_list_modes(u16 seg, u16 *dest, u16 *last)
337 {
338     int i;
339     for (i = 0; i < ARRAY_SIZE(vga_modes) && dest < last; i++) {
340         struct stdvga_mode_s *stdmode_g = &vga_modes[i];
341         u16 mode = GET_GLOBAL(stdmode_g->mode);
342         if (mode == 0xffff)
343             continue;
344         SET_FARVAR(seg, *dest, mode);
345         dest++;
346     }
347
348     SET_FARVAR(seg, *dest, 0xffff);
349 }
350
351 void
352 stdvga_build_video_param(void)
353 {
354     static u8 parammodes[] VAR16 = {
355         0, 0, 0, 0, 0x04, 0x05, 0x06, 0x07,
356         0, 0, 0, 0, 0, 0x0d, 0x0e, 0,
357         0, 0x0f, 0x10, 0, 0, 0, 0, 0x01,
358         0x03, 0x07, 0x11, 0x12, 0x13
359     };
360
361     int i;
362     for (i=0; i<ARRAY_SIZE(parammodes); i++) {
363         int mode = GET_GLOBAL(parammodes[i]);
364         if (! mode)
365             continue;
366         struct video_param_s *vparam_g = &video_param_table[i];
367         struct vgamode_s *vmode_g = stdvga_find_mode(mode);
368         if (!vmode_g)
369             continue;
370         int width = GET_GLOBAL(vmode_g->width);
371         int height = GET_GLOBAL(vmode_g->height);
372         u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
373         int cheight = GET_GLOBAL(vmode_g->cheight);
374         if (memmodel == MM_TEXT) {
375             SET_VGA(vparam_g->twidth, width);
376             SET_VGA(vparam_g->theightm1, height-1);
377         } else {
378             int cwidth = GET_GLOBAL(vmode_g->cwidth);
379             SET_VGA(vparam_g->twidth, width / cwidth);
380             SET_VGA(vparam_g->theightm1, (height / cheight) - 1);
381         }
382         SET_VGA(vparam_g->cheight, cheight);
383         SET_VGA(vparam_g->slength, calc_page_size(memmodel, width, height));
384         struct stdvga_mode_s *stdmode_g = container_of(
385             vmode_g, struct stdvga_mode_s, info);
386         memcpy_far(get_global_seg(), vparam_g->sequ_regs
387                    , get_global_seg(), GET_GLOBAL(stdmode_g->sequ_regs)
388                    , ARRAY_SIZE(vparam_g->sequ_regs));
389         SET_VGA(vparam_g->miscreg, GET_GLOBAL(stdmode_g->miscreg));
390         memcpy_far(get_global_seg(), vparam_g->crtc_regs
391                    , get_global_seg(), GET_GLOBAL(stdmode_g->crtc_regs)
392                    , ARRAY_SIZE(vparam_g->crtc_regs));
393         memcpy_far(get_global_seg(), vparam_g->actl_regs
394                    , get_global_seg(), GET_GLOBAL(stdmode_g->actl_regs)
395                    , ARRAY_SIZE(vparam_g->actl_regs));
396         memcpy_far(get_global_seg(), vparam_g->grdc_regs
397                    , get_global_seg(), GET_GLOBAL(stdmode_g->grdc_regs)
398                    , ARRAY_SIZE(vparam_g->grdc_regs));
399     }
400
401     // Fill available legacy modes in video_func_static table
402     u32 modes = 0;
403     for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
404         u16 mode = vga_modes[i].mode;
405         if (mode <= 0x13)
406             modes |= 1<<i;
407     }
408     SET_VGA(static_functionality.modes, modes);
409 }
410
411 void
412 stdvga_override_crtc(int mode, u8 *crtc)
413 {
414     struct vgamode_s *vmode_g = stdvga_find_mode(mode);
415     if (!vmode_g)
416         return;
417     struct stdvga_mode_s *stdmode_g = container_of(
418         vmode_g, struct stdvga_mode_s, info);
419     SET_VGA(stdmode_g->crtc_regs, crtc);
420 }
421
422 static void
423 clear_screen(struct vgamode_s *vmode_g)
424 {
425     switch (GET_GLOBAL(vmode_g->memmodel)) {
426     case MM_TEXT:
427         memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024);
428         break;
429     case MM_CGA:
430         memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024);
431         break;
432     default:
433         // XXX - old code gets/sets/restores sequ register 2 to 0xf -
434         // but it should always be 0xf anyway.
435         memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024);
436     }
437 }
438
439 int
440 stdvga_set_mode(struct vgamode_s *vmode_g, int flags)
441 {
442     if (! is_stdvga_mode(vmode_g)) {
443         warn_internalerror();
444         return -1;
445     }
446     struct stdvga_mode_s *stdmode_g = container_of(
447         vmode_g, struct stdvga_mode_s, info);
448
449     // if palette loading (bit 3 of modeset ctl = 0)
450     if (!(flags & MF_NOPALETTE)) {    // Set the PEL mask
451         stdvga_pelmask_write(GET_GLOBAL(stdmode_g->pelmask));
452
453         // From which palette
454         u8 *palette_g = GET_GLOBAL(stdmode_g->dac);
455         u16 palsize = GET_GLOBAL(stdmode_g->dacsize) / 3;
456
457         // Always 256*3 values
458         stdvga_dac_write(get_global_seg(), palette_g, 0, palsize);
459         int i;
460         for (i = palsize; i < 0x0100; i++) {
461             static u8 rgb[3] VAR16;
462             stdvga_dac_write(get_global_seg(), rgb, i, 1);
463         }
464
465         if (flags & MF_GRAYSUM)
466             stdvga_perform_gray_scale_summing(0x00, 0x100);
467     }
468
469     // Set Attribute Ctl
470     u8 *regs = GET_GLOBAL(stdmode_g->actl_regs);
471     int i;
472     for (i = 0; i <= 0x13; i++)
473         stdvga_attr_write(i, GET_GLOBAL(regs[i]));
474     stdvga_attr_write(0x14, 0x00);
475
476     // Set Sequencer Ctl
477     stdvga_sequ_write(0x00, 0x03);
478     regs = GET_GLOBAL(stdmode_g->sequ_regs);
479     for (i = 1; i <= 4; i++)
480         stdvga_sequ_write(i, GET_GLOBAL(regs[i - 1]));
481
482     // Set Grafx Ctl
483     regs = GET_GLOBAL(stdmode_g->grdc_regs);
484     for (i = 0; i <= 8; i++)
485         stdvga_grdc_write(i, GET_GLOBAL(regs[i]));
486
487     // Set CRTC address VGA or MDA
488     u8 miscreg = GET_GLOBAL(stdmode_g->miscreg);
489     u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
490     if (!(miscreg & 1))
491         crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
492
493     // Disable CRTC write protection
494     stdvga_crtc_write(crtc_addr, 0x11, 0x00);
495     // Set CRTC regs
496     regs = GET_GLOBAL(stdmode_g->crtc_regs);
497     for (i = 0; i <= 0x18; i++)
498         stdvga_crtc_write(crtc_addr, i, GET_GLOBAL(regs[i]));
499
500     // Set the misc register
501     stdvga_misc_write(miscreg);
502
503     // Enable video
504     stdvga_attrindex_write(0x20);
505
506     // Clear screen
507     if (!(flags & MF_NOCLEARMEM))
508         clear_screen(vmode_g);
509
510     // Write the fonts in memory
511     u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
512     if (memmodel == MM_TEXT)
513         stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
514
515     return 0;
516 }
517
518 // Load the standard palette associated with 8bpp packed pixel vga modes.
519 void
520 stdvga_set_packed_palette(void)
521 {
522     stdvga_dac_write(get_global_seg(), palette3, 0, sizeof(palette3) / 3);
523 }