assembly BIOS VESA扩展:指向空数组的视频模式缓冲区

mccptt67  于 2023-03-02  发布在  iOS
关注(0)|答案(2)|浏览(129)

我用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”结尾。

mzaanser

mzaanser1#

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

您错误地检索了相对于DS的VideoModePtr,而实际上VbeInfoBlock被放置在代码段中,因此相对于CS,甚至ES,因为您将CS复制到ES。

;-- 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 @@sigMatch                       ;
MAC_DPT_PRINTIMM "VESA buffer: signature does not match!"
DRV_VESA_panic                      ;
                                    ;
@@sigMatch:                         ;
;-- check vesa version              ;
MOV ax, ES:[DRV_VESA_infoBlock].version
CMP ax, 00102H                      ;
JGE @@versionOk                     ;
MAC_DPT_PRINTIMM "VESA: version to low"
DRV_VESA_panic                      ;
                                    ;
@@versionOk:                        ;
;-- get vesa modes buffer address   ;
MOV si, ES:[DRV_VESA_infoBlock].modesOff
MOV fs, ES:[DRV_VESA_infoBlock].modesSeg

我在您的ModeInfoBlock中发现了另一个问题。您没有在偏移量29处包含NumberOfImagePages字段。

oxalkeyp

oxalkeyp2#

您在哪里为;-- get vesa modes buffer address设置BX?
;--- get mode information需要指向DRV_VESA_VBE_MODE_INFO_STRUCT的ES:DI

相关问题