Bochs VESA trouble (no output)
Posted: Wed Aug 14, 2013 3:31 am
I've made some simple demo in asm (GAS syntax) using VESA. It search thru list of modes for mode 800x600x16, linear fb, and if available, select it and write some gradient lines. The problem is, that it works fine on real PC with NVidia GT240 and in QEMU, but in Bochs I see no output (no gradient). Mode seems to be changing (as Bochs change window size and clears "screen"), but nothing is displayed. Bochs displays no warning or errors, except about hlt with IF = 0. With help of Bochs internal debugger, I see that code runs OK, finds video mode and changing to it.
Tested on Bochs-2.4.6 and Bochs-2.6.2, built from source, --enable-vbe and VGABIOS-lgpl-latest are in place. From my expirience, if code works wrong in Bochs, it's some trouble with code, not Bochs
Actual code:
Tested on Bochs-2.4.6 and Bochs-2.6.2, built from source, --enable-vbe and VGABIOS-lgpl-latest are in place. From my expirience, if code works wrong in Bochs, it's some trouble with code, not Bochs
Actual code:
Code: Select all
.org 0x7C00
.align 0
.text
.code16
.globl _start
_start:
cld
cli
// 0x1000 = buffer for GetVBEInfo
xor %ax, %ax
mov %ax, %es
mov %ax, %ds
mov $0x1000, %di
movl $0x33454256, (%di) // "VBE3"
mov $0x4F00, %ax // GetVBEInfo
int $0x10 // Video interrupt
mov 0xE(%di), %si
// 0x2000 = buffer for GetVideoModeInfo
mov $0x2000, %di
// Cycle through video modes list
sub $2, %si
.l1:
add $2, %si
mov (%si), %cx
cmp $0xFFFF, %cx // 0xFFFF = end of list
je .l3
mov $0x4F01, %ax // GetVideoModeInfo
int $0x10
// di+0 - attributes
// di+16 - bytes per scanline
// di+18 - xres
// di+20 - yres
// di+25 - bpp
// di+27 - memory model
// di+40 - linear fb addr
mov (%di), %bx // Get attributes word
and $0x90, %bx // Linear FB support?
cmp $0x90, %bx
jne .l1
mov 0x1B(%di), %bx // Mem model: 4 = packed pixel, 6 = direct color
cmp $4, %bx
je .l2
cmp $6, %bx
jne .l1
.l2:
// Search for 800x600x16
mov 0x12(%di), %bx
cmp $800, %bx
jne .l1
mov 0x14(%di), %bx
cmp $600, %bx
jne .l1
mov 0x19(%di), %bl
cmp $16, %bl
jne .l1
.l3:
// If mode found
cmp $0xFFFF, %cx
je .l4
// Then set it
mov $0x4F02, %ax // SetVideoMode
mov %cx, %bx
int $0x10
.l4:
// Enable A20 line
inb $0x60, %al
or $2, %al
outb %al, $0x60
// Enable 32-bit Pmode (no paging)
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
lgdt gdtr
ljmp $0x08, $code32
.code32
code32:
mov $0x10, %ax
mov %ax, %es
mov %ax, %ds
cmp $0xFFFF, %cx
je .lh
// We are in VESA mode 800x600x16
// Let's draw!
mov 0x28(%di), %edi // Framebuffer address
// We will draw vertical lines gradient
// Color = X*81, so we will have 64800 colors from 65536 max
mov $81, %si
xor %bx, %bx
// Cycle through lines
.ly:
xor %cx, %cx
// Cycle through pixels
.lx:
mov %cx, %ax
mul %si // ax = ax*si
mov %ax, (%edi)
add $2, %edi
inc %cx
cmp $800, %cx
jne .lx
inc %bx
cmp $600, %bx
jne .ly
.lh:
hlt
jmp .lh
gdt:
.quad 0x0000000000000000
.quad 0x00CF9A000000FFFF // Code
.quad 0x00CF92000000FFFF // Data
gdtr:
.short 0x23, gdt // Limit and address
.org 0x7DFE
.word 0xAA55 // Floppy boot signature