811f35d7da6f9f51887ca218021fa7a309c1723a
[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     /* different timing due to extra fetch of offset, */
77     /* less troulesome to emulate */
78     movea.l     a0, a1
79     subq.l      #1, a1
80     move.w      d0, 1(a1)
81 #endif
82     move.l      (a0), d0
83     move.l      (a0), d1
84
85     ldarg       2, 0, a1
86     move.l      d0, (a1)+
87     move.l      d1, (a1)+
88     rts
89
90 .global move_sr /* u16 sr */
91 move_sr:
92     ldargw      0, 0, d0
93     move.w      d0, sr
94     rts
95
96 .global move_sr_and_read /* u16 sr, u32 a */
97 move_sr_and_read:
98     ldargw      0, 0, d0
99     ldarg       1, 0, a0
100     move.w      d0, sr
101     move.w      (a0), d0
102     rts
103
104 .global read_sr
105 read_sr:
106     move.w      sr, d0
107     rts
108
109 .global memcpy_ /* void *dst, const void *src, u16 size */
110 memcpy_:
111     ldarg       0, 0, a0
112     ldarg       1, 0, a1
113     ldargw      2, 0, d0
114     subq.w      #1, d0
115 0:
116     move.b      (a1)+, (a0)+      /* not in a hurry */
117     dbra        d0, 0b
118     rts
119
120 .global memset_ /* void *dst, int d, u16 size */
121 memset_:
122     ldarg       0, 0, a0
123     ldargw      1, 0, d1
124     ldargw      2, 0, d0
125     subq.w      #1, d0
126 0:
127     move.b      d1, (a0)+         /* not in a hurry */
128     dbra        d0, 0b
129     rts
130
131 # tests
132
133 .global test_vcnt_vb
134 test_vcnt_vb:
135     movem.l     d2-d7/a2, -(sp)
136     movea.l     #0xc00007, a0
137     movea.l     #0xc00008, a1
138     movea.l     #0xff0000, a2
139     moveq.l     #0, d4          /* d4 = count */
140     moveq.l     #0, d5          /* d5 = vcnt_expect */
141                                 /* d6 = old */
142     move.l      #1<<(3+16), d7  /* d7 = SR_VB */
143 0:
144     btst        #3, (a0)
145     beq         0b          /* not blanking */
146 0:
147     btst        #3, (a0)
148     bne         0b          /* blanking */
149
150     addq.l      #1, a0
151 0:
152     tst.b       (a0)
153     bne         0b          /* not line 0 */
154
155     subq.l      #2, a0
156     move.l      (a0), d6
157     move.l      d6, (a2)+   /* d0 = old */
158 ###
159 0:
160     move.b      (a1), d2    /*  8 d2 = vcnt */
161     cmp.b       (a1), d2    /*  8 reread for corruption */
162     bne 0b                  /* 10 on changing vcounter? */
163     cmp.b       d2, d5      /*  4 vcnt == vcnt_expect? */
164     beq         0b          /* 10 */
165     move.l      (a0), d0    /* 12 */
166     tst.b       d2          /*  4 */
167     beq         3f
168 1:
169     addq.l      #1, d4      /* count++ */
170     addq.l      #1, d5
171     cmp.b       d2, d5
172     bne         2f          /* vcnt == vcnt_expect + 1 */
173     move.l      d0, d1
174     eor.l       d6, d1
175     and.l       d7, d1      /* (old ^ val) & vb */
176     bne         2f
177     move.l      d0, d6      /* old = val */
178     bra         0b
179
180 2: /* vcnt jump or vb change */
181     move.l      d6, (a2)+   /* *ram++ = old */
182     move.l      d0, (a2)+   /* *ram++ = val */
183     move.b      d2, d5      /* vcnt_expect = vcnt */
184     move.l      d0, d6      /* old = val */
185     bra         0b
186
187 3: /* vcnt == 0 */
188     move.l      d0, d1
189     and.l       d7, d1
190     bne         1b          /* still in VB */
191
192     move.l      d0, (a2)+   /* *ram++ = val */
193     move.l      d4, (a2)+   /* *ram++ = count */
194
195     movem.l     (sp)+, d2-d7/a2
196     rts
197
198 .global test_hint
199 test_hint:
200     move.w      d0, -(sp)         /*  8 */
201     move.w      (0xc00008).l, d0  /* 16 */
202     addq.w      #1, (0xf000).w    /* 16 */
203     tst.w       (0xf002).w        /* 12 */
204     bne         0f                /* 10 */
205     move.w      d0, (0xf002).w    /* 12 */
206 0:
207     move.w      d0, (0xf004).w    /* 12 */
208     move.w      (sp)+, d0         /*  8 */
209     rte                           /* 20 114+44 */
210 .global test_hint_end
211 test_hint_end:
212
213 .global test_vint
214 test_vint:
215     move.w      d0, -(sp)         /*  8 */
216     move.w      (0xc00008).l, d0  /* 16 */
217     addq.w      #1, (0xf008).w    /* 16 */
218     tst.w       (0xf00a).w        /* 12 */
219     bne         0f                /* 10 */
220     move.w      d0, (0xf00a).w    /* 12 */
221 0:
222     move.w      d0, (0xf00c).w    /* 12 */
223     move.w      (sp)+, d0         /*  8 */
224     rte                           /* 20 114 */
225 .global test_vint_end
226 test_vint_end:
227
228 .global x32x_enable
229 x32x_enable:
230     movea.l     #0xa15100, a0
231     movea.l     #0xa15122, a1
232     move.w      #1, (a0)          /* ADEN */
233 # wait for min(20_sh2_cycles, pll_setup_time)
234 # pll time is unclear, icd_mars.prg mentions 10ms which sounds
235 # way too much. Hope 40 68k cycles is enough
236     move.w      #40/10, d0
237 0:
238     dbra        d0, 0b
239     move.w      #3, (a0)          /* ADEN, nRES */
240 0:
241     move.w      #0xffff, d0       /* waste some cycles */
242     tst.w       (a1)
243     beq         0b                /* master BIOS busy */
244
245 0:                                /* for slave, use a limit, as it */
246     tst.w       4(a1)             /* won't respond on master error. */
247     dbne        d0, 0b            /* slave BIOS busy */
248
249     or.w        #1, 6(a0)         /* RV */
250     rts
251 .global x32x_enable_end
252 x32x_enable_end:
253
254 .global x32x_disable
255 x32x_disable:
256     movea.l     #0xa15100, a0
257     move.w      #1, (a0)          /* ADEN (reset sh2) */
258     move.w      #0, (a0)          /* adapter disable, reset sh2 */
259     move.w      #1, d0
260 0:
261     dbra        d0, 0b
262     move.w      #2, (a0)          /* nRES - sh2s should see no ADEN and sleep */
263     rts
264 .global x32x_disable_end
265 x32x_disable_end:
266
267 .global test_32x_b_c0
268 test_32x_b_c0:
269     ldarg       0, 0, a1
270     ldargw      1, 0, d0
271     jsr         (0xc0).l          /* move.b d0, (a1); RV=0 */
272     bset        #0, (0xa15107).l  /* RV=1 */
273     rts
274 .global test_32x_b_c0_end
275 test_32x_b_c0_end:
276
277 # some nastyness from Fatal Rewind
278 .global test_h_v_2
279 test_h_v_2:
280     move.w      #0x2000, sr
281     move.w      #0x8014, (0xFFC00004).l
282     move.w      #0x8164, (0xFFC00004).l
283     move.w      #1, d0
284 0:
285     dbra        d0, 0b
286     move.w      #0x2700, sr
287     rts
288
289 .global test_v_h_2
290 test_v_h_2:
291     move.w      #0x2000, sr
292     movea.l     #0xc00004, a0
293     move.w      #0x8164, (a0)
294     move.w      #0x8144, (a0)
295     move.w      #480/2/10-1, d0
296 0:
297     dbra        d0, 0b
298     move.w      #0x8164, (0xFFC00004).l
299     move.w      #0x8014, (0xFFC00004).l
300     move.w      #0x2700, sr
301     rts
302
303 .global test_f_vint
304 test_f_vint:
305     move.w      (a1), d0
306     rte
307 .global test_f_vint_end
308 test_f_vint_end:
309
310 .global test_f
311 test_f:
312     movea.l     #0xc00005, a0
313     movea.l     #0xc00004, a1
314     move.w      #0x2000, sr
315 0:
316     btst        #3, (a0)
317     bne         0b
318 0:
319     btst        #3, (a0)
320     beq         0b
321     movem.l     d2-d7/a2, -(sp)
322     move.l      (a1), d1
323     move.l      (a1), d2
324     move.l      (a1), d3
325     move.l      (a1), d4
326     move.l      (a1), d5
327     move.l      (a1), d6
328     move.w      #0x2700, sr
329     movea.l     #0xff0000, a0
330     move.b      d0, (a0)+
331     move.b      #0, (a0)+
332 .macro test_lb_s sr, dr
333     swap        \sr
334     move.b      \sr, (\dr)+
335     swap        \sr
336     move.b      \sr, (\dr)+
337 .endm
338     test_lb_s   d1, a0
339     test_lb_s   d2, a0
340     test_lb_s   d3, a0
341     test_lb_s   d4, a0
342     test_lb_s   d5, a0
343     movem.l     (sp)+, d2-d7/a2
344     rts
345
346 .global test_hb
347 test_hb:
348     movem.l     d2-d7, -(sp)
349     movea.l     #0xc00004, a0
350     movea.l     #0xc00008, a1
351     moveq.l     #1, d0
352 0:
353     cmp.b       (a1), d0
354     beq         0b
355 0:
356     cmp.b       (a1), d0
357     bne         0b
358     move.l      (a0), d0
359     move.l      (a0), d1
360     move.l      (a0), d2
361     movea.l     #0xff0000, a1
362     movea.l     #0xff0000, a1
363     nop
364     nop
365     move.l      (a0), d3
366     move.l      (a0), d4
367     move.l      (a0), d5
368     move.l      (a0), d6
369     move.l      (a0), d7
370     test_lb_s   d0, a1
371     test_lb_s   d1, a1
372     test_lb_s   d2, a1
373     test_lb_s   d3, a1
374     test_lb_s   d4, a1
375     test_lb_s   d5, a1
376     test_lb_s   d6, a1
377     test_lb_s   d7, a1
378     movem.l     (sp)+, d2-d7
379     rts
380
381 # vim:filetype=asmM68k:ts=4:sw=4:expandtab