VirtualBox

Changeset 75149 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Oct 29, 2018 2:14:22 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126227
Message:

BIOS: Added custom video mode set function not limited by the list of available VBE modes (bugref:9273).

Location:
trunk/src/VBox/Devices
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/BIOS/makefile

    r43115 r75149  
    1515!endif
    1616CFLAGS = -q -3 -wx -zu -zl -s -oas -d1 -ms
    17 DEFS   = -DVBOX -DVBE -DVBOX_VERSION_STRING=$(Q)0.9.90$(Q) -DVBOX_VENDOR=$(Q)Oracle_Corporation$(Q) -DVBOX_PRODUCT=$(Q)Oracle_VM_VirtualBox$(Q)
     17DEFS   = -DVBOX -DVBE -DVBOX_VERSION_STRING=$(Q)0.9.90$(Q) -DVBOX_VENDOR=$(Q)Oracle_Corporation$(Q) -DVBOX_PRODUCT=$(Q)Oracle_VM_VirtualBox$(Q) -DVBOX_BIOS_CPU=80386
    1818#DEFS   = -DVBOX -DVBOX_VERSION_STRING=$(Q)0.9$(Q) -DVBOX_VENDOR=$(Q)Oracle$(Q) -DVBOX_PRODUCT=$(Q)VirtualBox$(Q)
    1919
    2020AFLAGS = -q -0 -wx
    2121
    22 INCLS  = -I$(Q)../../../../../include$(Q)
     22INCLS  = -I$(Q)../../../../../include$(Q) -I$(Q)../../../../../include/VBox/Graphics$(Q)
     23AINCS  = -I$(Q)../../BiosCommonCode$(Q)
    2324
    2425.c.obj : .autodepend
     
    2627
    2728.asm.obj : .autodepend
    28         wasm -fo=.obj $(AFLAGS) $(DEFS) $<
     29        wasm -fo=.obj $(AFLAGS) $(DEFS) $(AINCS) $<
    2930
    3031OBJS =  vgarom.obj vberom.obj vgabios.obj vbe.obj
  • trunk/src/VBox/Devices/Graphics/BIOS/vbe.c

    r69047 r75149  
    699699    *AX = result;
    700700}
     701
     702
     703/* We would very much like to avoid dragging in the long multiply library
     704 * routine, and we really just need to multiply two 16-bit numbers to
     705 * obtain a 32-bit result, so...
     706 */
     707uint32_t mul32_16x16(uint16_t a, uint16_t b);
     708#pragma aux mul32_16x16 =   \
     709    "mul    dx"             \
     710    parm [ax] [dx] modify nomemory;
     711
     712
     713/** Private INT 10h function 5642h - Manage custom video modes using X/Y
     714 *  resolution and bit depth rather than mode number
     715 *
     716 *  Input:
     717 *              AX      = 5642h ('VB')
     718 *              BL      = 00h Set video mode
     719 *              BH      = If BL=00h Desired bit depth in pixels
     720 *              CX      = If BL=00h Desired width in pixels
     721 *              DX      = If BL=00h Desired height in pixels
     722 *
     723 *  Output:
     724 *              AX      = VBE style return status
     725 */
     726void private_biosfn_custom_mode(uint16_t STACK_BASED *AX, uint16_t STACK_BASED *BX,
     727                                uint16_t STACK_BASED *CX, uint16_t STACK_BASED *DX)
     728{
     729    uint16_t    result;
     730    uint8_t     subfn;
     731    uint8_t     bpp;
     732    uint8_t     lfb_flag;
     733    uint16_t    xres;
     734    uint16_t    yres;
     735    uint16_t    line_size;
     736    uint32_t    vram_size;
     737    uint32_t    mode_size;
     738
     739    result = 0x004F;
     740    subfn  = *BX & 0xFF;
     741    switch (subfn) {
     742    case 0x00:
     743        xres = *CX;
     744        yres = *DX;
     745        bpp  = (*BX >> 8) & 0x7F;
     746#ifdef VGA_DEBUG
     747        printf("Set custom mode %04x by %04x %xbpp\n", xres, yres, bpp);
     748#endif
     749        /* Only allow 32/16/8bpp. */
     750        if (bpp != 8 && bpp != 16 && bpp != 32) {
     751            result = 0x100;
     752            break;
     753        }
     754
     755        /* Determine the LFB flag. */
     756        lfb_flag = *BX & 0x8000 ? VBE_DISPI_LFB_ENABLED : 0;
     757
     758        /* Cap the resolution to something not insanely high or low. */
     759        if (xres < 640)
     760            xres = 640;
     761        else if (xres > 2560)
     762            xres = 2560;
     763        if (yres < 480)
     764            yres = 480;
     765        else if (yres > 1920)
     766            yres = 1920;
     767#ifdef VGA_DEBUG
     768        printf("Adjusted resolution %04x by %04x\n", xres, yres);
     769#endif
     770
     771        /* Calculate the VRAM size in bytes. */
     772        vram_size = (uint32_t)in_word(VBE_EXTRA_PORT, 0xffff) << 16;
     773
     774        /* Calculate the scanline size in bytes. */
     775        line_size = xres * (bpp / 8);
     776        line_size = (line_size + 3) & ~3;
     777        /* And now the memory required for the mode. */
     778        mode_size = mul32_16x16(line_size, yres);
     779
     780        if (mode_size > vram_size) {
     781            /* No can do. Don't have that much VRAM. */
     782            result = 0x200;
     783            break;
     784        }
     785
     786        /* Mode looks valid, let's get cracking. */
     787        dispi_set_enable(VBE_DISPI_DISABLED);
     788        dispi_set_bpp(bpp);
     789        dispi_set_xres(xres);
     790        dispi_set_yres(yres);
     791        dispi_set_bank(0);
     792        dispi_set_enable(VBE_DISPI_ENABLED | lfb_flag);
     793        vga_compat_setup();
     794        break;
     795
     796    default:
     797        // unsupported sub-function
     798        result = 0x100;
     799        break;
     800    }
     801    *AX = result;
     802}
  • trunk/src/VBox/Devices/Graphics/BIOS/vgabios.c

    r67853 r75149  
    21082108extern void vbe_biosfn_save_restore_state(uint16_t STACK_BASED *AX, uint16_t CX, uint16_t DX, uint16_t ES, uint16_t STACK_BASED *BX);
    21092109extern void vbe_biosfn_get_set_scanline_length(uint16_t STACK_BASED *AX, uint16_t STACK_BASED *BX, uint16_t STACK_BASED *CX, uint16_t STACK_BASED *DX);
     2110extern void private_biosfn_custom_mode(uint16_t STACK_BASED *AX, uint16_t STACK_BASED *BX, uint16_t STACK_BASED *CX, uint16_t STACK_BASED *DX);
     2111
    21102112
    21112113// --------------------------------------------------------------------------------------------
     
    23352337          }
    23362338        break;
     2339   case 0x56:
     2340     if (vbe_has_vbe_display()) {
     2341       switch(GET_AL())
     2342       {
     2343         case 0x42:
     2344           private_biosfn_custom_mode(&AX,&BX,&CX,&DX);
     2345           break;
     2346         default:
     2347           AX=0x0100;
     2348           break;
     2349       }
     2350     } else {
     2351         // No VBE display
     2352         AX=0x0100;
     2353     }
     2354     break;
    23372355#endif
    23382356
  • trunk/src/VBox/Devices/PC/BIOS/logo.c

    r69500 r75149  
    6161    parm [es di] modify [ax bx] nomemory;
    6262
     63
     64/**
     65 * Set custom video mode.
     66 * @param   xres    Requested width
     67 * @param   yres    Requested height
     68 * @param   bpp     Requested bits per pixel
     69 */
     70uint16_t custom_set_mode(uint16_t xres, uint16_t yres, uint8_t bpp);
     71#pragma aux custom_set_mode = \
     72    "mov    ax, 5642h"      \
     73    "mov    bl, 0"          \
     74    "int    10h"            \
     75    parm [cx] [dx] [bh] modify [ax] nomemory;
    6376
    6477/**
     
    369382        goto done;
    370383
    371     // Set video mode #0x142 640x480x32bpp
    372     vesa_set_mode(0x142);
     384    /* Set video mode using private video BIOS interface. */
     385    tmp = custom_set_mode(640*2, 480*2, 32);
     386    /* If custom mode set failed, fall back to VBE. */
     387    if (tmp != 0x4F)
     388        vesa_set_mode(0x142);
    373389
    374390    if (is_fade_in)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette