[英]VESA skipping “blocks” of video memory when trying to fill the screen
我正在開發一個簡單的操作系統內核,我正在嘗試制作一個有效的視頻庫,以便以后可以使用它。 (VBE 3.0 版,1920 * 1080 像素,32bpp)。
我在 C 中編寫了一個像素繪圖函數,它似乎工作正常:
void putPixelRGB(struct MODEINFOBLOCK mib, short x, short y, int color) {
int *pos = (char *)mib.framebuffer + x * 4 + y * 7680;
*pos = color;
}
然后我嘗試使用這個函數和兩個for
循環來填充整個屏幕:
for(int i = 0; i < 1920; i++) {
for(int j = 0; j < 1080; j++) {
putPixelRGB(mib, i, j, 0xFFFFFF);
}
}
dloop: mov byte[eax], 0xFF ;eax contains the address of the FB memory. inc eax cmp eax, 829440 ;829440 = 1920 * 1080 * 4 jg done jmp dloop done: hlt
知道為什么這不起作用嗎? 我是否以錯誤的方式訪問內存?
MODEINFOBLOCK
結構:
struct MODEINFOBLOCK { int attributes; char windowA, windowB; int granularity; int windowSize; int segmentA, segmentB; long winFuncPtr; int pitch; int resolutionX, resolutionY; char wChar, yChar, planes, bpp, banks; char memoryModel, bankSize, imagePages; char reserved0; char readMask, redPosition; char greenMask, greenPosition; char blueMask, bluePosition; char reservedMask, reservedPosition; char directColorAttributes; char* framebuffer; long offScreenMemOff; int offScreenMemSize; char reserved1 [206]; };
您可能沒有啟用 A20 門。
禁用 A20 門后,物理地址的第 21 位將被忽略/屏蔽為零(以幫助模擬只有 20 個地址線的舊 8086 CPU)。 結果是當你嘗試填充幀緩沖區時; 第一個 1 MiB 像素有效,然后第二個 1 MiB 像素覆蓋前 1 MiB 像素(留下未填充的黑色帶),然后第三個 1 MiB 像素有效但被第四個 1 MiB 像素覆蓋,並且很快。
這會創建“填充和未填充”水平帶。 如果您進行數學計算,(“1 MiB / 1920 / 4”)您會期望水平帶的高度約為 136.5 像素; 所以會有略多於 7 個頻段(“1000 / 136.5”); 這就是你得到的。
啟用 A20 門; 見https://wiki.osdev.org/A20_Line 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.