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