; vi:filetype=nasm ts=8 sts=8 sw=8:
-;
-; list of functions
-; -----------------
-; init_gfx
-; initializes the video hardware and graphics routines
-; clear
-; clears the framebuffer (not vmem)
-; clobbers: ax, cx, di
-; swap_buffers
-; copies the framebuffer to video memory
-; clobbers: ax, cx, di, si
-; wait_vsync
-; clobbers: al, dx
-; set_palette_entry(idx[al], r[ah], g[bl], b[bh])
-; colors are 0-255
-
-VIDMEM_SEG equ 0a000h
-FRAMEBUF_SEG equ 09000h
+ bits 32
+ section .text
+
+%define GFX_ASM_
+%include "gfx.inc"
REG_CRTC_STATUS equ 3dah
CRTC_VBLANK_BIT equ 08h
REG_DAC_ADDR equ 3c8h
REG_DAC_DATA equ 3c9h
-init_gfx:
- ; video mode 13h (320x200 8bpp)
- mov ax, 13h
- int 10h
+ extern sprsheet
+ extern sprsheet_cmap
+ global init_gfx
+init_gfx:
call clear
+
+ ; setup the spritesheet palette
+ mov esi, sprsheet_cmap
+ xor cl, cl
+.cmaploop:
+ mov al, cl
+ mov ah, [esi]
+ mov bl, [esi + 1]
+ mov bh, [esi + 2]
+ add esi, 3
+ call set_palette_entry
+ inc cl
+ jnz .cmaploop
+
+ ; force color 0 to black
+ xor ax, ax
+ xor bx, bx
+ call set_palette_entry
+
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:
out dx, al
pop dx
ret
+
+ ; slow_sprite(int id, int x, int y)
+ ; assumptions: 32x32, one after the other, 0 is transparent
+ global slow_sprite
+slow_sprite:
+ push ebp
+ mov ebp, esp
+ pusha
+
+ 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
+ ; calculate sprite id offset (each spr is 32*32=1k)
+ mov eax, [ebp + 8]
+ shl eax, 10
+ add esi, eax
+
+ mov ecx, 32
+.yloop:
+ xor ebx, ebx
+.xloop:
+ mov al, [esi]
+ cmp al, 0
+ ;jz .skip_pixel
+ mov [edi + ebx], al
+.skip_pixel:
+ inc esi
+ inc ebx
+ cmp ebx, 32
+ jnz .xloop
+
+ add edi, 320
+ dec ecx
+ jnz .yloop
+
+ popa
+ pop ebp
+ ret