Annotation of qemu/roms/vgabios/clext.c, revision 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.