d216a83aff5e99041fff3d5b183174527907771c
[megadrive.git] / testpico / asmtools.S
1 # Assemble with gas
2 #   --register-prefix-optional --bitwise-or
3
4 .macro ldarg  arg, stacksz, reg
5     move.l (4 + \arg * 4 + \stacksz)(%sp), \reg
6 .endm
7
8 .macro ldargw arg, stacksz, reg
9     move.w (4 + \arg * 4 + 2 + \stacksz)(%sp), \reg
10 .endm
11
12 .global burn10 /* u16 val */
13 burn10:
14     ldarg       0, 0, d0
15     subq.l      #1, d0
16 0:
17     dbra        d0, 0b
18     rts
19
20 .global write16_x16 /* u32 a, u16 count, u16 d */
21 write16_x16:
22     ldarg       0, 0, a0
23     ldarg       2, 0, d0
24     move.w      d0, d1
25     swap        d0
26     move.w      d1, d0
27     ldarg       1, 0, d1
28     subq.l      #1, d1
29 0:
30     move.l      d0, (a0)
31     move.l      d0, (a0)
32     move.l      d0, (a0)
33     move.l      d0, (a0)
34     move.l      d0, (a0)
35     move.l      d0, (a0)
36     move.l      d0, (a0)
37     move.l      d0, (a0)
38     dbra        d1, 0b
39     rts
40
41 # read single phase from controller
42 #  d0 - result
43 #  destroys d1,d2
44 .global get_input
45 get_input:
46         move.b          #0x40,(0xa10003)
47         moveq.l         #0,d0
48         nop
49         nop
50         move.b          (0xa10003),d1
51         move.b          #0x00,(0xa10003)
52         andi.w          #0x3f,d1        /* 00CB RLDU */
53         nop
54         move.b          (0xa10003),d0
55         lsl.b           #2,d0
56         andi.w          #0xc0,d0        /* SA00 0000 */
57         or.b            d1,d0
58         eor.b           #0xff,d0
59 .if 0
60         swap            d7
61         move.w          d7,d1
62         eor.w           d0,d1           /* changed btns */
63         move.w          d0,d7           /* old val */
64         swap            d7
65         and.w           d0,d1           /* what changed now */
66 .endif
67         rts
68
69 .global write_and_read1 /* u32 a, u16 d, void *dst */
70 write_and_read1:
71     ldarg       0, 0, a0
72     ldargw      1, 0, d0
73 #ifndef PICO
74     move.w      d0, (a0)
75 #else
76     movea.l     a0, a1
77     subq.l      #1, a1
78     move.w      d0, 1(a1)
79 #endif
80     move.l      (a0), d0
81     move.l      (a0), d1
82
83     ldarg       2, 0, a1
84     move.l      d0, (a1)+
85     move.l      d1, (a1)+
86     rts
87
88 .global move_sr /* u16 sr */
89 move_sr:
90     ldargw      0, 0, d0
91     move.w      d0, sr
92     rts
93
94 .global move_sr_and_read /* u16 sr, u32 a */
95 move_sr_and_read:
96     ldargw      0, 0, d0
97     ldarg       1, 0, a0
98     move.w      d0, sr
99     move.w      (a0), d0
100     rts
101
102 .global read_sr
103 read_sr:
104     move.w      sr, d0
105     rts
106
107 .global memcpy_ /* void *dst, const void *src, u16 size */
108 memcpy_:
109     ldarg       0, 0, a0
110     ldarg       1, 0, a1
111     ldargw      2, 0, d0
112     subq.w      #1, d0
113 0:
114     move.b      (a1)+, (a0)+      /* not in a hurry */
115     dbra        d0, 0b
116     rts
117
118 .global memset_ /* void *dst, int d, u16 size */
119 memset_:
120     ldarg       0, 0, a0
121     ldargw      1, 0, d1
122     ldargw      2, 0, d0
123     subq.w      #1, d0
124 0:
125     move.b      d1, (a0)+         /* not in a hurry */
126     dbra        d0, 0b
127     rts
128
129 # tests
130
131 .global test_vcnt_vb
132 test_vcnt_vb:
133     movem.l     d2-d7/a2, -(sp)
134     movea.l     #0xc00007, a0
135     movea.l     #0xc00008, a1
136     movea.l     #0xff0000, a2
137     moveq.l     #0, d4          /* d4 = count */
138     moveq.l     #0, d5          /* d5 = vcnt_expect */
139                                 /* d6 = old */
140     move.l      #1<<(3+16), d7  /* d7 = SR_VB */
141 0:
142     btst        #3, (a0)
143     beq         0b          /* not blanking */
144 0:
145     btst        #3, (a0)
146     bne         0b          /* blanking */
147
148     addq.l      #1, a0
149 0:
150     tst.b       (a0)
151     bne         0b          /* not line 0 */
152
153     subq.l      #2, a0
154     move.l      (a0), d6
155     move.l      d6, (a2)+   /* d0 = old */
156 ###
157 0:
158     move.b      (a1), d2    /*  8 d2 = vcnt */
159     cmp.b       (a1), d2    /*  8 reread for corruption */
160     bne 0b                  /* 10 on changing vcounter? */
161     cmp.b       d2, d5      /*  4 vcnt == vcnt_expect? */
162     beq         0b          /* 10 */
163     move.l      (a0), d0    /* 12 */
164     tst.b       d2          /*  4 */
165     beq         3f
166 1:
167     addq.l      #1, d4      /* count++ */
168     addq.l      #1, d5
169     cmp.b       d2, d5
170     bne         2f          /* vcnt == vcnt_expect + 1 */
171     move.l      d0, d1
172     eor.l       d6, d1
173     and.l       d7, d1      /* (old ^ val) & vb */
174     bne         2f
175     move.l      d0, d6      /* old = val */
176     bra         0b
177
178 2: /* vcnt jump or vb change */
179     move.l      d6, (a2)+   /* *ram++ = old */
180     move.l      d0, (a2)+   /* *ram++ = val */
181     move.b      d2, d5      /* vcnt_expect = vcnt */
182     move.l      d0, d6      /* old = val */
183     bra         0b
184
185 3: /* vcnt == 0 */
186     move.l      d0, d1
187     and.l       d7, d1
188     bne         1b          /* still in VB */
189
190     move.l      d0, (a2)+   /* *ram++ = val */
191     move.l      d4, (a2)+   /* *ram++ = count */
192
193     movem.l     (sp)+, d2-d7/a2
194     rts
195
196 .global test_hint
197 test_hint:
198     move.w      d0, -(sp)         /*  8 */
199     move.w      (0xc00008).l, d0  /* 16 */
200     addq.w      #1, (0xf000).w    /* 16 */
201     tst.w       (0xf002).w        /* 12 */
202     bne         0f                /* 10 */
203     move.w      d0, (0xf002).w    /* 12 */
204 0:
205     move.w      d0, (0xf004).w    /* 12 */
206     move.w      (sp)+, d0         /*  8 */
207     rte                           /* 20 114+44 */
208 .global test_hint_end
209 test_hint_end:
210
211 .global test_vint
212 test_vint:
213     move.w      d0, -(sp)         /*  8 */
214     move.w      (0xc00008).l, d0  /* 16 */
215     addq.w      #1, (0xf008).w    /* 16 */
216     tst.w       (0xf00a).w        /* 12 */
217     bne         0f                /* 10 */
218     move.w      d0, (0xf00a).w    /* 12 */
219 0:
220     move.w      d0, (0xf00c).w    /* 12 */
221     move.w      (sp)+, d0         /*  8 */
222     rte                           /* 20 114 */
223 .global test_vint_end
224 test_vint_end:
225
226 .global x32x_enable
227 x32x_enable:
228     movea.l     #0xa15100, a0
229     movea.l     #0xa15122, a1
230     move.w      #1, (a0)          /* ADEN */
231 # wait for min(20_sh2_cycles, pll_setup_time)
232 # pll time is unclear, icd_mars.prg mentions 10ms which sounds
233 # way too much. Hope 40 68k cycles is enough
234     move.w      #40/10, d0
235 0:
236     dbra        d0, 0b
237     move.w      #3, (a0)          /* ADEN, nRES */
238 0:
239     move.w      #0xffff, d0       /* waste some cycles */
240     tst.w       (a1)
241     beq         0b                /* master BIOS busy */
242
243 0:                                /* for slave, use a limit, as it */
244     tst.w       4(a1)             /* won't respond on master error. */
245     dbne        d0, 0b            /* slave BIOS busy */
246
247     or.w        #1, 6(a0)         /* RV */
248     rts
249 .global x32x_enable_end
250 x32x_enable_end:
251
252 .global test_32x_b_c0
253 test_32x_b_c0:
254     ldarg       0, 0, a1
255     ldargw      1, 0, d0
256     jsr         (0xc0).l          /* move.b d0, (a1); RV=0 */
257     bset        #0, (0xa15107).l
258     rts
259 .global test_32x_b_c0_end
260 test_32x_b_c0_end:
261
262 # some nastyness from Fatal Rewind
263 .global test_h_v_2
264 test_h_v_2:
265     move.w      #0x2000, sr
266     move.w      #0x8014, (0xFFC00004).l
267     move.w      #0x8164, (0xFFC00004).l
268     move.w      #1, d0
269 0:
270     dbra        d0, 0b
271     move.w      #0x2700, sr
272     rts
273
274 .global test_v_h_2
275 test_v_h_2:
276     move.w      #0x2000, sr
277     movea.l     #0xc00004, a0
278     move.w      #0x8164, (a0)
279     move.w      #0x8144, (a0)
280     move.w      #480/2/10-1, d0
281 0:
282     dbra        d0, 0b
283     move.w      #0x8164, (0xFFC00004).l
284     move.w      #0x8014, (0xFFC00004).l
285     move.w      #0x2700, sr
286     rts
287
288 .global test_f_vint
289 test_f_vint:
290     move.w      (a1), d0
291     rte
292 .global test_f_vint_end
293 test_f_vint_end:
294
295 .global test_f
296 test_f:
297     movea.l     #0xc00005, a0
298     movea.l     #0xc00004, a1
299     move.w      #0x2000, sr
300 0:
301     btst        #3, (a0)
302     bne         0b
303 0:
304     btst        #3, (a0)
305     beq         0b
306     movem.l     d2-d7/a2, -(sp)
307     move.l      (a1), d1
308     move.l      (a1), d2
309     move.l      (a1), d3
310     move.l      (a1), d4
311     move.l      (a1), d5
312     move.l      (a1), d6
313     move.w      #0x2700, sr
314     movea.l     #0xff0000, a0
315     move.b      d0, (a0)+
316     move.b      #0, (a0)+
317 .macro test_lb_s sr, dr
318     swap        \sr
319     move.b      \sr, (\dr)+
320     swap        \sr
321     move.b      \sr, (\dr)+
322 .endm
323     test_lb_s   d1, a0
324     test_lb_s   d2, a0
325     test_lb_s   d3, a0
326     test_lb_s   d4, a0
327     test_lb_s   d5, a0
328     movem.l     (sp)+, d2-d7/a2
329     rts
330
331 .global test_hb
332 test_hb:
333     movem.l     d2-d7, -(sp)
334     movea.l     #0xc00004, a0
335     movea.l     #0xc00008, a1
336     moveq.l     #1, d0
337 0:
338     cmp.b       (a1), d0
339     beq         0b
340 0:
341     cmp.b       (a1), d0
342     bne         0b
343     move.l      (a0), d0
344     move.l      (a0), d1
345     move.l      (a0), d2
346     movea.l     #0xff0000, a1
347     movea.l     #0xff0000, a1
348     nop
349     nop
350     move.l      (a0), d3
351     move.l      (a0), d4
352     move.l      (a0), d5
353     move.l      (a0), d6
354     move.l      (a0), d7
355     test_lb_s   d0, a1
356     test_lb_s   d1, a1
357     test_lb_s   d2, a1
358     test_lb_s   d3, a1
359     test_lb_s   d4, a1
360     test_lb_s   d5, a1
361     test_lb_s   d6, a1
362     test_lb_s   d7, a1
363     movem.l     (sp)+, d2-d7
364     rts
365
366 # vim:filetype=asmM68k:ts=4:sw=4:expandtab