;----------------------------------------------------------;
; BOS 0.04 Christoffer Bubach, 2004-2005. ;
;----------------------------------------------------------;
; ;
; VGA functions. Change video mode etc. ;
; ;
;----------------------------------------------------------;
;-------------------;
; VGA palettes ;
;-------------------;
palette256 db 00, 00, 00, 00, 10, 41, 12, 28, 18, 02, 43, 22, 35
db 19, 09, 58, 00, 00, 57, 35, 12, 43, 43, 47, 24, 24
db 28, 20, 24, 60, 10, 60, 15, 31, 47, 63, 62, 56, 20
db 60, 56, 22, 63, 61, 36, 63, 63, 63, 00, 00, 00, 05
db 05, 05, 08, 08, 08, 11, 11, 11, 14, 14, 14, 17, 17
db 17, 20, 20, 20, 24, 24, 24, 28, 28, 28, 32, 32, 32
db 36, 36, 36, 40, 40, 40, 45, 45, 45, 50, 50, 50, 56
db 56, 56, 63, 63, 63, 13, 12, 15, 15, 16, 22, 17, 20
db 29, 19, 24, 36, 21, 28, 43, 23, 31, 50, 25, 34, 57
db 26, 42, 63, 00, 15, 02, 01, 22, 04, 02, 29, 06, 03
db 36, 08, 04, 43, 10, 05, 50, 12, 06, 57, 14, 20, 63
db 40, 18, 06, 07, 25, 12, 11, 33, 17, 14, 40, 23, 18
db 48, 28, 21, 55, 34, 25, 62, 39, 27, 63, 48, 36, 15
db 03, 02, 22, 06, 04, 29, 09, 06, 36, 12, 08, 43, 15
db 10, 50, 18, 12, 57, 21, 14, 63, 28, 20, 15, 00, 00
db 22, 07, 00, 29, 15, 00, 36, 23, 00, 43, 31, 00, 50
db 39, 00, 57, 47, 00, 63, 55, 00, 15, 05, 03, 22, 11
db 07, 29, 17, 11, 36, 23, 15, 43, 29, 19, 50, 35, 23
db 57, 41, 27, 63, 53, 34, 28, 14, 12, 33, 20, 14, 38
db 26, 16, 43, 32, 18, 48, 38, 20, 53, 44, 22, 58, 50
db 24, 63, 56, 30, 05, 05, 06, 10, 10, 13, 15, 15, 20
db 20, 20, 27, 25, 25, 34, 30, 30, 41, 35, 35, 48, 44
db 44, 63, 03, 06, 05, 05, 11, 09, 07, 16, 13, 09, 21
db 17, 11, 26, 21, 13, 31, 25, 15, 36, 29, 20, 48, 38
db 06, 06, 07, 13, 13, 15, 20, 20, 23, 27, 27, 31, 34
db 34, 39, 41, 41, 47, 48, 48, 55, 57, 57, 63, 06, 15
db 04, 12, 22, 08, 18, 29, 12, 24, 36, 16, 30, 43, 20
db 36, 50, 24, 42, 57, 28, 54, 63, 35, 15, 10, 10, 22
db 16, 16, 29, 21, 21, 36, 27, 27, 43, 32, 32, 50, 38
db 38, 57, 43, 43, 63, 54, 54, 15, 15, 06, 22, 22, 12
db 29, 29, 18, 36, 36, 24, 43, 43, 30, 50, 50, 36, 57
db 57, 42, 63, 63, 54, 02, 04, 14, 06, 12, 21, 10, 20
db 28, 14, 28, 35, 18, 36, 42, 22, 44, 49, 26, 52, 56
db 36, 63, 63, 18, 04, 14, 24, 08, 21, 31, 12, 28, 37
db 16, 35, 44, 20, 42, 50, 24, 49, 57, 28, 56, 63, 38
db 63, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 53, 44, 22, 09
db 08, 12, 16, 14, 16, 22, 21, 20, 29, 27, 24, 35, 34
db 28, 42, 40, 32, 48, 47, 36, 57, 56, 43, 08, 12, 16
db 14, 16, 22, 21, 20, 29, 27, 24, 35, 34, 28, 42, 40
db 32, 48, 47, 36, 57, 56, 43, 63, 13, 09, 11, 21, 16
db 15, 27, 22, 18, 36, 29, 22, 42, 35, 25, 51, 42, 29
db 57, 48, 32, 63, 56, 39, 06, 14, 09, 12, 21, 14, 18
db 27, 22, 24, 33, 28, 30, 39, 36, 36, 46, 42, 42, 52
db 47, 50, 59, 53, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00
palette16 db 00, 00, 00, 00, 00, 42, 00, 42, 00, 00, 42, 42, 42
db 00, 00, 42, 00, 42, 42, 21, 00, 42, 42, 42, 21, 21
db 21, 21, 21, 63, 21, 63, 21, 21, 63, 63, 63, 21, 21
db 63, 21, 63, 63, 63, 21, 63, 63, 63
;---------------------;
; VGA mode values. ;
;---------------------;
mode0x03 db 0x67, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x5F, 0x4F
db 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0E
db 0x0F, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0E, 0x8F, 0x28
db 0x01, 0x96, 0xB9, 0xA3, 0xFF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x10, 0x0E, 0x00, 0xFF, 0x00, 0x01, 0x02, 0x03
db 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, 0x3C
db 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00
mode0x13 db 0x63, 0x00, 0x03, 0x01, 0x0F, 0x00, 0x0E, 0x5F, 0x4F
db 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0E, 0x8F, 0x28
db 0x40, 0x96, 0xB9, 0xA3, 0xFF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x40, 0x05, 0x0F, 0xFF, 0x00, 0x01, 0x02, 0x03
db 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C
db 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00
vga_buff dd 0
;---------------------------------;
; sets the screen to mode 0x03 ;
;---------------------------------;
set_mode_0x03:
pushad
push ax
mov esi, mode0x03
call set_regs
call load_font ; IT WORKS!! FINALLY!
mov esi, palette16
call set_palette16
pop ax
cmp ax, 1
jne .cont
call cls ; in text.inc
.cont:
popad
ret
;---------------------------------;
; sets the screen to mode 0x13 ;
;---------------------------------;
set_mode_0x13:
pushad
push ax
mov esi, mode0x13
call set_regs
mov esi, palette256
call set_palette256
pop ax
cmp ax, 1
jne .cont
mov edi, 0xa0000 ; write directly to mem
mov ax, 0x0000 ; clear all 256kb with color 0
mov ecx, 0x20000 ; 256kb, 0x20000 = (256*1024)/2
rep stosw ; by wordwrites
.cont:
popad
ret
;----------------------------;
; loads the standard font ;
;----------------------------;
load_font:
cld
mov edi, vga_buff
mov dx, 0x03ce ; graphics
mov al, 5 ; write mode reg
out dx, al
inc dx
in al, dx
stosb
and al, 0xfc
xchg al, ah
mov al, 5
dec dx
out dx, ax
mov al, 6 ; misc reg
out dx, al
inc dx
in al, dx
stosb
and al, 0xf1
or al, 4
xchg al, ah
mov al, 6
dec dx
out dx, ax
mov dx, 0x03c4 ; sequencer port
mov al, 2 ; map mask reg
out dx, al
inc dx
in al, dx
stosb
dec dx
mov ax, 0x0402
out dx, ax
mov al, 4 ; memory selector reg
out dx, al
inc dx
in al, dx
stosb
or al, 4
xchg al, ah
mov al, 4
dec dx
out dx, ax
mov esi, font_8x16 ; font pointer
mov edi, 0xa0000
xor ecx, ecx
mov ebx, ecx
.l1:
mov cl, 16 ; font bytes (16 is standard)
rep movsb
mov cl, 32
sub cl, 16 ; font bytes
xor eax, eax
rep stosb
dec bl ; 256 chars
jnz .l1
mov esi, vga_buff
mov dx, 0x03ce
lodsb
xchg al, ah
mov al, 5
out dx, ax
lodsb
xchg al, ah
mov al, 6
out dx, ax
mov dx, 0x03c4
lodsb
xchg al, ah
mov al, 2
out dx, ax
lodsb
xchg al, ah
mov al, 4
out dx, ax
ret
;------------------------------------;
; put a pixel at x, y with color ;
; used only in mode 0x13 ;
; ;
; input: bx = x ;
; cx = y ;
; al = color ;
; ;
; output: none. ;
;------------------------------------;
put_0x13_pixel:
push ax
push bx
push cx
push edi
mov edi, 0xa0000 ; directly to mem
add di, bx
mov bx, cx
shl cx, 8
shl bx, 6
add cx, bx
add di, cx
stosb
pop edi
pop cx
pop bx
pop ax
ret
;-----------------------------------------------------;
; put a sprite at x, y. only for mode 0x13 ;
; ;
; input: ax = x, bx = y, cx = width, dx = height ;
; esi = pointer to sprite ;
; ;
; output: none. ;
;-----------------------------------------------------;
put_0x13_sprite:
pushad ; this was a
.row_loop: ; nightmare to write.
dec dx ; guess how many times
push cx ; i got lost in the push
push ax ; and pops here.. ;)
.col_loop: ; not to mention what
dec cx ; time it was when i wrote
push ax ; it.. :P
push bx
push cx
mov cx, bx
mov bx, ax
lodsb
call put_0x13_pixel
pop cx
pop bx
pop ax
inc ax
cmp cx, 0
jne .col_loop
pop ax
pop cx
inc bx
cmp dx, 0
jne .row_loop
popad
ret
;---------------------------------------------;
; sets the palette (256 colors) ;
; ;
; input: esi = palette. ;
; output: none. ;
;---------------------------------------------;
set_palette256:
push ax
push cx
push dx
xor cx, cx
.l1:
mov dx, 0x03C8
mov al, cl ; color no. = loop no.
out dx, al
inc dx ; port 0x3C9
mov al, byte [esi] ; red
out dx, al
inc esi
mov al, byte [esi] ; green
out dx, al
inc esi
mov al, byte [esi] ; blue
out dx, al
inc esi
inc cx
cmp cx, 256
jl .l1
pop dx
pop cx
pop ax
ret
;---------------------------------------------;
; sets the palette (16 colors) ;
; ;
; input: esi = pointer to palette. ;
; output: none. ;
;---------------------------------------------;
set_palette16:
push ax
push cx
push dx
xor cx, cx
.l1:
mov dx, 0x3DA
in al, dx
mov al, cl ; color no.
mov dx, 0x3C0
out dx, al
inc dx ; port 0x3C1
in al, dx
mov dx, 0x3C8
out dx, al
inc dx ; port 0x3C9
mov al, byte [esi] ; red
out dx, al
inc esi
mov al, byte [esi] ; green
out dx, al
inc esi
mov al, byte [esi] ; blue
out dx, al
inc esi
inc cx
cmp cx, 16
jl .l1
mov dx, 0x3DA
in al, dx
mov al, 0x20
mov dx, 0x3C0
out dx, al
pop dx
pop cx
pop ax
ret
;---------------------------------;
; Set VGA regs to choosen mode ;
; internal use. ;
;---------------------------------;
set_regs:
cli
mov dx, 0x3C2
lodsb
out dx, al
mov dx, 0x3DA
lodsb
out dx, al
xor ecx, ecx
mov dx, 0x3C4
.l1:
lodsb
xchg al, ah
mov al, cl
out dx, ax
inc ecx
cmp cl, 4
jbe .l1
mov dx, 0x3D4
mov ax, 0x0E11
out dx, ax
xor ecx, ecx
mov dx, 0x3D4
.l2:
lodsb
xchg al, ah
mov al, cl
out dx, ax
inc ecx
cmp cl, 0x18
jbe .l2
xor ecx, ecx
mov dx, 0x3CE
.l3:
lodsb
xchg al, ah
mov al, cl
out dx, ax
inc ecx
cmp cl, 8
jbe .l3
mov dx, 0x3DA
in al, dx
xor ecx, ecx
mov dx, 0x3C0
.l4:
in ax, dx
mov al, cl
out dx, al
lodsb
out dx, al
inc ecx
cmp cl, 0x14
jbe .l4
mov al, 0x20
out dx, al
sti
ret