Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / vgabios / clext.c
1 //
2 //  QEMU Cirrus CLGD 54xx VGABIOS Extension.
3 //
4 //  Copyright (c) 2004 Makoto Suzuki (suzu)
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2 of the License, or (at your option) any later version.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 // 
20
21 //#define CIRRUS_VESA3_PMINFO
22 #ifdef VBE
23 #undef CIRRUS_VESA3_PMINFO
24 #endif
25
26 #define PM_BIOSMEM_CURRENT_MODE 0x449
27 #define PM_BIOSMEM_CRTC_ADDRESS 0x463
28 #define PM_BIOSMEM_VBE_MODE 0x4BA
29
30 typedef struct
31 {
32   /* + 0 */
33   unsigned short mode;
34   unsigned short width;
35   unsigned short height;
36   unsigned short depth;
37   /* + 8 */
38   unsigned short hidden_dac; /* 0x3c6 */
39   unsigned short *seq; /* 0x3c4 */
40   unsigned short *graph; /* 0x3ce */
41   unsigned short *crtc; /* 0x3d4 */
42   /* +16 */
43   unsigned char bitsperpixel;
44   unsigned char vesacolortype;
45   unsigned char vesaredmask;
46   unsigned char vesaredpos;
47   unsigned char vesagreenmask;
48   unsigned char vesagreenpos;
49   unsigned char vesabluemask;
50   unsigned char vesabluepos;
51   /* +24 */
52   unsigned char vesareservedmask;
53   unsigned char vesareservedpos;
54 } cirrus_mode_t;
55 #define CIRRUS_MODE_SIZE 26
56
57
58 /* For VESA BIOS 3.0 */
59 #define CIRRUS_PM16INFO_SIZE 20
60
61 /* VGA */
62 unsigned short cseq_vga[] = {0x0007,0xffff};
63 unsigned short cgraph_vga[] = {0x0009,0x000a,0x000b,0xffff};
64 unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff};
65
66 /* extensions */
67 unsigned short cgraph_svgacolor[] = {
68 0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08,
69 0x0009,0x000a,0x000b,
70 0xffff
71 };
72 /* 640x480x8 */
73 unsigned short cseq_640x480x8[] = {
74 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
75 0x580b,0x580c,0x580d,0x580e,
76 0x0412,0x0013,0x2017,
77 0x331b,0x331c,0x331d,0x331e,
78 0xffff
79 };
80 unsigned short ccrtc_640x480x8[] = {
81 0x2c11,
82 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
83 0x4009,0x000c,0x000d,
84 0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
85 0x001a,0x221b,0x001d,
86 0xffff
87 };
88 /* 640x480x16 */
89 unsigned short cseq_640x480x16[] = {
90 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
91 0x580b,0x580c,0x580d,0x580e,
92 0x0412,0x0013,0x2017,
93 0x331b,0x331c,0x331d,0x331e,
94 0xffff
95 };
96 unsigned short ccrtc_640x480x16[] = {
97 0x2c11,
98 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
99 0x4009,0x000c,0x000d,
100 0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
101 0x001a,0x221b,0x001d,
102 0xffff
103 };
104 /* 640x480x24 */
105 unsigned short cseq_640x480x24[] = {
106 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
107 0x580b,0x580c,0x580d,0x580e,
108 0x0412,0x0013,0x2017,
109 0x331b,0x331c,0x331d,0x331e,
110 0xffff
111 };
112 unsigned short ccrtc_640x480x24[] = {
113 0x2c11,
114 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
115 0x4009,0x000c,0x000d,
116 0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
117 0x001a,0x321b,0x001d,
118 0xffff
119 };
120 /* 800x600x8 */
121 unsigned short cseq_800x600x8[] = {
122 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
123 0x230b,0x230c,0x230d,0x230e,
124 0x0412,0x0013,0x2017,
125 0x141b,0x141c,0x141d,0x141e,
126 0xffff
127 };
128 unsigned short ccrtc_800x600x8[] = {
129 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
130 0x6009,0x000c,0x000d,
131 0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18,
132 0x001a,0x221b,0x001d,
133 0xffff
134 };
135 /* 800x600x16 */
136 unsigned short cseq_800x600x16[] = {
137 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
138 0x230b,0x230c,0x230d,0x230e,
139 0x0412,0x0013,0x2017,
140 0x141b,0x141c,0x141d,0x141e,
141 0xffff
142 };
143 unsigned short ccrtc_800x600x16[] = {
144 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
145 0x6009,0x000c,0x000d,
146 0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18,
147 0x001a,0x221b,0x001d,
148 0xffff
149 };
150 /* 800x600x24 */
151 unsigned short cseq_800x600x24[] = {
152 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
153 0x230b,0x230c,0x230d,0x230e,
154 0x0412,0x0013,0x2017,
155 0x141b,0x141c,0x141d,0x141e,
156 0xffff
157 };
158 unsigned short ccrtc_800x600x24[] = {
159 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
160 0x6009,0x000c,0x000d,
161 0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18,
162 0x001a,0x321b,0x001d,
163 0xffff
164 };
165 /* 1024x768x8 */
166 unsigned short cseq_1024x768x8[] = {
167 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
168 0x760b,0x760c,0x760d,0x760e,
169 0x0412,0x0013,0x2017,
170 0x341b,0x341c,0x341d,0x341e,
171 0xffff
172 };
173 unsigned short ccrtc_1024x768x8[] = {
174 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
175 0x6009,0x000c,0x000d,
176 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
177 0x001a,0x221b,0x001d,
178 0xffff
179 };
180 /* 1024x768x16 */
181 unsigned short cseq_1024x768x16[] = {
182 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
183 0x760b,0x760c,0x760d,0x760e,
184 0x0412,0x0013,0x2017,
185 0x341b,0x341c,0x341d,0x341e,
186 0xffff
187 };
188 unsigned short ccrtc_1024x768x16[] = {
189 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
190 0x6009,0x000c,0x000d,
191 0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18,
192 0x001a,0x321b,0x001d,
193 0xffff
194 };
195 /* 1024x768x24 */
196 unsigned short cseq_1024x768x24[] = {
197 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
198 0x760b,0x760c,0x760d,0x760e,
199 0x0412,0x0013,0x2017,
200 0x341b,0x341c,0x341d,0x341e,
201 0xffff
202 };
203 unsigned short ccrtc_1024x768x24[] = {
204 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
205 0x6009,0x000c,0x000d,
206 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
207 0x001a,0x321b,0x001d,
208 0xffff
209 };
210 /* 1280x1024x8 */
211 unsigned short cseq_1280x1024x8[] = {
212 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
213 0x760b,0x760c,0x760d,0x760e,
214 0x0412,0x0013,0x2017,
215 0x341b,0x341c,0x341d,0x341e,
216 0xffff
217 };
218 unsigned short ccrtc_1280x1024x8[] = {
219 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
220 0x6009,0x000c,0x000d,
221 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
222 0x001a,0x221b,0x001d,
223 0xffff
224 };
225 /* 1280x1024x16 */
226 unsigned short cseq_1280x1024x16[] = {
227 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
228 0x760b,0x760c,0x760d,0x760e,
229 0x0412,0x0013,0x2017,
230 0x341b,0x341c,0x341d,0x341e,
231 0xffff
232 };
233 unsigned short ccrtc_1280x1024x16[] = {
234 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
235 0x6009,0x000c,0x000d,
236 0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18,
237 0x001a,0x321b,0x001d,
238 0xffff
239 };
240
241 /* 1600x1200x8 */
242 unsigned short cseq_1600x1200x8[] = {
243 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
244 0x760b,0x760c,0x760d,0x760e,
245 0x0412,0x0013,0x2017,
246 0x341b,0x341c,0x341d,0x341e,
247 0xffff
248 };
249 unsigned short ccrtc_1600x1200x8[] = {
250 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
251 0x6009,0x000c,0x000d,
252 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
253 0x001a,0x221b,0x001d,
254 0xffff
255 };
256
257 cirrus_mode_t cirrus_modes[] =
258 {
259  {0x5f,640,480,8,0x00,
260    cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8,
261    4,0,0,0,0,0,0,0,0},
262  {0x64,640,480,16,0xe1,
263    cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16,
264    6,5,11,6,5,5,0,0,0},
265  {0x66,640,480,15,0xf0,
266    cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16,
267    6,5,10,5,5,5,0,1,15},
268  {0x71,640,480,24,0xe5,
269    cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24,
270    6,8,16,8,8,8,0,0,0},
271
272  {0x5c,800,600,8,0x00,
273    cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8,
274    4,0,0,0,0,0,0,0,0},
275  {0x65,800,600,16,0xe1,
276    cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16,
277    6,5,11,6,5,5,0,0,0},
278  {0x67,800,600,15,0xf0,
279    cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16,
280    6,5,10,5,5,5,0,1,15},
281
282  {0x60,1024,768,8,0x00,
283    cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8,
284    4,0,0,0,0,0,0,0,0},
285  {0x74,1024,768,16,0xe1,
286    cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16,
287    6,5,11,6,5,5,0,0,0},
288  {0x68,1024,768,15,0xf0,
289    cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16,
290    6,5,10,5,5,5,0,1,15},
291
292  {0x78,800,600,24,0xe5,
293    cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24,
294    6,8,16,8,8,8,0,0,0},
295  {0x79,1024,768,24,0xe5,
296    cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24,
297    6,8,16,8,8,8,0,0,0},
298
299  {0x6d,1280,1024,8,0x00,
300    cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8,
301    4,0,0,0,0,0,0,0,0},
302  {0x69,1280,1024,15,0xf0,
303    cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16,
304    6,5,10,5,5,5,0,1,15},
305  {0x75,1280,1024,16,0xe1,
306    cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16,
307    6,5,11,6,5,5,0,0,0},
308
309  {0x7b,1600,1200,8,0x00,
310    cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8,
311    4,0,0,0,0,0,0,0,0},
312
313  {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0,
314    0xff,0,0,0,0,0,0,0,0},
315  {0xff,0,0,0,0,0,0,0,0,
316    0xff,0,0,0,0,0,0,0,0},
317 };
318
319 unsigned char cirrus_id_table[] = {
320   // 5430
321   0xA0, 0x32,
322   // 5446
323   0xB8, 0x39,
324
325   0xff, 0xff
326 };
327
328
329 unsigned short cirrus_vesa_modelist[] = {
330 // 640x480x8
331   0x101, 0x5f,
332 // 640x480x15
333   0x110, 0x66,
334 // 640x480x16
335   0x111, 0x64,
336 // 640x480x24
337   0x112, 0x71,
338 // 800x600x8
339   0x103, 0x5c,
340 // 800x600x15
341   0x113, 0x67,
342 // 800x600x16
343   0x114, 0x65,
344 // 800x600x24
345   0x115, 0x78,
346 // 1024x768x8
347   0x105, 0x60,
348 // 1024x768x15
349   0x116, 0x68,
350 // 1024x768x16
351   0x117, 0x74,
352 // 1024x768x24
353   0x118, 0x79,
354 // 1280x1024x8
355   0x107, 0x6d,
356 // 1280x1024x15
357   0x119, 0x69,
358 // 1280x1024x16
359   0x11a, 0x75,
360 // invalid
361   0xffff,0xffff
362 };
363
364
365 ASM_START
366
367 cirrus_installed:
368 .ascii "cirrus-compatible VGA is detected"
369 .byte 0x0d,0x0a
370 .byte 0x0d,0x0a,0x00
371
372 cirrus_not_installed:
373 .ascii "cirrus-compatible VGA is not detected"
374 .byte 0x0d,0x0a
375 .byte 0x0d,0x0a,0x00
376
377 cirrus_vesa_vendorname:
378 cirrus_vesa_productname:
379 cirrus_vesa_oemname:
380 .ascii "VGABIOS Cirrus extension"
381 .byte 0
382 cirrus_vesa_productrevision:
383 .ascii "1.0"
384 .byte 0
385
386 cirrus_init:
387   call cirrus_check
388   jnz no_cirrus
389   SET_INT_VECTOR(0x10, #0xC000, #cirrus_int10_handler)
390   mov al, #0x0f ; memory setup
391   mov dx, #0x3C4
392   out dx, al
393   inc dx
394   in  al, dx
395   and al, #0x18
396   mov ah, al
397   mov al, #0x0a
398   dec dx
399   out dx, ax
400   mov ax, #0x0007 ; set vga mode
401   out dx, ax
402   mov ax, #0x0431 ; reset bitblt
403   mov dx, #0x3CE
404   out dx, ax
405   mov ax, #0x0031
406   out dx, ax
407 no_cirrus:
408   ret
409
410 cirrus_display_info:
411   push ds
412   push si
413   push cs
414   pop ds
415   call cirrus_check
416   mov si, #cirrus_not_installed
417   jnz cirrus_msgnotinstalled
418   mov si, #cirrus_installed
419
420 cirrus_msgnotinstalled:
421   call _display_string
422   pop si
423   pop ds
424   ret
425
426 cirrus_check:
427   push ax
428   push dx
429   mov ax, #0x9206
430   mov dx, #0x3C4
431   out dx, ax
432   inc dx
433   in al, dx
434   cmp al, #0x12
435   pop dx
436   pop ax
437   ret
438
439
440 cirrus_int10_handler:
441   pushf
442   push bp
443   cmp ah, #0x00  ;; set video mode
444   jz cirrus_set_video_mode
445   cmp ah, #0x12  ;; cirrus extension
446   jz cirrus_extbios
447   cmp ah, #0x4F  ;; VESA extension
448   jz cirrus_vesa
449
450 cirrus_unhandled:
451   pop bp
452   popf
453   jmp vgabios_int10_handler
454
455 cirrus_return:
456 #ifdef CIRRUS_DEBUG
457   call cirrus_debug_dump
458 #endif
459   pop bp
460   popf
461   iret
462
463 cirrus_set_video_mode:
464 #ifdef CIRRUS_DEBUG
465   call cirrus_debug_dump
466 #endif
467   push si
468   push ax
469   push bx
470   push ds
471 #ifdef CIRRUS_VESA3_PMINFO
472  db 0x2e ;; cs:
473   mov si, [cirrus_vesa_sel0000_data]
474 #else
475   xor si, si
476 #endif
477   mov ds, si
478   xor bx, bx
479   mov [PM_BIOSMEM_VBE_MODE], bx
480   pop ds
481   pop bx
482   call cirrus_get_modeentry
483   jnc cirrus_set_video_mode_extended
484   mov al, #0xfe
485   call cirrus_get_modeentry_nomask
486   call cirrus_switch_mode
487   pop ax
488   pop si
489   jmp cirrus_unhandled
490
491 cirrus_extbios:
492 #ifdef CIRRUS_DEBUG
493   call cirrus_debug_dump
494 #endif
495   cmp bl, #0x80
496   jb cirrus_unhandled
497   cmp bl, #0xAF
498   ja cirrus_unhandled
499   push bx
500   and bx, #0x7F
501   shl bx, 1
502  db 0x2e ;; cs:
503   mov bp, cirrus_extbios_handlers[bx]
504   pop bx
505   push #cirrus_return
506   push bp
507   ret
508
509 cirrus_vesa:
510 #ifdef CIRRUS_DEBUG
511   call cirrus_debug_dump
512 #endif
513   cmp al, #0x10
514   ja cirrus_vesa_not_handled
515   push bx
516   xor bx, bx
517   mov bl, al
518   shl bx, 1
519  db 0x2e ;; cs:
520   mov bp, cirrus_vesa_handlers[bx]
521   pop bx
522   push #cirrus_return
523   push bp
524   ret
525
526 cirrus_vesa_not_handled:
527   mov ax, #0x014F ;; not implemented
528   jmp cirrus_return
529
530 #ifdef CIRRUS_DEBUG
531 cirrus_debug_dump:
532   push es
533   push ds
534   pusha
535   push cs
536   pop ds
537   call _cirrus_debugmsg
538   popa
539   pop ds
540   pop es
541   ret
542 #endif
543
544 cirrus_set_video_mode_extended:
545   call cirrus_switch_mode
546   pop ax ;; mode
547   test al, #0x80
548   jnz cirrus_set_video_mode_extended_1
549   push ax
550   mov ax, #0xffff ; set to 0xff to keep win 2K happy
551   call cirrus_clear_vram
552   pop ax
553 cirrus_set_video_mode_extended_1:
554   and al, #0x7f
555
556   push ds
557 #ifdef CIRRUS_VESA3_PMINFO
558  db 0x2e ;; cs:
559   mov si, [cirrus_vesa_sel0000_data]
560 #else
561   xor si, si
562 #endif
563   mov ds, si
564   mov [PM_BIOSMEM_CURRENT_MODE], al
565   pop ds
566
567   mov al, #0x20
568
569   pop si
570   jmp cirrus_return
571
572 cirrus_vesa_pmbios_init:
573   retf
574 cirrus_vesa_pmbios_entry:
575   pushf
576   push bp
577   cmp ah, #0x4F
578   jnz cirrus_vesa_pmbios_unimplemented
579   cmp al, #0x0F
580   ja cirrus_vesa_pmbios_unimplemented
581   push bx
582   xor bx, bx
583   mov bl, al
584   shl bx, 1
585  db 0x2e ;; cs:
586   mov bp, cirrus_vesa_handlers[bx]
587   pop bx
588   push #cirrus_vesa_pmbios_return
589   push bp
590   ret
591 cirrus_vesa_pmbios_unimplemented:
592   mov ax, #0x014F
593 cirrus_vesa_pmbios_return:
594   pop bp
595   popf
596   retf
597
598 ; in si:mode table
599 cirrus_switch_mode:
600   push ds
601   push bx
602   push dx
603   push cs
604   pop ds
605
606   mov bx, [si+10] ;; seq
607   mov dx, #0x3c4
608   mov ax, #0x1206
609   out dx, ax ;; Unlock cirrus special
610   call cirrus_switch_mode_setregs
611
612   mov bx, [si+12] ;; graph
613   mov dx, #0x3ce
614   call cirrus_switch_mode_setregs
615
616   mov bx, [si+14] ;; crtc
617   call cirrus_get_crtc
618   call cirrus_switch_mode_setregs
619
620   mov dx, #0x3c6
621   mov al, #0x00
622   out dx, al
623   in al, dx
624   in al, dx
625   in al, dx
626   in al, dx
627   mov al, [si+8]  ;; hidden dac
628   out dx, al
629   mov al, #0xff
630   out dx, al
631
632   mov al, #0x00
633   mov bl, [si+17]  ;; memory model
634   or  bl, bl
635   jz is_text_mode
636   mov al, #0x01
637   cmp bl, #0x03
638   jnz is_text_mode
639   or al, #0x40
640 is_text_mode:
641   mov bl, #0x10
642   call biosfn_get_single_palette_reg
643   and bh, #0xfe
644   or bh, al
645   call biosfn_set_single_palette_reg
646
647   pop dx
648   pop bx
649   pop ds
650   ret
651
652 cirrus_enable_16k_granularity:
653   push ax
654   push dx
655   mov dx, #0x3ce
656   mov al, #0x0b
657   out dx, al
658   inc dx
659   in al, dx
660   or al, #0x20 ;; enable 16k
661   out dx, al
662   pop dx
663   pop ax
664   ret
665
666 cirrus_switch_mode_setregs:
667 csms_1:
668   mov ax, [bx]
669   cmp ax, #0xffff
670   jz csms_2
671   out dx, ax
672   add bx, #0x2
673   jmp csms_1
674 csms_2:
675   ret
676
677 cirrus_extbios_80h:
678   push dx
679   call cirrus_get_crtc
680   mov al, #0x27
681   out dx, al
682   inc dx
683   in al, dx
684   mov bx, #_cirrus_id_table
685 c80h_1:
686  db 0x2e ;; cs:
687   mov ah, [bx]
688   cmp ah, al
689   jz c80h_2
690   cmp ah, #0xff
691   jz c80h_2
692   inc bx
693   inc bx
694   jmp c80h_1
695 c80h_2:
696  db 0x2e ;; cs:
697   mov al, 0x1[bx]
698   pop dx
699   mov ah, #0x00
700   xor bx, bx
701   ret
702
703 cirrus_extbios_81h:
704   mov ax, #0x100 ;; XXX
705   ret
706 cirrus_extbios_82h:
707   push dx
708   call cirrus_get_crtc
709   xor ax, ax
710   mov al, #0x27
711   out dx, al
712   inc dx
713   in al, dx
714   and al, #0x03
715   mov ah, #0xAF
716   pop dx
717   ret
718
719 cirrus_extbios_85h:
720   push cx
721   push dx
722   mov dx, #0x3C4
723   mov al, #0x0f ;; get DRAM band width
724   out dx, al
725   inc dx
726   in al, dx
727   ;; al = 4 << bandwidth
728   mov cl, al
729   shr cl, #0x03
730   and cl, #0x03
731   cmp cl, #0x03
732   je c85h2
733   mov al, #0x04
734   shl al, cl
735   jmp c85h3
736 c85h2:
737 ;; 4MB or 2MB
738   and al, #0x80
739   mov al, #0x20 ;; 2 MB
740   je c85h3
741   mov al, #0x40 ;; 4 MB
742 c85h3:
743   pop dx
744   pop cx
745   ret
746
747 cirrus_extbios_9Ah:
748   mov ax, #0x4060
749   mov cx, #0x1132
750   ret
751
752 cirrus_extbios_A0h:
753   call cirrus_get_modeentry
754   mov ah, #0x01
755   sbb ah, #0x00
756   mov bx, cirrus_extbios_A0h_callback
757   mov si, #0xffff
758   mov di, bx
759   mov ds, bx
760   mov es, bx
761   ret
762
763 cirrus_extbios_A0h_callback:
764   ;; fatal: not implemented yet
765   cli
766   hlt
767   retf
768
769 cirrus_extbios_A1h:
770   mov bx, #0x0E00 ;; IBM 8512/8513, color
771   ret
772
773 cirrus_extbios_A2h:
774   mov al, #0x07   ;; HSync 31.5 - 64.0 kHz
775   ret
776
777 cirrus_extbios_AEh:
778   mov al, #0x01   ;; High Refresh 75Hz
779   ret
780
781 cirrus_extbios_unimplemented:
782   ret
783
784 cirrus_vesa_00h:
785   push ds
786   push si
787   mov bp, di
788   push es
789   pop ds
790   cld
791   mov ax, [di]
792   cmp ax, #0x4256 ;; VB
793   jnz cv00_1
794   mov ax, [di+2]
795   cmp ax, #0x3245 ;; E2
796   jnz cv00_1
797   ;; VBE2
798   lea di, 0x14[bp]
799   mov ax, #0x0100 ;; soft ver.
800   stosw
801   mov ax, # cirrus_vesa_vendorname
802   stosw
803   mov ax, cs
804   stosw
805   mov ax, # cirrus_vesa_productname
806   stosw
807   mov ax, cs
808   stosw
809   mov ax, # cirrus_vesa_productrevision
810   stosw
811   mov ax, cs
812   stosw
813 cv00_1:
814   mov di, bp
815   mov ax, #0x4556 ;; VE
816   stosw
817   mov ax, #0x4153 ;; SA
818   stosw
819   mov ax, #0x0200 ;; v2.00
820   stosw
821   mov ax, # cirrus_vesa_oemname
822   stosw
823   mov ax, cs
824   stosw
825   xor ax, ax ;; caps
826   stosw
827   stosw
828   lea ax, 0x40[bp]
829   stosw
830   mov ax, es
831   stosw
832   call cirrus_extbios_85h ;; vram in 64k
833   mov ah, #0x00
834   stosw
835
836   push cs
837   pop ds
838   lea di, 0x40[bp]
839   mov si, #_cirrus_vesa_modelist
840 cv00_2:
841   lodsw
842   stosw
843   add si, #2
844   cmp ax, #0xffff
845   jnz cv00_2
846
847   mov ax, #0x004F
848   mov di, bp
849   pop si
850   pop ds
851   ret
852
853 cirrus_vesa_01h:
854   mov ax, cx
855   and ax, #0x3fff
856   call cirrus_vesamode_to_mode
857   cmp ax, #0xffff
858   jnz cirrus_vesa_01h_1
859   jmp cirrus_vesa_unimplemented
860 cirrus_vesa_01h_1:
861   push ds
862   push si
863   push cx
864   push dx
865   push bx
866   mov bp, di
867   cld
868   push cs
869   pop ds
870   call cirrus_get_modeentry_nomask
871
872   push di
873   xor ax, ax
874   mov cx, #0x80
875   rep
876     stosw ;; clear buffer
877   pop di
878
879   mov ax, #0x003b ;; mode
880   stosw
881   mov ax, #0x0007 ;; attr
882   stosw
883   mov ax, #0x0010 ;; granularity =16K
884   stosw
885   mov ax, #0x0040 ;; size =64K
886   stosw
887   mov ax, #0xA000 ;; segment A
888   stosw
889   xor ax, ax ;; no segment B
890   stosw
891   mov ax, #cirrus_vesa_05h_farentry
892   stosw
893   mov ax, cs
894   stosw
895   call cirrus_get_line_offset_entry
896   stosw ;; bytes per scan line
897   mov ax, [si+2] ;; width
898   stosw
899   mov ax, [si+4] ;; height
900   stosw
901   mov ax, #0x08
902   stosb
903   mov ax, #0x10
904   stosb
905   mov al, #1 ;; count of planes
906   stosb
907   mov al, [si+6] ;; bpp
908   stosb
909   mov al, #0x1 ;; XXX number of banks
910   stosb
911   mov al, [si+17]
912   stosb ;; memory model
913   mov al, #0x0   ;; XXX size of bank in K
914   stosb
915   call cirrus_get_line_offset_entry
916   mov bx, [si+4]
917   mul bx ;; dx:ax=vramdisp
918   or ax, ax
919   jz cirrus_vesa_01h_3
920   inc dx
921 cirrus_vesa_01h_3:
922   call cirrus_extbios_85h ;; al=vram in 64k
923   mov ah, #0x00
924   mov cx, dx
925   xor dx, dx
926   div cx
927   dec ax
928   stosb  ;; number of image pages = vramtotal/vramdisp-1
929   mov al, #0x00
930   stosb
931
932   ;; v1.2+ stuffs
933   push si
934   add si, #18
935   movsw
936   movsw
937   movsw
938   movsw
939   pop si
940
941   mov ah, [si+16]
942   mov al, #0x0
943   sub ah, #9
944   rcl al, #1 ; bit 0=palette flag
945   stosb ;; direct screen mode info
946
947   ;; v2.0+ stuffs
948   ;; 32-bit LFB address
949   xor ax, ax
950   stosw
951   mov ax, #0x1013 ;; vendor Cirrus
952   call _pci_get_lfb_addr
953   stosw
954   or ax, ax
955   jz cirrus_vesa_01h_4
956   push di
957   mov di, bp
958  db 0x26 ;; es:
959   mov ax, [di]
960   or ax, #0x0080 ;; mode bit 7:LFB
961   stosw
962   pop di
963 cirrus_vesa_01h_4:
964
965   xor ax, ax
966   stosw ; reserved
967   stosw ; reserved
968   stosw ; reserved
969
970   mov ax, #0x004F
971   mov di, bp
972   pop bx
973   pop dx
974   pop cx
975   pop si
976   pop ds
977
978   test cx, #0x4000 ;; LFB flag
979   jz cirrus_vesa_01h_5
980   push cx
981  db 0x26 ;; es:
982   mov cx, [di]
983   cmp cx, #0x0080 ;; is LFB supported?
984   jnz cirrus_vesa_01h_6
985   mov ax, #0x014F ;; error - no LFB
986 cirrus_vesa_01h_6:
987   pop cx
988 cirrus_vesa_01h_5:
989   ret
990
991 cirrus_vesa_02h:
992   ;; XXX support CRTC registers
993   test bx, #0x3e00
994   jnz cirrus_vesa_02h_2 ;; unknown flags
995   mov ax, bx
996   and ax, #0x1ff ;; bit 8-0 mode
997   cmp ax, #0x100 ;; legacy VGA mode
998   jb cirrus_vesa_02h_legacy
999   call cirrus_vesamode_to_mode
1000   cmp ax, #0xffff
1001   jnz cirrus_vesa_02h_1
1002 cirrus_vesa_02h_2:
1003   jmp cirrus_vesa_unimplemented
1004 cirrus_vesa_02h_legacy:
1005 #ifdef CIRRUS_VESA3_PMINFO
1006  db 0x2e ;; cs:
1007   cmp byte ptr [cirrus_vesa_is_protected_mode], #0
1008   jnz cirrus_vesa_02h_2
1009 #endif // CIRRUS_VESA3_PMINFO
1010   int #0x10
1011   mov ax, #0x004F
1012   ret
1013 cirrus_vesa_02h_1:
1014   push si
1015   push ax
1016   call cirrus_get_modeentry_nomask
1017   call cirrus_switch_mode
1018   test bx, #0x4000 ;; LFB
1019   jnz cirrus_vesa_02h_3
1020   call cirrus_enable_16k_granularity
1021 cirrus_vesa_02h_3:
1022   test bx, #0x8000 ;; no clear
1023   jnz cirrus_vesa_02h_4
1024   push ax
1025   xor ax,ax
1026   call cirrus_clear_vram
1027   pop ax
1028 cirrus_vesa_02h_4:
1029   pop ax
1030   push ds
1031 #ifdef CIRRUS_VESA3_PMINFO
1032  db 0x2e ;; cs:
1033   mov si, [cirrus_vesa_sel0000_data]
1034 #else
1035   xor si, si
1036 #endif
1037   mov ds, si
1038   mov [PM_BIOSMEM_CURRENT_MODE], al
1039   mov [PM_BIOSMEM_VBE_MODE], bx
1040   pop ds
1041   pop si
1042   mov ax, #0x004F
1043   ret
1044
1045 cirrus_vesa_03h:
1046   push ds
1047 #ifdef CIRRUS_VESA3_PMINFO
1048  db 0x2e ;; cs:
1049   mov ax, [cirrus_vesa_sel0000_data]
1050 #else
1051   xor ax, ax
1052 #endif
1053   mov  ds, ax
1054   mov  bx, # PM_BIOSMEM_VBE_MODE
1055   mov  ax, [bx]
1056   mov  bx, ax
1057   test bx, bx
1058   jnz   cirrus_vesa_03h_1
1059   mov  bx, # PM_BIOSMEM_CURRENT_MODE
1060   mov  al, [bx]
1061   mov  bl, al
1062   xor  bh, bh
1063 cirrus_vesa_03h_1:
1064   mov  ax, #0x004f
1065   pop  ds
1066   ret
1067
1068 cirrus_vesa_05h_farentry:
1069   call cirrus_vesa_05h
1070   retf
1071
1072 cirrus_vesa_05h:
1073   cmp bl, #0x01
1074   ja cirrus_vesa_05h_1
1075   cmp bh, #0x00
1076   jz cirrus_vesa_05h_setmempage
1077   cmp bh, #0x01
1078   jz cirrus_vesa_05h_getmempage
1079 cirrus_vesa_05h_1:
1080   jmp cirrus_vesa_unimplemented
1081 cirrus_vesa_05h_setmempage:
1082   or dh, dh ; address must be < 0x100
1083   jnz cirrus_vesa_05h_1
1084   push dx
1085   mov al, bl ;; bl=bank number
1086   add al, #0x09
1087   mov ah, dl ;; dx=window address in granularity
1088   mov dx, #0x3ce
1089   out dx, ax
1090   pop dx
1091   mov ax, #0x004F
1092   ret
1093 cirrus_vesa_05h_getmempage:
1094   mov al, bl ;; bl=bank number
1095   add al, #0x09
1096   mov dx, #0x3ce
1097   out dx, al
1098   inc dx
1099   in al, dx
1100   xor dx, dx
1101   mov dl, al ;; dx=window address in granularity
1102   mov ax, #0x004F
1103   ret
1104
1105 cirrus_vesa_06h:
1106   mov  ax, cx
1107   cmp  bl, #0x01
1108   je   cirrus_vesa_06h_3
1109   cmp  bl, #0x02
1110   je   cirrus_vesa_06h_2
1111   jb   cirrus_vesa_06h_1
1112   mov  ax, #0x0100
1113   ret
1114 cirrus_vesa_06h_1:
1115   call cirrus_get_bpp_bytes
1116   mov  bl, al
1117   xor  bh, bh
1118   mov  ax, cx
1119   mul  bx
1120 cirrus_vesa_06h_2:
1121   call cirrus_set_line_offset
1122 cirrus_vesa_06h_3:
1123   call cirrus_get_bpp_bytes
1124   mov  bl, al
1125   xor  bh, bh
1126   xor  dx, dx
1127   call cirrus_get_line_offset
1128   push ax
1129   div  bx
1130   mov  cx, ax
1131   pop  bx
1132   call cirrus_extbios_85h ;; al=vram in 64k
1133   xor  dx, dx
1134   mov  dl, al
1135   xor  ax, ax
1136   div  bx
1137   mov  dx, ax
1138   mov  ax, #0x004f
1139   ret
1140
1141 cirrus_vesa_07h:
1142   cmp  bl, #0x80
1143   je   cirrus_vesa_07h_1
1144   cmp  bl, #0x01
1145   je   cirrus_vesa_07h_2
1146   jb   cirrus_vesa_07h_1
1147   mov  ax, #0x0100
1148   ret
1149 cirrus_vesa_07h_1:
1150   push dx
1151   call cirrus_get_bpp_bytes
1152   mov  bl, al
1153   xor  bh, bh
1154   mov  ax, cx
1155   mul  bx
1156   pop  bx
1157   push ax
1158   call cirrus_get_line_offset
1159   mul  bx
1160   pop  bx
1161   add  ax, bx
1162   jnc  cirrus_vesa_07h_3
1163   inc  dx
1164 cirrus_vesa_07h_3:
1165   push dx
1166   and  dx, #0x0003
1167   mov  bx, #0x04
1168   div  bx
1169   pop  dx
1170   shr  dx, #2
1171   call cirrus_set_start_addr
1172   mov  ax, #0x004f
1173   ret
1174 cirrus_vesa_07h_2:
1175   call cirrus_get_start_addr
1176   shl  dx, #2
1177   push dx
1178   mov  bx, #0x04
1179   mul  bx
1180   pop  bx
1181   or   dx, bx
1182   push ax
1183   call cirrus_get_line_offset
1184   mov  bx, ax
1185   pop  ax
1186   div  bx
1187   push ax
1188   push dx
1189   call cirrus_get_bpp_bytes
1190   mov  bl, al
1191   xor  bh, bh
1192   pop  ax
1193   xor  dx, dx
1194   div  bx
1195   mov  cx, ax
1196   pop  dx
1197   mov  ax, #0x004f
1198   ret
1199
1200 cirrus_vesa_10h:
1201   cmp bl, #0x00
1202   jne cirrus_vesa_10h_01
1203   mov bx, #0x0f30
1204   mov ax, #0x004f
1205   ret
1206 cirrus_vesa_10h_01:
1207   cmp bl, #0x01
1208   jne cirrus_vesa_10h_02
1209   push dx
1210   push ds
1211   mov dx, #0x40
1212   mov ds, dx
1213   mov [0xb9], bh
1214   pop ds
1215   pop dx
1216   mov ax, #0x004f
1217   ret
1218 cirrus_vesa_10h_02:
1219   cmp bl, #0x02
1220   jne cirrus_vesa_unimplemented
1221   push dx
1222   push ds
1223   mov dx, #0x40
1224   mov ds, dx
1225   mov bh, [0xb9]
1226   pop ds
1227   pop dx
1228   mov ax, #0x004f
1229   ret
1230
1231 cirrus_vesa_unimplemented:
1232   mov ax, #0x014F ;; not implemented
1233   ret
1234
1235
1236 ;; in ax:vesamode, out ax:cirrusmode
1237 cirrus_vesamode_to_mode:
1238   push ds
1239   push cx
1240   push si
1241   push cs
1242   pop ds
1243   mov cx, #0xffff
1244   mov si, #_cirrus_vesa_modelist
1245 cvtm_1:
1246   cmp [si],ax
1247   jz cvtm_2
1248   cmp [si],cx
1249   jz cvtm_2
1250   add si, #4
1251   jmp cvtm_1
1252 cvtm_2:
1253   mov ax,[si+2]
1254   pop si
1255   pop cx
1256   pop ds
1257   ret
1258
1259   ; cirrus_get_crtc
1260   ;; NOTE - may be called in protected mode
1261 cirrus_get_crtc:
1262   push ds
1263   push ax
1264   mov  dx, #0x3cc
1265   in   al, dx
1266   and  al, #0x01
1267   shl  al, #5
1268   mov  dx, #0x3b4
1269   add  dl, al
1270   pop  ax
1271   pop  ds
1272   ret
1273
1274 ;; in - al:mode, out - cflag:result, si:table, ax:destroyed
1275 cirrus_get_modeentry:
1276   and al, #0x7f
1277 cirrus_get_modeentry_nomask:
1278   mov si, #_cirrus_modes
1279 cgm_1:
1280  db 0x2e ;; cs:
1281   mov ah, [si]
1282   cmp al, ah
1283   jz cgm_2
1284   cmp ah, #0xff
1285   jz cgm_4
1286   add si, # CIRRUS_MODE_SIZE
1287   jmp cgm_1
1288 cgm_4:
1289   xor si, si
1290   stc ;; video mode is not supported
1291   jmp cgm_3
1292 cgm_2:
1293   clc ;; video mode is supported
1294 cgm_3:
1295   ret
1296
1297 ;; out - al:bytes per pixel
1298 cirrus_get_bpp_bytes:
1299   push dx
1300   mov  dx, #0x03c4
1301   mov  al, #0x07
1302   out  dx, al
1303   inc  dx
1304   in   al, dx
1305   and  al, #0x0e
1306   cmp  al, #0x06
1307   jne  cirrus_get_bpp_bytes_1
1308   and  al, #0x02
1309 cirrus_get_bpp_bytes_1:
1310   shr  al, #1
1311   cmp  al, #0x04
1312   je  cirrus_get_bpp_bytes_2
1313   inc  al
1314 cirrus_get_bpp_bytes_2:
1315   pop  dx
1316   ret
1317
1318 ;; in - ax: new line offset
1319 cirrus_set_line_offset:
1320   shr  ax, #3
1321   push ax
1322   call cirrus_get_crtc
1323   mov  al, #0x13
1324   out  dx, al
1325   inc  dx
1326   pop  ax
1327   out  dx, al
1328   dec  dx
1329   mov  al, #0x1b
1330   out  dx, al
1331   inc  dx
1332   shl  ah, #4
1333   in   al, dx
1334   and  al, #ef
1335   or   al, ah
1336   out  dx, al
1337   ret
1338
1339 ;; out - ax: active line offset
1340 cirrus_get_line_offset:
1341   push dx
1342   push bx
1343   call cirrus_get_crtc
1344   mov  al, #0x13
1345   out  dx, al
1346   inc  dx
1347   in   al, dx
1348   mov  bl, al
1349   dec  dx
1350   mov  al, #0x1b
1351   out  dx, al
1352   inc  dx
1353   in   al, dx
1354   mov  ah, al
1355   shr  ah, #4
1356   and  ah, #0x01
1357   mov  al, bl
1358   shl  ax, #3
1359   pop  bx
1360   pop  dx
1361   ret
1362
1363 ;; in - si: table
1364 ;; out - ax: line offset for mode
1365 cirrus_get_line_offset_entry:
1366   push bx
1367   mov  bx, [si+14] ;; crtc table
1368   push bx
1369 offset_loop1:
1370   mov  ax, [bx]
1371   cmp  al, #0x13
1372   je   offset_found1
1373   inc  bx
1374   inc  bx
1375   jnz  offset_loop1
1376 offset_found1:
1377   xor  al, al
1378   shr  ax, #5
1379   pop  bx
1380   push ax
1381 offset_loop2:
1382   mov  ax, [bx]
1383   cmp  al, #0x1b
1384   je offset_found2
1385   inc  bx
1386   inc  bx
1387   jnz offset_loop2
1388 offset_found2:
1389   pop  bx
1390   and  ax, #0x1000
1391   shr  ax, #1
1392   or   ax, bx
1393   pop  bx
1394   ret
1395
1396 ;; in - new address in DX:AX
1397 cirrus_set_start_addr:
1398   push bx
1399   push dx
1400   push ax
1401   call cirrus_get_crtc
1402   mov  al, #0x0d
1403   out  dx, al
1404   inc  dx
1405   pop  ax
1406   out  dx, al
1407   dec  dx
1408   mov  al, #0x0c
1409   out  dx, al
1410   inc  dx
1411   mov  al, ah
1412   out  dx, al
1413   dec  dx
1414   mov  al, #0x1d
1415   out  dx, al
1416   inc  dx
1417   in   al, dx
1418   and  al, #0x7f
1419   pop  bx
1420   mov  ah, bl
1421   shl  bl, #4
1422   and  bl, #0x80
1423   or   al, bl
1424   out  dx, al
1425   dec  dx
1426   mov  bl, ah
1427   and  ah, #0x01
1428   shl  bl, #1
1429   and  bl, #0x0c
1430   or   ah, bl
1431   mov  al, #0x1b
1432   out  dx, al
1433   inc  dx
1434   in   al, dx
1435   and  al, #0xf2
1436   or   al, ah
1437   out  dx, al
1438   pop  bx
1439   ret
1440
1441 ;; out - current address in DX:AX
1442 cirrus_get_start_addr:
1443   push bx
1444   call cirrus_get_crtc
1445   mov  al, #0x0c
1446   out  dx, al
1447   inc  dx
1448   in   al, dx
1449   mov  ah, al
1450   dec  dx
1451   mov  al, #0x0d
1452   out  dx, al
1453   inc  dx
1454   in   al, dx
1455   push ax
1456   dec  dx
1457   mov  al, #0x1b
1458   out  dx, al
1459   inc  dx
1460   in   al, dx
1461   dec  dx
1462   mov  bl, al
1463   and  al, #0x01
1464   and  bl, #0x0c
1465   shr  bl, #1
1466   or   bl, al
1467   mov  al, #0x1d
1468   out  dx, al
1469   inc  dx
1470   in   al, dx
1471   and  al, #0x80
1472   shr  al, #4
1473   or   bl, al
1474   mov  dl, bl
1475   xor  dh, dh
1476   pop  ax
1477   pop  bx
1478   ret
1479
1480 cirrus_clear_vram:
1481   pusha
1482   push es
1483   mov si, ax
1484
1485   call cirrus_enable_16k_granularity
1486   call cirrus_extbios_85h
1487   shl al, #2
1488   mov bl, al
1489   xor ah,ah
1490 cirrus_clear_vram_1:
1491   mov al, #0x09
1492   mov dx, #0x3ce
1493   out dx, ax
1494   push ax
1495   mov cx, #0xa000
1496   mov es, cx
1497   xor di, di
1498   mov ax, si
1499   mov cx, #8192
1500   cld
1501   rep 
1502       stosw
1503   pop ax
1504   inc ah
1505   cmp ah, bl
1506   jne cirrus_clear_vram_1
1507
1508   xor ah,ah
1509   mov dx, #0x3ce
1510   out dx, ax
1511
1512   pop es
1513   popa
1514   ret
1515
1516 cirrus_extbios_handlers:
1517   ;; 80h
1518   dw cirrus_extbios_80h
1519   dw cirrus_extbios_81h
1520   dw cirrus_extbios_82h
1521   dw cirrus_extbios_unimplemented
1522   ;; 84h
1523   dw cirrus_extbios_unimplemented
1524   dw cirrus_extbios_85h
1525   dw cirrus_extbios_unimplemented
1526   dw cirrus_extbios_unimplemented
1527   ;; 88h
1528   dw cirrus_extbios_unimplemented
1529   dw cirrus_extbios_unimplemented
1530   dw cirrus_extbios_unimplemented
1531   dw cirrus_extbios_unimplemented
1532   ;; 8Ch
1533   dw cirrus_extbios_unimplemented
1534   dw cirrus_extbios_unimplemented
1535   dw cirrus_extbios_unimplemented
1536   dw cirrus_extbios_unimplemented
1537   ;; 90h
1538   dw cirrus_extbios_unimplemented
1539   dw cirrus_extbios_unimplemented
1540   dw cirrus_extbios_unimplemented
1541   dw cirrus_extbios_unimplemented
1542   ;; 94h
1543   dw cirrus_extbios_unimplemented
1544   dw cirrus_extbios_unimplemented
1545   dw cirrus_extbios_unimplemented
1546   dw cirrus_extbios_unimplemented
1547   ;; 98h
1548   dw cirrus_extbios_unimplemented
1549   dw cirrus_extbios_unimplemented
1550   dw cirrus_extbios_9Ah
1551   dw cirrus_extbios_unimplemented
1552   ;; 9Ch
1553   dw cirrus_extbios_unimplemented
1554   dw cirrus_extbios_unimplemented
1555   dw cirrus_extbios_unimplemented
1556   dw cirrus_extbios_unimplemented
1557   ;; A0h
1558   dw cirrus_extbios_A0h
1559   dw cirrus_extbios_A1h
1560   dw cirrus_extbios_A2h
1561   dw cirrus_extbios_unimplemented
1562   ;; A4h
1563   dw cirrus_extbios_unimplemented
1564   dw cirrus_extbios_unimplemented
1565   dw cirrus_extbios_unimplemented
1566   dw cirrus_extbios_unimplemented
1567   ;; A8h
1568   dw cirrus_extbios_unimplemented
1569   dw cirrus_extbios_unimplemented
1570   dw cirrus_extbios_unimplemented
1571   dw cirrus_extbios_unimplemented
1572   ;; ACh
1573   dw cirrus_extbios_unimplemented
1574   dw cirrus_extbios_unimplemented
1575   dw cirrus_extbios_AEh
1576   dw cirrus_extbios_unimplemented
1577
1578 cirrus_vesa_handlers:
1579   ;; 00h
1580   dw cirrus_vesa_00h
1581   dw cirrus_vesa_01h
1582   dw cirrus_vesa_02h
1583   dw cirrus_vesa_03h
1584   ;; 04h
1585   dw cirrus_vesa_unimplemented
1586   dw cirrus_vesa_05h
1587   dw cirrus_vesa_06h
1588   dw cirrus_vesa_07h
1589   ;; 08h
1590   dw cirrus_vesa_unimplemented
1591   dw cirrus_vesa_unimplemented
1592   dw cirrus_vesa_unimplemented
1593   dw cirrus_vesa_unimplemented
1594   ;; 0Ch
1595   dw cirrus_vesa_unimplemented
1596   dw cirrus_vesa_unimplemented
1597   dw cirrus_vesa_unimplemented
1598   dw cirrus_vesa_unimplemented
1599   ;; 10h
1600   dw cirrus_vesa_10h
1601
1602
1603 ASM_END
1604
1605 #ifdef CIRRUS_VESA3_PMINFO
1606 ASM_START
1607 cirrus_vesa_pminfo:
1608   /* + 0 */
1609   .byte 0x50,0x4d,0x49,0x44 ;; signature[4]
1610   /* + 4 */
1611   dw cirrus_vesa_pmbios_entry ;; entry_bios
1612   dw cirrus_vesa_pmbios_init  ;; entry_init
1613   /* + 8 */
1614 cirrus_vesa_sel0000_data:
1615   dw 0x0000 ;; sel_00000
1616 cirrus_vesa_selA000_data:
1617   dw 0xA000 ;; sel_A0000
1618   /* +12 */
1619 cirrus_vesa_selB000_data:
1620   dw 0xB000 ;; sel_B0000
1621 cirrus_vesa_selB800_data:
1622   dw 0xB800 ;; sel_B8000
1623   /* +16 */
1624 cirrus_vesa_selC000_data:
1625   dw 0xC000 ;; sel_C0000
1626 cirrus_vesa_is_protected_mode:
1627   ;; protected mode flag and checksum
1628   dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \
1629      + (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01
1630 ASM_END
1631 #endif // CIRRUS_VESA3_PMINFO
1632
1633
1634 #ifdef CIRRUS_DEBUG
1635 static void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
1636   Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
1637 {
1638  if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05))
1639   printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX);
1640 }
1641 #endif