796ede04b4e17acde19f78b7bc879510a6080bc4
[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         ret
50
51
52         global clear
53 clear:
54         mov edi, FRAMEBUF_ADDR
55         xor eax, eax
56         mov ecx, 16000
57         rep stosd
58         ret
59
60         global swap_buffers
61 swap_buffers:
62         mov esi, FRAMEBUF_ADDR
63         mov edi, VIDMEM_ADDR
64         mov ecx, 16000
65         rep movsd
66         ret
67
68         global wait_vsync
69 wait_vsync:
70         mov dx, REG_CRTC_STATUS
71 .wait_vblank_end:
72         in al, dx
73         and al, CRTC_VBLANK_BIT
74         jnz .wait_vblank_end
75 .wait_vblank_start:
76         in al, dx
77         and al, CRTC_VBLANK_BIT
78         jz .wait_vblank_start
79         ret
80
81 set_palette_entry:
82         push dx
83         mov dx, REG_DAC_ADDR
84         out dx, al
85         inc dx  ; dx <- REG_DAC_DATA
86         mov al, ah
87         shr al, 2
88         out dx, al
89         mov al, bl
90         shr al, 2
91         out dx, al
92         mov al, bh
93         shr al, 2
94         out dx, al
95         pop dx
96         ret
97
98         ; slow_sprite(int id, int x, int y)
99         ; assumptions: 32x32, one after the other, 0 is transparent
100         global slow_sprite
101 slow_sprite:
102         push ebp
103         mov ebp, esp
104         pusha
105
106         mov eax, [ebp + 16]     ; ax <- y
107         sub eax, 16             ; ax <- y - 16 (center sprite vertically)
108         mov ebx, eax
109         shl eax, 8
110         shl ebx, 6
111         add eax, ebx            ; ax <- (y - 16) * 320
112         mov edi, [ebp + 12]     ; di <- x
113         sub edi, 16             ; di <- x - 16 (center sprite horizontally)
114         add edi, eax            ; di <- (y - 16) * 320 + (x - 16)
115         add edi, FRAMEBUF_ADDR
116
117         mov esi, sprsheet_tiles
118         ; calculate sprite id offset (each spr is 32*32=1k)
119         mov eax, [ebp + 8]
120         shl eax, 10
121         add esi, eax
122
123         mov ecx, 32
124 .yloop:
125         xor ebx, ebx
126 .xloop:
127         mov al, [esi]
128         cmp al, 0
129         ;jz .skip_pixel
130         mov [edi + ebx], al
131 .skip_pixel:
132         inc esi
133         inc ebx
134         cmp ebx, 32
135         jnz .xloop
136
137         add edi, 320
138         dec ecx
139         jnz .yloop
140
141         popa
142         pop ebp
143         ret