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

1.1       root        1: // Video Bios Extensions handlers
                      2: //
                      3: // Copyright (C) 2012  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2011  Julian Pidancet <[email protected]>
                      5: // Copyright (C) 2001-2008 the LGPL VGABios developers Team
                      6: //
                      7: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      8: 
                      9: #include "vgabios.h" // handle_104f
                     10: #include "config.h" // CONFIG_*
                     11: #include "bregs.h" // struct bregs
                     12: #include "vbe.h" // struct vbe_info
                     13: #include "util.h" // dprintf
                     14: #include "biosvar.h" // GET_GLOBAL
                     15: #include "vgahw.h" // vgahw_set_mode
                     16: 
                     17: u32 VBE_total_memory VAR16 = 256 * 1024;
                     18: u32 VBE_capabilities VAR16;
                     19: u32 VBE_framebuffer VAR16;
                     20: u16 VBE_win_granularity VAR16 = 64;
                     21: 
                     22: static void
                     23: vbe_104f00(struct bregs *regs)
                     24: {
                     25:     u16 seg = regs->es;
                     26:     struct vbe_info *info = (void*)(regs->di+0);
                     27: 
                     28:     if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) {
                     29:         dprintf(4, "Get VBE Controller: VBE2 Signature found\n");
                     30:     } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) {
                     31:         dprintf(4, "Get VBE Controller: VESA Signature found\n");
                     32:     } else {
                     33:         dprintf(4, "Get VBE Controller: Invalid Signature\n");
                     34:     }
                     35: 
                     36:     memset_far(seg, info, 0, sizeof(*info));
                     37: 
                     38:     SET_FARVAR(seg, info->signature, VESA_SIGNATURE);
                     39: 
                     40:     SET_FARVAR(seg, info->version, 0x0300);
                     41: 
                     42:     SET_FARVAR(seg, info->oem_string,
                     43:             SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING));
                     44:     SET_FARVAR(seg, info->capabilities, GET_GLOBAL(VBE_capabilities));
                     45: 
                     46:     /* We generate our mode list in the reserved field of the info block */
                     47:     u16 *destmode = (void*)info->reserved;
                     48:     SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode));
                     49: 
                     50:     /* Total memory (in 64k blocks) */
                     51:     SET_FARVAR(seg, info->total_memory
                     52:                , GET_GLOBAL(VBE_total_memory) / (64*1024));
                     53: 
                     54:     SET_FARVAR(seg, info->oem_vendor_string,
                     55:             SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING));
                     56:     SET_FARVAR(seg, info->oem_product_string,
                     57:             SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING));
                     58:     SET_FARVAR(seg, info->oem_revision_string,
                     59:             SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING));
                     60: 
                     61:     /* Fill list of modes */
                     62:     u16 *last = (void*)&info->reserved[sizeof(info->reserved)];
                     63:     vgahw_list_modes(seg, destmode, last - 1);
                     64: 
                     65:     regs->ax = 0x004f;
                     66: }
                     67: 
                     68: static void
                     69: vbe_104f01(struct bregs *regs)
                     70: {
                     71:     u16 seg = regs->es;
                     72:     struct vbe_mode_info *info = (void*)(regs->di+0);
                     73:     u16 mode = regs->cx;
                     74: 
                     75:     dprintf(1, "VBE mode info request: %x\n", mode);
                     76: 
                     77:     struct vgamode_s *vmode_g = vgahw_find_mode(mode);
                     78:     if (! vmode_g) {
                     79:         dprintf(1, "VBE mode %x not found\n", mode);
                     80:         regs->ax = 0x014f;
                     81:         return;
                     82:     }
                     83: 
                     84:     memset_far(seg, info, 0, sizeof(*info));
                     85:     u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED |
                     86:                     VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE |
                     87:                     VBE_MODE_ATTRIBUTE_COLOR_MODE |
                     88:                     VBE_MODE_ATTRIBUTE_GRAPHICS_MODE |
                     89:                     VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE;
                     90:     u32 framebuffer = GET_GLOBAL(VBE_framebuffer);
                     91:     if (framebuffer)
                     92:         mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE;
                     93:     SET_FARVAR(seg, info->mode_attributes, mode_attr);
                     94:     SET_FARVAR(seg, info->winA_attributes,
                     95:                VBE_WINDOW_ATTRIBUTE_RELOCATABLE |
                     96:                VBE_WINDOW_ATTRIBUTE_READABLE |
                     97:                VBE_WINDOW_ATTRIBUTE_WRITEABLE);
                     98:     SET_FARVAR(seg, info->winB_attributes, 0);
                     99:     SET_FARVAR(seg, info->win_granularity, GET_GLOBAL(VBE_win_granularity));
                    100:     SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */
                    101:     SET_FARVAR(seg, info->winA_seg, GET_GLOBAL(vmode_g->sstart));
                    102:     SET_FARVAR(seg, info->winB_seg, 0x0);
                    103:     extern void entry_104f05(void);
                    104:     SET_FARVAR(seg, info->win_func_ptr
                    105:                , SEGOFF(get_global_seg(), (u32)entry_104f05));
                    106:     int width = GET_GLOBAL(vmode_g->width);
                    107:     int height = GET_GLOBAL(vmode_g->height);
                    108:     int linesize = DIV_ROUND_UP(width * vga_bpp(vmode_g), 8);
                    109:     SET_FARVAR(seg, info->bytes_per_scanline, linesize);
                    110:     SET_FARVAR(seg, info->xres, width);
                    111:     SET_FARVAR(seg, info->yres, height);
                    112:     SET_FARVAR(seg, info->xcharsize, GET_GLOBAL(vmode_g->cwidth));
                    113:     SET_FARVAR(seg, info->ycharsize, GET_GLOBAL(vmode_g->cheight));
                    114:     int depth = GET_GLOBAL(vmode_g->depth);
                    115:     int planes = (depth == 4) ? 4 : 1;
                    116:     SET_FARVAR(seg, info->planes, planes);
                    117:     SET_FARVAR(seg, info->bits_per_pixel, depth);
                    118:     SET_FARVAR(seg, info->banks, 1);
                    119:     SET_FARVAR(seg, info->mem_model, GET_GLOBAL(vmode_g->memmodel));
                    120:     SET_FARVAR(seg, info->bank_size, 0);
                    121:     u32 pages = GET_GLOBAL(VBE_total_memory) / ALIGN(height * linesize, 64*1024);
                    122:     SET_FARVAR(seg, info->pages, (pages / planes) - 1);
                    123:     SET_FARVAR(seg, info->reserved0, 1);
                    124: 
                    125:     u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos;
                    126: 
                    127:     switch (depth) {
                    128:     case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5;
                    129:              b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break;
                    130:     case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5;
                    131:              b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break;
                    132:     case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8;
                    133:              b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break;
                    134:     case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8;
                    135:              b_size = 8; b_pos = 0; a_size = 8; a_pos = 24; break;
                    136:     default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0;
                    137:              b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break;
                    138:     }
                    139: 
                    140:     SET_FARVAR(seg, info->red_size, r_size);
                    141:     SET_FARVAR(seg, info->red_pos, r_pos);
                    142:     SET_FARVAR(seg, info->green_size, g_size);
                    143:     SET_FARVAR(seg, info->green_pos, g_pos);
                    144:     SET_FARVAR(seg, info->blue_size, b_size);
                    145:     SET_FARVAR(seg, info->blue_pos, b_pos);
                    146:     SET_FARVAR(seg, info->alpha_size, a_size);
                    147:     SET_FARVAR(seg, info->alpha_pos, a_pos);
                    148: 
                    149:     if (depth == 32)
                    150:         SET_FARVAR(seg, info->directcolor_info,
                    151:                    VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE);
                    152:     else
                    153:         SET_FARVAR(seg, info->directcolor_info, 0);
                    154: 
                    155:     if (depth > 4)
                    156:         SET_FARVAR(seg, info->phys_base, GET_GLOBAL(VBE_framebuffer));
                    157:     else
                    158:         SET_FARVAR(seg, info->phys_base, 0);
                    159: 
                    160:     SET_FARVAR(seg, info->reserved1, 0);
                    161:     SET_FARVAR(seg, info->reserved2, 0);
                    162:     SET_FARVAR(seg, info->linear_bytes_per_scanline, linesize);
                    163:     SET_FARVAR(seg, info->bank_pages, 0);
                    164:     SET_FARVAR(seg, info->linear_pages, 0);
                    165:     SET_FARVAR(seg, info->linear_red_size, r_size);
                    166:     SET_FARVAR(seg, info->linear_red_pos, r_pos);
                    167:     SET_FARVAR(seg, info->linear_green_size, g_size);
                    168:     SET_FARVAR(seg, info->linear_green_pos, g_pos);
                    169:     SET_FARVAR(seg, info->linear_blue_size, b_size);
                    170:     SET_FARVAR(seg, info->linear_blue_pos, b_pos);
                    171:     SET_FARVAR(seg, info->linear_alpha_size, a_size);
                    172:     SET_FARVAR(seg, info->linear_alpha_pos, a_pos);
                    173:     SET_FARVAR(seg, info->pixclock_max, 0);
                    174: 
                    175:     regs->ax = 0x004f;
                    176: }
                    177: 
                    178: static void
                    179: vbe_104f02(struct bregs *regs)
                    180: {
                    181:     dprintf(1, "VBE mode set: %x\n", regs->bx);
                    182: 
                    183:     int mode = regs->bx & ~MF_VBEFLAGS;
                    184:     int flags = regs->bx & MF_VBEFLAGS;
                    185:     int ret = vga_set_mode(mode, flags);
                    186: 
                    187:     regs->ah = ret;
                    188:     regs->al = 0x4f;
                    189: }
                    190: 
                    191: static void
                    192: vbe_104f03(struct bregs *regs)
                    193: {
                    194:     regs->bx = GET_BDA(vbe_mode);
                    195:     dprintf(1, "VBE current mode=%x\n", regs->bx);
                    196:     regs->ax = 0x004f;
                    197: }
                    198: 
                    199: static void
                    200: vbe_104f04(struct bregs *regs)
                    201: {
                    202:     u16 seg = regs->es;
                    203:     void *data = (void*)(regs->bx+0);
                    204:     u16 states = regs->cx;
                    205:     if (states & ~0x0f)
                    206:         goto fail;
                    207:     int ret;
                    208:     switch (regs->dl) {
                    209:     case 0x00:
                    210:         ret = vgahw_size_state(states);
                    211:         if (ret < 0)
                    212:             goto fail;
                    213:         regs->bx = ret / 64;
                    214:         break;
                    215:     case 0x01:
                    216:         ret = vgahw_save_state(seg, data, states);
                    217:         if (ret)
                    218:             goto fail;
                    219:         break;
                    220:     case 0x02:
                    221:         ret = vgahw_restore_state(seg, data, states);
                    222:         if (ret)
                    223:             goto fail;
                    224:         break;
                    225:     default:
                    226:         goto fail;
                    227:     }
                    228:     regs->ax = 0x004f;
                    229:     return;
                    230: fail:
                    231:     regs->ax = 0x014f;
                    232: }
                    233: 
                    234: void VISIBLE16
                    235: vbe_104f05(struct bregs *regs)
                    236: {
                    237:     if (regs->bh > 1 || regs->bl > 1)
                    238:         goto fail;
                    239:     if (GET_BDA(vbe_mode) & MF_LINEARFB) {
                    240:         regs->ah = VBE_RETURN_STATUS_INVALID;
                    241:         return;
                    242:     }
                    243:     struct vgamode_s *vmode_g = get_current_mode();
                    244:     if (! vmode_g)
                    245:         goto fail;
                    246:     if (regs->bh) {
                    247:         int ret = vgahw_get_window(vmode_g, regs->bl);
                    248:         if (ret < 0)
                    249:             goto fail;
                    250:         regs->dx = ret;
                    251:         regs->ax = 0x004f;
                    252:         return;
                    253:     }
                    254:     int ret = vgahw_set_window(vmode_g, regs->bl, regs->dx);
                    255:     if (ret)
                    256:         goto fail;
                    257:     regs->ax = 0x004f;
                    258:     return;
                    259: fail:
                    260:     regs->ax = 0x014f;
                    261: }
                    262: 
                    263: static void
                    264: vbe_104f06(struct bregs *regs)
                    265: {
                    266:     if (regs->bl > 0x02)
                    267:         goto fail;
                    268:     struct vgamode_s *vmode_g = get_current_mode();
                    269:     if (! vmode_g)
                    270:         goto fail;
                    271:     int bpp = vga_bpp(vmode_g);
                    272: 
                    273:     if (regs->bl == 0x00) {
                    274:         int ret = vgahw_set_linelength(vmode_g, DIV_ROUND_UP(regs->cx * bpp, 8));
                    275:         if (ret)
                    276:             goto fail;
                    277:     } else if (regs->bl == 0x02) {
                    278:         int ret = vgahw_set_linelength(vmode_g, regs->cx);
                    279:         if (ret)
                    280:             goto fail;
                    281:     }
                    282:     int linelength = vgahw_get_linelength(vmode_g);
                    283:     if (linelength < 0)
                    284:         goto fail;
                    285: 
                    286:     regs->bx = linelength;
                    287:     regs->cx = (linelength * 8) / bpp;
                    288:     regs->dx = GET_GLOBAL(VBE_total_memory) / linelength;
                    289:     regs->ax = 0x004f;
                    290:     return;
                    291: fail:
                    292:     regs->ax = 0x014f;
                    293: }
                    294: 
                    295: static void
                    296: vbe_104f07(struct bregs *regs)
                    297: {
                    298:     struct vgamode_s *vmode_g = get_current_mode();
                    299:     if (! vmode_g)
                    300:         goto fail;
                    301:     int bpp = vga_bpp(vmode_g);
                    302:     int linelength = vgahw_get_linelength(vmode_g);
                    303:     if (linelength < 0)
                    304:         goto fail;
                    305: 
                    306:     int ret;
                    307:     switch (regs->bl) {
                    308:     case 0x80:
                    309:     case 0x00:
                    310:         ret = vgahw_set_displaystart(
                    311:             vmode_g, DIV_ROUND_UP(regs->cx * bpp, 8) + linelength * regs->dx);
                    312:         if (ret)
                    313:             goto fail;
                    314:         break;
                    315:     case 0x01:
                    316:         ret = vgahw_get_displaystart(vmode_g);
                    317:         if (ret < 0)
                    318:             goto fail;
                    319:         regs->dx = ret / linelength;
                    320:         regs->cx = (ret % linelength) * 8 / bpp;
                    321:         break;
                    322:     default:
                    323:         goto fail;
                    324:     }
                    325:     regs->ax = 0x004f;
                    326:     return;
                    327: fail:
                    328:     regs->ax = 0x014f;
                    329: }
                    330: 
                    331: static void
                    332: vbe_104f08(struct bregs *regs)
                    333: {
                    334:     struct vgamode_s *vmode_g = get_current_mode();
                    335:     if (! vmode_g)
                    336:         goto fail;
                    337:     u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
                    338:     if (memmodel == MM_DIRECT || memmodel == MM_YUV) {
                    339:         regs->ax = 0x034f;
                    340:         return;
                    341:     }
                    342:     if (regs->bl > 1)
                    343:         goto fail;
                    344:     if (regs->bl == 0) {
                    345:         int ret = vgahw_set_dacformat(vmode_g, regs->bh);
                    346:         if (ret < 0)
                    347:             goto fail;
                    348:     }
                    349:     int ret = vgahw_get_dacformat(vmode_g);
                    350:     if (ret < 0)
                    351:         goto fail;
                    352:     regs->bh = ret;
                    353:     regs->ax = 0x004f;
                    354:     return;
                    355: fail:
                    356:     regs->ax = 0x014f;
                    357: }
                    358: 
                    359: static void
                    360: vbe_104f0a(struct bregs *regs)
                    361: {
                    362:     debug_stub(regs);
                    363:     regs->ax = 0x0100;
                    364: }
                    365: 
                    366: static void
                    367: vbe_104f10(struct bregs *regs)
                    368: {
                    369:     switch (regs->bl) {
                    370:     case 0x00:
                    371:         regs->bx = 0x0f30;
                    372:         break;
                    373:     case 0x01:
                    374:         SET_BDA(vbe_flag, regs->bh);
                    375:         break;
                    376:     case 0x02:
                    377:         regs->bh = GET_BDA(vbe_flag);
                    378:         break;
                    379:     default:
                    380:         regs->ax = 0x014f;
                    381:         return;
                    382:     }
                    383:     regs->ax = 0x004f;
                    384: }
                    385: 
                    386: static void
                    387: vbe_104fXX(struct bregs *regs)
                    388: {
                    389:     debug_stub(regs);
                    390:     regs->ax = 0x0100;
                    391: }
                    392: 
                    393: void noinline
                    394: handle_104f(struct bregs *regs)
                    395: {
                    396:     if (!CONFIG_VGA_VBE) {
                    397:         vbe_104fXX(regs);
                    398:         return;
                    399:     }
                    400: 
                    401:     switch (regs->al) {
                    402:     case 0x00: vbe_104f00(regs); break;
                    403:     case 0x01: vbe_104f01(regs); break;
                    404:     case 0x02: vbe_104f02(regs); break;
                    405:     case 0x03: vbe_104f03(regs); break;
                    406:     case 0x04: vbe_104f04(regs); break;
                    407:     case 0x05: vbe_104f05(regs); break;
                    408:     case 0x06: vbe_104f06(regs); break;
                    409:     case 0x07: vbe_104f07(regs); break;
                    410:     case 0x08: vbe_104f08(regs); break;
                    411:     case 0x0a: vbe_104f0a(regs); break;
                    412:     case 0x10: vbe_104f10(regs); break;
                    413:     default:   vbe_104fXX(regs); break;
                    414:     }
                    415: }

unix.superglobalmegacorp.com

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