; 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
-init_gfx:
- ; video mode 13h (320x200 8bpp)
- mov ax, 13h
- int 10h
+ extern sprsheet_cmap
+ extern sprsheet_tiles
+
+ 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_tiles
+ ; 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