; initializes the video hardware and graphics routines
; clear
; clears the framebuffer (not vmem)
-; clobbers: ax, cx, di
+; clobbers: eax, ecx, edi
; swap_buffers
; copies the framebuffer to video memory
-; clobbers: ax, cx, di, si
+; clobbers: eax, ecx, edi, esi
; wait_vsync
; clobbers: al, dx
; set_palette_entry(idx[al], r[ah], g[bl], b[bh])
; colors are 0-255
+ bits 32
+ section .text
-VIDMEM_SEG equ 0a000h
-FRAMEBUF_SEG equ 09000h
+VIDMEM_ADDR equ 0a0000h
+FRAMEBUF_ADDR equ 090000h
REG_CRTC_STATUS equ 3dah
CRTC_VBLANK_BIT equ 08h
REG_DAC_ADDR equ 3c8h
REG_DAC_DATA equ 3c9h
+ extern sprsheet_cmap
+ extern sprsheet_tiles
+
+
+ global init_gfx
init_gfx:
- ; video mode 13h (320x200 8bpp)
- mov ax, 13h
- int 10h
call clear
; setup the spritesheet palette
- mov si, sprsheet_cmap
+ mov esi, sprsheet_cmap
xor cl, cl
.cmaploop:
mov al, cl
- mov ah, [si]
- mov bl, [si + 1]
- mov bh, [si + 2]
- add si, 3
+ mov ah, [esi]
+ mov bl, [esi + 1]
+ mov bh, [esi + 2]
+ add esi, 3
call set_palette_entry
- dec cl
+ inc cl
jnz .cmaploop
-
ret
+
+ global clear
clear:
- push es
- mov ax, FRAMEBUF_SEG
- mov es, ax
- xor di, di
- xor ax, ax
- mov cx, 16000
+ mov edi, FRAMEBUF_ADDR
+ xor eax, eax
+ mov ecx, 16000
rep stosd
- pop es
ret
+ global swap_buffers
swap_buffers:
- push ds
- push es
- mov ax, FRAMEBUF_SEG
- mov ds, ax
- xor si, si
- mov ax, VIDMEM_SEG
- mov es, ax
- xor di, di
- mov cx, 16000
+ mov esi, FRAMEBUF_ADDR
+ mov edi, VIDMEM_ADDR
+ mov ecx, 16000
rep movsd
- pop es
- pop ds
ret
+ global wait_vsync
wait_vsync:
mov dx, REG_CRTC_STATUS
.wait_vblank_end:
pop dx
ret
- ; slow_sprite(short id, short x, short y)
+ ; slow_sprite(int id, int x, int y)
; assumptions: 32x32, one after the other, 0 is transparent
- ; XXX sprsheet needs to go to its own segment
+ global slow_sprite
slow_sprite:
- push bp
- mov bp, sp
+ push ebp
+ mov ebp, esp
pusha
- mov ax, FRAMEBUF_SEG
- mov es, ax
- mov ax, [bp + 8] ; ax <- y
- sub ax, 16 ; ax <- y - 16 (center sprite vertically)
- mov bx, ax
- shl ax, 8
- shl bx, 6
- add ax, bx ; ax <- (y - 16) * 320
- mov di, [bp + 6] ; di <- x
- sub di, 16 ; di <- x - 16 (center sprite horizontally)
- add di, ax ; di <- (y - 16) * 320 + (x - 16)
-
- mov si, sprsheet_tiles
+ mov eax, [ebp + 16] ; ax <- y
+ sub eax, 16 ; ax <- y - 16 (center sprite vertically)
+ mov ebx, eax
+ shl eax, 8
+ shl ebx, 6
+ add eax, ebx ; ax <- (y - 16) * 320
+ mov edi, [ebp + 12] ; di <- x
+ sub edi, 16 ; di <- x - 16 (center sprite horizontally)
+ add edi, eax ; di <- (y - 16) * 320 + (x - 16)
+ add edi, FRAMEBUF_ADDR
+
+ mov esi, sprsheet_tiles
; calculate sprite id offset (each spr is 32*32=1k)
- mov ax, [bp + 4]
- shl ax, 10
- add si, ax
+ mov eax, [ebp + 8]
+ shl eax, 10
+ add esi, eax
- mov cx, 32
+ mov ecx, 32
.yloop:
- xor bx, bx
+ xor ebx, ebx
.xloop:
- mov al, [si]
+ mov al, [esi]
cmp al, 0
;jz .skip_pixel
- mov [es:di + bx], al
+ mov [edi + ebx], al
.skip_pixel:
- inc si
- inc bx
- cmp bx, 32
+ inc esi
+ inc ebx
+ cmp ebx, 32
jnz .xloop
- add di, 320
- dec cx
+ add edi, 320
+ dec ecx
jnz .yloop
popa
- pop bp
+ pop ebp
ret