This is the code I am using at the moment which seems to work OK, even with banked VESA modes.
set_vga_mode:
mov ax,12h
int 10h
mov dx,3ceh
mov ax,205h ;5=mode register
out dx,ax ;2=write mode 2
ret
write_pixel_4bit:
pusha
push es
mov bx,ax ;save AL (colour)
and bl,15
mov ax,[bpline] ;bytes per line
mov di,cx ;column
mul dx ;row*bytes per line = byte address
shr di,3 ;column/8 = bit address
add di,ax ;byte that has the pixel (1 of 8 )
;here you would check for carry and switch banks for VESA
mov ax,0a000h
mov es,ax
not cl ;bits reversed, column<>bit
and cl,7 ;bit position of pixel
mov dx,3ceh
mov ax,108h ;8=bitmask register
shl ah,cl ;correct bit
out dx,ax ;?=bitmask
cli
mov al,[es:di] ;load latch and ignore
mov [es:di],bl ;set the colour planes
sti
pop es
popa
ret
I set the mode and then set write mode 2 because that's all I am using, since it seems
to make it as easy to write a character (aligned at 8 bits) a line at once.
My thoughts are:
1. Is it correct? It seems to work (both bochs and my real computer).
2. It even seems to work with a VESA banked mode like 1024x768 even though my 8800GT says the mode is not VGA compatible.
I only want to support 16-colour graphics to make my VESA routines complete, but after reading parts of the "graphics black book" I'm not so sure what I'm doing...