vgabios: Fix compile error due to missing include in clext.c.
[seabios.git] / vgasrc / clext.c
1 //  QEMU Cirrus CLGD 54xx VGABIOS Extension.
2 //
3 // Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
4 //  Copyright (c) 2004 Makoto Suzuki (suzu)
5 //
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
7
8 #include "vgatables.h" // cirrus_init
9 #include "biosvar.h" // GET_GLOBAL
10 #include "util.h" // dprintf
11 #include "bregs.h" // struct bregs
12
13
14 /****************************************************************
15  * tables
16  ****************************************************************/
17
18 struct cirrus_mode_s {
19     /* + 0 */
20     u16 mode;
21     u16 width;
22     u16 height;
23     u16 depth;
24     /* + 8 */
25     u16 hidden_dac; /* 0x3c6 */
26     u16 *seq; /* 0x3c4 */
27     u16 *graph; /* 0x3ce */
28     u16 *crtc; /* 0x3d4 */
29     /* +16 */
30     u8 bitsperpixel;
31     u8 vesacolortype;
32     u8 vesaredmask;
33     u8 vesaredpos;
34     u8 vesagreenmask;
35     u8 vesagreenpos;
36     u8 vesabluemask;
37     u8 vesabluepos;
38     /* +24 */
39     u8 vesareservedmask;
40     u8 vesareservedpos;
41 };
42
43 /* VGA */
44 static u16 cseq_vga[] VAR16 = {0x0007,0xffff};
45 static u16 cgraph_vga[] VAR16 = {0x0009,0x000a,0x000b,0xffff};
46 static u16 ccrtc_vga[] VAR16 = {0x001a,0x001b,0x001d,0xffff};
47
48 /* extensions */
49 static u16 cgraph_svgacolor[] VAR16 = {
50     0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08,
51     0x0009,0x000a,0x000b,
52     0xffff
53 };
54 /* 640x480x8 */
55 static u16 cseq_640x480x8[] VAR16 = {
56     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
57     0x580b,0x580c,0x580d,0x580e,
58     0x0412,0x0013,0x2017,
59     0x331b,0x331c,0x331d,0x331e,
60     0xffff
61 };
62 static u16 ccrtc_640x480x8[] VAR16 = {
63     0x2c11,
64     0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
65     0x4009,0x000c,0x000d,
66     0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
67     0x001a,0x221b,0x001d,
68     0xffff
69 };
70 /* 640x480x16 */
71 static u16 cseq_640x480x16[] VAR16 = {
72     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
73     0x580b,0x580c,0x580d,0x580e,
74     0x0412,0x0013,0x2017,
75     0x331b,0x331c,0x331d,0x331e,
76     0xffff
77 };
78 static u16 ccrtc_640x480x16[] VAR16 = {
79     0x2c11,
80     0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
81     0x4009,0x000c,0x000d,
82     0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
83     0x001a,0x221b,0x001d,
84     0xffff
85 };
86 /* 640x480x24 */
87 static u16 cseq_640x480x24[] VAR16 = {
88     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
89     0x580b,0x580c,0x580d,0x580e,
90     0x0412,0x0013,0x2017,
91     0x331b,0x331c,0x331d,0x331e,
92     0xffff
93 };
94 static u16 ccrtc_640x480x24[] VAR16 = {
95     0x2c11,
96     0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
97     0x4009,0x000c,0x000d,
98     0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
99     0x001a,0x321b,0x001d,
100     0xffff
101 };
102 /* 800x600x8 */
103 static u16 cseq_800x600x8[] VAR16 = {
104     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
105     0x230b,0x230c,0x230d,0x230e,
106     0x0412,0x0013,0x2017,
107     0x141b,0x141c,0x141d,0x141e,
108     0xffff
109 };
110 static u16 ccrtc_800x600x8[] VAR16 = {
111     0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
112     0x6009,0x000c,0x000d,
113     0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18,
114     0x001a,0x221b,0x001d,
115     0xffff
116 };
117 /* 800x600x16 */
118 static u16 cseq_800x600x16[] VAR16 = {
119     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
120     0x230b,0x230c,0x230d,0x230e,
121     0x0412,0x0013,0x2017,
122     0x141b,0x141c,0x141d,0x141e,
123     0xffff
124 };
125 static u16 ccrtc_800x600x16[] VAR16 = {
126     0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
127     0x6009,0x000c,0x000d,
128     0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18,
129     0x001a,0x221b,0x001d,
130     0xffff
131 };
132 /* 800x600x24 */
133 static u16 cseq_800x600x24[] VAR16 = {
134     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
135     0x230b,0x230c,0x230d,0x230e,
136     0x0412,0x0013,0x2017,
137     0x141b,0x141c,0x141d,0x141e,
138     0xffff
139 };
140 static u16 ccrtc_800x600x24[] VAR16 = {
141     0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
142     0x6009,0x000c,0x000d,
143     0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18,
144     0x001a,0x321b,0x001d,
145     0xffff
146 };
147 /* 1024x768x8 */
148 static u16 cseq_1024x768x8[] VAR16 = {
149     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
150     0x760b,0x760c,0x760d,0x760e,
151     0x0412,0x0013,0x2017,
152     0x341b,0x341c,0x341d,0x341e,
153     0xffff
154 };
155 static u16 ccrtc_1024x768x8[] VAR16 = {
156     0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
157     0x6009,0x000c,0x000d,
158     0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
159     0x001a,0x221b,0x001d,
160     0xffff
161 };
162 /* 1024x768x16 */
163 static u16 cseq_1024x768x16[] VAR16 = {
164     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
165     0x760b,0x760c,0x760d,0x760e,
166     0x0412,0x0013,0x2017,
167     0x341b,0x341c,0x341d,0x341e,
168     0xffff
169 };
170 static u16 ccrtc_1024x768x16[] VAR16 = {
171     0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
172     0x6009,0x000c,0x000d,
173     0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18,
174     0x001a,0x321b,0x001d,
175     0xffff
176 };
177 /* 1024x768x24 */
178 static u16 cseq_1024x768x24[] VAR16 = {
179     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
180     0x760b,0x760c,0x760d,0x760e,
181     0x0412,0x0013,0x2017,
182     0x341b,0x341c,0x341d,0x341e,
183     0xffff
184 };
185 static u16 ccrtc_1024x768x24[] VAR16 = {
186     0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
187     0x6009,0x000c,0x000d,
188     0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
189     0x001a,0x321b,0x001d,
190     0xffff
191 };
192 /* 1280x1024x8 */
193 static u16 cseq_1280x1024x8[] VAR16 = {
194     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
195     0x760b,0x760c,0x760d,0x760e,
196     0x0412,0x0013,0x2017,
197     0x341b,0x341c,0x341d,0x341e,
198     0xffff
199 };
200 static u16 ccrtc_1280x1024x8[] VAR16 = {
201     0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
202     0x6009,0x000c,0x000d,
203     0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
204     0x001a,0x221b,0x001d,
205     0xffff
206 };
207 /* 1280x1024x16 */
208 static u16 cseq_1280x1024x16[] VAR16 = {
209     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
210     0x760b,0x760c,0x760d,0x760e,
211     0x0412,0x0013,0x2017,
212     0x341b,0x341c,0x341d,0x341e,
213     0xffff
214 };
215 static u16 ccrtc_1280x1024x16[] VAR16 = {
216     0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
217     0x6009,0x000c,0x000d,
218     0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18,
219     0x001a,0x321b,0x001d,
220     0xffff
221 };
222
223 /* 1600x1200x8 */
224 static u16 cseq_1600x1200x8[] VAR16 = {
225     0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
226     0x760b,0x760c,0x760d,0x760e,
227     0x0412,0x0013,0x2017,
228     0x341b,0x341c,0x341d,0x341e,
229     0xffff
230 };
231 static u16 ccrtc_1600x1200x8[] VAR16 = {
232     0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
233     0x6009,0x000c,0x000d,
234     0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
235     0x001a,0x221b,0x001d,
236     0xffff
237 };
238
239 static struct cirrus_mode_s cirrus_modes[] VAR16 = {
240     {0x5f,640,480,8,0x00,
241      cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8,
242      4,0,0,0,0,0,0,0,0},
243     {0x64,640,480,16,0xe1,
244      cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16,
245      6,5,11,6,5,5,0,0,0},
246     {0x66,640,480,15,0xf0,
247      cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16,
248      6,5,10,5,5,5,0,1,15},
249     {0x71,640,480,24,0xe5,
250      cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24,
251      6,8,16,8,8,8,0,0,0},
252
253     {0x5c,800,600,8,0x00,
254      cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8,
255      4,0,0,0,0,0,0,0,0},
256     {0x65,800,600,16,0xe1,
257      cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16,
258      6,5,11,6,5,5,0,0,0},
259     {0x67,800,600,15,0xf0,
260      cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16,
261      6,5,10,5,5,5,0,1,15},
262
263     {0x60,1024,768,8,0x00,
264      cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8,
265      4,0,0,0,0,0,0,0,0},
266     {0x74,1024,768,16,0xe1,
267      cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16,
268      6,5,11,6,5,5,0,0,0},
269     {0x68,1024,768,15,0xf0,
270      cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16,
271      6,5,10,5,5,5,0,1,15},
272
273     {0x78,800,600,24,0xe5,
274      cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24,
275      6,8,16,8,8,8,0,0,0},
276     {0x79,1024,768,24,0xe5,
277      cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24,
278      6,8,16,8,8,8,0,0,0},
279
280     {0x6d,1280,1024,8,0x00,
281      cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8,
282      4,0,0,0,0,0,0,0,0},
283     {0x69,1280,1024,15,0xf0,
284      cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16,
285      6,5,10,5,5,5,0,1,15},
286     {0x75,1280,1024,16,0xe1,
287      cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16,
288      6,5,11,6,5,5,0,0,0},
289
290     {0x7b,1600,1200,8,0x00,
291      cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8,
292      4,0,0,0,0,0,0,0,0},
293
294     {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0,
295      0xff,0,0,0,0,0,0,0,0},
296 };
297
298
299 /****************************************************************
300  * helper functions
301  ****************************************************************/
302
303 static struct cirrus_mode_s *
304 cirrus_get_modeentry(u8 mode)
305 {
306     struct cirrus_mode_s *table_g = cirrus_modes;
307     while (table_g < &cirrus_modes[ARRAY_SIZE(cirrus_modes)]) {
308         u16 tmode = GET_GLOBAL(table_g->mode);
309         if (tmode == mode)
310             return table_g;
311         table_g++;
312     }
313     return NULL;
314 }
315
316 static void
317 cirrus_switch_mode_setregs(u16 *data, u16 port)
318 {
319     for (;;) {
320         u16 val = GET_GLOBAL(*data);
321         if (val == 0xffff)
322             return;
323         outw(val, port);
324         data++;
325     }
326 }
327
328 static u16
329 cirrus_get_crtc(void)
330 {
331     if (inb(VGAREG_READ_MISC_OUTPUT) & 1)
332         return VGAREG_VGA_CRTC_ADDRESS;
333     return VGAREG_MDA_CRTC_ADDRESS;
334 }
335
336 static void
337 cirrus_switch_mode(struct cirrus_mode_s *table)
338 {
339     // Unlock cirrus special
340     outw(0x1206, VGAREG_SEQU_ADDRESS);
341     cirrus_switch_mode_setregs(GET_GLOBAL(table->seq), VGAREG_SEQU_ADDRESS);
342     cirrus_switch_mode_setregs(GET_GLOBAL(table->graph), VGAREG_GRDC_ADDRESS);
343     cirrus_switch_mode_setregs(GET_GLOBAL(table->crtc), cirrus_get_crtc());
344
345     outb(0x00, VGAREG_PEL_MASK);
346     inb(VGAREG_PEL_MASK);
347     inb(VGAREG_PEL_MASK);
348     inb(VGAREG_PEL_MASK);
349     inb(VGAREG_PEL_MASK);
350     outb(GET_GLOBAL(table->hidden_dac), VGAREG_PEL_MASK);
351     outb(0xff, VGAREG_PEL_MASK);
352
353     u8 vesacolortype = GET_GLOBAL(table->vesacolortype);
354     u8 v = vgahw_get_single_palette_reg(0x10) & 0xfe;
355     if (vesacolortype == 3)
356         v |= 0x41;
357     else if (vesacolortype)
358         v |= 0x01;
359     vgahw_set_single_palette_reg(0x10, v);
360 }
361
362 static u8
363 cirrus_get_memsize(void)
364 {
365     // get DRAM band width
366     outb(0x0f, VGAREG_SEQU_ADDRESS);
367     u8 v = inb(VGAREG_SEQU_DATA);
368     u8 x = (v >> 3) & 0x03;
369     if (x == 0x03) {
370         if (v & 0x80)
371             // 4MB
372             return 0x40;
373         // 2MB
374         return 0x20;
375     }
376     return 0x04 << x;
377 }
378
379 static void
380 cirrus_enable_16k_granularity(void)
381 {
382     outb(0x0b, VGAREG_GRDC_ADDRESS);
383     u8 v = inb(VGAREG_GRDC_DATA);
384     outb(v | 0x20, VGAREG_GRDC_DATA);
385 }
386
387 static void
388 cirrus_clear_vram(u16 param)
389 {
390     cirrus_enable_16k_granularity();
391     u8 count = cirrus_get_memsize() * 4;
392     u8 i;
393     for (i=0; i<count; i++) {
394         outw((i<<8) | 0x09, VGAREG_GRDC_ADDRESS);
395         memset16_far(SEG_GRAPH, 0, param, 16 * 1024);
396     }
397     outw(0x0009, VGAREG_GRDC_ADDRESS);
398 }
399
400 int
401 cirrus_set_video_mode(u8 mode, u8 noclearmem)
402 {
403     dprintf(1, "cirrus mode %d\n", mode);
404     SET_BDA(vbe_mode, 0);
405     struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode);
406     if (table_g) {
407         cirrus_switch_mode(table_g);
408         if (!noclearmem)
409             cirrus_clear_vram(0xffff);
410         SET_BDA(video_mode, mode);
411         return 1;
412     }
413     table_g = cirrus_get_modeentry(0xfe);
414     cirrus_switch_mode(table_g);
415     dprintf(1, "cirrus mode switch regular\n");
416     return 0;
417 }
418
419 static int
420 cirrus_check(void)
421 {
422     outw(0x9206, VGAREG_SEQU_ADDRESS);
423     return inb(VGAREG_SEQU_DATA) == 0x12;
424 }
425
426
427 /****************************************************************
428  * extbios
429  ****************************************************************/
430
431 static void
432 cirrus_extbios_80h(struct bregs *regs)
433 {
434     u16 crtc_addr = cirrus_get_crtc();
435     outb(0x27, crtc_addr);
436     u8 v = inb(crtc_addr + 1);
437     if (v == 0xa0)
438         // 5430
439         regs->ax = 0x0032;
440     else if (v == 0xb8)
441         // 5446
442         regs->ax = 0x0039;
443     else
444         regs->ax = 0x00ff;
445     regs->bx = 0x00;
446     return;
447 }
448
449 static void
450 cirrus_extbios_81h(struct bregs *regs)
451 {
452     // XXX
453     regs->ax = 0x0100;
454 }
455
456 static void
457 cirrus_extbios_82h(struct bregs *regs)
458 {
459     u16 crtc_addr = cirrus_get_crtc();
460     outb(0x27, crtc_addr);
461     regs->al = inb(crtc_addr + 1) & 0x03;
462     regs->ah = 0xAF;
463 }
464
465 static void
466 cirrus_extbios_85h(struct bregs *regs)
467 {
468     regs->al = cirrus_get_memsize();
469 }
470
471 static void
472 cirrus_extbios_9Ah(struct bregs *regs)
473 {
474     regs->ax = 0x4060;
475     regs->cx = 0x1132;
476 }
477
478 extern void a0h_callback(void);
479 ASM16(
480     // fatal: not implemented yet
481     "a0h_callback:"
482     "cli\n"
483     "hlt\n"
484     "retf");
485
486 static void
487 cirrus_extbios_A0h(struct bregs *regs)
488 {
489     struct cirrus_mode_s *table_g = cirrus_get_modeentry(regs->al & 0x7f);
490     regs->ah = (table_g ? 1 : 0);
491     regs->si = 0xffff;
492     regs->di = regs->ds = regs->es = regs->bx = (u32)a0h_callback;
493 }
494
495 static void
496 cirrus_extbios_A1h(struct bregs *regs)
497 {
498     regs->bx = 0x0e00; // IBM 8512/8513, color
499 }
500
501 static void
502 cirrus_extbios_A2h(struct bregs *regs)
503 {
504     regs->al = 0x07; // HSync 31.5 - 64.0 kHz
505 }
506
507 static void
508 cirrus_extbios_AEh(struct bregs *regs)
509 {
510     regs->al = 0x01; // High Refresh 75Hz
511 }
512
513 void
514 cirrus_extbios(struct bregs *regs)
515 {
516     // XXX - regs->bl < 0x80 or > 0xaf call regular handlers.
517     switch (regs->bl) {
518     case 0x80: cirrus_extbios_80h(regs); break;
519     case 0x81: cirrus_extbios_81h(regs); break;
520     case 0x82: cirrus_extbios_82h(regs); break;
521     case 0x85: cirrus_extbios_85h(regs); break;
522     case 0x9a: cirrus_extbios_9Ah(regs); break;
523     case 0xa0: cirrus_extbios_A0h(regs); break;
524     case 0xa1: cirrus_extbios_A1h(regs); break;
525     case 0xa2: cirrus_extbios_A2h(regs); break;
526     case 0xae: cirrus_extbios_AEh(regs); break;
527     default: break;
528     }
529 }
530
531
532 /****************************************************************
533  * vesa calls
534  ****************************************************************/
535
536 #if 0
537 static u16
538 cirrus_vesamode_to_mode(u16 vesamode)
539 {
540     // XXX - convert assembler
541     return 0;
542 }
543
544 static u8
545 cirrus_get_bpp_bytes(void)
546 {
547     // XXX - convert assembler
548     return 0;
549 }
550
551 static void
552 cirrus_set_line_offset(u16 new_line_offset)
553 {
554     // XXX - convert assembler
555 }
556
557 static u16
558 cirrus_get_line_offset(void)
559 {
560     // XXX - convert assembler
561     return 0;
562 }
563
564 static u16
565 cirrus_get_line_offset_entry(void *table)
566 {
567     // XXX - convert assembler
568     return 0;
569 }
570
571 static void
572 cirrus_set_start_addr(void *addr)
573 {
574     // XXX - convert assembler
575 }
576
577 static void *
578 cirrus_get_start_addr(void)
579 {
580     // XXX - convert assembler
581     return NULL;
582 }
583 #endif
584
585 static void
586 cirrus_vesa_00h(struct bregs *regs)
587 {
588     // XXX - convert assembler
589 }
590
591 static void
592 cirrus_vesa_01h(struct bregs *regs)
593 {
594     // XXX - convert assembler
595 }
596
597 static void
598 cirrus_vesa_02h(struct bregs *regs)
599 {
600     // XXX - convert assembler
601 }
602
603 static void
604 cirrus_vesa_03h(struct bregs *regs)
605 {
606     // XXX - convert assembler
607 }
608
609 // XXX - add cirrus_vesa_05h_farentry to vgaentry.S
610
611 static void
612 cirrus_vesa_05h(struct bregs *regs)
613 {
614     // XXX - convert assembler
615 }
616
617 static void
618 cirrus_vesa_06h(struct bregs *regs)
619 {
620     // XXX - convert assembler
621 }
622
623 static void
624 cirrus_vesa_07h(struct bregs *regs)
625 {
626     // XXX - convert assembler
627 }
628
629 static void
630 cirrus_vesa_10h(struct bregs *regs)
631 {
632     // XXX - convert assembler
633 }
634
635 static void
636 cirrus_vesa_not_handled(struct bregs *regs)
637 {
638     debug_stub(regs);
639     regs->ax = 0x014f;
640 }
641
642 void
643 cirrus_vesa(struct bregs *regs)
644 {
645     switch (regs->al) {
646     case 0x00: cirrus_vesa_00h(regs); break;
647     case 0x01: cirrus_vesa_01h(regs); break;
648     case 0x02: cirrus_vesa_02h(regs); break;
649     case 0x03: cirrus_vesa_03h(regs); break;
650     case 0x05: cirrus_vesa_05h(regs); break;
651     case 0x06: cirrus_vesa_06h(regs); break;
652     case 0x07: cirrus_vesa_07h(regs); break;
653     case 0x10: cirrus_vesa_10h(regs); break;
654     default:   cirrus_vesa_not_handled(regs); break;
655     }
656 }
657
658
659 /****************************************************************
660  * init
661  ****************************************************************/
662
663 void
664 cirrus_init(void)
665 {
666     dprintf(1, "cirrus init\n");
667     if (! cirrus_check())
668         return;
669     dprintf(1, "cirrus init 2\n");
670
671     // memory setup
672     outb(0x0f, VGAREG_SEQU_ADDRESS);
673     u8 v = inb(VGAREG_SEQU_DATA);
674     outb(((v & 0x18) << 8) | 0x0a, VGAREG_SEQU_ADDRESS);
675     // set vga mode
676     outw(0x0007, VGAREG_SEQU_ADDRESS);
677     // reset bitblt
678     outw(0x0431, VGAREG_GRDC_ADDRESS);
679     outw(0x0031, VGAREG_GRDC_ADDRESS);
680 }