Annotation of qemu/roms/seabios/vgasrc/vga.c, revision 1.1

1.1     ! root        1: // VGA bios implementation
        !             2: //
        !             3: // Copyright (C) 2009  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: 
        !             9: // TODO:
        !            10: //  * review correctness of converted asm by comparing with RBIL
        !            11: //
        !            12: //  * convert vbe/clext code
        !            13: 
        !            14: #include "bregs.h" // struct bregs
        !            15: #include "biosvar.h" // GET_BDA
        !            16: #include "util.h" // memset
        !            17: #include "vgatables.h" // find_vga_entry
        !            18: 
        !            19: // XXX
        !            20: #define CONFIG_VBE 0
        !            21: #define CONFIG_CIRRUS 0
        !            22: 
        !            23: // XXX
        !            24: #define DEBUG_VGA_POST 1
        !            25: #define DEBUG_VGA_10 3
        !            26: 
        !            27: #define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val))
        !            28: 
        !            29: 
        !            30: /****************************************************************
        !            31:  * Helper functions
        !            32:  ****************************************************************/
        !            33: 
        !            34: static inline void
        !            35: call16_vgaint(u32 eax, u32 ebx)
        !            36: {
        !            37:     asm volatile(
        !            38:         "int $0x10\n"
        !            39:         "cli\n"
        !            40:         "cld"
        !            41:         :
        !            42:         : "a"(eax), "b"(ebx)
        !            43:         : "cc", "memory");
        !            44: }
        !            45: 
        !            46: static void
        !            47: perform_gray_scale_summing(u16 start, u16 count)
        !            48: {
        !            49:     vgahw_screen_disable();
        !            50:     int i;
        !            51:     for (i = start; i < start+count; i++) {
        !            52:         u8 rgb[3];
        !            53:         vgahw_get_dac_regs(GET_SEG(SS), rgb, i, 1);
        !            54: 
        !            55:         // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
        !            56:         u16 intensity = ((77 * rgb[0] + 151 * rgb[1] + 28 * rgb[2]) + 0x80) >> 8;
        !            57:         if (intensity > 0x3f)
        !            58:             intensity = 0x3f;
        !            59: 
        !            60:         vgahw_set_dac_regs(GET_SEG(SS), rgb, i, 1);
        !            61:     }
        !            62:     vgahw_screen_enable();
        !            63: }
        !            64: 
        !            65: static void
        !            66: set_cursor_shape(u8 start, u8 end)
        !            67: {
        !            68:     start &= 0x3f;
        !            69:     end &= 0x1f;
        !            70: 
        !            71:     u16 curs = (start << 8) + end;
        !            72:     SET_BDA(cursor_type, curs);
        !            73: 
        !            74:     u8 modeset_ctl = GET_BDA(modeset_ctl);
        !            75:     u16 cheight = GET_BDA(char_height);
        !            76:     if ((modeset_ctl & 0x01) && (cheight > 8) && (end < 8) && (start < 0x20)) {
        !            77:         if (end != (start + 1))
        !            78:             start = ((start + 1) * cheight / 8) - 1;
        !            79:         else
        !            80:             start = ((end + 1) * cheight / 8) - 2;
        !            81:         end = ((end + 1) * cheight / 8) - 1;
        !            82:     }
        !            83:     vgahw_set_cursor_shape(start, end);
        !            84: }
        !            85: 
        !            86: static u16
        !            87: get_cursor_shape(u8 page)
        !            88: {
        !            89:     if (page > 7)
        !            90:         return 0;
        !            91:     // FIXME should handle VGA 14/16 lines
        !            92:     return GET_BDA(cursor_type);
        !            93: }
        !            94: 
        !            95: static void
        !            96: set_cursor_pos(struct cursorpos cp)
        !            97: {
        !            98:     // Should not happen...
        !            99:     if (cp.page > 7)
        !           100:         return;
        !           101: 
        !           102:     // Bios cursor pos
        !           103:     SET_BDA(cursor_pos[cp.page], (cp.y << 8) | cp.x);
        !           104: 
        !           105:     // Set the hardware cursor
        !           106:     u8 current = GET_BDA(video_page);
        !           107:     if (cp.page != current)
        !           108:         return;
        !           109: 
        !           110:     // Get the dimensions
        !           111:     u16 nbcols = GET_BDA(video_cols);
        !           112:     u16 nbrows = GET_BDA(video_rows) + 1;
        !           113: 
        !           114:     // Calculate the address knowing nbcols nbrows and page num
        !           115:     u16 address = (SCREEN_IO_START(nbcols, nbrows, cp.page)
        !           116:                    + cp.x + cp.y * nbcols);
        !           117: 
        !           118:     vgahw_set_cursor_pos(address);
        !           119: }
        !           120: 
        !           121: static struct cursorpos
        !           122: get_cursor_pos(u8 page)
        !           123: {
        !           124:     if (page == 0xff)
        !           125:         // special case - use current page
        !           126:         page = GET_BDA(video_page);
        !           127:     if (page > 7) {
        !           128:         struct cursorpos cp = { 0, 0, 0xfe };
        !           129:         return cp;
        !           130:     }
        !           131:     // FIXME should handle VGA 14/16 lines
        !           132:     u16 xy = GET_BDA(cursor_pos[page]);
        !           133:     struct cursorpos cp = {xy, xy>>8, page};
        !           134:     return cp;
        !           135: }
        !           136: 
        !           137: static void
        !           138: set_active_page(u8 page)
        !           139: {
        !           140:     if (page > 7)
        !           141:         return;
        !           142: 
        !           143:     // Get the mode
        !           144:     struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
        !           145:     if (!vmode_g)
        !           146:         return;
        !           147: 
        !           148:     // Get pos curs pos for the right page
        !           149:     struct cursorpos cp = get_cursor_pos(page);
        !           150: 
        !           151:     u16 address;
        !           152:     if (GET_GLOBAL(vmode_g->memmodel) & TEXT) {
        !           153:         // Get the dimensions
        !           154:         u16 nbcols = GET_BDA(video_cols);
        !           155:         u16 nbrows = GET_BDA(video_rows) + 1;
        !           156: 
        !           157:         // Calculate the address knowing nbcols nbrows and page num
        !           158:         address = SCREEN_MEM_START(nbcols, nbrows, page);
        !           159:         SET_BDA(video_pagestart, address);
        !           160: 
        !           161:         // Start address
        !           162:         address = SCREEN_IO_START(nbcols, nbrows, page);
        !           163:     } else {
        !           164:         struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
        !           165:         address = page * GET_GLOBAL(vparam_g->slength);
        !           166:     }
        !           167: 
        !           168:     vgahw_set_active_page(address);
        !           169: 
        !           170:     // And change the BIOS page
        !           171:     SET_BDA(video_page, page);
        !           172: 
        !           173:     dprintf(1, "Set active page %02x address %04x\n", page, address);
        !           174: 
        !           175:     // Display the cursor, now the page is active
        !           176:     set_cursor_pos(cp);
        !           177: }
        !           178: 
        !           179: static void
        !           180: set_scan_lines(u8 lines)
        !           181: {
        !           182:     vgahw_set_scan_lines(lines);
        !           183:     if (lines == 8)
        !           184:         set_cursor_shape(0x06, 0x07);
        !           185:     else
        !           186:         set_cursor_shape(lines - 4, lines - 3);
        !           187:     SET_BDA(char_height, lines);
        !           188:     u16 vde = vgahw_get_vde();
        !           189:     u8 rows = vde / lines;
        !           190:     SET_BDA(video_rows, rows - 1);
        !           191:     u16 cols = GET_BDA(video_cols);
        !           192:     SET_BDA(video_pagesize, rows * cols * 2);
        !           193: }
        !           194: 
        !           195: 
        !           196: /****************************************************************
        !           197:  * Character writing
        !           198:  ****************************************************************/
        !           199: 
        !           200: // Scroll the screen one line.  This function is designed to be called
        !           201: // tail-recursive to reduce stack usage.
        !           202: static void noinline
        !           203: scroll_one(u16 nbrows, u16 nbcols, u8 page)
        !           204: {
        !           205:     struct cursorpos ul = {0, 0, page};
        !           206:     struct cursorpos lr = {nbcols-1, nbrows-1, page};
        !           207:     vgafb_scroll(1, -1, ul, lr);
        !           208: }
        !           209: 
        !           210: // Write a character to the screen at a given position.  Implement
        !           211: // special characters and scroll the screen if necessary.
        !           212: static void
        !           213: write_teletype(struct cursorpos *pcp, struct carattr ca)
        !           214: {
        !           215:     struct cursorpos cp = *pcp;
        !           216: 
        !           217:     // Get the dimensions
        !           218:     u16 nbrows = GET_BDA(video_rows) + 1;
        !           219:     u16 nbcols = GET_BDA(video_cols);
        !           220: 
        !           221:     switch (ca.car) {
        !           222:     case 7:
        !           223:         //FIXME should beep
        !           224:         break;
        !           225:     case 8:
        !           226:         if (cp.x > 0)
        !           227:             cp.x--;
        !           228:         break;
        !           229:     case '\r':
        !           230:         cp.x = 0;
        !           231:         break;
        !           232:     case '\n':
        !           233:         cp.y++;
        !           234:         break;
        !           235:     case '\t':
        !           236:         do {
        !           237:             struct carattr dummyca = {' ', ca.attr, ca.use_attr};
        !           238:             vgafb_write_char(cp, dummyca);
        !           239:             cp.x++;
        !           240:         } while (cp.x < nbcols && cp.x % 8);
        !           241:         break;
        !           242:     default:
        !           243:         vgafb_write_char(cp, ca);
        !           244:         cp.x++;
        !           245:     }
        !           246: 
        !           247:     // Do we need to wrap ?
        !           248:     if (cp.x == nbcols) {
        !           249:         cp.x = 0;
        !           250:         cp.y++;
        !           251:     }
        !           252:     // Do we need to scroll ?
        !           253:     if (cp.y < nbrows) {
        !           254:         *pcp = cp;
        !           255:         return;
        !           256:     }
        !           257:     // Scroll screen
        !           258:     cp.y--;
        !           259:     *pcp = cp;
        !           260:     scroll_one(nbrows, nbcols, cp.page);
        !           261: }
        !           262: 
        !           263: // Write out a buffer of alternating characters and attributes.
        !           264: static void
        !           265: write_attr_string(struct cursorpos *pcp, u16 count, u16 seg, u8 *offset_far)
        !           266: {
        !           267:     while (count--) {
        !           268:         u8 car = GET_FARVAR(seg, *offset_far);
        !           269:         offset_far++;
        !           270:         u8 attr = GET_FARVAR(seg, *offset_far);
        !           271:         offset_far++;
        !           272: 
        !           273:         struct carattr ca = {car, attr, 1};
        !           274:         write_teletype(pcp, ca);
        !           275:     }
        !           276: }
        !           277: 
        !           278: // Write out a buffer of characters.
        !           279: static void
        !           280: write_string(struct cursorpos *pcp, u8 attr, u16 count, u16 seg, u8 *offset_far)
        !           281: {
        !           282:     while (count--) {
        !           283:         u8 car = GET_FARVAR(seg, *offset_far);
        !           284:         offset_far++;
        !           285: 
        !           286:         struct carattr ca = {car, attr, 1};
        !           287:         write_teletype(pcp, ca);
        !           288:     }
        !           289: }
        !           290: 
        !           291: 
        !           292: /****************************************************************
        !           293:  * Save and restore bda state
        !           294:  ****************************************************************/
        !           295: 
        !           296: static void
        !           297: save_bda_state(u16 seg, struct saveBDAstate *info)
        !           298: {
        !           299:     SET_FARVAR(seg, info->video_mode, GET_BDA(video_mode));
        !           300:     SET_FARVAR(seg, info->video_cols, GET_BDA(video_cols));
        !           301:     SET_FARVAR(seg, info->video_pagesize, GET_BDA(video_pagesize));
        !           302:     SET_FARVAR(seg, info->crtc_address, GET_BDA(crtc_address));
        !           303:     SET_FARVAR(seg, info->video_rows, GET_BDA(video_rows));
        !           304:     SET_FARVAR(seg, info->char_height, GET_BDA(char_height));
        !           305:     SET_FARVAR(seg, info->video_ctl, GET_BDA(video_ctl));
        !           306:     SET_FARVAR(seg, info->video_switches, GET_BDA(video_switches));
        !           307:     SET_FARVAR(seg, info->modeset_ctl, GET_BDA(modeset_ctl));
        !           308:     SET_FARVAR(seg, info->cursor_type, GET_BDA(cursor_type));
        !           309:     u16 i;
        !           310:     for (i=0; i<8; i++)
        !           311:         SET_FARVAR(seg, info->cursor_pos[i], GET_BDA(cursor_pos[i]));
        !           312:     SET_FARVAR(seg, info->video_pagestart, GET_BDA(video_pagestart));
        !           313:     SET_FARVAR(seg, info->video_page, GET_BDA(video_page));
        !           314:     /* current font */
        !           315:     SET_FARVAR(seg, info->font0, GET_IVT(0x1f));
        !           316:     SET_FARVAR(seg, info->font1, GET_IVT(0x43));
        !           317: }
        !           318: 
        !           319: static void
        !           320: restore_bda_state(u16 seg, struct saveBDAstate *info)
        !           321: {
        !           322:     SET_BDA(video_mode, GET_FARVAR(seg, info->video_mode));
        !           323:     SET_BDA(video_cols, GET_FARVAR(seg, info->video_cols));
        !           324:     SET_BDA(video_pagesize, GET_FARVAR(seg, info->video_pagesize));
        !           325:     SET_BDA(crtc_address, GET_FARVAR(seg, info->crtc_address));
        !           326:     SET_BDA(video_rows, GET_FARVAR(seg, info->video_rows));
        !           327:     SET_BDA(char_height, GET_FARVAR(seg, info->char_height));
        !           328:     SET_BDA(video_ctl, GET_FARVAR(seg, info->video_ctl));
        !           329:     SET_BDA(video_switches, GET_FARVAR(seg, info->video_switches));
        !           330:     SET_BDA(modeset_ctl, GET_FARVAR(seg, info->modeset_ctl));
        !           331:     SET_BDA(cursor_type, GET_FARVAR(seg, info->cursor_type));
        !           332:     u16 i;
        !           333:     for (i = 0; i < 8; i++)
        !           334:         SET_BDA(cursor_pos[i], GET_FARVAR(seg, info->cursor_pos[i]));
        !           335:     SET_BDA(video_pagestart, GET_FARVAR(seg, info->video_pagestart));
        !           336:     SET_BDA(video_page, GET_FARVAR(seg, info->video_page));
        !           337:     /* current font */
        !           338:     SET_IVT(0x1f, GET_FARVAR(seg, info->font0));
        !           339:     SET_IVT(0x43, GET_FARVAR(seg, info->font1));
        !           340: }
        !           341: 
        !           342: 
        !           343: /****************************************************************
        !           344:  * VGA int 10 handler
        !           345:  ****************************************************************/
        !           346: 
        !           347: // set video mode
        !           348: static void
        !           349: handle_1000(struct bregs *regs)
        !           350: {
        !           351:     u8 noclearmem = regs->al & 0x80;
        !           352:     u8 mode = regs->al & 0x7f;
        !           353: 
        !           354:     // Set regs->al
        !           355:     if (mode > 7)
        !           356:         regs->al = 0x20;
        !           357:     else if (mode == 6)
        !           358:         regs->al = 0x3f;
        !           359:     else
        !           360:         regs->al = 0x30;
        !           361: 
        !           362:     if (CONFIG_CIRRUS)
        !           363:         cirrus_set_video_mode(mode);
        !           364: 
        !           365:     if (CONFIG_VBE)
        !           366:         if (vbe_has_vbe_display())
        !           367:             dispi_set_enable(VBE_DISPI_DISABLED);
        !           368: 
        !           369:     // find the entry in the video modes
        !           370:     struct vgamode_s *vmode_g = find_vga_entry(mode);
        !           371:     dprintf(1, "mode search %02x found %p\n", mode, vmode_g);
        !           372:     if (!vmode_g)
        !           373:         return;
        !           374: 
        !           375:     // Read the bios mode set control
        !           376:     u8 modeset_ctl = GET_BDA(modeset_ctl);
        !           377: 
        !           378:     // Then we know the number of lines
        !           379: // FIXME
        !           380: 
        !           381:     // if palette loading (bit 3 of modeset ctl = 0)
        !           382:     if ((modeset_ctl & 0x08) == 0) {    // Set the PEL mask
        !           383:         vgahw_set_pel_mask(GET_GLOBAL(vmode_g->pelmask));
        !           384: 
        !           385:         // From which palette
        !           386:         u8 *palette_g = GET_GLOBAL(vmode_g->dac);
        !           387:         u16 palsize = GET_GLOBAL(vmode_g->dacsize) / 3;
        !           388: 
        !           389:         // Always 256*3 values
        !           390:         vgahw_set_dac_regs(get_global_seg(), palette_g, 0, palsize);
        !           391:         u16 i;
        !           392:         for (i = palsize; i < 0x0100; i++) {
        !           393:             static u8 rgb[3] VAR16;
        !           394:             vgahw_set_dac_regs(get_global_seg(), rgb, i, 1);
        !           395:         }
        !           396: 
        !           397:         if ((modeset_ctl & 0x02) == 0x02)
        !           398:             perform_gray_scale_summing(0x00, 0x100);
        !           399:     }
        !           400: 
        !           401:     struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
        !           402:     vgahw_set_mode(vparam_g);
        !           403: 
        !           404:     if (noclearmem == 0x00)
        !           405:         clear_screen(vmode_g);
        !           406: 
        !           407:     // Set CRTC address VGA or MDA
        !           408:     u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
        !           409:     if (GET_GLOBAL(vmode_g->memmodel) == MTEXT)
        !           410:         crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
        !           411: 
        !           412:     // Set the BIOS mem
        !           413:     u16 cheight = GET_GLOBAL(vparam_g->cheight);
        !           414:     SET_BDA(video_mode, mode);
        !           415:     SET_BDA(video_cols, GET_GLOBAL(vparam_g->twidth));
        !           416:     SET_BDA(video_pagesize, GET_GLOBAL(vparam_g->slength));
        !           417:     SET_BDA(crtc_address, crtc_addr);
        !           418:     SET_BDA(video_rows, GET_GLOBAL(vparam_g->theightm1));
        !           419:     SET_BDA(char_height, cheight);
        !           420:     SET_BDA(video_ctl, (0x60 | noclearmem));
        !           421:     SET_BDA(video_switches, 0xF9);
        !           422:     SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f);
        !           423: 
        !           424:     // FIXME We nearly have the good tables. to be reworked
        !           425:     SET_BDA(dcc_index, 0x08);   // 8 is VGA should be ok for now
        !           426:     SET_BDA(video_savetable
        !           427:             , SEGOFF(get_global_seg(), (u32)video_save_pointer_table));
        !           428: 
        !           429:     // FIXME
        !           430:     SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
        !           431:     SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
        !           432: 
        !           433:     // Set cursor shape
        !           434:     if (GET_GLOBAL(vmode_g->memmodel) & TEXT)
        !           435:         set_cursor_shape(0x06, 0x07);
        !           436:     // Set cursor pos for page 0..7
        !           437:     int i;
        !           438:     for (i = 0; i < 8; i++) {
        !           439:         struct cursorpos cp = {0, 0, i};
        !           440:         set_cursor_pos(cp);
        !           441:     }
        !           442: 
        !           443:     // Set active page 0
        !           444:     set_active_page(0x00);
        !           445: 
        !           446:     // Write the fonts in memory
        !           447:     if (GET_GLOBAL(vmode_g->memmodel) & TEXT) {
        !           448:         call16_vgaint(0x1104, 0);
        !           449:         call16_vgaint(0x1103, 0);
        !           450:     }
        !           451:     // Set the ints 0x1F and 0x43
        !           452:     SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8]));
        !           453: 
        !           454:     switch (cheight) {
        !           455:     case 8:
        !           456:         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8));
        !           457:         break;
        !           458:     case 14:
        !           459:         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14));
        !           460:         break;
        !           461:     case 16:
        !           462:         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
        !           463:         break;
        !           464:     }
        !           465: }
        !           466: 
        !           467: static void
        !           468: handle_1001(struct bregs *regs)
        !           469: {
        !           470:     set_cursor_shape(regs->ch, regs->cl);
        !           471: }
        !           472: 
        !           473: static void
        !           474: handle_1002(struct bregs *regs)
        !           475: {
        !           476:     struct cursorpos cp = {regs->dl, regs->dh, regs->bh};
        !           477:     set_cursor_pos(cp);
        !           478: }
        !           479: 
        !           480: static void
        !           481: handle_1003(struct bregs *regs)
        !           482: {
        !           483:     regs->cx = get_cursor_shape(regs->bh);
        !           484:     struct cursorpos cp = get_cursor_pos(regs->bh);
        !           485:     regs->dl = cp.x;
        !           486:     regs->dh = cp.y;
        !           487: }
        !           488: 
        !           489: // Read light pen pos (unimplemented)
        !           490: static void
        !           491: handle_1004(struct bregs *regs)
        !           492: {
        !           493:     debug_stub(regs);
        !           494:     regs->ax = regs->bx = regs->cx = regs->dx = 0;
        !           495: }
        !           496: 
        !           497: static void
        !           498: handle_1005(struct bregs *regs)
        !           499: {
        !           500:     set_active_page(regs->al);
        !           501: }
        !           502: 
        !           503: static void
        !           504: verify_scroll(struct bregs *regs, int dir)
        !           505: {
        !           506:     u8 page = GET_BDA(video_page);
        !           507:     struct cursorpos ul = {regs->cl, regs->ch, page};
        !           508:     struct cursorpos lr = {regs->dl, regs->dh, page};
        !           509: 
        !           510:     u16 nbrows = GET_BDA(video_rows) + 1;
        !           511:     if (lr.y >= nbrows)
        !           512:         lr.y = nbrows - 1;
        !           513:     u16 nbcols = GET_BDA(video_cols);
        !           514:     if (lr.x >= nbcols)
        !           515:         lr.x = nbcols - 1;
        !           516: 
        !           517:     if (ul.x > lr.x || ul.y > lr.y)
        !           518:         return;
        !           519: 
        !           520:     u16 nblines = regs->al;
        !           521:     if (!nblines || nblines > lr.y - ul.y + 1)
        !           522:         nblines = lr.y - ul.y + 1;
        !           523: 
        !           524:     vgafb_scroll(dir * nblines, regs->bh, ul, lr);
        !           525: }
        !           526: 
        !           527: static void
        !           528: handle_1006(struct bregs *regs)
        !           529: {
        !           530:     verify_scroll(regs, 1);
        !           531: }
        !           532: 
        !           533: static void
        !           534: handle_1007(struct bregs *regs)
        !           535: {
        !           536:     verify_scroll(regs, -1);
        !           537: }
        !           538: 
        !           539: static void
        !           540: handle_1008(struct bregs *regs)
        !           541: {
        !           542:     struct carattr ca = vgafb_read_char(get_cursor_pos(regs->bh));
        !           543:     regs->al = ca.car;
        !           544:     regs->ah = ca.attr;
        !           545: }
        !           546: 
        !           547: static void noinline
        !           548: write_chars(u8 page, struct carattr ca, u16 count)
        !           549: {
        !           550:     struct cursorpos cp = get_cursor_pos(page);
        !           551:     while (count--) {
        !           552:         vgafb_write_char(cp, ca);
        !           553:         cp.x++;
        !           554:     }
        !           555: }
        !           556: 
        !           557: static void
        !           558: handle_1009(struct bregs *regs)
        !           559: {
        !           560:     struct carattr ca = {regs->al, regs->bl, 1};
        !           561:     write_chars(regs->bh, ca, regs->cx);
        !           562: }
        !           563: 
        !           564: static void
        !           565: handle_100a(struct bregs *regs)
        !           566: {
        !           567:     struct carattr ca = {regs->al, regs->bl, 0};
        !           568:     write_chars(regs->bh, ca, regs->cx);
        !           569: }
        !           570: 
        !           571: 
        !           572: static void
        !           573: handle_100b00(struct bregs *regs)
        !           574: {
        !           575:     vgahw_set_border_color(regs->bl);
        !           576: }
        !           577: 
        !           578: static void
        !           579: handle_100b01(struct bregs *regs)
        !           580: {
        !           581:     vgahw_set_palette(regs->bl);
        !           582: }
        !           583: 
        !           584: static void
        !           585: handle_100bXX(struct bregs *regs)
        !           586: {
        !           587:     debug_stub(regs);
        !           588: }
        !           589: 
        !           590: static void
        !           591: handle_100b(struct bregs *regs)
        !           592: {
        !           593:     switch (regs->bh) {
        !           594:     case 0x00: handle_100b00(regs); break;
        !           595:     case 0x01: handle_100b01(regs); break;
        !           596:     default:   handle_100bXX(regs); break;
        !           597:     }
        !           598: }
        !           599: 
        !           600: 
        !           601: static void
        !           602: handle_100c(struct bregs *regs)
        !           603: {
        !           604:     // XXX - page (regs->bh) is unused
        !           605:     vgafb_write_pixel(regs->al, regs->cx, regs->dx);
        !           606: }
        !           607: 
        !           608: static void
        !           609: handle_100d(struct bregs *regs)
        !           610: {
        !           611:     // XXX - page (regs->bh) is unused
        !           612:     regs->al = vgafb_read_pixel(regs->cx, regs->dx);
        !           613: }
        !           614: 
        !           615: static void noinline
        !           616: handle_100e(struct bregs *regs)
        !           617: {
        !           618:     // Ralf Brown Interrupt list is WRONG on bh(page)
        !           619:     // We do output only on the current page !
        !           620:     struct carattr ca = {regs->al, regs->bl, 0};
        !           621:     struct cursorpos cp = get_cursor_pos(0xff);
        !           622:     write_teletype(&cp, ca);
        !           623:     set_cursor_pos(cp);
        !           624: }
        !           625: 
        !           626: static void
        !           627: handle_100f(struct bregs *regs)
        !           628: {
        !           629:     regs->bh = GET_BDA(video_page);
        !           630:     regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80);
        !           631:     regs->ah = GET_BDA(video_cols);
        !           632: }
        !           633: 
        !           634: 
        !           635: static void
        !           636: handle_101000(struct bregs *regs)
        !           637: {
        !           638:     if (regs->bl > 0x14)
        !           639:         return;
        !           640:     vgahw_set_single_palette_reg(regs->bl, regs->bh);
        !           641: }
        !           642: 
        !           643: static void
        !           644: handle_101001(struct bregs *regs)
        !           645: {
        !           646:     vgahw_set_overscan_border_color(regs->bh);
        !           647: }
        !           648: 
        !           649: static void
        !           650: handle_101002(struct bregs *regs)
        !           651: {
        !           652:     vgahw_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0));
        !           653: }
        !           654: 
        !           655: static void
        !           656: handle_101003(struct bregs *regs)
        !           657: {
        !           658:     vgahw_toggle_intensity(regs->bl);
        !           659: }
        !           660: 
        !           661: static void
        !           662: handle_101007(struct bregs *regs)
        !           663: {
        !           664:     if (regs->bl > 0x14)
        !           665:         return;
        !           666:     regs->bh = vgahw_get_single_palette_reg(regs->bl);
        !           667: }
        !           668: 
        !           669: static void
        !           670: handle_101008(struct bregs *regs)
        !           671: {
        !           672:     regs->bh = vgahw_get_overscan_border_color(regs);
        !           673: }
        !           674: 
        !           675: static void
        !           676: handle_101009(struct bregs *regs)
        !           677: {
        !           678:     vgahw_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0));
        !           679: }
        !           680: 
        !           681: static void noinline
        !           682: handle_101010(struct bregs *regs)
        !           683: {
        !           684:     u8 rgb[3] = {regs->dh, regs->ch, regs->cl};
        !           685:     vgahw_set_dac_regs(GET_SEG(SS), rgb, regs->bx, 1);
        !           686: }
        !           687: 
        !           688: static void
        !           689: handle_101012(struct bregs *regs)
        !           690: {
        !           691:     vgahw_set_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
        !           692: }
        !           693: 
        !           694: static void
        !           695: handle_101013(struct bregs *regs)
        !           696: {
        !           697:     vgahw_select_video_dac_color_page(regs->bl, regs->bh);
        !           698: }
        !           699: 
        !           700: static void noinline
        !           701: handle_101015(struct bregs *regs)
        !           702: {
        !           703:     u8 rgb[3];
        !           704:     vgahw_get_dac_regs(GET_SEG(SS), rgb, regs->bx, 1);
        !           705:     regs->dh = rgb[0];
        !           706:     regs->ch = rgb[1];
        !           707:     regs->cl = rgb[2];
        !           708: }
        !           709: 
        !           710: static void
        !           711: handle_101017(struct bregs *regs)
        !           712: {
        !           713:     vgahw_get_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
        !           714: }
        !           715: 
        !           716: static void
        !           717: handle_101018(struct bregs *regs)
        !           718: {
        !           719:     vgahw_set_pel_mask(regs->bl);
        !           720: }
        !           721: 
        !           722: static void
        !           723: handle_101019(struct bregs *regs)
        !           724: {
        !           725:     regs->bl = vgahw_get_pel_mask();
        !           726: }
        !           727: 
        !           728: static void
        !           729: handle_10101a(struct bregs *regs)
        !           730: {
        !           731:     vgahw_read_video_dac_state(&regs->bl, &regs->bh);
        !           732: }
        !           733: 
        !           734: static void
        !           735: handle_10101b(struct bregs *regs)
        !           736: {
        !           737:     perform_gray_scale_summing(regs->bx, regs->cx);
        !           738: }
        !           739: 
        !           740: static void
        !           741: handle_1010XX(struct bregs *regs)
        !           742: {
        !           743:     debug_stub(regs);
        !           744: }
        !           745: 
        !           746: static void
        !           747: handle_1010(struct bregs *regs)
        !           748: {
        !           749:     switch (regs->al) {
        !           750:     case 0x00: handle_101000(regs); break;
        !           751:     case 0x01: handle_101001(regs); break;
        !           752:     case 0x02: handle_101002(regs); break;
        !           753:     case 0x03: handle_101003(regs); break;
        !           754:     case 0x07: handle_101007(regs); break;
        !           755:     case 0x08: handle_101008(regs); break;
        !           756:     case 0x09: handle_101009(regs); break;
        !           757:     case 0x10: handle_101010(regs); break;
        !           758:     case 0x12: handle_101012(regs); break;
        !           759:     case 0x13: handle_101013(regs); break;
        !           760:     case 0x15: handle_101015(regs); break;
        !           761:     case 0x17: handle_101017(regs); break;
        !           762:     case 0x18: handle_101018(regs); break;
        !           763:     case 0x19: handle_101019(regs); break;
        !           764:     case 0x1a: handle_10101a(regs); break;
        !           765:     case 0x1b: handle_10101b(regs); break;
        !           766:     default:   handle_1010XX(regs); break;
        !           767:     }
        !           768: }
        !           769: 
        !           770: 
        !           771: static void
        !           772: handle_101100(struct bregs *regs)
        !           773: {
        !           774:     vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx
        !           775:                     , regs->dx, regs->bl, regs->bh);
        !           776: }
        !           777: 
        !           778: static void
        !           779: handle_101101(struct bregs *regs)
        !           780: {
        !           781:     vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14);
        !           782: }
        !           783: 
        !           784: static void
        !           785: handle_101102(struct bregs *regs)
        !           786: {
        !           787:     vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8);
        !           788: }
        !           789: 
        !           790: static void
        !           791: handle_101103(struct bregs *regs)
        !           792: {
        !           793:     vgahw_set_text_block_specifier(regs->bl);
        !           794: }
        !           795: 
        !           796: static void
        !           797: handle_101104(struct bregs *regs)
        !           798: {
        !           799:     vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16);
        !           800: }
        !           801: 
        !           802: static void
        !           803: handle_101110(struct bregs *regs)
        !           804: {
        !           805:     vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx
        !           806:                     , regs->dx, regs->bl, regs->bh);
        !           807:     set_scan_lines(regs->bh);
        !           808: }
        !           809: 
        !           810: static void
        !           811: handle_101111(struct bregs *regs)
        !           812: {
        !           813:     vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14);
        !           814:     set_scan_lines(14);
        !           815: }
        !           816: 
        !           817: static void
        !           818: handle_101112(struct bregs *regs)
        !           819: {
        !           820:     vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8);
        !           821:     set_scan_lines(8);
        !           822: }
        !           823: 
        !           824: static void
        !           825: handle_101114(struct bregs *regs)
        !           826: {
        !           827:     vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16);
        !           828:     set_scan_lines(16);
        !           829: }
        !           830: 
        !           831: static void
        !           832: handle_101130(struct bregs *regs)
        !           833: {
        !           834:     switch (regs->bh) {
        !           835:     case 0x00: {
        !           836:         u32 segoff = GET_IVT(0x1f).segoff;
        !           837:         regs->es = segoff >> 16;
        !           838:         regs->bp = segoff;
        !           839:         break;
        !           840:     }
        !           841:     case 0x01: {
        !           842:         u32 segoff = GET_IVT(0x43).segoff;
        !           843:         regs->es = segoff >> 16;
        !           844:         regs->bp = segoff;
        !           845:         break;
        !           846:     }
        !           847:     case 0x02:
        !           848:         regs->es = get_global_seg();
        !           849:         regs->bp = (u32)vgafont14;
        !           850:         break;
        !           851:     case 0x03:
        !           852:         regs->es = get_global_seg();
        !           853:         regs->bp = (u32)vgafont8;
        !           854:         break;
        !           855:     case 0x04:
        !           856:         regs->es = get_global_seg();
        !           857:         regs->bp = (u32)vgafont8 + 128 * 8;
        !           858:         break;
        !           859:     case 0x05:
        !           860:         regs->es = get_global_seg();
        !           861:         regs->bp = (u32)vgafont14alt;
        !           862:         break;
        !           863:     case 0x06:
        !           864:         regs->es = get_global_seg();
        !           865:         regs->bp = (u32)vgafont16;
        !           866:         break;
        !           867:     case 0x07:
        !           868:         regs->es = get_global_seg();
        !           869:         regs->bp = (u32)vgafont16alt;
        !           870:         break;
        !           871:     default:
        !           872:         dprintf(1, "Get font info BH(%02x) was discarded\n", regs->bh);
        !           873:         return;
        !           874:     }
        !           875:     // Set byte/char of on screen font
        !           876:     regs->cx = GET_BDA(char_height) & 0xff;
        !           877: 
        !           878:     // Set Highest char row
        !           879:     regs->dx = GET_BDA(video_rows);
        !           880: }
        !           881: 
        !           882: static void
        !           883: handle_1011XX(struct bregs *regs)
        !           884: {
        !           885:     debug_stub(regs);
        !           886: }
        !           887: 
        !           888: static void
        !           889: handle_1011(struct bregs *regs)
        !           890: {
        !           891:     switch (regs->al) {
        !           892:     case 0x00: handle_101100(regs); break;
        !           893:     case 0x01: handle_101101(regs); break;
        !           894:     case 0x02: handle_101102(regs); break;
        !           895:     case 0x03: handle_101103(regs); break;
        !           896:     case 0x04: handle_101104(regs); break;
        !           897:     case 0x10: handle_101110(regs); break;
        !           898:     case 0x11: handle_101111(regs); break;
        !           899:     case 0x12: handle_101112(regs); break;
        !           900:     case 0x14: handle_101114(regs); break;
        !           901:     case 0x30: handle_101130(regs); break;
        !           902:     default:   handle_1011XX(regs); break;
        !           903:     }
        !           904: }
        !           905: 
        !           906: 
        !           907: static void
        !           908: handle_101210(struct bregs *regs)
        !           909: {
        !           910:     u16 crtc_addr = GET_BDA(crtc_address);
        !           911:     if (crtc_addr == VGAREG_MDA_CRTC_ADDRESS)
        !           912:         regs->bx = 0x0103;
        !           913:     else
        !           914:         regs->bx = 0x0003;
        !           915:     regs->cx = GET_BDA(video_switches) & 0x0f;
        !           916: }
        !           917: 
        !           918: static void
        !           919: handle_101230(struct bregs *regs)
        !           920: {
        !           921:     u8 mctl = GET_BDA(modeset_ctl);
        !           922:     u8 vswt = GET_BDA(video_switches);
        !           923:     switch (regs->al) {
        !           924:     case 0x00:
        !           925:         // 200 lines
        !           926:         mctl = (mctl & ~0x10) | 0x80;
        !           927:         vswt = (vswt & ~0x0f) | 0x08;
        !           928:         break;
        !           929:     case 0x01:
        !           930:         // 350 lines
        !           931:         mctl &= ~0x90;
        !           932:         vswt = (vswt & ~0x0f) | 0x09;
        !           933:         break;
        !           934:     case 0x02:
        !           935:         // 400 lines
        !           936:         mctl = (mctl & ~0x80) | 0x10;
        !           937:         vswt = (vswt & ~0x0f) | 0x09;
        !           938:         break;
        !           939:     default:
        !           940:         dprintf(1, "Select vert res (%02x) was discarded\n", regs->al);
        !           941:         break;
        !           942:     }
        !           943:     SET_BDA(modeset_ctl, mctl);
        !           944:     SET_BDA(video_switches, vswt);
        !           945:     regs->al = 0x12;
        !           946: }
        !           947: 
        !           948: static void
        !           949: handle_101231(struct bregs *regs)
        !           950: {
        !           951:     u8 v = (regs->al & 0x01) << 3;
        !           952:     u8 mctl = GET_BDA(video_ctl) & ~0x08;
        !           953:     SET_BDA(video_ctl, mctl | v);
        !           954:     regs->al = 0x12;
        !           955: }
        !           956: 
        !           957: static void
        !           958: handle_101232(struct bregs *regs)
        !           959: {
        !           960:     vgahw_enable_video_addressing(regs->al);
        !           961:     regs->al = 0x12;
        !           962: }
        !           963: 
        !           964: static void
        !           965: handle_101233(struct bregs *regs)
        !           966: {
        !           967:     u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
        !           968:     u8 v2 = GET_BDA(modeset_ctl) & ~0x02;
        !           969:     SET_BDA(modeset_ctl, v | v2);
        !           970:     regs->al = 0x12;
        !           971: }
        !           972: 
        !           973: static void
        !           974: handle_101234(struct bregs *regs)
        !           975: {
        !           976:     u8 v = (regs->al & 0x01) ^ 0x01;
        !           977:     u8 v2 = GET_BDA(modeset_ctl) & ~0x01;
        !           978:     SET_BDA(modeset_ctl, v | v2);
        !           979:     regs->al = 0x12;
        !           980: }
        !           981: 
        !           982: static void
        !           983: handle_101235(struct bregs *regs)
        !           984: {
        !           985:     debug_stub(regs);
        !           986:     regs->al = 0x12;
        !           987: }
        !           988: 
        !           989: static void
        !           990: handle_101236(struct bregs *regs)
        !           991: {
        !           992:     debug_stub(regs);
        !           993:     regs->al = 0x12;
        !           994: }
        !           995: 
        !           996: static void
        !           997: handle_1012XX(struct bregs *regs)
        !           998: {
        !           999:     debug_stub(regs);
        !          1000: }
        !          1001: 
        !          1002: static void
        !          1003: handle_1012(struct bregs *regs)
        !          1004: {
        !          1005:     switch (regs->bl) {
        !          1006:     case 0x10: handle_101210(regs); break;
        !          1007:     case 0x30: handle_101230(regs); break;
        !          1008:     case 0x31: handle_101231(regs); break;
        !          1009:     case 0x32: handle_101232(regs); break;
        !          1010:     case 0x33: handle_101233(regs); break;
        !          1011:     case 0x34: handle_101234(regs); break;
        !          1012:     case 0x35: handle_101235(regs); break;
        !          1013:     case 0x36: handle_101236(regs); break;
        !          1014:     default:   handle_1012XX(regs); break;
        !          1015:     }
        !          1016: 
        !          1017:     // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae
        !          1018: }
        !          1019: 
        !          1020: 
        !          1021: // Write string
        !          1022: static void noinline
        !          1023: handle_1013(struct bregs *regs)
        !          1024: {
        !          1025:     struct cursorpos cp = {regs->dl, regs->dh, regs->bh};
        !          1026:     // if row=0xff special case : use current cursor position
        !          1027:     if (cp.y == 0xff)
        !          1028:         cp = get_cursor_pos(cp.page);
        !          1029:     u8 flag = regs->al;
        !          1030:     if (flag & 2)
        !          1031:         write_attr_string(&cp, regs->cx, regs->es, (void*)(regs->bp + 0));
        !          1032:     else
        !          1033:         write_string(&cp, regs->bl, regs->cx, regs->es, (void*)(regs->bp + 0));
        !          1034: 
        !          1035:     if (flag & 1)
        !          1036:         set_cursor_pos(cp);
        !          1037: }
        !          1038: 
        !          1039: 
        !          1040: static void
        !          1041: handle_101a00(struct bregs *regs)
        !          1042: {
        !          1043:     regs->bx = GET_BDA(dcc_index);
        !          1044:     regs->al = 0x1a;
        !          1045: }
        !          1046: 
        !          1047: static void
        !          1048: handle_101a01(struct bregs *regs)
        !          1049: {
        !          1050:     SET_BDA(dcc_index, regs->bl);
        !          1051:     dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh);
        !          1052:     regs->al = 0x1a;
        !          1053: }
        !          1054: 
        !          1055: static void
        !          1056: handle_101aXX(struct bregs *regs)
        !          1057: {
        !          1058:     debug_stub(regs);
        !          1059: }
        !          1060: 
        !          1061: static void
        !          1062: handle_101a(struct bregs *regs)
        !          1063: {
        !          1064:     switch (regs->al) {
        !          1065:     case 0x00: handle_101a00(regs); break;
        !          1066:     case 0x01: handle_101a01(regs); break;
        !          1067:     default:   handle_101aXX(regs); break;
        !          1068:     }
        !          1069: }
        !          1070: 
        !          1071: 
        !          1072: struct funcInfo {
        !          1073:     u16 static_functionality_off;
        !          1074:     u16 static_functionality_seg;
        !          1075:     u8 bda_0x49[30];
        !          1076:     u8 bda_0x84[3];
        !          1077:     u8 dcc_index;
        !          1078:     u8 dcc_alt;
        !          1079:     u16 colors;
        !          1080:     u8 pages;
        !          1081:     u8 scan_lines;
        !          1082:     u8 primary_char;
        !          1083:     u8 secondar_char;
        !          1084:     u8 misc;
        !          1085:     u8 non_vga_mode;
        !          1086:     u8 reserved_2f[2];
        !          1087:     u8 video_mem;
        !          1088:     u8 save_flags;
        !          1089:     u8 disp_info;
        !          1090:     u8 reserved_34[12];
        !          1091: };
        !          1092: 
        !          1093: static void
        !          1094: handle_101b(struct bregs *regs)
        !          1095: {
        !          1096:     u16 seg = regs->es;
        !          1097:     struct funcInfo *info = (void*)(regs->di+0);
        !          1098:     memset_far(seg, info, 0, sizeof(*info));
        !          1099:     // Address of static functionality table
        !          1100:     SET_FARVAR(seg, info->static_functionality_off, (u32)static_functionality);
        !          1101:     SET_FARVAR(seg, info->static_functionality_seg, get_global_seg());
        !          1102: 
        !          1103:     // Hard coded copy from BIOS area. Should it be cleaner ?
        !          1104:     memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49
        !          1105:                , sizeof(info->bda_0x49));
        !          1106:     memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84
        !          1107:                , sizeof(info->bda_0x84));
        !          1108: 
        !          1109:     SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index));
        !          1110:     SET_FARVAR(seg, info->colors, 16);
        !          1111:     SET_FARVAR(seg, info->pages, 8);
        !          1112:     SET_FARVAR(seg, info->scan_lines, 2);
        !          1113:     SET_FARVAR(seg, info->video_mem, 3);
        !          1114:     regs->al = 0x1B;
        !          1115: }
        !          1116: 
        !          1117: 
        !          1118: static void
        !          1119: handle_101c00(struct bregs *regs)
        !          1120: {
        !          1121:     u16 flags = regs->cx;
        !          1122:     u16 size = 0;
        !          1123:     if (flags & 1)
        !          1124:         size += sizeof(struct saveVideoHardware);
        !          1125:     if (flags & 2)
        !          1126:         size += sizeof(struct saveBDAstate);
        !          1127:     if (flags & 4)
        !          1128:         size += sizeof(struct saveDACcolors);
        !          1129:     regs->bx = size;
        !          1130:     regs->al = 0x1c;
        !          1131: }
        !          1132: 
        !          1133: static void
        !          1134: handle_101c01(struct bregs *regs)
        !          1135: {
        !          1136:     u16 flags = regs->cx;
        !          1137:     u16 seg = regs->es;
        !          1138:     void *data = (void*)(regs->bx+0);
        !          1139:     if (flags & 1) {
        !          1140:         vgahw_save_state(seg, data);
        !          1141:         data += sizeof(struct saveVideoHardware);
        !          1142:     }
        !          1143:     if (flags & 2) {
        !          1144:         save_bda_state(seg, data);
        !          1145:         data += sizeof(struct saveBDAstate);
        !          1146:     }
        !          1147:     if (flags & 4)
        !          1148:         vgahw_save_dac_state(seg, data);
        !          1149:     regs->al = 0x1c;
        !          1150: }
        !          1151: 
        !          1152: static void
        !          1153: handle_101c02(struct bregs *regs)
        !          1154: {
        !          1155:     u16 flags = regs->cx;
        !          1156:     u16 seg = regs->es;
        !          1157:     void *data = (void*)(regs->bx+0);
        !          1158:     if (flags & 1) {
        !          1159:         vgahw_restore_state(seg, data);
        !          1160:         data += sizeof(struct saveVideoHardware);
        !          1161:     }
        !          1162:     if (flags & 2) {
        !          1163:         restore_bda_state(seg, data);
        !          1164:         data += sizeof(struct saveBDAstate);
        !          1165:     }
        !          1166:     if (flags & 4)
        !          1167:         vgahw_restore_dac_state(seg, data);
        !          1168:     regs->al = 0x1c;
        !          1169: }
        !          1170: 
        !          1171: static void
        !          1172: handle_101cXX(struct bregs *regs)
        !          1173: {
        !          1174:     debug_stub(regs);
        !          1175: }
        !          1176: 
        !          1177: static void
        !          1178: handle_101c(struct bregs *regs)
        !          1179: {
        !          1180:     switch (regs->al) {
        !          1181:     case 0x00: handle_101c00(regs); break;
        !          1182:     case 0x01: handle_101c01(regs); break;
        !          1183:     case 0x02: handle_101c02(regs); break;
        !          1184:     default:   handle_101cXX(regs); break;
        !          1185:     }
        !          1186: }
        !          1187: 
        !          1188: 
        !          1189: static void
        !          1190: handle_104f00(struct bregs *regs)
        !          1191: {
        !          1192:     // XXX - vbe_biosfn_return_controller_information(&AX,ES,DI);
        !          1193:     // XXX - OR cirrus_vesa_00h
        !          1194: }
        !          1195: 
        !          1196: static void
        !          1197: handle_104f01(struct bregs *regs)
        !          1198: {
        !          1199:     // XXX - vbe_biosfn_return_mode_information(&AX,CX,ES,DI);
        !          1200:     // XXX - OR cirrus_vesa_01h
        !          1201: }
        !          1202: 
        !          1203: static void
        !          1204: handle_104f02(struct bregs *regs)
        !          1205: {
        !          1206:     // XXX - vbe_biosfn_set_mode(&AX,BX,ES,DI);
        !          1207:     // XXX - OR cirrus_vesa_02h
        !          1208: }
        !          1209: 
        !          1210: static void
        !          1211: handle_104f03(struct bregs *regs)
        !          1212: {
        !          1213:     // XXX - vbe_biosfn_return_current_mode
        !          1214:     // XXX - OR cirrus_vesa_03h
        !          1215: }
        !          1216: 
        !          1217: static void
        !          1218: handle_104f04(struct bregs *regs)
        !          1219: {
        !          1220:     // XXX - vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);
        !          1221: }
        !          1222: 
        !          1223: static void
        !          1224: handle_104f05(struct bregs *regs)
        !          1225: {
        !          1226:     // XXX - vbe_biosfn_display_window_control
        !          1227:     // XXX - OR cirrus_vesa_05h
        !          1228: }
        !          1229: 
        !          1230: static void
        !          1231: handle_104f06(struct bregs *regs)
        !          1232: {
        !          1233:     // XXX - vbe_biosfn_set_get_logical_scan_line_length
        !          1234:     // XXX - OR cirrus_vesa_06h
        !          1235: }
        !          1236: 
        !          1237: static void
        !          1238: handle_104f07(struct bregs *regs)
        !          1239: {
        !          1240:     // XXX - vbe_biosfn_set_get_display_start
        !          1241:     // XXX - OR cirrus_vesa_07h
        !          1242: }
        !          1243: 
        !          1244: static void
        !          1245: handle_104f08(struct bregs *regs)
        !          1246: {
        !          1247:     // XXX - vbe_biosfn_set_get_dac_palette_format
        !          1248: }
        !          1249: 
        !          1250: static void
        !          1251: handle_104f0a(struct bregs *regs)
        !          1252: {
        !          1253:     // XXX - vbe_biosfn_return_protected_mode_interface
        !          1254: }
        !          1255: 
        !          1256: static void
        !          1257: handle_104fXX(struct bregs *regs)
        !          1258: {
        !          1259:     debug_stub(regs);
        !          1260:     regs->ax = 0x0100;
        !          1261: }
        !          1262: 
        !          1263: static void
        !          1264: handle_104f(struct bregs *regs)
        !          1265: {
        !          1266:     if (! CONFIG_VBE || !vbe_has_vbe_display()) {
        !          1267:         handle_104fXX(regs);
        !          1268:         return;
        !          1269:     }
        !          1270: 
        !          1271:     switch (regs->al) {
        !          1272:     case 0x00: handle_104f00(regs); break;
        !          1273:     case 0x01: handle_104f01(regs); break;
        !          1274:     case 0x02: handle_104f02(regs); break;
        !          1275:     case 0x03: handle_104f03(regs); break;
        !          1276:     case 0x04: handle_104f04(regs); break;
        !          1277:     case 0x05: handle_104f05(regs); break;
        !          1278:     case 0x06: handle_104f06(regs); break;
        !          1279:     case 0x07: handle_104f07(regs); break;
        !          1280:     case 0x08: handle_104f08(regs); break;
        !          1281:     case 0x0a: handle_104f0a(regs); break;
        !          1282:     default:   handle_104fXX(regs); break;
        !          1283:     }
        !          1284: }
        !          1285: 
        !          1286: 
        !          1287: static void
        !          1288: handle_10XX(struct bregs *regs)
        !          1289: {
        !          1290:     debug_stub(regs);
        !          1291: }
        !          1292: 
        !          1293: // INT 10h Video Support Service Entry Point
        !          1294: void VISIBLE16
        !          1295: handle_10(struct bregs *regs)
        !          1296: {
        !          1297:     debug_enter(regs, DEBUG_VGA_10);
        !          1298:     switch (regs->ah) {
        !          1299:     case 0x00: handle_1000(regs); break;
        !          1300:     case 0x01: handle_1001(regs); break;
        !          1301:     case 0x02: handle_1002(regs); break;
        !          1302:     case 0x03: handle_1003(regs); break;
        !          1303:     case 0x04: handle_1004(regs); break;
        !          1304:     case 0x05: handle_1005(regs); break;
        !          1305:     case 0x06: handle_1006(regs); break;
        !          1306:     case 0x07: handle_1007(regs); break;
        !          1307:     case 0x08: handle_1008(regs); break;
        !          1308:     case 0x09: handle_1009(regs); break;
        !          1309:     case 0x0a: handle_100a(regs); break;
        !          1310:     case 0x0b: handle_100b(regs); break;
        !          1311:     case 0x0c: handle_100c(regs); break;
        !          1312:     case 0x0d: handle_100d(regs); break;
        !          1313:     case 0x0e: handle_100e(regs); break;
        !          1314:     case 0x0f: handle_100f(regs); break;
        !          1315:     case 0x10: handle_1010(regs); break;
        !          1316:     case 0x11: handle_1011(regs); break;
        !          1317:     case 0x12: handle_1012(regs); break;
        !          1318:     case 0x13: handle_1013(regs); break;
        !          1319:     case 0x1a: handle_101a(regs); break;
        !          1320:     case 0x1b: handle_101b(regs); break;
        !          1321:     case 0x1c: handle_101c(regs); break;
        !          1322:     case 0x4f: handle_104f(regs); break;
        !          1323:     default:   handle_10XX(regs); break;
        !          1324:     }
        !          1325: }
        !          1326: 
        !          1327: 
        !          1328: /****************************************************************
        !          1329:  * VGA post
        !          1330:  ****************************************************************/
        !          1331: 
        !          1332: static void
        !          1333: init_bios_area()
        !          1334: {
        !          1335:     // init detected hardware BIOS Area
        !          1336:     // set 80x25 color (not clear from RBIL but usual)
        !          1337:     u16 eqf = GET_BDA(equipment_list_flags);
        !          1338:     SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20);
        !          1339: 
        !          1340:     // Just for the first int10 find its children
        !          1341: 
        !          1342:     // the default char height
        !          1343:     SET_BDA(char_height, 0x10);
        !          1344: 
        !          1345:     // Clear the screen
        !          1346:     SET_BDA(video_ctl, 0x60);
        !          1347: 
        !          1348:     // Set the basic screen we have
        !          1349:     SET_BDA(video_switches, 0xf9);
        !          1350: 
        !          1351:     // Set the basic modeset options
        !          1352:     SET_BDA(modeset_ctl, 0x51);
        !          1353: 
        !          1354:     // Set the  default MSR
        !          1355:     SET_BDA(video_msr, 0x09);
        !          1356: }
        !          1357: 
        !          1358: void VISIBLE16
        !          1359: vga_post(struct bregs *regs)
        !          1360: {
        !          1361:     debug_enter(regs, DEBUG_VGA_POST);
        !          1362: 
        !          1363:     vgahw_init();
        !          1364: 
        !          1365:     init_bios_area();
        !          1366: 
        !          1367:     if (CONFIG_VBE)
        !          1368:         vbe_init();
        !          1369: 
        !          1370:     extern void entry_10(void);
        !          1371:     SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
        !          1372: 
        !          1373:     if (CONFIG_CIRRUS)
        !          1374:         cirrus_init();
        !          1375: 
        !          1376:     // XXX - clear screen and display info
        !          1377: 
        !          1378:     // XXX: fill it
        !          1379:     SET_VGA(video_save_pointer_table[0], (u32)video_param_table);
        !          1380:     SET_VGA(video_save_pointer_table[1], get_global_seg());
        !          1381: 
        !          1382:     // Fixup checksum
        !          1383:     extern u8 _rom_header_size, _rom_header_checksum;
        !          1384:     SET_VGA(_rom_header_checksum, 0);
        !          1385:     u8 sum = -checksum_far(get_global_seg(), 0, _rom_header_size * 512);
        !          1386:     SET_VGA(_rom_header_checksum, sum);
        !          1387: }

unix.superglobalmegacorp.com

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