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