簡體   English   中英

如何正確獲取 VBE 數據? int 10h/ax=4F

[英]How to correctly get the VBE data? with int 10h/ax=4F

我得到了使用 web 的一些信息和代碼構建的代碼,但我嘗試了至少一百次,重寫mode_infovbe_info結構,我無法獲得正確的值,我看到 vbe3.pdf 但它使用dd? db? 這在NASM中不起作用,在某些站點上,我發現vbe_infomode_info數據結構的字節大小不同,所以我寫了我猜的,系統甚至不打印味精“設置 vieo 模式”,停在get_mode_info ,我想當我嘗試使用mode_info數據調用函數時系統錯誤(可能/可能結構不正確),但代碼有什么問題?

(代碼不適合引導加載程序,所以我不得不加載第二個扇區)

makefile:

all: compile run

compile:
    nasm -f bin bootloader.asm -o bin/bootloader.bin
    nasm -f bin system.asm -o bin/system.bin
    cat bin/bootloader.bin bin/system.bin > img/system.img

run:
    qemu-system-i386 -fda img/system.img

引導加載程序:

[BITS 16]
[ORG 0x7C00]

setup_stack:

    xor ax, ax;                     // ax = 0
    mov ds, ax;                     // ds = 0

    mov es, ax;                     // es = ds
    mov bx, 0x8000;                 // stack segment can be any usable memory

    mov ss, bx;                     // stack start 0x80000
    mov sp, ax;                     // stack final 0x8FFFF

    cld;                            // clear direction flag

read_kernel:

    pushf;                          // save values
    stc;                            // set carry flag

    mov ah, 00;                     // reset disk
    int 13h;                        // disk interrupt

    mov ax, 0x0000;                 // register ax [0000]:1000
    mov bx, 0x1000;                 // register bx  0000:[1000]

    mov ah, 0x2;                    // read sector instruction
    mov al, 0x3;                    // sectors to read
    mov ch, 0x0;                    // cylinder
    mov cl, 0x2;                    // local to write
    mov dh, 0x0;                    // head

    int 0x13;                       // call the disk interupter

    popf;                           // restore values

    jmp 0x0000:0x1000;              // Jump to kernel

    cli;                            // clear interrupt flag
    hlt;                            // halt

TIMES 510 - ($-$$) DB 0;            // complete the bootsector with zeros
DW 0xAA55;                          // end of bootsector

系統:

[org 0x1000]
[bits 16]

jmp main;

vbe_info:

    .signature db "VBE2";           // must be "VESA" to indicate valid VBE support
    .version resw 1;                // VBE version; high byte is major version, low byte is minor version
    .oem resd 1;                    // segment:offset pointer to OEM
    .capabilities resd 1;           // bitfield that describes card capabilities
    .video_modes resd 1;            // segment:offset pointer to list of supported video modes
    .video_memory resw 1;           // amount of video memory in 64KB blocks
    .software_rev resw 1;           // software revision
    .vendor resd 1;                 // segment:offset to card vendor string
    .product_name resd 1;           // segment:offset to card model name
    .product_rev resd 1;            // segment:offset pointer to product revision
    .reserved resb 222;             // reserved for future expansion
    .oem_data resb 256;             // OEM BIOSes store their strings in this area

mode_info:

    .attributes resw 1;             // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
    .window_a resb 1;               // deprecated
    .window_b resb 1;               // deprecated
    .granularity resw 1;            // deprecated; used while calculating bank numbers
    .window_size resw 1;
    .segment_a resw 1;
    .segment_b resw 1;
    .win_func_ptr resd 1;           // deprecated; used to switch banks from protected mode without returning to real mode
    .pitch resw 1;                  // number of bytes per horizontal line
    .width resw 1;                  // width in pixels
    .height resw 1;                 // height in pixels
    .w_char resb 1;                 // unused...
    .y_char resb 1;                 // ...
    .planes resb 1;
    .bpp resb 1;                    // bits per pixel in this mode
    .banks resb 1;                  // deprecated; total number of banks in this mode
    .memory_model resb 1;
    .bank_size resb 1;              // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
    .image_pages resb 1;
    .reserved0 resb 1;

    .red_mask resb 1;
    .red_position resb 1;
    .green_mask resb 1;
    .green_position resb 1;
    .blue_mask resb 1;
    .blue_position resb 1;
    .reserved_mask resb 1;
    .reserved_position resb 1;
    .direct_color_attributes resb 1;

    .framebuffer resd 1;            // physical address of the linear frame buffer; write here to draw to the screen
    .off_screen_mem_off resd 1;
    .off_screen_mem_size resw 1;    // size of memory in the framebuffer but not being displayed on the screen
    .reserved1 resb 206;

main:

vbe_get_info:

    mov ah, 4Fh;                    // super VGA support
    mov al, 00h;                    // return Super VGA information
    mov di, vbe_info;               // pointer to buffer

    int 0x10;                       // video interrupt

    cmp ax, 0x4F;                   // BIOS support VBE?
    jne error;                      // if doesn't jump to error

get_mode_info:

    ;mov ax, 4F01h is the same
    mov ah, 4Fh;                    // return mode information
    mov al, 01h
    mov cx, [vbe_info.video_modes]; // first mode
    mov di, mode_info;              // pointer to buffer

    int 0x10;                       // video interrupt

    cmp ax, 0x4F;                   // check vbe error
    jne error;                      // jump to error

set_mode:

    mov ah, 0
    mov ax, 0x4F02
    mov bx, [vbe_info.video_modes]; first mode

    int 0x10

draw:

    mov edi, [mode_info.framebuffer];   framebuffer
    add edi, 0;                         pixel_offset = y * pitch + ( x * ( bpp/8 )) + framebuffer;
    mov al,0x0F;                        the color of the pixel
    mov [edi], al;                      mov pixel derect to memory

    jmp $

error:

    mov ah, 0x00;                   // restart instruction
    int 19h;                        // restart the system

    ret

答案在這里:

1:我在get_mode_info使用cs而不是cx ,所以 vesa 返回錯誤 2:我使用vbe_video_modes作為模式(字)數組,但我需要用作地址或指針 3:首先我需要在繪制前配置 window ,現在我可以在所有屏幕上畫畫(什么回答了我的另一個問題)......

vbe_info:

    .signature db "VBE2";   // must be "VESA" to indicate valid VBE support
    .version resw 1;            // VBE version; high byte is major version, low byte is minor version
    .oem resd 1;            // segment:offset pointer to OEM
    .capabilities resd 1;       // bitfield that describes card capabilities
    .video_modes resd 1;        // segment:offset pointer to list of supported video modes
    .video_memory resw 1;       // amount of video memory in 64KB blocks
    .software_rev resw 1;       // software revision
    .vendor resd 1;         // segment:offset to card vendor string
    .product_name resd 1;       // segment:offset to card model name
    .product_rev resd 1;        // segment:offset pointer to product revision
    .reserved resb 222;     // reserved for future expansion
    .oem_data resb 256;     // OEM BIOSes store their strings in this area

mode_info:

    .attributes resw 1;     // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
    .window_a resb 1;           // deprecated
    .window_b resb 1;           // deprecated
    .granularity resw 1;        // deprecated; used while calculating bank numbers
    .window_size resw 1;
    .segment_a resw 1;
    .segment_b resw 1;
    .win_func_ptr resd 1;       // deprecated; used to switch banks from protected mode without returning to real mode
    .pitch resw 1;          // number of bytes per horizontal line
    .width resw 1;          // width in pixels
    .height resw 1;         // height in pixels
    .w_char resb 1;         // unused...
    .y_char resb 1;         // ...
    .planes resb 1;
    .bpp resb 1;            // bits per pixel in this mode
    .banks resb 1;          // deprecated; total number of banks in this mode
    .memory_model resb 1;
    .bank_size resb 1;      // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
    .image_pages resb 1;
    .reserved0 resb 1;

    .red_mask resb 1;
    .red_position resb 1;
    .green_mask resb 1;
    .green_position resb 1;
    .blue_mask resb 1;
    .blue_position resb 1;
    .reserved_mask resb 1;
    .reserved_position resb 1;
    .direct_color_attributes resb 1;

    .framebuffer resd 1;        // physical address of the linear frame buffer; write here to draw to the screen
    .off_screen_mem_off resd 1;
    .off_screen_mem_size resw 1;    // size of memory in the framebuffer but not being displayed on the screen
    .reserved1 resb 206;

enable_vesa:

vbe_get_info:

    mov ah, 4Fh;        Super VGA support
    mov al, 00h;        Return Super VGA information
    mov di, vbe_info;   Pointer to buffer

    int 0x10;

    cmp ax, 0x4F                ; BIOS doesn't support VBE?
    jne error

get_mode_info:

    mov ax, 4F01h;        Return mode information
    mov cx, 0x101;[vbe_info.video_modes]; first mode
    mov di, mode_info;  Pointer to buffer

    int 0x10;

    cmp ax, 0x4F                ; BIOS doesn't support VBE?
    jne error

set_mode:

    mov ah, 0
    mov ax, 0x4F02
    mov ebx, [vbe_info.video_modes]; estore de modes pointer at ebx to can access as a adress
    mov bx, [ebx+8]; 8/2 = 4th mode in the mode array!!!!!!!

    int 0x10

draw:

    ;Assume first window is valid 
    mov ax, WORD [es:mode_info + 08h]
    mov es, ax

    ;Example of how to change the window 
    mov ax, 4f05h
    xor bx, bx
    mov dx, 5       ;This is granularity units
    int 10h

    ;fist atempt
    mov edi, [mode_info.framebuffer];   framebuffer
    add edi, 180050;                        pixel_offset = y * pitch + ( x * ( bpp/8 )) + framebuffer;
    mov al,0x0F;                        the color of the pixel
    mov [edi], al

    mov si, msg;
    call print

    jmp $

msg db "finish", 0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM