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.


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