我编写了一个简单的引导程序,它设置了视频模式,并设置了一些像素。我已经测试了它在虚拟盒,QEMU,Dosbox和真正的硬件。对它们很有用,但对Bochs却不管用。模式设置正确,但像素未绘制。
org 0x7c00
[BITS 16] ;Tell Assembler to generate 16-bit code
jmp short start ;Goto start, skip BIOS-Parameter-Block
nop
;------------BIOS Parameter Block---------------;
; Needed to recognize the disk ;
;-----------------------------------------------;
OEMName: db 'TEST OS ' ;Name of Orignal Equipment Manufacturer
bytesPerSector: dw 512 ;Number of bytes in each sector
sectPerCluster: db 1 ;Sectors in one cluster, 1 for FAT12
reservedCluster: dw 1 ;1 sector is reserved for boot
totalFATs: db 2 ;There are 2 fats in FAT12 these are copies of each other
rootDirEntries: dw 224 ;Total entries (files or folders) in root directory
totalSectors: dw 2880 ;Total Sectors in whole disk
mediaType: db 0xf0 ;Media type 240 for floppies
sectorsPerFAT: dw 9 ;Sectors used in on FAT
sectorsPerTrack: dw 18 ;Sectors in one Track
totalHeads: dw 2 ;Total sides of disk
hiddenSectors: dd 0
hugeSectors: dd 0
driveNumber: db 0 ;Drive Number 0 for A:\ floppy
db 0
signature: db 41 ;41 for floppies
volumeID: dd 0 ;Any number
volumeLabel: db 'TEST OS ';Any 11-char name
fileSystem: db 'FAT12 ' ;Type of file system on disk
;------------------------------------------------
;_______________________________________________
gdt: dd 0x00000000,0x00000000 ;null descriptor
dd 0x0000ffff,0x00cf9a00 ;code
dd 0x0000ffff,0x00cf9200
gdtreg: dw 0x17 ;gdt size + 1
dd 0 ;gdt base (latter filled)
start:
mov ax,0x4f01 ;get vesa mode info
mov cx,0115h ;video mode number
mov di,modeblock
int 0x10
mov esi, [modeblock+0x28] ;save linear frame buffer base = es:di+0x28
mov ax,0x4f02 ;set vesa mode
mov bx,0115h ;video mode number
int 0x10
mov ax,0x2401
int 0x15 ;enable a20 gate
xor eax,eax
mov ax,cs
shl eax,4
mov [gdt+0x08+2],ax
shr eax,16
mov [gdt+0x20+4],al
xor eax,eax
mov ax,cs
shl eax,4
add eax,gdt
mov [gdtreg+2],eax
lgdt[gdtreg]
mov eax,cr0
or eax,1
cli
mov cr0,eax
jmp 0x08:pstart
[bits 32]
pstart:
mov eax,0x10
mov es,ax
mov ds,ax
mov fs,ax
mov ss,ax
mov gs,ax
cls:
mov eax,0xffffffff
mov edi, esi
mov ecx,1024*768*1/2
cld
rep stosd
;************ THIS PART IS NOT WORKING ON BOCHS. ************
main:
;test code
mov edi,esi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0xff
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0xff
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0xff
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0xff
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0xff
inc edi
mov byte[edi],0x00
inc edi
mov byte[edi],0x00
inc edi
jmp $
times 510-($-$$) db 0
dw 0xaa55
modeblock:
有什么建议吗?谢谢。
发布于 2014-10-07 17:53:38
为了获得线性框架缓冲区,您需要通过在BX
寄存器中为4F02
函数设置位#14来请求它。Bochs似乎对此很挑剔,如果您还没有启用线性框架缓冲区,就会忽略写:
if (BX_VGA_THIS vbe.lfb_enabled)
{
...
}
else
{
if (addr < BX_VGA_THIS vbe.base_address) {
// banked mode write
offset = (Bit32u)(BX_VGA_THIS vbe.bank*65536 + (addr - 0xA0000));
}
else {
// LFB write while in banked mode -> ignore
return;
}
还请注意,您不应该硬编码模式编号,因为它们在不同的系统上可能有所不同。bochs认为0x115
是800x600x24,但您的代码中有1024*768*1/2
,这并不是您所期望的。
https://stackoverflow.com/questions/26236272
复制相似问题