Annotation of qemu/roms/vgabios/clext.c, revision 1.1.1.1

1.1       root        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:   call cirrus_get_lfb_addr
                    952:   stosw
                    953:   or ax, ax
                    954:   jz cirrus_vesa_01h_4
                    955:   push di
                    956:   mov di, bp
                    957:  db 0x26 ;; es:
                    958:   mov ax, [di]
                    959:   or ax, #0x0080 ;; mode bit 7:LFB
                    960:   stosw
                    961:   pop di
                    962: cirrus_vesa_01h_4:
                    963: 
                    964:   xor ax, ax
                    965:   stosw ; reserved
                    966:   stosw ; reserved
                    967:   stosw ; reserved
                    968: 
                    969:   mov ax, #0x004F
                    970:   mov di, bp
                    971:   pop bx
                    972:   pop dx
                    973:   pop cx
                    974:   pop si
                    975:   pop ds
                    976: 
                    977:   test cx, #0x4000 ;; LFB flag
                    978:   jz cirrus_vesa_01h_5
                    979:   push cx
                    980:  db 0x26 ;; es:
                    981:   mov cx, [di]
                    982:   cmp cx, #0x0080 ;; is LFB supported?
                    983:   jnz cirrus_vesa_01h_6
                    984:   mov ax, #0x014F ;; error - no LFB
                    985: cirrus_vesa_01h_6:
                    986:   pop cx
                    987: cirrus_vesa_01h_5:
                    988:   ret
                    989: 
                    990: cirrus_vesa_02h:
                    991:   ;; XXX support CRTC registers
                    992:   test bx, #0x3e00
                    993:   jnz cirrus_vesa_02h_2 ;; unknown flags
                    994:   mov ax, bx
                    995:   and ax, #0x1ff ;; bit 8-0 mode
                    996:   cmp ax, #0x100 ;; legacy VGA mode
                    997:   jb cirrus_vesa_02h_legacy
                    998:   call cirrus_vesamode_to_mode
                    999:   cmp ax, #0xffff
                   1000:   jnz cirrus_vesa_02h_1
                   1001: cirrus_vesa_02h_2:
                   1002:   jmp cirrus_vesa_unimplemented
                   1003: cirrus_vesa_02h_legacy:
                   1004: #ifdef CIRRUS_VESA3_PMINFO
                   1005:  db 0x2e ;; cs:
                   1006:   cmp byte ptr [cirrus_vesa_is_protected_mode], #0
                   1007:   jnz cirrus_vesa_02h_2
                   1008: #endif // CIRRUS_VESA3_PMINFO
                   1009:   int #0x10
                   1010:   mov ax, #0x004F
                   1011:   ret
                   1012: cirrus_vesa_02h_1:
                   1013:   push si
                   1014:   push ax
                   1015:   call cirrus_get_modeentry_nomask
                   1016:   call cirrus_switch_mode
                   1017:   test bx, #0x4000 ;; LFB
                   1018:   jnz cirrus_vesa_02h_3
                   1019:   call cirrus_enable_16k_granularity
                   1020: cirrus_vesa_02h_3:
                   1021:   test bx, #0x8000 ;; no clear
                   1022:   jnz cirrus_vesa_02h_4
                   1023:   push ax
                   1024:   xor ax,ax
                   1025:   call cirrus_clear_vram
                   1026:   pop ax
                   1027: cirrus_vesa_02h_4:
                   1028:   pop ax
                   1029:   push ds
                   1030: #ifdef CIRRUS_VESA3_PMINFO
                   1031:  db 0x2e ;; cs:
                   1032:   mov si, [cirrus_vesa_sel0000_data]
                   1033: #else
                   1034:   xor si, si
                   1035: #endif
                   1036:   mov ds, si
                   1037:   mov [PM_BIOSMEM_CURRENT_MODE], al
                   1038:   mov [PM_BIOSMEM_VBE_MODE], bx
                   1039:   pop ds
                   1040:   pop si
                   1041:   mov ax, #0x004F
                   1042:   ret
                   1043: 
                   1044: cirrus_vesa_03h:
                   1045:   push ds
                   1046: #ifdef CIRRUS_VESA3_PMINFO
                   1047:  db 0x2e ;; cs:
                   1048:   mov ax, [cirrus_vesa_sel0000_data]
                   1049: #else
                   1050:   xor ax, ax
                   1051: #endif
                   1052:   mov  ds, ax
                   1053:   mov  bx, # PM_BIOSMEM_VBE_MODE
                   1054:   mov  ax, [bx]
                   1055:   mov  bx, ax
                   1056:   test bx, bx
                   1057:   jnz   cirrus_vesa_03h_1
                   1058:   mov  bx, # PM_BIOSMEM_CURRENT_MODE
                   1059:   mov  al, [bx]
                   1060:   mov  bl, al
                   1061:   xor  bh, bh
                   1062: cirrus_vesa_03h_1:
                   1063:   mov  ax, #0x004f
                   1064:   pop  ds
                   1065:   ret
                   1066: 
                   1067: cirrus_vesa_05h_farentry:
                   1068:   call cirrus_vesa_05h
                   1069:   retf
                   1070: 
                   1071: cirrus_vesa_05h:
                   1072:   cmp bl, #0x01
                   1073:   ja cirrus_vesa_05h_1
                   1074:   cmp bh, #0x00
                   1075:   jz cirrus_vesa_05h_setmempage
                   1076:   cmp bh, #0x01
                   1077:   jz cirrus_vesa_05h_getmempage
                   1078: cirrus_vesa_05h_1:
                   1079:   jmp cirrus_vesa_unimplemented
                   1080: cirrus_vesa_05h_setmempage:
                   1081:   or dh, dh ; address must be < 0x100
                   1082:   jnz cirrus_vesa_05h_1
                   1083:   push dx
                   1084:   mov al, bl ;; bl=bank number
                   1085:   add al, #0x09
                   1086:   mov ah, dl ;; dx=window address in granularity
                   1087:   mov dx, #0x3ce
                   1088:   out dx, ax
                   1089:   pop dx
                   1090:   mov ax, #0x004F
                   1091:   ret
                   1092: cirrus_vesa_05h_getmempage:
                   1093:   mov al, bl ;; bl=bank number
                   1094:   add al, #0x09
                   1095:   mov dx, #0x3ce
                   1096:   out dx, al
                   1097:   inc dx
                   1098:   in al, dx
                   1099:   xor dx, dx
                   1100:   mov dl, al ;; dx=window address in granularity
                   1101:   mov ax, #0x004F
                   1102:   ret
                   1103: 
                   1104: cirrus_vesa_06h:
                   1105:   mov  ax, cx
                   1106:   cmp  bl, #0x01
                   1107:   je   cirrus_vesa_06h_3
                   1108:   cmp  bl, #0x02
                   1109:   je   cirrus_vesa_06h_2
                   1110:   jb   cirrus_vesa_06h_1
                   1111:   mov  ax, #0x0100
                   1112:   ret
                   1113: cirrus_vesa_06h_1:
                   1114:   call cirrus_get_bpp_bytes
                   1115:   mov  bl, al
                   1116:   xor  bh, bh
                   1117:   mov  ax, cx
                   1118:   mul  bx
                   1119: cirrus_vesa_06h_2:
                   1120:   call cirrus_set_line_offset
                   1121: cirrus_vesa_06h_3:
                   1122:   call cirrus_get_bpp_bytes
                   1123:   mov  bl, al
                   1124:   xor  bh, bh
                   1125:   xor  dx, dx
                   1126:   call cirrus_get_line_offset
                   1127:   push ax
                   1128:   div  bx
                   1129:   mov  cx, ax
                   1130:   pop  bx
                   1131:   call cirrus_extbios_85h ;; al=vram in 64k
                   1132:   xor  dx, dx
                   1133:   mov  dl, al
                   1134:   xor  ax, ax
                   1135:   div  bx
                   1136:   mov  dx, ax
                   1137:   mov  ax, #0x004f
                   1138:   ret
                   1139: 
                   1140: cirrus_vesa_07h:
                   1141:   cmp  bl, #0x80
                   1142:   je   cirrus_vesa_07h_1
                   1143:   cmp  bl, #0x01
                   1144:   je   cirrus_vesa_07h_2
                   1145:   jb   cirrus_vesa_07h_1
                   1146:   mov  ax, #0x0100
                   1147:   ret
                   1148: cirrus_vesa_07h_1:
                   1149:   push dx
                   1150:   call cirrus_get_bpp_bytes
                   1151:   mov  bl, al
                   1152:   xor  bh, bh
                   1153:   mov  ax, cx
                   1154:   mul  bx
                   1155:   pop  bx
                   1156:   push ax
                   1157:   call cirrus_get_line_offset
                   1158:   mul  bx
                   1159:   pop  bx
                   1160:   add  ax, bx
                   1161:   jnc  cirrus_vesa_07h_3
                   1162:   inc  dx
                   1163: cirrus_vesa_07h_3:
                   1164:   push dx
                   1165:   and  dx, #0x0003
                   1166:   mov  bx, #0x04
                   1167:   div  bx
                   1168:   pop  dx
                   1169:   shr  dx, #2
                   1170:   call cirrus_set_start_addr
                   1171:   mov  ax, #0x004f
                   1172:   ret
                   1173: cirrus_vesa_07h_2:
                   1174:   call cirrus_get_start_addr
                   1175:   shl  dx, #2
                   1176:   push dx
                   1177:   mov  bx, #0x04
                   1178:   mul  bx
                   1179:   pop  bx
                   1180:   or   dx, bx
                   1181:   push ax
                   1182:   call cirrus_get_line_offset
                   1183:   mov  bx, ax
                   1184:   pop  ax
                   1185:   div  bx
                   1186:   push ax
                   1187:   push dx
                   1188:   call cirrus_get_bpp_bytes
                   1189:   mov  bl, al
                   1190:   xor  bh, bh
                   1191:   pop  ax
                   1192:   xor  dx, dx
                   1193:   div  bx
                   1194:   mov  cx, ax
                   1195:   pop  dx
                   1196:   mov  ax, #0x004f
                   1197:   ret
                   1198: 
                   1199: cirrus_vesa_10h:
                   1200:   cmp bl, #0x00
                   1201:   jne cirrus_vesa_10h_01
                   1202:   mov bx, #0x0f30
                   1203:   mov ax, #0x004f
                   1204:   ret
                   1205: cirrus_vesa_10h_01:
                   1206:   cmp bl, #0x01
                   1207:   jne cirrus_vesa_10h_02
                   1208:   push dx
                   1209:   push ds
                   1210:   mov dx, #0x40
                   1211:   mov ds, dx
                   1212:   mov [0xb9], bh
                   1213:   pop ds
                   1214:   pop dx
                   1215:   mov ax, #0x004f
                   1216:   ret
                   1217: cirrus_vesa_10h_02:
                   1218:   cmp bl, #0x02
                   1219:   jne cirrus_vesa_unimplemented
                   1220:   push dx
                   1221:   push ds
                   1222:   mov dx, #0x40
                   1223:   mov ds, dx
                   1224:   mov bh, [0xb9]
                   1225:   pop ds
                   1226:   pop dx
                   1227:   mov ax, #0x004f
                   1228:   ret
                   1229: 
                   1230: cirrus_vesa_unimplemented:
                   1231:   mov ax, #0x014F ;; not implemented
                   1232:   ret
                   1233: 
                   1234: 
                   1235: ;; in ax:vesamode, out ax:cirrusmode
                   1236: cirrus_vesamode_to_mode:
                   1237:   push ds
                   1238:   push cx
                   1239:   push si
                   1240:   push cs
                   1241:   pop ds
                   1242:   mov cx, #0xffff
                   1243:   mov si, #_cirrus_vesa_modelist
                   1244: cvtm_1:
                   1245:   cmp [si],ax
                   1246:   jz cvtm_2
                   1247:   cmp [si],cx
                   1248:   jz cvtm_2
                   1249:   add si, #4
                   1250:   jmp cvtm_1
                   1251: cvtm_2:
                   1252:   mov ax,[si+2]
                   1253:   pop si
                   1254:   pop cx
                   1255:   pop ds
                   1256:   ret
                   1257: 
                   1258:   ; cirrus_get_crtc
                   1259:   ;; NOTE - may be called in protected mode
                   1260: cirrus_get_crtc:
                   1261:   push ds
                   1262:   push ax
                   1263:   mov  dx, #0x3cc
                   1264:   in   al, dx
                   1265:   and  al, #0x01
                   1266:   shl  al, #5
                   1267:   mov  dx, #0x3b4
                   1268:   add  dl, al
                   1269:   pop  ax
                   1270:   pop  ds
                   1271:   ret
                   1272: 
                   1273: ;; in - al:mode, out - cflag:result, si:table, ax:destroyed
                   1274: cirrus_get_modeentry:
                   1275:   and al, #0x7f
                   1276: cirrus_get_modeentry_nomask:
                   1277:   mov si, #_cirrus_modes
                   1278: cgm_1:
                   1279:  db 0x2e ;; cs:
                   1280:   mov ah, [si]
                   1281:   cmp al, ah
                   1282:   jz cgm_2
                   1283:   cmp ah, #0xff
                   1284:   jz cgm_4
                   1285:   add si, # CIRRUS_MODE_SIZE
                   1286:   jmp cgm_1
                   1287: cgm_4:
                   1288:   xor si, si
                   1289:   stc ;; video mode is not supported
                   1290:   jmp cgm_3
                   1291: cgm_2:
                   1292:   clc ;; video mode is supported
                   1293: cgm_3:
                   1294:   ret
                   1295: 
                   1296:   ; get LFB address
                   1297:   ; out - ax:LFB address (high 16 bit)
                   1298:   ;; NOTE - may be called in protected mode
                   1299: cirrus_get_lfb_addr:
                   1300:   push cx
                   1301:   push dx
                   1302:   push eax
                   1303:     xor cx, cx
                   1304:     mov dl, #0x00
                   1305:     call cirrus_pci_read
                   1306:     cmp ax, #0xffff
                   1307:     jz cirrus_get_lfb_addr_5
                   1308:  cirrus_get_lfb_addr_3:
                   1309:     mov dl, #0x00
                   1310:     call cirrus_pci_read
                   1311:     cmp ax, #0x1013 ;; cirrus
                   1312:     jz cirrus_get_lfb_addr_4
                   1313:     add cx, #0x8
                   1314:     cmp cx, #0x200 ;; search bus #0 and #1
                   1315:     jb cirrus_get_lfb_addr_3
                   1316:  cirrus_get_lfb_addr_5:
                   1317:     xor dx, dx ;; no LFB
                   1318:     jmp cirrus_get_lfb_addr_6
                   1319:  cirrus_get_lfb_addr_4:
                   1320:     mov dl, #0x10 ;; I/O space #0
                   1321:     call cirrus_pci_read
                   1322:     test ax, #0xfff1
                   1323:     jnz cirrus_get_lfb_addr_5
                   1324:     shr eax, #16
                   1325:     mov dx, ax ;; LFB address
                   1326:  cirrus_get_lfb_addr_6:
                   1327:   pop eax
                   1328:   mov ax, dx
                   1329:   pop dx
                   1330:   pop cx
                   1331:   ret
                   1332: 
                   1333: cirrus_pci_read:
                   1334:   mov eax, #0x00800000
                   1335:   mov ax, cx
                   1336:   shl eax, #8
                   1337:   mov al, dl
                   1338:   mov dx, #0xcf8
                   1339:   out dx, eax
                   1340:   add dl, #4
                   1341:   in  eax, dx
                   1342:   ret
                   1343: 
                   1344: ;; out - al:bytes per pixel
                   1345: cirrus_get_bpp_bytes:
                   1346:   push dx
                   1347:   mov  dx, #0x03c4
                   1348:   mov  al, #0x07
                   1349:   out  dx, al
                   1350:   inc  dx
                   1351:   in   al, dx
                   1352:   and  al, #0x0e
                   1353:   cmp  al, #0x06
                   1354:   jne  cirrus_get_bpp_bytes_1
                   1355:   and  al, #0x02
                   1356: cirrus_get_bpp_bytes_1:
                   1357:   shr  al, #1
                   1358:   cmp  al, #0x04
                   1359:   je  cirrus_get_bpp_bytes_2
                   1360:   inc  al
                   1361: cirrus_get_bpp_bytes_2:
                   1362:   pop  dx
                   1363:   ret
                   1364: 
                   1365: ;; in - ax: new line offset
                   1366: cirrus_set_line_offset:
                   1367:   shr  ax, #3
                   1368:   push ax
                   1369:   call cirrus_get_crtc
                   1370:   mov  al, #0x13
                   1371:   out  dx, al
                   1372:   inc  dx
                   1373:   pop  ax
                   1374:   out  dx, al
                   1375:   dec  dx
                   1376:   mov  al, #0x1b
                   1377:   out  dx, al
                   1378:   inc  dx
                   1379:   shl  ah, #4
                   1380:   in   al, dx
                   1381:   and  al, #ef
                   1382:   or   al, ah
                   1383:   out  dx, al
                   1384:   ret
                   1385: 
                   1386: ;; out - ax: active line offset
                   1387: cirrus_get_line_offset:
                   1388:   push dx
                   1389:   push bx
                   1390:   call cirrus_get_crtc
                   1391:   mov  al, #0x13
                   1392:   out  dx, al
                   1393:   inc  dx
                   1394:   in   al, dx
                   1395:   mov  bl, al
                   1396:   dec  dx
                   1397:   mov  al, #0x1b
                   1398:   out  dx, al
                   1399:   inc  dx
                   1400:   in   al, dx
                   1401:   mov  ah, al
                   1402:   shr  ah, #4
                   1403:   and  ah, #0x01
                   1404:   mov  al, bl
                   1405:   shl  ax, #3
                   1406:   pop  bx
                   1407:   pop  dx
                   1408:   ret
                   1409: 
                   1410: ;; in - si: table
                   1411: ;; out - ax: line offset for mode
                   1412: cirrus_get_line_offset_entry:
                   1413:   push bx
                   1414:   mov  bx, [si+14] ;; crtc table
                   1415:   push bx
                   1416: offset_loop1:
                   1417:   mov  ax, [bx]
                   1418:   cmp  al, #0x13
                   1419:   je   offset_found1
                   1420:   inc  bx
                   1421:   inc  bx
                   1422:   jnz  offset_loop1
                   1423: offset_found1:
                   1424:   xor  al, al
                   1425:   shr  ax, #5
                   1426:   pop  bx
                   1427:   push ax
                   1428: offset_loop2:
                   1429:   mov  ax, [bx]
                   1430:   cmp  al, #0x1b
                   1431:   je offset_found2
                   1432:   inc  bx
                   1433:   inc  bx
                   1434:   jnz offset_loop2
                   1435: offset_found2:
                   1436:   pop  bx
                   1437:   and  ax, #0x1000
                   1438:   shr  ax, #1
                   1439:   or   ax, bx
                   1440:   pop  bx
                   1441:   ret
                   1442: 
                   1443: ;; in - new address in DX:AX
                   1444: cirrus_set_start_addr:
                   1445:   push bx
                   1446:   push dx
                   1447:   push ax
                   1448:   call cirrus_get_crtc
                   1449:   mov  al, #0x0d
                   1450:   out  dx, al
                   1451:   inc  dx
                   1452:   pop  ax
                   1453:   out  dx, al
                   1454:   dec  dx
                   1455:   mov  al, #0x0c
                   1456:   out  dx, al
                   1457:   inc  dx
                   1458:   mov  al, ah
                   1459:   out  dx, al
                   1460:   dec  dx
                   1461:   mov  al, #0x1d
                   1462:   out  dx, al
                   1463:   inc  dx
                   1464:   in   al, dx
                   1465:   and  al, #0x7f
                   1466:   pop  bx
                   1467:   mov  ah, bl
                   1468:   shl  bl, #4
                   1469:   and  bl, #0x80
                   1470:   or   al, bl
                   1471:   out  dx, al
                   1472:   dec  dx
                   1473:   mov  bl, ah
                   1474:   and  ah, #0x01
                   1475:   shl  bl, #1
                   1476:   and  bl, #0x0c
                   1477:   or   ah, bl
                   1478:   mov  al, #0x1b
                   1479:   out  dx, al
                   1480:   inc  dx
                   1481:   in   al, dx
                   1482:   and  al, #0xf2
                   1483:   or   al, ah
                   1484:   out  dx, al
                   1485:   pop  bx
                   1486:   ret
                   1487: 
                   1488: ;; out - current address in DX:AX
                   1489: cirrus_get_start_addr:
                   1490:   push bx
                   1491:   call cirrus_get_crtc
                   1492:   mov  al, #0x0c
                   1493:   out  dx, al
                   1494:   inc  dx
                   1495:   in   al, dx
                   1496:   mov  ah, al
                   1497:   dec  dx
                   1498:   mov  al, #0x0d
                   1499:   out  dx, al
                   1500:   inc  dx
                   1501:   in   al, dx
                   1502:   push ax
                   1503:   dec  dx
                   1504:   mov  al, #0x1b
                   1505:   out  dx, al
                   1506:   inc  dx
                   1507:   in   al, dx
                   1508:   dec  dx
                   1509:   mov  bl, al
                   1510:   and  al, #0x01
                   1511:   and  bl, #0x0c
                   1512:   shr  bl, #1
                   1513:   or   bl, al
                   1514:   mov  al, #0x1d
                   1515:   out  dx, al
                   1516:   inc  dx
                   1517:   in   al, dx
                   1518:   and  al, #0x80
                   1519:   shr  al, #4
                   1520:   or   bl, al
                   1521:   mov  dl, bl
                   1522:   xor  dh, dh
                   1523:   pop  ax
                   1524:   pop  bx
                   1525:   ret
                   1526: 
                   1527: cirrus_clear_vram:
                   1528:   pusha
                   1529:   push es
                   1530:   mov si, ax
                   1531: 
                   1532:   call cirrus_enable_16k_granularity
                   1533:   call cirrus_extbios_85h
                   1534:   shl al, #2
                   1535:   mov bl, al
                   1536:   xor ah,ah
                   1537: cirrus_clear_vram_1:
                   1538:   mov al, #0x09
                   1539:   mov dx, #0x3ce
                   1540:   out dx, ax
                   1541:   push ax
                   1542:   mov cx, #0xa000
                   1543:   mov es, cx
                   1544:   xor di, di
                   1545:   mov ax, si
                   1546:   mov cx, #8192
                   1547:   cld
                   1548:   rep 
                   1549:       stosw
                   1550:   pop ax
                   1551:   inc ah
                   1552:   cmp ah, bl
                   1553:   jne cirrus_clear_vram_1
                   1554: 
                   1555:   xor ah,ah
                   1556:   mov dx, #0x3ce
                   1557:   out dx, ax
                   1558: 
                   1559:   pop es
                   1560:   popa
                   1561:   ret
                   1562: 
                   1563: cirrus_extbios_handlers:
                   1564:   ;; 80h
                   1565:   dw cirrus_extbios_80h
                   1566:   dw cirrus_extbios_81h
                   1567:   dw cirrus_extbios_82h
                   1568:   dw cirrus_extbios_unimplemented
                   1569:   ;; 84h
                   1570:   dw cirrus_extbios_unimplemented
                   1571:   dw cirrus_extbios_85h
                   1572:   dw cirrus_extbios_unimplemented
                   1573:   dw cirrus_extbios_unimplemented
                   1574:   ;; 88h
                   1575:   dw cirrus_extbios_unimplemented
                   1576:   dw cirrus_extbios_unimplemented
                   1577:   dw cirrus_extbios_unimplemented
                   1578:   dw cirrus_extbios_unimplemented
                   1579:   ;; 8Ch
                   1580:   dw cirrus_extbios_unimplemented
                   1581:   dw cirrus_extbios_unimplemented
                   1582:   dw cirrus_extbios_unimplemented
                   1583:   dw cirrus_extbios_unimplemented
                   1584:   ;; 90h
                   1585:   dw cirrus_extbios_unimplemented
                   1586:   dw cirrus_extbios_unimplemented
                   1587:   dw cirrus_extbios_unimplemented
                   1588:   dw cirrus_extbios_unimplemented
                   1589:   ;; 94h
                   1590:   dw cirrus_extbios_unimplemented
                   1591:   dw cirrus_extbios_unimplemented
                   1592:   dw cirrus_extbios_unimplemented
                   1593:   dw cirrus_extbios_unimplemented
                   1594:   ;; 98h
                   1595:   dw cirrus_extbios_unimplemented
                   1596:   dw cirrus_extbios_unimplemented
                   1597:   dw cirrus_extbios_9Ah
                   1598:   dw cirrus_extbios_unimplemented
                   1599:   ;; 9Ch
                   1600:   dw cirrus_extbios_unimplemented
                   1601:   dw cirrus_extbios_unimplemented
                   1602:   dw cirrus_extbios_unimplemented
                   1603:   dw cirrus_extbios_unimplemented
                   1604:   ;; A0h
                   1605:   dw cirrus_extbios_A0h
                   1606:   dw cirrus_extbios_A1h
                   1607:   dw cirrus_extbios_A2h
                   1608:   dw cirrus_extbios_unimplemented
                   1609:   ;; A4h
                   1610:   dw cirrus_extbios_unimplemented
                   1611:   dw cirrus_extbios_unimplemented
                   1612:   dw cirrus_extbios_unimplemented
                   1613:   dw cirrus_extbios_unimplemented
                   1614:   ;; A8h
                   1615:   dw cirrus_extbios_unimplemented
                   1616:   dw cirrus_extbios_unimplemented
                   1617:   dw cirrus_extbios_unimplemented
                   1618:   dw cirrus_extbios_unimplemented
                   1619:   ;; ACh
                   1620:   dw cirrus_extbios_unimplemented
                   1621:   dw cirrus_extbios_unimplemented
                   1622:   dw cirrus_extbios_AEh
                   1623:   dw cirrus_extbios_unimplemented
                   1624: 
                   1625: cirrus_vesa_handlers:
                   1626:   ;; 00h
                   1627:   dw cirrus_vesa_00h
                   1628:   dw cirrus_vesa_01h
                   1629:   dw cirrus_vesa_02h
                   1630:   dw cirrus_vesa_03h
                   1631:   ;; 04h
                   1632:   dw cirrus_vesa_unimplemented
                   1633:   dw cirrus_vesa_05h
                   1634:   dw cirrus_vesa_06h
                   1635:   dw cirrus_vesa_07h
                   1636:   ;; 08h
                   1637:   dw cirrus_vesa_unimplemented
                   1638:   dw cirrus_vesa_unimplemented
                   1639:   dw cirrus_vesa_unimplemented
                   1640:   dw cirrus_vesa_unimplemented
                   1641:   ;; 0Ch
                   1642:   dw cirrus_vesa_unimplemented
                   1643:   dw cirrus_vesa_unimplemented
                   1644:   dw cirrus_vesa_unimplemented
                   1645:   dw cirrus_vesa_unimplemented
                   1646:   ;; 10h
                   1647:   dw cirrus_vesa_10h
                   1648: 
                   1649: 
                   1650: ASM_END
                   1651: 
                   1652: #ifdef CIRRUS_VESA3_PMINFO
                   1653: ASM_START
                   1654: cirrus_vesa_pminfo:
                   1655:   /* + 0 */
                   1656:   .byte 0x50,0x4d,0x49,0x44 ;; signature[4]
                   1657:   /* + 4 */
                   1658:   dw cirrus_vesa_pmbios_entry ;; entry_bios
                   1659:   dw cirrus_vesa_pmbios_init  ;; entry_init
                   1660:   /* + 8 */
                   1661: cirrus_vesa_sel0000_data:
                   1662:   dw 0x0000 ;; sel_00000
                   1663: cirrus_vesa_selA000_data:
                   1664:   dw 0xA000 ;; sel_A0000
                   1665:   /* +12 */
                   1666: cirrus_vesa_selB000_data:
                   1667:   dw 0xB000 ;; sel_B0000
                   1668: cirrus_vesa_selB800_data:
                   1669:   dw 0xB800 ;; sel_B8000
                   1670:   /* +16 */
                   1671: cirrus_vesa_selC000_data:
                   1672:   dw 0xC000 ;; sel_C0000
                   1673: cirrus_vesa_is_protected_mode:
                   1674:   ;; protected mode flag and checksum
                   1675:   dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \
                   1676:      + (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01
                   1677: ASM_END
                   1678: #endif // CIRRUS_VESA3_PMINFO
                   1679: 
                   1680: 
                   1681: #ifdef CIRRUS_DEBUG
                   1682: static void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
                   1683:   Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
                   1684: {
                   1685:  if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05))
                   1686:   printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX);
                   1687: }
                   1688: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.