Annotation of qemu/roms/seabios/vgasrc/vgabios.c, revision 1.1.1.1

1.1       root        1: // VGA bios implementation
                      2: //
                      3: // Copyright (C) 2009-2012  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2001-2008 the LGPL VGABios developers Team
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "bregs.h" // struct bregs
                      9: #include "biosvar.h" // GET_BDA
                     10: #include "util.h" // memset
                     11: #include "vgabios.h" // calc_page_size
                     12: #include "optionroms.h" // struct pci_data
                     13: #include "config.h" // CONFIG_*
                     14: #include "stdvga.h" // stdvga_set_cursor_shape
                     15: #include "clext.h" // clext_1012
                     16: #include "vgahw.h" // vgahw_set_mode
                     17: #include "vbe.h" // VBE_RETURN_STATUS_FAILED
                     18: #include "pci.h" // pci_config_readw
                     19: #include "pci_regs.h" // PCI_VENDOR_ID
                     20: 
                     21: // Standard Video Save Pointer Table
                     22: struct VideoSavePointer_s {
                     23:     struct segoff_s videoparam;
                     24:     struct segoff_s paramdynamicsave;
                     25:     struct segoff_s textcharset;
                     26:     struct segoff_s graphcharset;
                     27:     struct segoff_s secsavepointer;
                     28:     u8 reserved[8];
                     29: } PACKED;
                     30: 
                     31: static struct VideoSavePointer_s video_save_pointer_table VAR16;
                     32: 
                     33: struct VideoParam_s video_param_table[29] VAR16;
                     34: 
                     35: 
                     36: /****************************************************************
                     37:  * PCI Data
                     38:  ****************************************************************/
                     39: 
                     40: struct pci_data rom_pci_data VAR16VISIBLE = {
                     41:     .signature = PCI_ROM_SIGNATURE,
                     42:     .vendor = CONFIG_VGA_VID,
                     43:     .device = CONFIG_VGA_DID,
                     44:     .dlen = 0x18,
                     45:     .class_hi = 0x300,
                     46:     .irevision = 1,
                     47:     .type = PCIROM_CODETYPE_X86,
                     48:     .indicator = 0x80,
                     49: };
                     50: 
                     51: 
                     52: /****************************************************************
                     53:  * Helper functions
                     54:  ****************************************************************/
                     55: 
                     56: // Return the bits per pixel in system memory for a given mode.
                     57: int
                     58: vga_bpp(struct vgamode_s *vmode_g)
                     59: {
                     60:     switch (GET_GLOBAL(vmode_g->memmodel)) {
                     61:     case MM_TEXT:
                     62:         return 16;
                     63:     case MM_PLANAR:
                     64:         return 1;
                     65:     }
                     66:     u8 depth = GET_GLOBAL(vmode_g->depth);
                     67:     if (depth > 8)
                     68:         return ALIGN(depth, 8);
                     69:     return depth;
                     70: }
                     71: 
                     72: u16
                     73: calc_page_size(u8 memmodel, u16 width, u16 height)
                     74: {
                     75:     switch (memmodel) {
                     76:     case MM_TEXT:
                     77:         return ALIGN(width * height * 2, 2*1024);
                     78:     case MM_CGA:
                     79:         return 16*1024;
                     80:     default:
                     81:         return ALIGN(width * height / 8, 8*1024);
                     82:     }
                     83: }
                     84: 
                     85: static void
                     86: set_cursor_shape(u8 start, u8 end)
                     87: {
                     88:     start &= 0x3f;
                     89:     end &= 0x1f;
                     90: 
                     91:     u16 curs = (start << 8) + end;
                     92:     SET_BDA(cursor_type, curs);
                     93: 
                     94:     u8 modeset_ctl = GET_BDA(modeset_ctl);
                     95:     u16 cheight = GET_BDA(char_height);
                     96:     if ((modeset_ctl & 0x01) && (cheight > 8) && (end < 8) && (start < 0x20)) {
                     97:         if (end != (start + 1))
                     98:             start = ((start + 1) * cheight / 8) - 1;
                     99:         else
                    100:             start = ((end + 1) * cheight / 8) - 2;
                    101:         end = ((end + 1) * cheight / 8) - 1;
                    102:     }
                    103:     stdvga_set_cursor_shape(start, end);
                    104: }
                    105: 
                    106: static u16
                    107: get_cursor_shape(u8 page)
                    108: {
                    109:     if (page > 7)
                    110:         return 0;
                    111:     // FIXME should handle VGA 14/16 lines
                    112:     return GET_BDA(cursor_type);
                    113: }
                    114: 
                    115: static void
                    116: set_cursor_pos(struct cursorpos cp)
                    117: {
                    118:     u8 page = cp.page, x = cp.x, y = cp.y;
                    119: 
                    120:     // Should not happen...
                    121:     if (page > 7)
                    122:         return;
                    123: 
                    124:     // Bios cursor pos
                    125:     SET_BDA(cursor_pos[page], (y << 8) | x);
                    126: 
                    127:     // Set the hardware cursor
                    128:     u8 current = GET_BDA(video_page);
                    129:     if (cp.page != current)
                    130:         return;
                    131: 
                    132:     // Calculate the memory address
                    133:     int address = (GET_BDA(video_pagesize) * page
                    134:                    + (x + y * GET_BDA(video_cols)) * 2);
                    135:     stdvga_set_cursor_pos(address);
                    136: }
                    137: 
                    138: static struct cursorpos
                    139: get_cursor_pos(u8 page)
                    140: {
                    141:     if (page == 0xff)
                    142:         // special case - use current page
                    143:         page = GET_BDA(video_page);
                    144:     if (page > 7) {
                    145:         struct cursorpos cp = { 0, 0, 0xfe };
                    146:         return cp;
                    147:     }
                    148:     // FIXME should handle VGA 14/16 lines
                    149:     u16 xy = GET_BDA(cursor_pos[page]);
                    150:     struct cursorpos cp = {xy, xy>>8, page};
                    151:     return cp;
                    152: }
                    153: 
                    154: static void
                    155: set_active_page(u8 page)
                    156: {
                    157:     if (page > 7)
                    158:         return;
                    159: 
                    160:     // Get the mode
                    161:     struct vgamode_s *vmode_g = get_current_mode();
                    162:     if (!vmode_g)
                    163:         return;
                    164: 
                    165:     // Get cursor pos for the given page
                    166:     struct cursorpos cp = get_cursor_pos(page);
                    167: 
                    168:     // Calculate memory address of start of page
                    169:     int address = GET_BDA(video_pagesize) * page;
                    170:     vgahw_set_displaystart(vmode_g, address);
                    171: 
                    172:     // And change the BIOS page
                    173:     SET_BDA(video_pagestart, address);
                    174:     SET_BDA(video_page, page);
                    175: 
                    176:     dprintf(1, "Set active page %02x address %04x\n", page, address);
                    177: 
                    178:     // Display the cursor, now the page is active
                    179:     set_cursor_pos(cp);
                    180: }
                    181: 
                    182: static void
                    183: set_scan_lines(u8 lines)
                    184: {
                    185:     stdvga_set_scan_lines(lines);
                    186:     if (lines == 8)
                    187:         set_cursor_shape(0x06, 0x07);
                    188:     else
                    189:         set_cursor_shape(lines - 4, lines - 3);
                    190:     SET_BDA(char_height, lines);
                    191:     u16 vde = stdvga_get_vde();
                    192:     u8 rows = vde / lines;
                    193:     SET_BDA(video_rows, rows - 1);
                    194:     u16 cols = GET_BDA(video_cols);
                    195:     SET_BDA(video_pagesize, calc_page_size(MM_TEXT, cols, rows));
                    196: }
                    197: 
                    198: 
                    199: /****************************************************************
                    200:  * Character writing
                    201:  ****************************************************************/
                    202: 
                    203: // Scroll the screen one line.  This function is designed to be called
                    204: // tail-recursive to reduce stack usage.
                    205: static void noinline
                    206: scroll_one(u16 nbrows, u16 nbcols, u8 page)
                    207: {
                    208:     struct cursorpos ul = {0, 0, page};
                    209:     struct cursorpos lr = {nbcols-1, nbrows-1, page};
                    210:     vgafb_scroll(1, -1, ul, lr);
                    211: }
                    212: 
                    213: // Write a character to the screen at a given position.  Implement
                    214: // special characters and scroll the screen if necessary.
                    215: static void
                    216: write_teletype(struct cursorpos *pcp, struct carattr ca)
                    217: {
                    218:     struct cursorpos cp = *pcp;
                    219: 
                    220:     // Get the dimensions
                    221:     u16 nbrows = GET_BDA(video_rows) + 1;
                    222:     u16 nbcols = GET_BDA(video_cols);
                    223: 
                    224:     switch (ca.car) {
                    225:     case 7:
                    226:         //FIXME should beep
                    227:         break;
                    228:     case 8:
                    229:         if (cp.x > 0)
                    230:             cp.x--;
                    231:         break;
                    232:     case '\r':
                    233:         cp.x = 0;
                    234:         break;
                    235:     case '\n':
                    236:         cp.y++;
                    237:         break;
                    238:     case '\t':
                    239:         ca.car = ' ';
                    240:         do {
                    241:             vgafb_write_char(cp, ca);
                    242:             cp.x++;
                    243:         } while (cp.x < nbcols && cp.x % 8);
                    244:         break;
                    245:     default:
                    246:         vgafb_write_char(cp, ca);
                    247:         cp.x++;
                    248:     }
                    249: 
                    250:     // Do we need to wrap ?
                    251:     if (cp.x == nbcols) {
                    252:         cp.x = 0;
                    253:         cp.y++;
                    254:     }
                    255:     // Do we need to scroll ?
                    256:     if (cp.y < nbrows) {
                    257:         *pcp = cp;
                    258:         return;
                    259:     }
                    260:     // Scroll screen
                    261:     cp.y--;
                    262:     *pcp = cp;
                    263:     scroll_one(nbrows, nbcols, cp.page);
                    264: }
                    265: 
                    266: 
                    267: /****************************************************************
                    268:  * Save and restore bda state
                    269:  ****************************************************************/
                    270: 
                    271: void
                    272: save_bda_state(u16 seg, struct saveBDAstate *info)
                    273: {
                    274:     SET_FARVAR(seg, info->video_mode, GET_BDA(vbe_mode));
                    275:     SET_FARVAR(seg, info->video_cols, GET_BDA(video_cols));
                    276:     SET_FARVAR(seg, info->video_pagesize, GET_BDA(video_pagesize));
                    277:     SET_FARVAR(seg, info->crtc_address, GET_BDA(crtc_address));
                    278:     SET_FARVAR(seg, info->video_rows, GET_BDA(video_rows));
                    279:     SET_FARVAR(seg, info->char_height, GET_BDA(char_height));
                    280:     SET_FARVAR(seg, info->video_ctl, GET_BDA(video_ctl));
                    281:     SET_FARVAR(seg, info->video_switches, GET_BDA(video_switches));
                    282:     SET_FARVAR(seg, info->modeset_ctl, GET_BDA(modeset_ctl));
                    283:     SET_FARVAR(seg, info->cursor_type, GET_BDA(cursor_type));
                    284:     int i;
                    285:     for (i=0; i<8; i++)
                    286:         SET_FARVAR(seg, info->cursor_pos[i], GET_BDA(cursor_pos[i]));
                    287:     SET_FARVAR(seg, info->video_pagestart, GET_BDA(video_pagestart));
                    288:     SET_FARVAR(seg, info->video_page, GET_BDA(video_page));
                    289:     /* current font */
                    290:     SET_FARVAR(seg, info->font0, GET_IVT(0x1f));
                    291:     SET_FARVAR(seg, info->font1, GET_IVT(0x43));
                    292: }
                    293: 
                    294: void
                    295: restore_bda_state(u16 seg, struct saveBDAstate *info)
                    296: {
                    297:     u16 mode = GET_FARVAR(seg, info->video_mode);
                    298:     SET_BDA(vbe_mode, mode);
                    299:     if (mode < 0x100)
                    300:         SET_BDA(video_mode, mode);
                    301:     else
                    302:         SET_BDA(video_mode, 0xff);
                    303:     SET_BDA(video_cols, GET_FARVAR(seg, info->video_cols));
                    304:     SET_BDA(video_pagesize, GET_FARVAR(seg, info->video_pagesize));
                    305:     SET_BDA(crtc_address, GET_FARVAR(seg, info->crtc_address));
                    306:     SET_BDA(video_rows, GET_FARVAR(seg, info->video_rows));
                    307:     SET_BDA(char_height, GET_FARVAR(seg, info->char_height));
                    308:     SET_BDA(video_ctl, GET_FARVAR(seg, info->video_ctl));
                    309:     SET_BDA(video_switches, GET_FARVAR(seg, info->video_switches));
                    310:     SET_BDA(modeset_ctl, GET_FARVAR(seg, info->modeset_ctl));
                    311:     SET_BDA(cursor_type, GET_FARVAR(seg, info->cursor_type));
                    312:     int i;
                    313:     for (i = 0; i < 8; i++)
                    314:         SET_BDA(cursor_pos[i], GET_FARVAR(seg, info->cursor_pos[i]));
                    315:     SET_BDA(video_pagestart, GET_FARVAR(seg, info->video_pagestart));
                    316:     SET_BDA(video_page, GET_FARVAR(seg, info->video_page));
                    317:     /* current font */
                    318:     SET_IVT(0x1f, GET_FARVAR(seg, info->font0));
                    319:     SET_IVT(0x43, GET_FARVAR(seg, info->font1));
                    320: }
                    321: 
                    322: 
                    323: /****************************************************************
                    324:  * Mode setting
                    325:  ****************************************************************/
                    326: 
                    327: struct vgamode_s *
                    328: get_current_mode(void)
                    329: {
                    330:     return vgahw_find_mode(GET_BDA(vbe_mode) & ~MF_VBEFLAGS);
                    331: }
                    332: 
                    333: // Setup BDA after a mode switch.
                    334: int
                    335: vga_set_mode(int mode, int flags)
                    336: {
                    337:     dprintf(1, "set VGA mode %x\n", mode);
                    338:     struct vgamode_s *vmode_g = vgahw_find_mode(mode);
                    339:     if (!vmode_g)
                    340:         return VBE_RETURN_STATUS_FAILED;
                    341: 
                    342:     int ret = vgahw_set_mode(vmode_g, flags);
                    343:     if (ret)
                    344:         return ret;
                    345: 
                    346:     // Set the BIOS mem
                    347:     int width = GET_GLOBAL(vmode_g->width);
                    348:     int height = GET_GLOBAL(vmode_g->height);
                    349:     u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
                    350:     int cheight = GET_GLOBAL(vmode_g->cheight);
                    351:     if (mode < 0x100)
                    352:         SET_BDA(video_mode, mode);
                    353:     else
                    354:         SET_BDA(video_mode, 0xff);
                    355:     SET_BDA(vbe_mode, mode | (flags & MF_VBEFLAGS));
                    356:     if (memmodel == MM_TEXT) {
                    357:         SET_BDA(video_cols, width);
                    358:         SET_BDA(video_rows, height-1);
                    359:         SET_BDA(cursor_type, 0x0607);
                    360:     } else {
                    361:         int cwidth = GET_GLOBAL(vmode_g->cwidth);
                    362:         SET_BDA(video_cols, width / cwidth);
                    363:         SET_BDA(video_rows, (height / cheight) - 1);
                    364:         SET_BDA(cursor_type, 0x0000);
                    365:     }
                    366:     SET_BDA(video_pagesize, calc_page_size(memmodel, width, height));
                    367:     SET_BDA(crtc_address, stdvga_get_crtc());
                    368:     SET_BDA(char_height, cheight);
                    369:     SET_BDA(video_ctl, 0x60 | (flags & MF_NOCLEARMEM ? 0x80 : 0x00));
                    370:     SET_BDA(video_switches, 0xF9);
                    371:     SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f);
                    372:     int i;
                    373:     for (i=0; i<8; i++)
                    374:         SET_BDA(cursor_pos[i], 0x0000);
                    375:     SET_BDA(video_pagestart, 0x0000);
                    376:     SET_BDA(video_page, 0x00);
                    377: 
                    378:     // FIXME We nearly have the good tables. to be reworked
                    379:     SET_BDA(dcc_index, 0x08);   // 8 is VGA should be ok for now
                    380:     SET_BDA(video_savetable
                    381:             , SEGOFF(get_global_seg(), (u32)&video_save_pointer_table));
                    382: 
                    383:     // FIXME
                    384:     SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
                    385:     SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
                    386: 
                    387:     // Set the ints 0x1F and 0x43
                    388:     SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8]));
                    389: 
                    390:     switch (cheight) {
                    391:     case 8:
                    392:         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8));
                    393:         break;
                    394:     case 14:
                    395:         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14));
                    396:         break;
                    397:     case 16:
                    398:         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
                    399:         break;
                    400:     }
                    401: 
                    402:     return 0;
                    403: }
                    404: 
                    405: 
                    406: /****************************************************************
                    407:  * VGA int 10 handler
                    408:  ****************************************************************/
                    409: 
                    410: static void
                    411: handle_1000(struct bregs *regs)
                    412: {
                    413:     int mode = regs->al & 0x7f;
                    414: 
                    415:     // Set regs->al
                    416:     if (mode > 7)
                    417:         regs->al = 0x20;
                    418:     else if (mode == 6)
                    419:         regs->al = 0x3f;
                    420:     else
                    421:         regs->al = 0x30;
                    422: 
                    423:     int flags = GET_BDA(modeset_ctl) & (MF_NOPALETTE|MF_GRAYSUM);
                    424:     if (regs->al & 0x80)
                    425:         flags |= MF_NOCLEARMEM;
                    426: 
                    427:     vga_set_mode(mode, flags);
                    428: }
                    429: 
                    430: static void
                    431: handle_1001(struct bregs *regs)
                    432: {
                    433:     set_cursor_shape(regs->ch, regs->cl);
                    434: }
                    435: 
                    436: static void
                    437: handle_1002(struct bregs *regs)
                    438: {
                    439:     struct cursorpos cp = {regs->dl, regs->dh, regs->bh};
                    440:     set_cursor_pos(cp);
                    441: }
                    442: 
                    443: static void
                    444: handle_1003(struct bregs *regs)
                    445: {
                    446:     regs->cx = get_cursor_shape(regs->bh);
                    447:     struct cursorpos cp = get_cursor_pos(regs->bh);
                    448:     regs->dl = cp.x;
                    449:     regs->dh = cp.y;
                    450: }
                    451: 
                    452: // Read light pen pos (unimplemented)
                    453: static void
                    454: handle_1004(struct bregs *regs)
                    455: {
                    456:     debug_stub(regs);
                    457:     regs->ax = regs->bx = regs->cx = regs->dx = 0;
                    458: }
                    459: 
                    460: static void
                    461: handle_1005(struct bregs *regs)
                    462: {
                    463:     set_active_page(regs->al);
                    464: }
                    465: 
                    466: static void
                    467: verify_scroll(struct bregs *regs, int dir)
                    468: {
                    469:     u8 ulx = regs->cl, uly = regs->ch, lrx = regs->dl, lry = regs->dh;
                    470:     u16 nbrows = GET_BDA(video_rows) + 1;
                    471:     if (lry >= nbrows)
                    472:         lry = nbrows - 1;
                    473:     u16 nbcols = GET_BDA(video_cols);
                    474:     if (lrx >= nbcols)
                    475:         lrx = nbcols - 1;
                    476: 
                    477:     if (ulx > lrx || uly > lry)
                    478:         return;
                    479: 
                    480:     int nblines = regs->al;
                    481:     if (!nblines || nblines > lry - uly + 1)
                    482:         nblines = lry - uly + 1;
                    483: 
                    484:     u8 page = GET_BDA(video_page);
                    485:     struct cursorpos ul = {ulx, uly, page};
                    486:     struct cursorpos lr = {lrx, lry, page};
                    487:     vgafb_scroll(dir * nblines, regs->bh, ul, lr);
                    488: }
                    489: 
                    490: static void
                    491: handle_1006(struct bregs *regs)
                    492: {
                    493:     verify_scroll(regs, 1);
                    494: }
                    495: 
                    496: static void
                    497: handle_1007(struct bregs *regs)
                    498: {
                    499:     verify_scroll(regs, -1);
                    500: }
                    501: 
                    502: static void
                    503: handle_1008(struct bregs *regs)
                    504: {
                    505:     struct carattr ca = vgafb_read_char(get_cursor_pos(regs->bh));
                    506:     regs->al = ca.car;
                    507:     regs->ah = ca.attr;
                    508: }
                    509: 
                    510: static void noinline
                    511: write_chars(u8 page, struct carattr ca, u16 count)
                    512: {
                    513:     u16 nbcols = GET_BDA(video_cols);
                    514:     struct cursorpos cp = get_cursor_pos(page);
                    515:     while (count--) {
                    516:         vgafb_write_char(cp, ca);
                    517:         cp.x++;
                    518:         if (cp.x >= nbcols) {
                    519:             cp.x -= nbcols;
                    520:             cp.y++;
                    521:         }
                    522:     }
                    523: }
                    524: 
                    525: static void
                    526: handle_1009(struct bregs *regs)
                    527: {
                    528:     struct carattr ca = {regs->al, regs->bl, 1};
                    529:     write_chars(regs->bh, ca, regs->cx);
                    530: }
                    531: 
                    532: static void
                    533: handle_100a(struct bregs *regs)
                    534: {
                    535:     struct carattr ca = {regs->al, regs->bl, 0};
                    536:     write_chars(regs->bh, ca, regs->cx);
                    537: }
                    538: 
                    539: 
                    540: static void
                    541: handle_100b00(struct bregs *regs)
                    542: {
                    543:     stdvga_set_border_color(regs->bl);
                    544: }
                    545: 
                    546: static void
                    547: handle_100b01(struct bregs *regs)
                    548: {
                    549:     stdvga_set_palette(regs->bl);
                    550: }
                    551: 
                    552: static void
                    553: handle_100bXX(struct bregs *regs)
                    554: {
                    555:     debug_stub(regs);
                    556: }
                    557: 
                    558: static void
                    559: handle_100b(struct bregs *regs)
                    560: {
                    561:     switch (regs->bh) {
                    562:     case 0x00: handle_100b00(regs); break;
                    563:     case 0x01: handle_100b01(regs); break;
                    564:     default:   handle_100bXX(regs); break;
                    565:     }
                    566: }
                    567: 
                    568: 
                    569: static void
                    570: handle_100c(struct bregs *regs)
                    571: {
                    572:     // XXX - page (regs->bh) is unused
                    573:     vgafb_write_pixel(regs->al, regs->cx, regs->dx);
                    574: }
                    575: 
                    576: static void
                    577: handle_100d(struct bregs *regs)
                    578: {
                    579:     // XXX - page (regs->bh) is unused
                    580:     regs->al = vgafb_read_pixel(regs->cx, regs->dx);
                    581: }
                    582: 
                    583: static void noinline
                    584: handle_100e(struct bregs *regs)
                    585: {
                    586:     // Ralf Brown Interrupt list is WRONG on bh(page)
                    587:     // We do output only on the current page !
                    588:     struct carattr ca = {regs->al, regs->bl, 0};
                    589:     struct cursorpos cp = get_cursor_pos(0xff);
                    590:     write_teletype(&cp, ca);
                    591:     set_cursor_pos(cp);
                    592: }
                    593: 
                    594: static void
                    595: handle_100f(struct bregs *regs)
                    596: {
                    597:     regs->bh = GET_BDA(video_page);
                    598:     regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80);
                    599:     regs->ah = GET_BDA(video_cols);
                    600: }
                    601: 
                    602: 
                    603: static void
                    604: handle_101000(struct bregs *regs)
                    605: {
                    606:     if (regs->bl > 0x14)
                    607:         return;
                    608:     stdvga_attr_write(regs->bl, regs->bh);
                    609: }
                    610: 
                    611: static void
                    612: handle_101001(struct bregs *regs)
                    613: {
                    614:     stdvga_set_overscan_border_color(regs->bh);
                    615: }
                    616: 
                    617: static void
                    618: handle_101002(struct bregs *regs)
                    619: {
                    620:     stdvga_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0));
                    621: }
                    622: 
                    623: static void
                    624: handle_101003(struct bregs *regs)
                    625: {
                    626:     stdvga_toggle_intensity(regs->bl);
                    627: }
                    628: 
                    629: static void
                    630: handle_101007(struct bregs *regs)
                    631: {
                    632:     if (regs->bl > 0x14)
                    633:         return;
                    634:     regs->bh = stdvga_attr_read(regs->bl);
                    635: }
                    636: 
                    637: static void
                    638: handle_101008(struct bregs *regs)
                    639: {
                    640:     regs->bh = stdvga_get_overscan_border_color();
                    641: }
                    642: 
                    643: static void
                    644: handle_101009(struct bregs *regs)
                    645: {
                    646:     stdvga_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0));
                    647: }
                    648: 
                    649: static void noinline
                    650: handle_101010(struct bregs *regs)
                    651: {
                    652:     u8 rgb[3] = {regs->dh, regs->ch, regs->cl};
                    653:     stdvga_dac_write(GET_SEG(SS), rgb, regs->bx, 1);
                    654: }
                    655: 
                    656: static void
                    657: handle_101012(struct bregs *regs)
                    658: {
                    659:     stdvga_dac_write(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
                    660: }
                    661: 
                    662: static void
                    663: handle_101013(struct bregs *regs)
                    664: {
                    665:     stdvga_select_video_dac_color_page(regs->bl, regs->bh);
                    666: }
                    667: 
                    668: static void noinline
                    669: handle_101015(struct bregs *regs)
                    670: {
                    671:     u8 rgb[3];
                    672:     stdvga_dac_read(GET_SEG(SS), rgb, regs->bx, 1);
                    673:     regs->dh = rgb[0];
                    674:     regs->ch = rgb[1];
                    675:     regs->cl = rgb[2];
                    676: }
                    677: 
                    678: static void
                    679: handle_101017(struct bregs *regs)
                    680: {
                    681:     stdvga_dac_read(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
                    682: }
                    683: 
                    684: static void
                    685: handle_101018(struct bregs *regs)
                    686: {
                    687:     stdvga_pelmask_write(regs->bl);
                    688: }
                    689: 
                    690: static void
                    691: handle_101019(struct bregs *regs)
                    692: {
                    693:     regs->bl = stdvga_pelmask_read();
                    694: }
                    695: 
                    696: static void
                    697: handle_10101a(struct bregs *regs)
                    698: {
                    699:     stdvga_read_video_dac_state(&regs->bl, &regs->bh);
                    700: }
                    701: 
                    702: static void
                    703: handle_10101b(struct bregs *regs)
                    704: {
                    705:     stdvga_perform_gray_scale_summing(regs->bx, regs->cx);
                    706: }
                    707: 
                    708: static void
                    709: handle_1010XX(struct bregs *regs)
                    710: {
                    711:     debug_stub(regs);
                    712: }
                    713: 
                    714: static void
                    715: handle_1010(struct bregs *regs)
                    716: {
                    717:     switch (regs->al) {
                    718:     case 0x00: handle_101000(regs); break;
                    719:     case 0x01: handle_101001(regs); break;
                    720:     case 0x02: handle_101002(regs); break;
                    721:     case 0x03: handle_101003(regs); break;
                    722:     case 0x07: handle_101007(regs); break;
                    723:     case 0x08: handle_101008(regs); break;
                    724:     case 0x09: handle_101009(regs); break;
                    725:     case 0x10: handle_101010(regs); break;
                    726:     case 0x12: handle_101012(regs); break;
                    727:     case 0x13: handle_101013(regs); break;
                    728:     case 0x15: handle_101015(regs); break;
                    729:     case 0x17: handle_101017(regs); break;
                    730:     case 0x18: handle_101018(regs); break;
                    731:     case 0x19: handle_101019(regs); break;
                    732:     case 0x1a: handle_10101a(regs); break;
                    733:     case 0x1b: handle_10101b(regs); break;
                    734:     default:   handle_1010XX(regs); break;
                    735:     }
                    736: }
                    737: 
                    738: 
                    739: static void
                    740: handle_101100(struct bregs *regs)
                    741: {
                    742:     stdvga_load_font(regs->es, (void*)(regs->bp+0), regs->cx
                    743:                      , regs->dx, regs->bl, regs->bh);
                    744: }
                    745: 
                    746: static void
                    747: handle_101101(struct bregs *regs)
                    748: {
                    749:     stdvga_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14);
                    750: }
                    751: 
                    752: static void
                    753: handle_101102(struct bregs *regs)
                    754: {
                    755:     stdvga_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8);
                    756: }
                    757: 
                    758: static void
                    759: handle_101103(struct bregs *regs)
                    760: {
                    761:     stdvga_set_text_block_specifier(regs->bl);
                    762: }
                    763: 
                    764: static void
                    765: handle_101104(struct bregs *regs)
                    766: {
                    767:     stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16);
                    768: }
                    769: 
                    770: static void
                    771: handle_101110(struct bregs *regs)
                    772: {
                    773:     stdvga_load_font(regs->es, (void*)(regs->bp+0), regs->cx
                    774:                      , regs->dx, regs->bl, regs->bh);
                    775:     set_scan_lines(regs->bh);
                    776: }
                    777: 
                    778: static void
                    779: handle_101111(struct bregs *regs)
                    780: {
                    781:     stdvga_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14);
                    782:     set_scan_lines(14);
                    783: }
                    784: 
                    785: static void
                    786: handle_101112(struct bregs *regs)
                    787: {
                    788:     stdvga_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8);
                    789:     set_scan_lines(8);
                    790: }
                    791: 
                    792: static void
                    793: handle_101114(struct bregs *regs)
                    794: {
                    795:     stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16);
                    796:     set_scan_lines(16);
                    797: }
                    798: 
                    799: static void
                    800: handle_101130(struct bregs *regs)
                    801: {
                    802:     switch (regs->bh) {
                    803:     case 0x00: {
                    804:         struct segoff_s so = GET_IVT(0x1f);
                    805:         regs->es = so.seg;
                    806:         regs->bp = so.offset;
                    807:         break;
                    808:     }
                    809:     case 0x01: {
                    810:         struct segoff_s so = GET_IVT(0x43);
                    811:         regs->es = so.seg;
                    812:         regs->bp = so.offset;
                    813:         break;
                    814:     }
                    815:     case 0x02:
                    816:         regs->es = get_global_seg();
                    817:         regs->bp = (u32)vgafont14;
                    818:         break;
                    819:     case 0x03:
                    820:         regs->es = get_global_seg();
                    821:         regs->bp = (u32)vgafont8;
                    822:         break;
                    823:     case 0x04:
                    824:         regs->es = get_global_seg();
                    825:         regs->bp = (u32)vgafont8 + 128 * 8;
                    826:         break;
                    827:     case 0x05:
                    828:         regs->es = get_global_seg();
                    829:         regs->bp = (u32)vgafont14alt;
                    830:         break;
                    831:     case 0x06:
                    832:         regs->es = get_global_seg();
                    833:         regs->bp = (u32)vgafont16;
                    834:         break;
                    835:     case 0x07:
                    836:         regs->es = get_global_seg();
                    837:         regs->bp = (u32)vgafont16alt;
                    838:         break;
                    839:     default:
                    840:         dprintf(1, "Get font info BH(%02x) was discarded\n", regs->bh);
                    841:         return;
                    842:     }
                    843:     // Set byte/char of on screen font
                    844:     regs->cx = GET_BDA(char_height) & 0xff;
                    845: 
                    846:     // Set Highest char row
                    847:     regs->dl = GET_BDA(video_rows);
                    848: }
                    849: 
                    850: static void
                    851: handle_1011XX(struct bregs *regs)
                    852: {
                    853:     debug_stub(regs);
                    854: }
                    855: 
                    856: static void
                    857: handle_1011(struct bregs *regs)
                    858: {
                    859:     switch (regs->al) {
                    860:     case 0x00: handle_101100(regs); break;
                    861:     case 0x01: handle_101101(regs); break;
                    862:     case 0x02: handle_101102(regs); break;
                    863:     case 0x03: handle_101103(regs); break;
                    864:     case 0x04: handle_101104(regs); break;
                    865:     case 0x10: handle_101110(regs); break;
                    866:     case 0x11: handle_101111(regs); break;
                    867:     case 0x12: handle_101112(regs); break;
                    868:     case 0x14: handle_101114(regs); break;
                    869:     case 0x30: handle_101130(regs); break;
                    870:     default:   handle_1011XX(regs); break;
                    871:     }
                    872: }
                    873: 
                    874: 
                    875: static void
                    876: handle_101210(struct bregs *regs)
                    877: {
                    878:     u16 crtc_addr = GET_BDA(crtc_address);
                    879:     if (crtc_addr == VGAREG_MDA_CRTC_ADDRESS)
                    880:         regs->bx = 0x0103;
                    881:     else
                    882:         regs->bx = 0x0003;
                    883:     regs->cx = GET_BDA(video_switches) & 0x0f;
                    884: }
                    885: 
                    886: static void
                    887: handle_101230(struct bregs *regs)
                    888: {
                    889:     u8 mctl = GET_BDA(modeset_ctl);
                    890:     u8 vswt = GET_BDA(video_switches);
                    891:     switch (regs->al) {
                    892:     case 0x00:
                    893:         // 200 lines
                    894:         mctl = (mctl & ~0x10) | 0x80;
                    895:         vswt = (vswt & ~0x0f) | 0x08;
                    896:         break;
                    897:     case 0x01:
                    898:         // 350 lines
                    899:         mctl &= ~0x90;
                    900:         vswt = (vswt & ~0x0f) | 0x09;
                    901:         break;
                    902:     case 0x02:
                    903:         // 400 lines
                    904:         mctl = (mctl & ~0x80) | 0x10;
                    905:         vswt = (vswt & ~0x0f) | 0x09;
                    906:         break;
                    907:     default:
                    908:         dprintf(1, "Select vert res (%02x) was discarded\n", regs->al);
                    909:         break;
                    910:     }
                    911:     SET_BDA(modeset_ctl, mctl);
                    912:     SET_BDA(video_switches, vswt);
                    913:     regs->al = 0x12;
                    914: }
                    915: 
                    916: static void
                    917: handle_101231(struct bregs *regs)
                    918: {
                    919:     u8 v = (regs->al & 0x01) << 3;
                    920:     u8 mctl = GET_BDA(video_ctl) & ~0x08;
                    921:     SET_BDA(video_ctl, mctl | v);
                    922:     regs->al = 0x12;
                    923: }
                    924: 
                    925: static void
                    926: handle_101232(struct bregs *regs)
                    927: {
                    928:     stdvga_enable_video_addressing(regs->al);
                    929:     regs->al = 0x12;
                    930: }
                    931: 
                    932: static void
                    933: handle_101233(struct bregs *regs)
                    934: {
                    935:     u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
                    936:     u8 v2 = GET_BDA(modeset_ctl) & ~0x02;
                    937:     SET_BDA(modeset_ctl, v | v2);
                    938:     regs->al = 0x12;
                    939: }
                    940: 
                    941: static void
                    942: handle_101234(struct bregs *regs)
                    943: {
                    944:     u8 v = (regs->al & 0x01) ^ 0x01;
                    945:     u8 v2 = GET_BDA(modeset_ctl) & ~0x01;
                    946:     SET_BDA(modeset_ctl, v | v2);
                    947:     regs->al = 0x12;
                    948: }
                    949: 
                    950: static void
                    951: handle_101235(struct bregs *regs)
                    952: {
                    953:     debug_stub(regs);
                    954:     regs->al = 0x12;
                    955: }
                    956: 
                    957: static void
                    958: handle_101236(struct bregs *regs)
                    959: {
                    960:     debug_stub(regs);
                    961:     regs->al = 0x12;
                    962: }
                    963: 
                    964: static void
                    965: handle_1012XX(struct bregs *regs)
                    966: {
                    967:     debug_stub(regs);
                    968: }
                    969: 
                    970: static void
                    971: handle_1012(struct bregs *regs)
                    972: {
                    973:     if (CONFIG_VGA_CIRRUS && regs->bl >= 0x80) {
                    974:         clext_1012(regs);
                    975:         return;
                    976:     }
                    977: 
                    978:     switch (regs->bl) {
                    979:     case 0x10: handle_101210(regs); break;
                    980:     case 0x30: handle_101230(regs); break;
                    981:     case 0x31: handle_101231(regs); break;
                    982:     case 0x32: handle_101232(regs); break;
                    983:     case 0x33: handle_101233(regs); break;
                    984:     case 0x34: handle_101234(regs); break;
                    985:     case 0x35: handle_101235(regs); break;
                    986:     case 0x36: handle_101236(regs); break;
                    987:     default:   handle_1012XX(regs); break;
                    988:     }
                    989: }
                    990: 
                    991: 
                    992: // Write string
                    993: static void noinline
                    994: handle_1013(struct bregs *regs)
                    995: {
                    996:     struct cursorpos cp;
                    997:     if (regs->dh == 0xff)
                    998:         // if row=0xff special case : use current cursor position
                    999:         cp = get_cursor_pos(regs->bh);
                   1000:     else
                   1001:         cp = (struct cursorpos) {regs->dl, regs->dh, regs->bh};
                   1002: 
                   1003:     u16 count = regs->cx;
                   1004:     u8 *offset_far = (void*)(regs->bp + 0);
                   1005:     u8 attr = regs->bl;
                   1006:     while (count--) {
                   1007:         u8 car = GET_FARVAR(regs->es, *offset_far);
                   1008:         offset_far++;
                   1009:         if (regs->al & 2) {
                   1010:             attr = GET_FARVAR(regs->es, *offset_far);
                   1011:             offset_far++;
                   1012:         }
                   1013: 
                   1014:         struct carattr ca = {car, attr, 1};
                   1015:         write_teletype(&cp, ca);
                   1016:     }
                   1017: 
                   1018:     if (regs->al & 1)
                   1019:         set_cursor_pos(cp);
                   1020: }
                   1021: 
                   1022: 
                   1023: static void
                   1024: handle_101a00(struct bregs *regs)
                   1025: {
                   1026:     regs->bx = GET_BDA(dcc_index);
                   1027:     regs->al = 0x1a;
                   1028: }
                   1029: 
                   1030: static void
                   1031: handle_101a01(struct bregs *regs)
                   1032: {
                   1033:     SET_BDA(dcc_index, regs->bl);
                   1034:     dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh);
                   1035:     regs->al = 0x1a;
                   1036: }
                   1037: 
                   1038: static void
                   1039: handle_101aXX(struct bregs *regs)
                   1040: {
                   1041:     debug_stub(regs);
                   1042: }
                   1043: 
                   1044: static void
                   1045: handle_101a(struct bregs *regs)
                   1046: {
                   1047:     switch (regs->al) {
                   1048:     case 0x00: handle_101a00(regs); break;
                   1049:     case 0x01: handle_101a01(regs); break;
                   1050:     default:   handle_101aXX(regs); break;
                   1051:     }
                   1052: }
                   1053: 
                   1054: 
                   1055: static u8 static_functionality[0x10] VAR16 = {
                   1056:  /* 0 */ 0xff,  // All modes supported #1
                   1057:  /* 1 */ 0xe0,  // All modes supported #2
                   1058:  /* 2 */ 0x0f,  // All modes supported #3
                   1059:  /* 3 */ 0x00, 0x00, 0x00, 0x00,  // reserved
                   1060:  /* 7 */ 0x07,  // 200, 350, 400 scan lines
                   1061:  /* 8 */ 0x02,  // mamimum number of visible charsets in text mode
                   1062:  /* 9 */ 0x08,  // total number of charset blocks in text mode
                   1063:  /* a */ 0xe7,  // Change to add new functions
                   1064:  /* b */ 0x0c,  // Change to add new functions
                   1065:  /* c */ 0x00,  // reserved
                   1066:  /* d */ 0x00,  // reserved
                   1067:  /* e */ 0x00,  // Change to add new functions
                   1068:  /* f */ 0x00   // reserved
                   1069: };
                   1070: 
                   1071: struct funcInfo {
                   1072:     struct segoff_s static_functionality;
                   1073:     u8 bda_0x49[30];
                   1074:     u8 bda_0x84[3];
                   1075:     u8 dcc_index;
                   1076:     u8 dcc_alt;
                   1077:     u16 colors;
                   1078:     u8 pages;
                   1079:     u8 scan_lines;
                   1080:     u8 primary_char;
                   1081:     u8 secondar_char;
                   1082:     u8 misc;
                   1083:     u8 non_vga_mode;
                   1084:     u8 reserved_2f[2];
                   1085:     u8 video_mem;
                   1086:     u8 save_flags;
                   1087:     u8 disp_info;
                   1088:     u8 reserved_34[12];
                   1089: };
                   1090: 
                   1091: static void
                   1092: handle_101b(struct bregs *regs)
                   1093: {
                   1094:     u16 seg = regs->es;
                   1095:     struct funcInfo *info = (void*)(regs->di+0);
                   1096:     memset_far(seg, info, 0, sizeof(*info));
                   1097:     // Address of static functionality table
                   1098:     SET_FARVAR(seg, info->static_functionality
                   1099:                , SEGOFF(get_global_seg(), (u32)static_functionality));
                   1100: 
                   1101:     // Hard coded copy from BIOS area. Should it be cleaner ?
                   1102:     memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49
                   1103:                , sizeof(info->bda_0x49));
                   1104:     memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84
                   1105:                , sizeof(info->bda_0x84));
                   1106: 
                   1107:     SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index));
                   1108:     SET_FARVAR(seg, info->colors, 16);
                   1109:     SET_FARVAR(seg, info->pages, 8);
                   1110:     SET_FARVAR(seg, info->scan_lines, 2);
                   1111:     SET_FARVAR(seg, info->video_mem, 3);
                   1112:     regs->al = 0x1B;
                   1113: }
                   1114: 
                   1115: 
                   1116: static void
                   1117: handle_101c(struct bregs *regs)
                   1118: {
                   1119:     u16 seg = regs->es;
                   1120:     void *data = (void*)(regs->bx+0);
                   1121:     u16 states = regs->cx;
                   1122:     if (states & ~0x07)
                   1123:         goto fail;
                   1124:     int ret;
                   1125:     switch (regs->al) {
                   1126:     case 0x00:
                   1127:         ret = vgahw_size_state(states);
                   1128:         if (ret < 0)
                   1129:             goto fail;
                   1130:         regs->bx = ret / 64;
                   1131:         break;
                   1132:     case 0x01:
                   1133:         ret = vgahw_save_state(seg, data, states);
                   1134:         if (ret)
                   1135:             goto fail;
                   1136:         break;
                   1137:     case 0x02:
                   1138:         ret = vgahw_restore_state(seg, data, states);
                   1139:         if (ret)
                   1140:             goto fail;
                   1141:         break;
                   1142:     default:
                   1143:         goto fail;
                   1144:     }
                   1145:     regs->al = 0x1c;
                   1146: fail:
                   1147:     return;
                   1148: }
                   1149: 
                   1150: static void
                   1151: handle_10XX(struct bregs *regs)
                   1152: {
                   1153:     debug_stub(regs);
                   1154: }
                   1155: 
                   1156: // INT 10h Video Support Service Entry Point
                   1157: void VISIBLE16
                   1158: handle_10(struct bregs *regs)
                   1159: {
                   1160:     debug_enter(regs, DEBUG_VGA_10);
                   1161:     switch (regs->ah) {
                   1162:     case 0x00: handle_1000(regs); break;
                   1163:     case 0x01: handle_1001(regs); break;
                   1164:     case 0x02: handle_1002(regs); break;
                   1165:     case 0x03: handle_1003(regs); break;
                   1166:     case 0x04: handle_1004(regs); break;
                   1167:     case 0x05: handle_1005(regs); break;
                   1168:     case 0x06: handle_1006(regs); break;
                   1169:     case 0x07: handle_1007(regs); break;
                   1170:     case 0x08: handle_1008(regs); break;
                   1171:     case 0x09: handle_1009(regs); break;
                   1172:     case 0x0a: handle_100a(regs); break;
                   1173:     case 0x0b: handle_100b(regs); break;
                   1174:     case 0x0c: handle_100c(regs); break;
                   1175:     case 0x0d: handle_100d(regs); break;
                   1176:     case 0x0e: handle_100e(regs); break;
                   1177:     case 0x0f: handle_100f(regs); break;
                   1178:     case 0x10: handle_1010(regs); break;
                   1179:     case 0x11: handle_1011(regs); break;
                   1180:     case 0x12: handle_1012(regs); break;
                   1181:     case 0x13: handle_1013(regs); break;
                   1182:     case 0x1a: handle_101a(regs); break;
                   1183:     case 0x1b: handle_101b(regs); break;
                   1184:     case 0x1c: handle_101c(regs); break;
                   1185:     case 0x4f: handle_104f(regs); break;
                   1186:     default:   handle_10XX(regs); break;
                   1187:     }
                   1188: }
                   1189: 
                   1190: 
                   1191: /****************************************************************
                   1192:  * VGA post
                   1193:  ****************************************************************/
                   1194: 
                   1195: static void
                   1196: init_bios_area(void)
                   1197: {
                   1198:     // init detected hardware BIOS Area
                   1199:     // set 80x25 color (not clear from RBIL but usual)
                   1200:     u16 eqf = GET_BDA(equipment_list_flags);
                   1201:     SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20);
                   1202: 
                   1203:     // Just for the first int10 find its children
                   1204: 
                   1205:     // the default char height
                   1206:     SET_BDA(char_height, 0x10);
                   1207: 
                   1208:     // Clear the screen
                   1209:     SET_BDA(video_ctl, 0x60);
                   1210: 
                   1211:     // Set the basic screen we have
                   1212:     SET_BDA(video_switches, 0xf9);
                   1213: 
                   1214:     // Set the basic modeset options
                   1215:     SET_BDA(modeset_ctl, 0x51);
                   1216: 
                   1217:     // Set the  default MSR
                   1218:     SET_BDA(video_msr, 0x09);
                   1219: }
                   1220: 
                   1221: int VgaBDF VAR16 = -1;
                   1222: int HaveRunInit VAR16;
                   1223: 
                   1224: void VISIBLE16
                   1225: vga_post(struct bregs *regs)
                   1226: {
                   1227:     debug_serial_setup();
                   1228:     dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION);
                   1229:     debug_enter(regs, DEBUG_VGA_POST);
                   1230: 
                   1231:     if (CONFIG_VGA_PCI && !GET_GLOBAL(HaveRunInit)) {
                   1232:         u16 bdf = regs->ax;
                   1233:         if ((pci_config_readw(bdf, PCI_VENDOR_ID)
                   1234:              == GET_GLOBAL(rom_pci_data.vendor))
                   1235:             && (pci_config_readw(bdf, PCI_DEVICE_ID)
                   1236:                 == GET_GLOBAL(rom_pci_data.device)))
                   1237:             SET_VGA(VgaBDF, bdf);
                   1238:     }
                   1239: 
                   1240:     int ret = vgahw_init();
                   1241:     if (ret) {
                   1242:         dprintf(1, "Failed to initialize VGA hardware.  Exiting.\n");
                   1243:         return;
                   1244:     }
                   1245: 
                   1246:     if (GET_GLOBAL(HaveRunInit))
                   1247:         return;
                   1248: 
                   1249:     init_bios_area();
                   1250: 
                   1251:     SET_VGA(video_save_pointer_table.videoparam
                   1252:             , SEGOFF(get_global_seg(), (u32)video_param_table));
                   1253:     stdvga_build_video_param();
                   1254: 
                   1255:     extern void entry_10(void);
                   1256:     SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
                   1257: 
                   1258:     SET_VGA(HaveRunInit, 1);
                   1259: 
                   1260:     // Fixup checksum
                   1261:     extern u8 _rom_header_size, _rom_header_checksum;
                   1262:     SET_VGA(_rom_header_checksum, 0);
                   1263:     u8 sum = -checksum_far(get_global_seg(), 0,
                   1264:                            GET_GLOBAL(_rom_header_size) * 512);
                   1265:     SET_VGA(_rom_header_checksum, sum);
                   1266: }

unix.superglobalmegacorp.com

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