0a3e0c3e |
1 | ################################################## |
2 | # # |
fce27dd5 |
3 | # Assemble with gas # |
4 | # --register-prefix-optional --bitwise-or # |
0a3e0c3e |
5 | # # |
6 | ################################################## |
7 | |
8 | .text |
9 | .globl main |
10 | |
0a3e0c3e |
11 | ################################################## |
12 | # # |
13 | # Register and bitmask definitions # |
14 | # # |
15 | ################################################## |
16 | |
17 | .equ GFXDATA, 0xc00000 |
18 | .equ GFXCNTL, 0xc00004 |
19 | |
20 | .equ VDP0_E_HBI, 0x10 |
21 | .equ VDP0_E_DISPLAY, 0x02 |
22 | .equ VDP0_PLTT_FULL, 0x04 |
23 | |
24 | .equ VDP1_SMS_MODE, 0x80 |
25 | .equ VDP1_E_DISPLAY, 0x40 |
26 | .equ VDP1_E_VBI, 0x20 |
27 | .equ VDP1_E_DMA, 0x10 |
28 | .equ VDP1_NTSC, 0x00 |
29 | .equ VDP1_PAL, 0x08 |
30 | .equ VDP1_RESERVED, 0x04 |
31 | |
32 | .equ VDP12_SPR_SHADOWS, 0x08 |
33 | .equ VDP12_SCREEN_V224, 0x00 |
34 | .equ VDP12_SCREEN_V448, 0x04 |
35 | .equ VDP12_PROGRESSIVE, 0x00 |
36 | .equ VDP12_INTERLACED, 0x02 |
37 | .equ VDP12_SCREEN_H256, 0x00 |
38 | .equ VDP12_SCREEN_H320, 0x81 |
39 | |
40 | .equ VDP16_MAP_V32, 0x00 |
41 | .equ VDP16_MAP_V64, 0x10 |
42 | .equ VDP16_MAP_V128, 0x30 |
43 | .equ VDP16_MAP_H32, 0x00 |
44 | .equ VDP16_MAP_H64, 0x01 |
45 | .equ VDP16_MAP_H128, 0x03 |
46 | |
47 | |
48 | |
49 | ################################################## |
50 | # # |
51 | # MACROS # |
52 | # # |
53 | ################################################## |
54 | |
55 | |
56 | /* Write val to VDP register reg */ |
57 | .macro write_vdp_reg reg val |
58 | move.w #((\reg << 8) + 0x8000 + \val),(a3) |
59 | .endm |
60 | |
61 | |
62 | /* For immediate addresses */ |
63 | .macro VRAM_ADDR reg adr |
64 | move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg |
65 | .endm |
66 | |
67 | |
68 | /* For indirect (variable) addresses. |
69 | Destroys d6-d7. */ |
70 | .macro VRAM_ADDR_var reg adr |
71 | move.l \adr,d6 |
72 | move.l \adr,d7 |
73 | and.w #0x3fff,d6 |
74 | lsr.w #7,d7 |
75 | lsr.w #7,d7 |
76 | add.w #0x4000,d6 |
77 | lsl.l #7,d6 |
78 | lsl.l #7,d6 |
79 | lsl.l #2,d6 |
80 | or.l d7,d6 |
81 | move.l d6,\reg |
82 | .endm |
83 | |
84 | |
85 | .macro CRAM_ADDR reg adr |
86 | move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg |
87 | .endm |
88 | |
89 | |
90 | /* For indirect (variable) addresses */ |
91 | .macro CRAM_ADDR_var reg adr |
92 | move.l \adr,d6 |
93 | move.l \adr,d7 |
94 | and.w #0x3fff,d6 |
95 | lsr.w #7,d7 |
96 | lsr.w #7,d7 |
97 | add.w #0xc000,d6 |
98 | lsl.l #7,d6 |
99 | lsl.l #7,d6 |
100 | lsl.l #2,d6 |
101 | or.l d7,d6 |
102 | move.l d6,\reg |
103 | .endm |
104 | |
105 | |
106 | .macro VSCROLL_ADDR reg adr |
107 | move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg |
108 | .endm |
109 | |
110 | |
111 | .macro HSCROLL_ADDR reg adr |
112 | move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg |
113 | .endm |
114 | |
115 | |
fce27dd5 |
116 | ################################################# |
117 | # # |
118 | # DATA # |
119 | # # |
120 | ################################################# |
121 | |
0a3e0c3e |
122 | colors: |
123 | dc.w 0x0040,0x0080,0x000e,0x00e0,0x0e00,0x00ee |
124 | pattern: |
125 | dc.l 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 |
126 | dc.l 0x22334455,0x22334455,0x22334455,0x22334455,0x22334455,0x22334455,0x22334455,0x22334455 |
127 | /* shadow sprite */ |
128 | dc.l 0x00000fff |
129 | dc.l 0x0000ffff |
130 | dc.l 0x00ffffff |
131 | dc.l 0x00ffffff |
132 | dc.l 0x0fffffff |
133 | dc.l 0xffffffff |
134 | dc.l 0xffffffff |
135 | dc.l 0xffffffff |
136 | /* */ |
137 | dc.l 0xffffffff |
138 | dc.l 0xffffffff |
139 | dc.l 0xffffffff |
140 | dc.l 0x0fffffff |
141 | dc.l 0x00ffffff |
142 | dc.l 0x00ffffff |
143 | dc.l 0x0000ffff |
144 | dc.l 0x00000fff |
145 | /* */ |
146 | dc.l 0xfff00000 |
147 | dc.l 0xffff0000 |
148 | dc.l 0xffffff00 |
149 | dc.l 0xffffff00 |
150 | dc.l 0xfffffff0 |
151 | dc.l 0xffffffff |
152 | dc.l 0xffffffff |
153 | dc.l 0xffffffff |
154 | /* */ |
155 | dc.l 0xffffffff |
156 | dc.l 0xffffffff |
157 | dc.l 0xffffffff |
158 | dc.l 0xfffffff0 |
159 | dc.l 0xffffff00 |
160 | dc.l 0xffffff00 |
161 | dc.l 0xffff0000 |
162 | dc.l 0xfff00000 |
163 | /* hilight sprite */ |
164 | dc.l 0x00000eee |
165 | dc.l 0x0000eeee |
166 | dc.l 0x00eeeeee |
167 | dc.l 0x00eeeeee |
168 | dc.l 0x0eeeeeee |
169 | dc.l 0xeeeeeeee |
170 | dc.l 0xeeeeeeee |
171 | dc.l 0xeeeeeeee |
172 | /* */ |
173 | dc.l 0xeeeeeeee |
174 | dc.l 0xeeeeeeee |
175 | dc.l 0xeeeeeeee |
176 | dc.l 0x0eeeeeee |
177 | dc.l 0x00eeeeee |
178 | dc.l 0x00eeeeee |
179 | dc.l 0x0000eeee |
180 | dc.l 0x00000eee |
181 | /* */ |
182 | dc.l 0xeee00000 |
183 | dc.l 0xeeee0000 |
184 | dc.l 0xeeeeee00 |
185 | dc.l 0xeeeeee00 |
186 | dc.l 0xeeeeeee0 |
187 | dc.l 0xeeeeeeee |
188 | dc.l 0xeeeeeeee |
189 | dc.l 0xeeeeeeee |
190 | /* */ |
191 | dc.l 0xeeeeeeee |
192 | dc.l 0xeeeeeeee |
193 | dc.l 0xeeeeeeee |
194 | dc.l 0xeeeeeee0 |
195 | dc.l 0xeeeeee00 |
196 | dc.l 0xeeeeee00 |
197 | dc.l 0xeeee0000 |
198 | dc.l 0xeee00000 |
199 | |
200 | |
201 | sprite_data: |
202 | /* Y size link attr X */ |
203 | dc.w 10+128; dc.b 0x05; dc.b 1; dc.w 0x6002; dc.w 0 |
204 | dc.w 30+128; dc.b 0x05; dc.b 2; dc.w 0x6006; dc.w 0 |
205 | dc.w 60+128; dc.b 0x05; dc.b 3; dc.w 0xe002; dc.w 0 |
206 | dc.w 80+128; dc.b 0x05; dc.b 4; dc.w 0xe006; dc.w 0 |
207 | dc.w 120+128; dc.b 0x05; dc.b 5; dc.w 0x6002; dc.w 0 |
208 | dc.w 140+128; dc.b 0x05; dc.b 6; dc.w 0x6006; dc.w 0 |
209 | dc.w 170+128; dc.b 0x05; dc.b 7; dc.w 0xe002; dc.w 0 |
210 | dc.w 190+128; dc.b 0x05; dc.b 0; dc.w 0xe006; dc.w 0 |
211 | sprite_data_end: |
212 | |
213 | |
214 | ################################################## |
215 | # # |
216 | # MAIN PROGRAM # |
217 | # # |
218 | ################################################## |
219 | |
220 | main: |
221 | /* Initialize VDP */ |
222 | jsr init_gfx |
223 | |
224 | /* Load color data */ |
225 | movea.l #0,a3 |
226 | move.l #colors,a4 |
227 | moveq.l #6,d4 |
228 | jsr load_colors |
229 | |
230 | /* load patterns */ |
231 | movea.l #0,a3 |
232 | movea.l #pattern,a4 |
233 | move.l #10,d4 |
234 | jsr load_tiles |
235 | |
236 | /* generate A layer map */ |
237 | movea.l #0xe000+10*2,a6 |
238 | move.l #28-1,d4 |
239 | lmaploop0: |
240 | movea.l a6,a3 |
241 | jsr load_prepare |
242 | |
243 | moveq.l #6-1,d3 |
244 | 0: move.l #0x00010001,(a3) |
245 | dbra d3,0b |
246 | |
247 | moveq.l #9-1,d3 |
248 | 0: move.l #0x80018001,(a3) |
249 | dbra d3,0b |
250 | |
251 | add.l #64*2,a6 |
252 | dbra d4,lmaploop0 |
253 | |
254 | /* generate B layer map */ |
255 | movea.l #0xc000+64*14*2,a3 |
256 | jsr load_prepare |
257 | |
258 | move.l #64*14/2-1,d3 |
259 | 0: move.l #0x80008000,(a3) |
260 | dbra d3,0b |
261 | |
262 | /* upload sprite data */ |
263 | movea.l #0xfc00,a3 |
264 | jsr load_prepare |
265 | movea.l #sprite_data,a0 |
266 | |
267 | move.l #(sprite_data_end-sprite_data)/2-1,d3 |
268 | 0: move.l (a0)+,(a3) |
269 | dbra d3,0b |
270 | |
271 | jsr wait_vsync |
272 | |
273 | ################################################## |
274 | # # |
275 | # MAIN LOOP # |
276 | # # |
277 | ################################################## |
278 | |
279 | forever: |
280 | movea.l #vtimer,a0 |
281 | move.l (a0),d4 |
282 | and.w #0x1ff,d4 |
283 | movea.l #0xfc06,a6 |
284 | moveq.l #8-1,d5 |
285 | |
286 | 0: |
287 | movea.l a6,a3 |
288 | jsr load_prepare |
289 | move.w d4,(a3) |
290 | addq.w #8,a6 |
291 | dbra d5,0b |
292 | |
293 | jsr wait_vsync |
294 | bra forever |
295 | |
296 | |
297 | |
298 | ################################################# |
299 | # # |
300 | # Initialize VDP registers # |
301 | # # |
302 | ################################################# |
303 | |
304 | init_gfx: |
305 | move.l #GFXCNTL,a3 |
306 | write_vdp_reg 0,(VDP0_E_DISPLAY + VDP0_PLTT_FULL) |
307 | write_vdp_reg 1,(VDP1_E_VBI + VDP1_E_DISPLAY + VDP1_E_DMA + VDP1_RESERVED) |
308 | write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */ |
309 | write_vdp_reg 3,(0xe000 >> 10) /* Window address */ |
310 | write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */ |
311 | write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */ |
312 | write_vdp_reg 6,0 |
313 | write_vdp_reg 7,1 /* Border color */ |
314 | write_vdp_reg 10,1 /* Lines per hblank interrupt */ |
315 | write_vdp_reg 11,0 /* 2-cell vertical scrolling */ |
316 | write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_SPR_SHADOWS) |
317 | write_vdp_reg 13,(0x6000 >> 10) /* Horizontal scroll address */ |
318 | write_vdp_reg 15,2 |
319 | write_vdp_reg 16,(VDP16_MAP_V32 + VDP16_MAP_H64) |
320 | write_vdp_reg 17,0 |
321 | write_vdp_reg 18,0xff |
322 | rts |
323 | |
324 | |
325 | |
326 | ################################################# |
327 | # # |
328 | # Load tile data from ROM # |
329 | # # |
330 | # Parameters: # |
331 | # a3: VRAM base # |
332 | # a4: pattern address # |
333 | # d4: number of tiles to load # |
334 | # Destroys a2,d0,d6-d7... # |
335 | # # |
336 | ################################################# |
337 | |
338 | load_tiles: |
339 | move.l #GFXCNTL,a2 |
340 | VRAM_ADDR_var d0,a3 |
341 | move.l d0,(a2) |
342 | lsl #3,d4 |
343 | |
344 | move.l #GFXDATA,a3 |
345 | subq.l #1,d4 |
346 | _copy_tile_data: |
347 | move.l (a4)+,(a3) |
348 | dbra d4,_copy_tile_data |
349 | |
350 | rts |
351 | |
352 | |
353 | load_prepare: |
354 | move.l #GFXCNTL,a2 |
355 | VRAM_ADDR_var d0,a3 |
356 | move.l d0,(a2) |
357 | move.l #GFXDATA,a3 |
358 | |
359 | rts |
360 | |
361 | |
362 | ################################################# |
363 | # # |
364 | # Clear one of the screen maps # |
365 | # # |
366 | # Parameters: # |
367 | # a0: Map address # |
368 | # d0: Data to write to each map entry # |
369 | # # |
370 | ################################################# |
371 | |
372 | clear_map: |
373 | move.l #GFXCNTL,a4 |
374 | VRAM_ADDR_var d1,a0 |
375 | move.l d1,(a4) |
376 | move.l #GFXDATA,a3 |
377 | move.w #1023,d1 /* Loop counter */ |
378 | _clear_map_loop: |
379 | move.w d0,(a3) |
380 | move.w d0,(a3) |
381 | dbra d1,_clear_map_loop |
382 | rts |
383 | |
384 | |
385 | ################################################# |
386 | # # |
387 | # Load color data from ROM # |
388 | # # |
389 | # Parameters: # |
390 | # a3: CRAM base # |
391 | # a4: color list address # |
392 | # d4: number of colors to load # |
393 | # # |
394 | ################################################# |
395 | |
396 | load_colors: |
397 | move.l #GFXCNTL,a2 |
398 | CRAM_ADDR_var d0,a3 |
399 | move.l d0,(a2) |
400 | |
401 | move.l #GFXDATA,a3 |
402 | subq.w #1,d4 |
403 | _copy_color_data: |
404 | move.w (a4)+,(a3) |
405 | dbra d4,_copy_color_data |
406 | |
407 | rts |
408 | |
409 | |
410 | ################################################# |
411 | # # |
412 | # Wait for next VBlank interrupt # |
413 | # # |
414 | ################################################# |
415 | |
416 | wait_vsync: |
417 | movea.l #vtimer,a0 |
418 | move.l (a0),a1 |
419 | _wait_change: |
420 | stop #0x2000 |
421 | cmp.l (a0),a1 |
422 | beq _wait_change |
423 | rts |
424 | |
425 | |
426 | ################################################# |
427 | # # |
428 | # RAM DATA # |
429 | # # |
430 | ################################################# |
431 | |
432 | .bss |
433 | .globl htimer |
434 | .globl vtimer |
435 | .globl rand_num |
436 | htimer: .long 0 |
437 | vtimer: .long 0 |
438 | rand_num: .long 0 |
439 | scrollx: .long 0 |
440 | |
441 | .end |
442 | |
fce27dd5 |
443 | # vim:filetype=asmM68k |