我用INT 10h / AX=4F00h
得到了基本的VESA信息块。
PUSH cs ;
POP es ;
;- perform VESA check ;
PUSH es ; some BIOSes destroy ES with this call
MOV di, OFFSET DRV_VESA_infoBlock ; ES:DI buffer for at least 256 bytes (512 for VBE v2.0+)
MOV ax, 04F00H ;
INT 10H ;
POP es ;
;
;- check for errors ;
CALL DRV_VESA_bioscallErrorCheck ;
;
;-- check buffer signature ;
PUSH CS ;
POP ES ;
MOV di, OFFSET DRV_VESA_infoBlock ; ES:DI = buffer
MOV cx, 4 ;
MAC_IMMSTRING "VESA" ; DS:SI = "VESA" signature needs to match!
REPZ CMPSB ;
JZ @@noErrors ;
MAC_DPT_PRINTIMM "VESA buffer: signature does not match!"
DRV_VESA_panic ;
;
;-- check vesa version ;
MOV ax, CS:[DRV_VESA_infoBlock].version
CMP ax, 00102H ;
JGE @@noErrors ;
MAC_DPT_PRINTIMM "VESA: version too low"
DRV_VESA_panic ;
@@noErrors: ;
...
...
...
;
ALIGN DWORD ; some bioses might require the structs to be aligned
DRV_VESA_infoBlock DRV_VESA_VBE_INFO_STRUCT {}
ALIGN DWORD ;
DRV_VESA_modeInfo DRV_VESA_VBE_MODE_INFO_STRUCT {}
然后获取指向视频模式缓冲区的指针
;-- get vesa modes buffer address ;
MOV ax, WORD PTR [bx].DRV_VESA_VBE_INFO_STRUCT.modesOff
MOV si, ax
MOV ax, WORD PTR [bx].DRV_VESA_VBE_INFO_STRUCT.modesSeg
PUSH ax ;
POP fs ;
;
然后(作为预备步骤)打印出所有视频模式
@@displayModeLoop: ;
MOV cx, WORD PTR fs:[si] ;
CMP cx, 0FFFFH ;
JE @@displayModeEndLoop ;
MOV ax, cx ;
CALL DPT_printNum ;
;--- get mode information ;
MOV ax, 04F01H ;
INT 10H ;
CALL DRV_VESA_bioscallErrorCheck ;
ADD si, 2 ;
JMP @@displayModeLoop ;
@@displayModeEndLoop: ;
- DPT_printNum在这里肯定没有错(它在许多其他地方都能工作)
- 我已尝试删除BIOS函数调用,但这不是导致问题的原因
- 我仍处于RMODE状态
- 我正在使用自己的引导加载程序
相关文件如下:https://github.com/Wittmaxi/maxos/tree/master/kernel/drivers/graphics
当我运行这段代码时(在QEMU和DOSBox中),会打印出很多空的数组索引,只要打印出第一个非零值,内核就会崩溃。
我希望数组(如http://www.ctyme.com/intr/rb-0273.htm所指定的)充满显示模式代码,并以单词“FFFF”结尾。
2条答案
按热度按时间mzaanser1#
您错误地检索了相对于DS的VideoModePtr,而实际上VbeInfoBlock被放置在代码段中,因此相对于CS,甚至ES,因为您将CS复制到ES。
我在您的ModeInfoBlock中发现了另一个问题。您没有在偏移量29处包含NumberOfImagePages字段。
oxalkeyp2#
您在哪里为
;-- get vesa modes buffer address
设置BX?;--- get mode information
需要指向DRV_VESA_VBE_MODE_INFO_STRUCT
的ES:DI