[英]How to enable text cursor in IBMPC BIOS graphics mode 16 (INT 10H/AX=0010H)?
[英]How to correctly get the VBE data? with int 10h/ax=4F
我得到了使用 web 的一些信息和代碼構建的代碼,但我嘗試了至少一百次,重寫mode_info
和vbe_info
結構,我無法獲得正確的值,我看到 vbe3.pdf 但它使用dd?
和db?
這在NASM
中不起作用,在某些站點上,我發現vbe_info
和mode_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.