📄 vbe.c
字号:
/* if(environment == VMWARE) { setMode(VMWARE_MODE); return VMWARE_MODE; } else { AsmSetVgaMode(origMode); return origMode; } */}voidgetVbe3Info(){ /* Get VBE information */ /* Required registers: * AX = 4F00h VBE function number (Return VBE Controller Information) * ES:DI = pointer to buffer of VbeInfoBlock struct * * Output: * AX = should equal 4Fh if successful */ handleReturn(GetVbeControllerInfo(&Vbe3InfoBlock)); getVideoModes();}#if 0voidsetVbe3Info(){ /* Use this function for debug only. */ char *oemString,*vendorName,*productName,*productRev; printf("Setting sample VBE3 data...\n"); oemString = &Vbe3InfoBlock.reservedOEM[0]; strcpy(oemString,"Test OEM String"); vendorName = &Vbe3InfoBlock.reservedOEM[strlen(oemString)+1]; strcpy(vendorName,"Vendor Company Name"); productName = &Vbe3InfoBlock.reservedOEM[strlen(oemString)+strlen(vendorName)+2]; strcpy(productName,"ACME Graphics"); productRev = &Vbe3InfoBlock.reservedOEM[strlen(oemString)+strlen(vendorName)+strlen(productName)+3]; strcpy(productRev,"0.1 beta"); strcpy(Vbe3InfoBlock.VESASignature,"VBE2"); /* REQUIRED EVEN WHEN NOT DEBUGGING */ Vbe3InfoBlock.VESAVersion = 0x3D2; Vbe3InfoBlock.OEMStringPtr = "Test OEM string"; Vbe3InfoBlock.Capabilities = 0; Vbe3InfoBlock.VideoModePtr = 0; Vbe3InfoBlock.TotalMemory = 1024; Vbe3InfoBlock.OEMSoftwareRev = 0xFFFF; Vbe3InfoBlock.OEMVendorNamePtr = vendorName; Vbe3InfoBlock.OEMProductNamePtr = productName; Vbe3InfoBlock.OEMProductRevPtr = productRev;}#endifuint8_tfindEnvironment(){ if(!strcmp(Vbe3InfoBlock.OEMStringPtr,"VMware, Inc. SVGA")) return VMWARE; return UNKNOWN;}#if 0voidprintVbe3Info(){ char vbeString[5]; memcpy(vbeString, Vbe3InfoBlock.VESASignature, 4); vbeString[4] = 0; printf("VESA3 Communications Test\n"); printf("=========================\n\n"); printf("VESA signature : %s\n", vbeString); printf("VESA version : %d.%d\n",Vbe3InfoBlock.VESAVersion >> 8, Vbe3InfoBlock.VESAVersion & 0xFF); printf("OEM string : %s\n", Vbe3InfoBlock.OEMStringPtr); printf("Capabilities Word: 0x%x\n", Vbe3InfoBlock.Capabilities); printCapabilities(); printf("Video Modes Ptr : 0x%x\n", Vbe3InfoBlock.VideoModePtr); printVideoModes(); printf("Total memory : %d 64 kB chunks (%d bytes)\n", Vbe3InfoBlock.TotalMemory, (Vbe3InfoBlock.TotalMemory * 65536)); printf("OEM Software Rev : %d.%d\n", Vbe3InfoBlock.OEMSoftwareRev >> 8, Vbe3InfoBlock.OEMSoftwareRev & 0xFF); printf("OEM Vendor Name : %s\n", Vbe3InfoBlock.OEMVendorNamePtr); printf("OEM Product Name : %s\n", Vbe3InfoBlock.OEMProductNamePtr); printf("OEM Product Rev : %s\n", Vbe3InfoBlock.OEMProductRevPtr);}voidprintCapabilities(){ long caps = Vbe3InfoBlock.Capabilities; short int dac,vga,ramdac,stereo,signaling; dac = (caps<<31)>>31; vga = (caps<<30)>>31; ramdac = (caps<<29)>>31; stereo = (caps<<28)>>31; signaling = (caps<<27)>>31; if(dac) printf(" DAC width is switchable to 8 bits per primary color.\n"); else printf(" DAC is fixed width, with 6 bits per primary color.\n"); if(vga) printf(" Controller is not VGA compatible.\n"); else printf(" Controller is VGA compatible.\n"); if(ramdac) printf(" Abnormal (older) RAMDAC operation (refer to VESA spec).\n"); else printf(" Normal RAMDAC operation.\n"); if(stereo) { printf(" Hardware stereoscopic signaling supported by controller.\n"); if(signaling) printf(" Stereo signaling suported via VESA EVC connector.\n"); else printf(" Stereo signaling supported via external VESA stereo connector.\n"); } else printf(" No hardware stereoscopic signaling support.\n");}#endifvoidprintModeAttr(uint16_t attrs){ struct ModeAttributes attrib; attrib = *((struct ModeAttributes *) &attrs); printf (" %s %s %s %s %s %s %s %s %s %s %s %s\n", (attrib.hw) ? "hw" : "not-hw", (attrib.tty) ? "tty" : "notty", (attrib.color) ? "clr" : "mno", (attrib.graphics) ? "gfx" : "txt", (attrib.notvga) ? "novga" : "vga", (attrib.nowin) ? "novgawin" : "vgawin", (attrib.linfb) ? "fb" : "nofb", (attrib.dbscan) ? "dscan" : "nodscan", (attrib.ilace) ? "ilace" : "noilace", (attrib.tpbuf) ? "3buf" : "no3buf", (attrib.stereo) ? "3d" : "no3d", (attrib.dual) ? "2dsp" : "no2dsp"); /*printf ("%s %s %s %s %s %s %s %s %s %s %s %s\n", (attrs & 1u) ? "hw" : "not-hw", (attrs & (1u << 2)) ? "tty" : "notty", (attrs & (1u << 3)) ? "clr" : "mno", (attrs & (1u << 4)) ? "gfx" : "txt", (attrs & (1u << 5)) ? "novga" : "vga", (attrs & (1u << 6)) ? "novgawin" : "vgawin", (attrs & (1u << 7)) ? "fb" : "nofb", (attrs & (1u << 8)) ? "dscan" : "nodscan", (attrs & (1u << 9)) ? "ilace" : "noilace", (attrs & (1u << 10)) ? "3buf" : "no3buf", (attrs & (1u << 11)) ? "3d" : "no3d", (attrs & (1u << 12)) ? "2dsp" : "no2dsp");*/}voidgetVideoModes(){ int counter = 0; uint16_t *vmptr; vmptr = Vbe3InfoBlock.VideoModePtr; for (counter = 0; counter < MAX_MODES; counter++) { modeList[counter] = vmptr[counter]; if (vmptr[counter] == 0xffffu || vmptr[counter] == 0) break; } numModesSupported = counter;}voidprintCurrentModeInfo(){ printf("%4d x %4d %2d bits per pixel\n",modeInfoBlock.XResolution,modeInfoBlock.YResolution,modeInfoBlock.BitsPerPixel); printModeAttr(modeInfoBlock.modeAttributes); printf(" modeAttr 0x%04x LinearFB: (%c) pa=0x%08x memModel=0x%x r.g.b %d.%d.%d\n", modeInfoBlock.modeAttributes, (modeInfoBlock.modeAttributes & (1u << 7)) ? 'y' : 'n', modeInfoBlock.PhysBasePtr, modeInfoBlock.MemoryModel, modeInfoBlock.RedMaskSize, modeInfoBlock.GreenMaskSize, modeInfoBlock.BlueMaskSize); printf(" redFieldPos %d greenFieldPos %d blueFieldPos %d\n", modeInfoBlock.RedFieldPosition, modeInfoBlock.GreenFieldPosition, modeInfoBlock.BlueFieldPosition); printf(" winGran 0x%x winSz 0x%x winASeg 0x%08x winBSeg 0x%08x\n", modeInfoBlock.WinGranularity, modeInfoBlock.WinSize, modeInfoBlock.WinASegment, modeInfoBlock.WinBSegment); printf(" winAAttr 0x%x winBAttr 0x%x\n", modeInfoBlock.WinAAttributes, modeInfoBlock.WinBAttributes); printf(" numPlanes %d MikeLinFB? %c bytesPerScanLine %d\n", modeInfoBlock.NumberOfPlanes, modeAttributes.linfb ? 'y' : 'n', modeInfoBlock.BytesPerScanLine);}voidprintVideoModes(){ int counter = 0; if(!numModesSupported) { printf("ERROR: Running printVideoModes() function without modeList defined.\nRun getVideoModes() first.\n"); waitkbd(); return; } printf(" The following video mode numbers are supported by this controller:\n "); for (counter = 0; counter < numModesSupported; counter++) { printf("0x%04x ", modeList[counter]); if (counter % 8 == 7) printf("\n "); } printf("\n"); waitkbd(); for (counter = 0; counter < numModesSupported; counter++) { getModeInfo(modeList[counter]); printf(" Mode 0x%04x: ", modeList[counter]); printCurrentModeInfo(); if (modeList[counter] == 0xffffu || modeList[counter] == 0) break; if (counter % 4 == 3) { printf("Press any key to continue..."); waitkbd(); printf("\n"); } } printf(" This controller supports %d possible modes.\n",counter); printf("Press any key to continue..."); waitkbd(); printf("\n");}voidgetModeInfo(uint16_t modeNumber){ /* Get VBE Mode Information */ /* Call VBE function 01h - Return VBE Mode Information * Required registers to setup: * AX = 4F01h * CX = modeNumber * ES:DI = pointer to modeInfoBlock structure * * Output: * AX = should equal 4Fh if successful */ memset(&modeInfoBlock, 0, sizeof(modeInfoBlock)); /*printf("Getting mode information for mode 0x%x....\n", modeNumber);*/ /* do assembly magic here */ handleReturn(AsmGetVbeModeInfo(modeNumber, &modeInfoBlock)); /* VBE1.1: packed pixel. Convert expression to VBE3 conventions. Theoretically, this should only happen in version 1.1, but...*/ if (modeInfoBlock.MemoryModel == 0x4 && Vbe3InfoBlock.VESAVersion == 0x101) { switch(modeInfoBlock.BitsPerPixel) { case 16: modeInfoBlock.RedMaskSize = 5; modeInfoBlock.GreenMaskSize = 5; modeInfoBlock.BlueMaskSize = 5; /* Following are GUESSES: */ modeInfoBlock.RedFieldPosition = 10; modeInfoBlock.GreenFieldPosition = 5; modeInfoBlock.BlueFieldPosition = 0; modeInfoBlock.MemoryModel = 0x6; break; case 24: case 32: modeInfoBlock.RedMaskSize = 8; modeInfoBlock.GreenMaskSize = 8; modeInfoBlock.BlueMaskSize = 8; /* Following are GUESSES: */ modeInfoBlock.RedFieldPosition = 16; modeInfoBlock.GreenFieldPosition = 8; modeInfoBlock.BlueFieldPosition = 0; modeInfoBlock.MemoryModel = 0x6; break; } } frameBufferBase = (uint8_t *) modeInfoBlock.PhysBasePtr; modeAttributes = *((struct ModeAttributes *) &modeInfoBlock.modeAttributes); /* Override linfb setting with preference if possible */ modeAttributes.linfb = modeAttributes.nowin || (modeAttributes.linfb && FB_PREF); /* note that (linfb == 0 && nowin == 1) can never occur according to VESA spec */ /* linfb nowin pref final ======================= 0 0 0 0 final = 0 : use windowed fb 1 0 0 0 final = 1 : use linear fb 1 1 0 1 0 0 1 0 1 0 1 1 1 1 1 1 */}uint8_tsetMode(const uint16_t modeNumber){ /* Set VBE mode */ /* Put the system into a nice VBE mode, 1024x768x64k. * This corresponds to VBE mode 117h. * Required registers to setup: * AX = 4F02h VBE function number (Set VBE Mode) * BX = desired mode * D0-D8 = 117h mode number (117h=0x100010111) * D9-D10 = 0 VBE reserved * D11 = 0 use current default refresh rate * D12-D13 = 0 VBE reserved * D14 = 1 use linear frame buffer model (0=windowed) * D15 = 0 clear display memory * Thus, BX=0x0100000100010111=0x4117 * ES:DI = can safely ignore since we are not specifying * our own refresh rate * Output: * AX = should equal 4Fh if successful */ uint16_t setMode; struct Mode mode; uint8_t a; /* Let's play safely... */ for(a = 0; a < numModesSupported; a++) { if(modeList[a] == modeNumber) break; } if(modeList[a] != modeNumber) { printf("Bad mode number!\n"); return 1; } getModeInfo(modeNumber); mode.number = modeNumber; mode.reserved = 0; /* must be 0 */ mode.refresh = 0; /* 0 = current BIOS default refresh * 1 = user specified CRTC values */ mode.reserved2 = 0; /* must be 0 */ mode.linearmodel = modeAttributes.linfb; /* 0 = use banked/windowed frame buffer * 1 = use linear/flat frame buffer */ mode.cleardisplay = 0; /* 0 = clear display memory * 1 = preserve display memory */ setMode = *((uint16_t *) &mode); /* Ugly. This just grabs an int version of the struct. */ printf("Trying to change to mode 0x%x",modeNumber); if(modeAttributes.linfb) printf(" with a linear frame buffer....\n"); else printf(" with a windowed frame buffer....\n"); /* do assembly magic here */ if(!handleReturn(AsmSetVbeMode(setMode, 0))) { /* update mode state information */ bankShift = 0; while ((unsigned)(64 >> bankShift) != modeInfoBlock.WinGranularity) bankShift++; /*while(((uint16_t) 1 << bankShift) != modeInfoBlock.WinGranularity) bankShift++;*/ /*printf("Gran: %d Shift: %d\n",modeInfoBlock.WinGranularity, bankShift); waitkbd();*/ curBank = -1; /* TODO: double-check logic in here to automatically use lin fb or win fb appropriately */ if (modeAttributes.linfb) { //printf("Using physical base pointer 0x%08x per linfb bit\n", modeInfoBlock.PhysBasePtr); frameBufferBase = (PA2BOOT(modeInfoBlock.PhysBasePtr, uint8_t *)); } else { //printf("winAseg at 0x%x\n",modeInfoBlock.WinASegment * 16); frameBufferBase = (PA2BOOT(modeInfoBlock.WinASegment * 16, uint8_t *)); } /*printf("using fb at 0x%x\n",frameBufferBase); waitkbd();*/ /*if(getCurrentMode() != modeNumber) printf("%c%c%c%c%c%c",BELL,BELL,BELL,BELL,BELL,BELL); else printf("%c%c%c",BELL,BELL,BELL);*/ return 0; } return 1;}uint8_t moreHelpfulHandleReturn(const char *str, const uint16_t retVal){ if (retVal == 0x4f) return 0; /* Issue: It's actually quite useful to be able to SEE the diagnostics :-) */ AsmSetVgaMode(origMode); printf("Invocation: %s\n", str);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -