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