testpico: more on timer reload
[megadrive.git] / nshtest / test.s
1 ##################################################
2 #                                                #
3 # Assemble with gas                              #
4 #   --register-prefix-optional --bitwise-or      #
5 #                                                #
6 ##################################################
7
8 .text
9 .globl main
10
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
116 #################################################
117 #                                               #
118 #                    DATA                       #
119 #                                               #
120 #################################################
121
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
443 # vim:filetype=asmM68k