📄 vbe.c
字号:
#if 0 if((retVal & 0xFF) == 0x4F) printf("Function was supported, "); else printf("Function was NOT supported, ");#else printf("Function was NOT supported, ");#endif switch(retVal >> 8) { case 0x0: printf("and function call was successful.\n"); break; case 0x1: printf("and function call failed.\n"); break; case 0x2: printf("and function is not supported in the current hardware configuration.\n"); break; case 0x3: printf("and function call is invalid in current video mode.\n"); break; default: printf("and an unknown return value was received.\n"); } waitkbd(); return (retVal!=0x4f);}voidtestGraphics(){ uint32_t a; printf("Beginning test of %d graphics modes....\n",numModesSupported); for(a=0; a<numModesSupported; a++) { AsmSetVgaMode(origMode); getModeInfo(modeList[a]); /* Is it a graphics mode? */ if(!modeAttributes.graphics) continue; /* Issue: mode may not be available in current hardware configuration! */ if (!modeAttributes.hw) continue; if (modeInfoBlock.MemoryModel != mm_DirectColor) /* Not a direct color mode */ continue; printCurrentModeInfo(); printf("Press any key to test...\n"); waitkbd(); setMode(modeList[a]); ChezPaul(); horizline(); waitkbd(); ChezPaul(); vertline(); waitkbd(); ChezPaul(); dabble(); /* Issue: beeping is rude. printf("%c", BELL); */ waitkbd(); //test(); ChezPaul(); drawMoire(); /* Issue: beeping is rude. printf("%c", BELL); */ waitkbd(); } /*printf("%c%c",BELL,BELL); waitkbd();*/}void ChezPaul(){#define BLACKEN_POINTWISE#ifdef BLACKEN_POINTWISE uint32_t x, y; /* Let's draw a pretty pattern on the screen.... */ for (x = 0; x < modeInfoBlock.XResolution; x++) { for (y = 0; y < modeInfoBlock.YResolution; y++) { putPixel(x, y, 0); } }#else /* High temperature is the preferred method for blackening. */ uint32_t offset = 0; uint32_t totBytes = modeInfoBlock.YResolution * modeInfoBlock.BytesPerScanLine; uint32_t max = modeAttributes.linfb ? totBytes : 65536; while (totBytes) { uint32_t cur = min(max, totBytes); if (!modeAttributes.linfb) setBank(offset >> 16);#if 0 { int i; for (i = 0; i < cur / sizeof(uint32_t); i++) ((uint32_t *) frameBufferBase)[i] = 0; }#else memset(frameBufferBase, 0, cur);#endif totBytes -= cur; offset += cur; } curBank = -1;#endif}void vertline(){ uint32_t a; uint32_t row = 120; uint32_t white = ~0u; uint32_t red = ~0u & ((1u << modeInfoBlock.RedMaskSize) - 1); uint32_t green = ~0u & ((1u << modeInfoBlock.GreenMaskSize) - 1); uint32_t blue = ~0u & ((1u << modeInfoBlock.BlueMaskSize) - 1); red <<= modeInfoBlock.RedFieldPosition; blue <<= modeInfoBlock.BlueFieldPosition; green <<= modeInfoBlock.GreenFieldPosition; /* Let's draw a pretty pattern on the screen.... */ for(a = 0; a < modeInfoBlock.YResolution; a++) { unsigned i; unsigned width = 4; for (i = 0; i < width; i++) { putPixel(row + i + 0 * width, a, red); putPixel(row + i + 1 * width, a, green); putPixel(row + i + 2 * width, a, blue); putPixel(row + i + 3 * width, a, white); } }}void horizline(){ uint32_t a; uint32_t col = 120; uint32_t white = ~0u; uint32_t red = ~0u & ((1u << modeInfoBlock.RedMaskSize) - 1); uint32_t green = ~0u & ((1u << modeInfoBlock.GreenMaskSize) - 1); uint32_t blue = ~0u & ((1u << modeInfoBlock.BlueMaskSize) - 1); red <<= modeInfoBlock.RedFieldPosition; blue <<= modeInfoBlock.BlueFieldPosition; green <<= modeInfoBlock.GreenFieldPosition; /* Let's draw a pretty pattern on the screen.... */ for(a = 0; a < modeInfoBlock.XResolution; a++) { unsigned i; unsigned width = 4; for (i = 0; i < width; i++) { putPixel(a, col + i + 0 * width, red); putPixel(a, col + i + 1 * width, green); putPixel(a, col + i + 2 * width, blue); putPixel(a, col + i + 3 * width, white); } }}void dabble(){ uint32_t a, b; uint32_t clr = 0; uint8_t bpp = modeInfoBlock.BitsPerPixel; uint32_t maxc = 1 << (bpp - 1); /* Let's draw a pretty pattern on the screen.... */ /* shap: Actually, the picture is not so pretty if the total number of colors is not evenly divisible by the horizontal bits per line. */ for(a = 0; a < modeInfoBlock.YResolution; a++) { for(b = 0; b < modeInfoBlock.XResolution; b++) { putPixel(b, a, clr); clr = (clr == maxc ? clr = 0 : ++clr); } }}void putPixel(const uint16_t x, const uint16_t y, const uint32_t color){ /* Issue: if bits per pixel is not a multiple of 8, then the naive computation fails. */ uint32_t offset = (uint32_t) y * modeInfoBlock.BytesPerScanLine + x * ((modeInfoBlock.BitsPerPixel + 7) / 8); /* Assume 64k banks for the moment */ if(!modeAttributes.linfb) { setBank(offset >> 16); /* Note: general thing here would be offset -= (curBank * BankSize); */ offset &= 0xffffu; } /* Logically: effectiveAddress = frameBufferBase + (BankOffset + BankRelativeOffset); */ /* Issue: absence of funny cases (like 15 bits per pixel) was causing drawing to be entirely suppressed. */ /* *(frameBufferBase + (offset & 0xFFFF)) = (char) color; */ if (modeInfoBlock.BitsPerPixel <= 8) { /* 7, 8 bit modes use bytes */ *((uint8_t *) (frameBufferBase + offset)) = color; } else if (modeInfoBlock.BitsPerPixel <= 16) { /* 15, 16 bit modes use 16 bit values */ *((uint16_t *) (frameBufferBase + offset)) = color; } else { /* >16 bit modes use 32 bit values in the frame buffer. */ *((uint32_t *) (frameBufferBase + offset)) = color; }}void setBank(uint16_t bank){ if (bank == curBank) return; /* Bank is already active */ curBank = bank; /* Save current bank number */ bank <<= bankShift; /* Adjust to window granularity */ /* Issue: Need to check if bank flipping is even supported. On Dell, for example, there is no B window. */ if (modeInfoBlock.WinAAttributes & wa_relocatable) handleReturn(AsmDisplayWindowControl(SETWIN, WINA, bank)); if (modeInfoBlock.WinBAttributes & wa_relocatable) handleReturn(AsmDisplayWindowControl(SETWIN, WINB, bank));}uint16_tgetCurrentMode(){ return AsmReturnCurrentVbeMode();}/* Copied from VBE spec sample program. *//* Draw a line from (x1,y1) to (x2,y2) in specified color */voidline(int x1,int y1,int x2,int y2,int color){ int d; /* Decision variable */ int dx,dy; /* Dx and Dy values for the line */ int Eincr,NEincr; /* Decision variable increments */ int yincr; /* Increment for y values */ int t; /* Counters etc. */#define ABS(a) ((a) >= 0 ? (a) : -(a)) dx = ABS(x2 - x1); dy = ABS(y2 - y1); if (dy <= dx) { /* We have a line with a slope between -1 and 1 * * Ensure that we are always scan converting the line from left to * right to ensure that we produce the same line from P1 to P0 as the * line from P0 to P1. */ if (x2 < x1) { t = x2; x2 = x1; x1 = t; /* Swap X coordinates */ t = y2; y2 = y1; y1 = t; /* Swap Y coordinates */ } if (y2 > y1) yincr = 1; else yincr = -1; d = 2*dy - dx; /* Initial decision variable value */ Eincr = 2*dy; /* Increment to move to E pixel */ NEincr = 2*(dy - dx); /* Increment to move to NE pixel */ putPixel(x1,y1,color); /* Draw the first point at (x1,y1) */ /* Incrementally determine the positions of the remaining pixels */ for (x1++; x1 <= x2; x1++) { if (d < 0) d += Eincr; /* Choose the Eastern Pixel */ else { d += NEincr; /* Choose the North Eastern Pixel */ y1 += yincr; /* (or SE pixel for dx/dy < 0!) */ } putPixel(x1,y1,color); /* Draw the point */ } } else { /* We have a line with a slope between -1 and 1 (ie: includes * vertical lines). We must swap our x and y coordinates for this. * * Ensure that we are always scan converting the line from left to * right to ensure that we produce the same line from P1 to P0 as the * line from P0 to P1. */ if (y2 < y1) { t = x2; x2 = x1; x1 = t; /* Swap X coordinates */ t = y2; y2 = y1; y1 = t; /* Swap Y coordinates */ } if (x2 > x1) yincr = 1; else yincr = -1; d = 2*dx - dy; /* Initial decision variable value */ Eincr = 2*dx; /* Increment to move to E pixel */ NEincr = 2*(dx - dy); /* Increment to move to NE pixel */ putPixel(x1,y1,color); /* Draw the first point at (x1,y1) */ /* Incrementally determine the positions of the remaining pixels */ for (y1++; y1 <= y2; y1++) { if (d < 0) d += Eincr; /* Choose the Eastern Pixel */ else { d += NEincr; /* Choose the North Eastern Pixel */ x1 += yincr; /* (or SE pixel for dx/dy < 0!) */ } putPixel(x1,y1,color); /* Draw the point */ } }}/* Copied from VBE spec sample program. *//* Draw a simple moire pattern of lines on the display */voiddrawMoire(){ uint16_t i; uint16_t xres = modeInfoBlock.XResolution; uint16_t yres = modeInfoBlock.YResolution; uint16_t mask = 0xFF; /* original was 0xFF */ for (i = 0; i < xres; i += 5) { line(xres/2,yres/2,i,0,i % mask); line(xres/2,yres/2,i,yres,(i+1) % mask); } for (i = 0; i < yres; i += 5) { line(xres/2,yres/2,0,i,(i+2) % mask); line(xres/2,yres/2,xres,i,(i+3) % mask); } line(0,0,xres-1,0,15); line(0,0,0,yres-1,15); line(xres-1,0,xres-1,yres-1,15); line(0,yres-1,xres-1,yres-1,15);}voidtest(){ float i; uint32_t a, b; uint32_t cur = 0; for(i = 0; i < 1; i += 0.05) { drawMoire(); /* Issue: beeping is rude. printf("%c", BELL); */ waitkbd(); for(a = 0; a < modeInfoBlock.YResolution; a++) { for(b = 0; b < modeInfoBlock.XResolution; b++) { putPixel(b, a, cur); } } }}voidSetConsoleMode(BootInfo *bi, uint32_t mode){ ConsoleInfo *ci; bi->consInfo = ci = BootAlloc(sizeof(ConsoleInfo), sizeof(uint32_t)); /* FIXME: * mode == 0 check is here to handle case of windowed modes */ if(!VESAinit || mode == 0) return; bi->useGraphicsFB = 1; getModeInfo(mode); /* uses assembly magic */ /* populate the ConsoleInfo struct */ ci->len = sizeof(ConsoleInfo); ci->videoMode = mode; ci->frameBuffer = modeInfoBlock.PhysBasePtr; ci->Xlimit = modeInfoBlock.XResolution; /*chVange?*/ ci->Ylimit = modeInfoBlock.YResolution; /*change?*/ ci->winSize = modeInfoBlock.WinSize; ci->bytesPerScanLine = modeInfoBlock.BytesPerScanLine; ci->isBanked = !modeAttributes.linfb; /* linfb = 1 if linear, 0 if windowed */ ci->bpp = modeInfoBlock.BitsPerPixel; ci->redMask = modeInfoBlock.RedMaskSize; ci->blueMask = modeInfoBlock.BlueMaskSize; ci->greenMask = modeInfoBlock.GreenMaskSize; ci->redShift = modeInfoBlock.RedFieldPosition; ci->blueShift = modeInfoBlock.BlueFieldPosition; ci->greenShift = modeInfoBlock.GreenFieldPosition; setMode(mode);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -