interrupts half-done
[ld45_start_nothing] / src / gfx.asm
1 ; vi:filetype=nasm ts=8 sts=8 sw=8:
2         bits 32
3         section .text
4
5 %define GFX_ASM_
6 %include "gfx.inc"
7
8 REG_CRTC_STATUS equ 3dah
9 CRTC_VBLANK_BIT equ 08h
10
11 REG_DAC_ADDR    equ 3c8h
12 REG_DAC_DATA    equ 3c9h
13
14         extern sprsheet
15         extern sprsheet_cmap
16
17         global init_gfx
18 init_gfx:
19         call clear
20
21         ; setup the spritesheet palette
22         mov esi, sprsheet_cmap
23         xor cl, cl
24 .cmaploop:
25         mov al, cl
26         mov ah, [esi]
27         mov bl, [esi + 1]
28         mov bh, [esi + 2]
29         add esi, 3
30         call set_palette_entry
31         inc cl
32         jnz .cmaploop
33
34         ; force color 0 to black
35         xor ax, ax
36         xor bx, bx
37         call set_palette_entry
38
39         ret
40
41         global clear
42 clear:
43         mov edi, FRAMEBUF_ADDR
44         xor eax, eax
45         mov ecx, 16000
46         rep stosd
47         ret
48
49         global swap_buffers
50 swap_buffers:
51         mov esi, FRAMEBUF_ADDR
52         mov edi, VIDMEM_ADDR
53         mov ecx, 16000
54         rep movsd
55         ret
56
57         global wait_vsync
58 wait_vsync:
59         mov dx, REG_CRTC_STATUS
60 .wait_vblank_end:
61         in al, dx
62         and al, CRTC_VBLANK_BIT
63         jnz .wait_vblank_end
64 .wait_vblank_start:
65         in al, dx
66         and al, CRTC_VBLANK_BIT
67         jz .wait_vblank_start
68         ret
69
70 set_palette_entry:
71         push dx
72         mov dx, REG_DAC_ADDR
73         out dx, al
74         inc dx  ; dx <- REG_DAC_DATA
75         mov al, ah
76         shr al, 2
77         out dx, al
78         mov al, bl
79         shr al, 2
80         out dx, al
81         mov al, bh
82         shr al, 2
83         out dx, al
84         pop dx
85         ret
86
87         ; slow_sprite(int id, int x, int y)
88         ; assumptions: 32x32, one after the other, 0 is transparent
89         global slow_sprite
90 slow_sprite:
91         push ebp
92         mov ebp, esp
93         pusha
94
95         mov eax, [ebp + 16]     ; ax <- y
96         sub eax, 16             ; ax <- y - 16 (center sprite vertically)
97         mov ebx, eax
98         shl eax, 8
99         shl ebx, 6
100         add eax, ebx            ; ax <- (y - 16) * 320
101         mov edi, [ebp + 12]     ; di <- x
102         sub edi, 16             ; di <- x - 16 (center sprite horizontally)
103         add edi, eax            ; di <- (y - 16) * 320 + (x - 16)
104         add edi, FRAMEBUF_ADDR
105
106         mov esi, sprsheet
107         ; calculate sprite id offset (each spr is 32*32=1k)
108         mov eax, [ebp + 8]
109         shl eax, 10
110         add esi, eax
111
112         mov ecx, 32
113 .yloop:
114         xor ebx, ebx
115 .xloop:
116         mov al, [esi]
117         cmp al, 0
118         ;jz .skip_pixel
119         mov [edi + ebx], al
120 .skip_pixel:
121         inc esi
122         inc ebx
123         cmp ebx, 32
124         jnz .xloop
125
126         add edi, 320
127         dec ecx
128         jnz .yloop
129
130         popa
131         pop ebp
132         ret