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