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
30typedef 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 */
62unsigned short cseq_vga[] = {0x0007,0xffff};
63unsigned short cgraph_vga[] = {0x0009,0x000a,0x000b,0xffff};
64unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff};
65
66/* extensions */
67unsigned short cgraph_svgacolor[] = {
680x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08,
690x0009,0x000a,0x000b,
700xffff
71};
72/* 640x480x8 */
73unsigned short cseq_640x480x8[] = {
740x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
750x580b,0x580c,0x580d,0x580e,
760x0412,0x0013,0x2017,
770x331b,0x331c,0x331d,0x331e,
780xffff
79};
80unsigned short ccrtc_640x480x8[] = {
810x2c11,
820x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
830x4009,0x000c,0x000d,
840xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
850x001a,0x221b,0x001d,
860xffff
87};
88/* 640x480x16 */
89unsigned short cseq_640x480x16[] = {
900x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
910x580b,0x580c,0x580d,0x580e,
920x0412,0x0013,0x2017,
930x331b,0x331c,0x331d,0x331e,
940xffff
95};
96unsigned short ccrtc_640x480x16[] = {
970x2c11,
980x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
990x4009,0x000c,0x000d,
1000xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
1010x001a,0x221b,0x001d,
1020xffff
103};
104/* 640x480x24 */
105unsigned short cseq_640x480x24[] = {
1060x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
1070x580b,0x580c,0x580d,0x580e,
1080x0412,0x0013,0x2017,
1090x331b,0x331c,0x331d,0x331e,
1100xffff
111};
112unsigned short ccrtc_640x480x24[] = {
1130x2c11,
1140x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
1150x4009,0x000c,0x000d,
1160xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
1170x001a,0x321b,0x001d,
1180xffff
119};
120/* 800x600x8 */
121unsigned short cseq_800x600x8[] = {
1220x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
1230x230b,0x230c,0x230d,0x230e,
1240x0412,0x0013,0x2017,
1250x141b,0x141c,0x141d,0x141e,
1260xffff
127};
128unsigned short ccrtc_800x600x8[] = {
1290x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
1300x6009,0x000c,0x000d,
1310x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18,
1320x001a,0x221b,0x001d,
1330xffff
134};
135/* 800x600x16 */
136unsigned short cseq_800x600x16[] = {
1370x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
1380x230b,0x230c,0x230d,0x230e,
1390x0412,0x0013,0x2017,
1400x141b,0x141c,0x141d,0x141e,
1410xffff
142};
143unsigned short ccrtc_800x600x16[] = {
1440x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
1450x6009,0x000c,0x000d,
1460x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18,
1470x001a,0x221b,0x001d,
1480xffff
149};
150/* 800x600x24 */
151unsigned short cseq_800x600x24[] = {
1520x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
1530x230b,0x230c,0x230d,0x230e,
1540x0412,0x0013,0x2017,
1550x141b,0x141c,0x141d,0x141e,
1560xffff
157};
158unsigned short ccrtc_800x600x24[] = {
1590x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
1600x6009,0x000c,0x000d,
1610x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18,
1620x001a,0x321b,0x001d,
1630xffff
164};
165/* 1024x768x8 */
166unsigned short cseq_1024x768x8[] = {
1670x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
1680x760b,0x760c,0x760d,0x760e,
1690x0412,0x0013,0x2017,
1700x341b,0x341c,0x341d,0x341e,
1710xffff
172};
173unsigned short ccrtc_1024x768x8[] = {
1740x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
1750x6009,0x000c,0x000d,
1760x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
1770x001a,0x221b,0x001d,
1780xffff
179};
180/* 1024x768x16 */
181unsigned short cseq_1024x768x16[] = {
1820x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
1830x760b,0x760c,0x760d,0x760e,
1840x0412,0x0013,0x2017,
1850x341b,0x341c,0x341d,0x341e,
1860xffff
187};
188unsigned short ccrtc_1024x768x16[] = {
1890x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
1900x6009,0x000c,0x000d,
1910x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18,
1920x001a,0x321b,0x001d,
1930xffff
194};
195/* 1024x768x24 */
196unsigned short cseq_1024x768x24[] = {
1970x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
1980x760b,0x760c,0x760d,0x760e,
1990x0412,0x0013,0x2017,
2000x341b,0x341c,0x341d,0x341e,
2010xffff
202};
203unsigned short ccrtc_1024x768x24[] = {
2040x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
2050x6009,0x000c,0x000d,
2060x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
2070x001a,0x321b,0x001d,
2080xffff
209};
210/* 1280x1024x8 */
211unsigned short cseq_1280x1024x8[] = {
2120x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
2130x760b,0x760c,0x760d,0x760e,
2140x0412,0x0013,0x2017,
2150x341b,0x341c,0x341d,0x341e,
2160xffff
217};
218unsigned short ccrtc_1280x1024x8[] = {
2190x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
2200x6009,0x000c,0x000d,
2210x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
2220x001a,0x221b,0x001d,
2230xffff
224};
225/* 1280x1024x16 */
226unsigned short cseq_1280x1024x16[] = {
2270x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
2280x760b,0x760c,0x760d,0x760e,
2290x0412,0x0013,0x2017,
2300x341b,0x341c,0x341d,0x341e,
2310xffff
232};
233unsigned short ccrtc_1280x1024x16[] = {
2340x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
2350x6009,0x000c,0x000d,
2360x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18,
2370x001a,0x321b,0x001d,
2380xffff
239};
240
241/* 1600x1200x8 */
242unsigned short cseq_1600x1200x8[] = {
2430x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
2440x760b,0x760c,0x760d,0x760e,
2450x0412,0x0013,0x2017,
2460x341b,0x341c,0x341d,0x341e,
2470xffff
248};
249unsigned short ccrtc_1600x1200x8[] = {
2500x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
2510x6009,0x000c,0x000d,
2520x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
2530x001a,0x221b,0x001d,
2540xffff
255};
256
257cirrus_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
319unsigned char cirrus_id_table[] = {
320  // 5430
321  0xA0, 0x32,
322  // 5446
323  0xB8, 0x39,
324
325  0xff, 0xff
326};
327
328
329unsigned 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
365ASM_START
366
367cirrus_installed:
368.ascii "cirrus-compatible VGA is detected"
369.byte 0x0d,0x0a
370.byte 0x0d,0x0a,0x00
371
372cirrus_not_installed:
373.ascii "cirrus-compatible VGA is not detected"
374.byte 0x0d,0x0a
375.byte 0x0d,0x0a,0x00
376
377cirrus_vesa_vendorname:
378cirrus_vesa_productname:
379cirrus_vesa_oemname:
380.ascii "VGABIOS Cirrus extension"
381.byte 0
382cirrus_vesa_productrevision:
383.ascii "1.0"
384.byte 0
385
386cirrus_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
407no_cirrus:
408  ret
409
410cirrus_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
420cirrus_msgnotinstalled:
421  call _display_string
422  pop si
423  pop ds
424  ret
425
426cirrus_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
440cirrus_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
450cirrus_unhandled:
451  pop bp
452  popf
453  jmp vgabios_int10_handler
454
455cirrus_return:
456#ifdef CIRRUS_DEBUG
457  call cirrus_debug_dump
458#endif
459  pop bp
460  popf
461  iret
462
463cirrus_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
491cirrus_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
509cirrus_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
526cirrus_vesa_not_handled:
527  mov ax, #0x014F ;; not implemented
528  jmp cirrus_return
529
530#ifdef CIRRUS_DEBUG
531cirrus_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
544cirrus_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
553cirrus_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
572cirrus_vesa_pmbios_init:
573  retf
574cirrus_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
591cirrus_vesa_pmbios_unimplemented:
592  mov ax, #0x014F
593cirrus_vesa_pmbios_return:
594  pop bp
595  popf
596  retf
597
598; in si:mode table
599cirrus_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
640is_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
652cirrus_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
666cirrus_switch_mode_setregs:
667csms_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
674csms_2:
675  ret
676
677cirrus_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
685c80h_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
695c80h_2:
696 db 0x2e ;; cs:
697  mov al, 0x1[bx]
698  pop dx
699  mov ah, #0x00
700  xor bx, bx
701  ret
702
703cirrus_extbios_81h:
704  mov ax, #0x100 ;; XXX
705  ret
706cirrus_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
719cirrus_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
736c85h2:
737;; 4MB or 2MB
738  and al, #0x80
739  mov al, #0x20 ;; 2 MB
740  je c85h3
741  mov al, #0x40 ;; 4 MB
742c85h3:
743  pop dx
744  pop cx
745  ret
746
747cirrus_extbios_9Ah:
748  mov ax, #0x4060
749  mov cx, #0x1132
750  ret
751
752cirrus_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
763cirrus_extbios_A0h_callback:
764  ;; fatal: not implemented yet
765  cli
766  hlt
767  retf
768
769cirrus_extbios_A1h:
770  mov bx, #0x0E00 ;; IBM 8512/8513, color
771  ret
772
773cirrus_extbios_A2h:
774  mov al, #0x07   ;; HSync 31.5 - 64.0 kHz
775  ret
776
777cirrus_extbios_AEh:
778  mov al, #0x01   ;; High Refresh 75Hz
779  ret
780
781cirrus_extbios_unimplemented:
782  ret
783
784cirrus_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
813cv00_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
840cv00_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
853cirrus_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
860cirrus_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
921cirrus_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
963cirrus_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
986cirrus_vesa_01h_6:
987  pop cx
988cirrus_vesa_01h_5:
989  ret
990
991cirrus_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
1002cirrus_vesa_02h_2:
1003  jmp cirrus_vesa_unimplemented
1004cirrus_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
1013cirrus_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
1021cirrus_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
1028cirrus_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
1045cirrus_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
1063cirrus_vesa_03h_1:
1064  mov  ax, #0x004f
1065  pop  ds
1066  ret
1067
1068cirrus_vesa_05h_farentry:
1069  call cirrus_vesa_05h
1070  retf
1071
1072cirrus_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
1079cirrus_vesa_05h_1:
1080  jmp cirrus_vesa_unimplemented
1081cirrus_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
1093cirrus_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
1105cirrus_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
1114cirrus_vesa_06h_1:
1115  call cirrus_get_bpp_bytes
1116  mov  bl, al
1117  xor  bh, bh
1118  mov  ax, cx
1119  mul  bx
1120cirrus_vesa_06h_2:
1121  call cirrus_set_line_offset
1122cirrus_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
1141cirrus_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
1149cirrus_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
1164cirrus_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
1174cirrus_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
1200cirrus_vesa_10h:
1201  cmp bl, #0x00
1202  jne cirrus_vesa_10h_01
1203  mov bx, #0x0f30
1204  mov ax, #0x004f
1205  ret
1206cirrus_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
1218cirrus_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
1231cirrus_vesa_unimplemented:
1232  mov ax, #0x014F ;; not implemented
1233  ret
1234
1235
1236;; in ax:vesamode, out ax:cirrusmode
1237cirrus_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
1245cvtm_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
1252cvtm_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
1261cirrus_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
1275cirrus_get_modeentry:
1276  and al, #0x7f
1277cirrus_get_modeentry_nomask:
1278  mov si, #_cirrus_modes
1279cgm_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
1288cgm_4:
1289  xor si, si
1290  stc ;; video mode is not supported
1291  jmp cgm_3
1292cgm_2:
1293  clc ;; video mode is supported
1294cgm_3:
1295  ret
1296
1297;; out - al:bytes per pixel
1298cirrus_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
1309cirrus_get_bpp_bytes_1:
1310  shr  al, #1
1311  cmp  al, #0x04
1312  je  cirrus_get_bpp_bytes_2
1313  inc  al
1314cirrus_get_bpp_bytes_2:
1315  pop  dx
1316  ret
1317
1318;; in - ax: new line offset
1319cirrus_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
1340cirrus_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
1365cirrus_get_line_offset_entry:
1366  push bx
1367  mov  bx, [si+14] ;; crtc table
1368  push bx
1369offset_loop1:
1370  mov  ax, [bx]
1371  cmp  al, #0x13
1372  je   offset_found1
1373  inc  bx
1374  inc  bx
1375  jnz  offset_loop1
1376offset_found1:
1377  xor  al, al
1378  shr  ax, #5
1379  pop  bx
1380  push ax
1381offset_loop2:
1382  mov  ax, [bx]
1383  cmp  al, #0x1b
1384  je offset_found2
1385  inc  bx
1386  inc  bx
1387  jnz offset_loop2
1388offset_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
1397cirrus_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
1442cirrus_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
1480cirrus_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
1490cirrus_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
1516cirrus_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
1578cirrus_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
1603ASM_END
1604
1605#ifdef CIRRUS_VESA3_PMINFO
1606ASM_START
1607cirrus_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 */
1614cirrus_vesa_sel0000_data:
1615  dw 0x0000 ;; sel_00000
1616cirrus_vesa_selA000_data:
1617  dw 0xA000 ;; sel_A0000
1618  /* +12 */
1619cirrus_vesa_selB000_data:
1620  dw 0xB000 ;; sel_B0000
1621cirrus_vesa_selB800_data:
1622  dw 0xB800 ;; sel_B8000
1623  /* +16 */
1624cirrus_vesa_selC000_data:
1625  dw 0xC000 ;; sel_C0000
1626cirrus_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
1630ASM_END
1631#endif // CIRRUS_VESA3_PMINFO
1632
1633
1634#ifdef CIRRUS_DEBUG
1635static 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
1642