testpico: 32x reset + other tests
[megadrive.git] / testpico / asmtools.S
CommitLineData
ffd4b35c 1# Assemble with gas
2# --register-prefix-optional --bitwise-or
e71680d5 3# reminder: d2-d7/a2-a6 are callee-save
ffd4b35c 4
5.macro ldarg arg, stacksz, reg
6 move.l (4 + \arg * 4 + \stacksz)(%sp), \reg
7.endm
8
5073ab5a 9# args are always 4 bytes in stack, caller restores sp
6c839579 10.macro ldargw arg, stacksz, reg
11 move.w (4 + \arg * 4 + 2 + \stacksz)(%sp), \reg
12.endm
13
ffd4b35c 14.global burn10 /* u16 val */
15burn10:
635f2450 16 ldargw 0, 0, d0
ffd4b35c 17 subq.l #1, d0
180:
635f2450 19 dbra d0, 0b /* 10|14 */
20 rts /* 16 */
ffd4b35c 21
a385208c 22.global write16_x16 /* u32 a, u16 count, u16 d */
23write16_x16:
24 ldarg 0, 0, a0
25 ldarg 2, 0, d0
26 move.w d0, d1
27 swap d0
28 move.w d1, d0
29 ldarg 1, 0, d1
30 subq.l #1, d1
310:
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 move.l d0, (a0)
39 move.l d0, (a0)
40 dbra d1, 0b
41 rts
42
43# read single phase from controller
44# d0 - result
e71680d5 45# destroys d1
a385208c 46.global get_input
47get_input:
5073ab5a 48.global get_input_s
49get_input_s:
a385208c 50 move.b #0x40,(0xa10003)
51 moveq.l #0,d0
52 nop
53 nop
54 move.b (0xa10003),d1
55 move.b #0x00,(0xa10003)
56 andi.w #0x3f,d1 /* 00CB RLDU */
57 nop
58 move.b (0xa10003),d0
59 lsl.b #2,d0
60 andi.w #0xc0,d0 /* SA00 0000 */
61 or.b d1,d0
62 eor.b #0xff,d0
63.if 0
64 swap d7
65 move.w d7,d1
66 eor.w d0,d1 /* changed btns */
67 move.w d0,d7 /* old val */
68 swap d7
69 and.w d0,d1 /* what changed now */
70.endif
71 rts
5073ab5a 72.global get_input_end
73get_input_end:
a385208c 74
635f2450 75.global get_line
76get_line:
77 movea.l #0xc00008, a0
78 moveq.l #0, d0
790:
80 move.b (a0), d0 /* 8 d2 = vcnt */
81 cmp.b (a0), d0 /* 8 reread for super-rare corruption (torn read) */
82 bne 0b
83 rts
84
6c839579 85.global write_and_read1 /* u32 a, u16 d, void *dst */
86write_and_read1:
87 ldarg 0, 0, a0
88 ldargw 1, 0, d0
cc7e5122 89#ifndef PICO
6c839579 90 move.w d0, (a0)
cc7e5122 91#else
234c4556 92 /* different timing due to extra fetch of offset, */
93 /* less troulesome to emulate */
cc7e5122 94 movea.l a0, a1
95 subq.l #1, a1
96 move.w d0, 1(a1)
97#endif
6c839579 98 move.l (a0), d0
99 move.l (a0), d1
cc7e5122 100
101 ldarg 2, 0, a1
6c839579 102 move.l d0, (a1)+
103 move.l d1, (a1)+
104 rts
105
106.global move_sr /* u16 sr */
107move_sr:
108 ldargw 0, 0, d0
109 move.w d0, sr
110 rts
111
112.global move_sr_and_read /* u16 sr, u32 a */
113move_sr_and_read:
114 ldargw 0, 0, d0
115 ldarg 1, 0, a0
116 move.w d0, sr
117 move.w (a0), d0
118 rts
119
8517a6df 120.global read_sr
121read_sr:
122 move.w sr, d0
123 rts
124
6c839579 125.global memcpy_ /* void *dst, const void *src, u16 size */
126memcpy_:
127 ldarg 0, 0, a0
128 ldarg 1, 0, a1
129 ldargw 2, 0, d0
130 subq.w #1, d0
1310:
132 move.b (a1)+, (a0)+ /* not in a hurry */
133 dbra d0, 0b
134 rts
135
136.global memset_ /* void *dst, int d, u16 size */
137memset_:
138 ldarg 0, 0, a0
139 ldargw 1, 0, d1
140 ldargw 2, 0, d0
141 subq.w #1, d0
1420:
143 move.b d1, (a0)+ /* not in a hurry */
144 dbra d0, 0b
145 rts
146
147# tests
148
cc7e5122 149.global test_vcnt_vb
150test_vcnt_vb:
a385208c 151 movem.l d2-d7/a2, -(sp)
152 movea.l #0xc00007, a0
153 movea.l #0xc00008, a1
154 movea.l #0xff0000, a2
155 moveq.l #0, d4 /* d4 = count */
156 moveq.l #0, d5 /* d5 = vcnt_expect */
157 /* d6 = old */
158 move.l #1<<(3+16), d7 /* d7 = SR_VB */
1590:
160 btst #3, (a0)
161 beq 0b /* not blanking */
1620:
163 btst #3, (a0)
164 bne 0b /* blanking */
165
166 addq.l #1, a0
1670:
168 tst.b (a0)
169 bne 0b /* not line 0 */
170
171 subq.l #2, a0
172 move.l (a0), d6
173 move.l d6, (a2)+ /* d0 = old */
174###
1750:
176 move.b (a1), d2 /* 8 d2 = vcnt */
177 cmp.b (a1), d2 /* 8 reread for corruption */
178 bne 0b /* 10 on changing vcounter? */
179 cmp.b d2, d5 /* 4 vcnt == vcnt_expect? */
180 beq 0b /* 10 */
181 move.l (a0), d0 /* 12 */
182 tst.b d2 /* 4 */
183 beq 3f
1841:
185 addq.l #1, d4 /* count++ */
186 addq.l #1, d5
187 cmp.b d2, d5
188 bne 2f /* vcnt == vcnt_expect + 1 */
189 move.l d0, d1
190 eor.l d6, d1
191 and.l d7, d1 /* (old ^ val) & vb */
192 bne 2f
193 move.l d0, d6 /* old = val */
194 bra 0b
195
1962: /* vcnt jump or vb change */
197 move.l d6, (a2)+ /* *ram++ = old */
198 move.l d0, (a2)+ /* *ram++ = val */
199 move.b d2, d5 /* vcnt_expect = vcnt */
200 move.l d0, d6 /* old = val */
201 bra 0b
202
2033: /* vcnt == 0 */
204 move.l d0, d1
205 and.l d7, d1
206 bne 1b /* still in VB */
207
208 move.l d0, (a2)+ /* *ram++ = val */
209 move.l d4, (a2)+ /* *ram++ = count */
210
211 movem.l (sp)+, d2-d7/a2
9d39a80e 212 rts
a385208c 213
e71680d5 214.global test_vcnt_loops
215test_vcnt_loops:
216 movem.l d2, -(sp)
217 movea.l #0xc00007, a0
218 movea.l #0xfff000, a1
219 move.b #0xff, d0 /* d0 = current_vcnt */
220 moveq.l #0, d1 /* d1 = loop counter */
221 move.w #315-1, d2 /* d2 = line limit */
2220:
223 btst #3, (a0)
224 beq 0b /* not blanking */
2250:
226 btst #3, (a0)
227 bne 0b /* blanking */
228
229 addq.w #1, a0
2300:
231 addq.w #1, d1 /* 4 */
232 cmp.b (a0), d0 /* 8 vcnt changed? */
233 beq 0b /* 10 */
234
235 move.w d0, (a1)+ /* 8 save */
236 move.w d1, (a1)+
237 move.b (a0), d0 /* 8 new vcnt */
238 moveq.l #0, d1
239 dbra d2, 0b
240
241 movem.l (sp)+, d2
242 rts
243
6c839579 244.global test_hint
245test_hint:
246 move.w d0, -(sp) /* 8 */
247 move.w (0xc00008).l, d0 /* 16 */
248 addq.w #1, (0xf000).w /* 16 */
249 tst.w (0xf002).w /* 12 */
250 bne 0f /* 10 */
251 move.w d0, (0xf002).w /* 12 */
2520:
253 move.w d0, (0xf004).w /* 12 */
254 move.w (sp)+, d0 /* 8 */
8517a6df 255 rte /* 20 114+44 */
6c839579 256.global test_hint_end
257test_hint_end:
258
259.global test_vint
260test_vint:
261 move.w d0, -(sp) /* 8 */
262 move.w (0xc00008).l, d0 /* 16 */
263 addq.w #1, (0xf008).w /* 16 */
264 tst.w (0xf00a).w /* 12 */
265 bne 0f /* 10 */
266 move.w d0, (0xf00a).w /* 12 */
2670:
268 move.w d0, (0xf00c).w /* 12 */
269 move.w (sp)+, d0 /* 8 */
270 rte /* 20 114 */
271.global test_vint_end
272test_vint_end:
273
9d39a80e 274.global x32x_enable
275x32x_enable:
276 movea.l #0xa15100, a0
71b41fdd 277 movea.l #0xa15122, a1
278 move.w #1, (a0) /* ADEN */
279# wait for min(20_sh2_cycles, pll_setup_time)
280# pll time is unclear, icd_mars.prg mentions 10ms which sounds
281# way too much. Hope 40 68k cycles is enough
282 move.w #40/10, d0
2830:
284 dbra d0, 0b
9d39a80e 285 move.w #3, (a0) /* ADEN, nRES */
2860:
71b41fdd 287 move.w #0xffff, d0 /* waste some cycles */
9d39a80e 288 tst.w (a1)
71b41fdd 289 beq 0b /* master BIOS busy */
290
2910: /* for slave, use a limit, as it */
292 tst.w 4(a1) /* won't respond on master error. */
293 dbne d0, 0b /* slave BIOS busy */
294
9d39a80e 295 or.w #1, 6(a0) /* RV */
296 rts
297.global x32x_enable_end
298x32x_enable_end:
299
234c4556 300.global x32x_disable
301x32x_disable:
302 movea.l #0xa15100, a0
303 move.w #1, (a0) /* ADEN (reset sh2) */
304 move.w #0, (a0) /* adapter disable, reset sh2 */
305 move.w #1, d0
3060:
307 dbra d0, 0b
308 move.w #2, (a0) /* nRES - sh2s should see no ADEN and sleep */
309 rts
310.global x32x_disable_end
311x32x_disable_end:
312
06d7984c 313.global test_32x_b_c0
314test_32x_b_c0:
315 ldarg 0, 0, a1
316 ldargw 1, 0, d0
317 jsr (0xc0).l /* move.b d0, (a1); RV=0 */
234c4556 318 bset #0, (0xa15107).l /* RV=1 */
06d7984c 319 rts
320.global test_32x_b_c0_end
321test_32x_b_c0_end:
322
cc7e5122 323# some nastyness from Fatal Rewind
324.global test_h_v_2
325test_h_v_2:
326 move.w #0x2000, sr
327 move.w #0x8014, (0xFFC00004).l
328 move.w #0x8164, (0xFFC00004).l
329 move.w #1, d0
3300:
331 dbra d0, 0b
332 move.w #0x2700, sr
333 rts
334
335.global test_v_h_2
336test_v_h_2:
337 move.w #0x2000, sr
338 movea.l #0xc00004, a0
339 move.w #0x8164, (a0)
340 move.w #0x8144, (a0)
341 move.w #480/2/10-1, d0
3420:
343 dbra d0, 0b
344 move.w #0x8164, (0xFFC00004).l
345 move.w #0x8014, (0xFFC00004).l
346 move.w #0x2700, sr
347 rts
348
349.global test_f_vint
350test_f_vint:
351 move.w (a1), d0
352 rte
353.global test_f_vint_end
354test_f_vint_end:
355
356.global test_f
357test_f:
358 movea.l #0xc00005, a0
359 movea.l #0xc00004, a1
360 move.w #0x2000, sr
3610:
362 btst #3, (a0)
363 bne 0b
3640:
365 btst #3, (a0)
366 beq 0b
367 movem.l d2-d7/a2, -(sp)
368 move.l (a1), d1
369 move.l (a1), d2
370 move.l (a1), d3
371 move.l (a1), d4
372 move.l (a1), d5
373 move.l (a1), d6
374 move.w #0x2700, sr
375 movea.l #0xff0000, a0
376 move.b d0, (a0)+
377 move.b #0, (a0)+
378.macro test_lb_s sr, dr
379 swap \sr
380 move.b \sr, (\dr)+
381 swap \sr
382 move.b \sr, (\dr)+
383.endm
384 test_lb_s d1, a0
385 test_lb_s d2, a0
386 test_lb_s d3, a0
387 test_lb_s d4, a0
388 test_lb_s d5, a0
389 movem.l (sp)+, d2-d7/a2
9d39a80e 390 rts
cc7e5122 391
392.global test_hb
393test_hb:
394 movem.l d2-d7, -(sp)
395 movea.l #0xc00004, a0
396 movea.l #0xc00008, a1
397 moveq.l #1, d0
3980:
399 cmp.b (a1), d0
400 beq 0b
4010:
402 cmp.b (a1), d0
403 bne 0b
404 move.l (a0), d0
405 move.l (a0), d1
406 move.l (a0), d2
407 movea.l #0xff0000, a1
408 movea.l #0xff0000, a1
409 nop
410 nop
411 move.l (a0), d3
412 move.l (a0), d4
413 move.l (a0), d5
414 move.l (a0), d6
415 move.l (a0), d7
416 test_lb_s d0, a1
417 test_lb_s d1, a1
418 test_lb_s d2, a1
419 test_lb_s d3, a1
420 test_lb_s d4, a1
421 test_lb_s d5, a1
422 test_lb_s d6, a1
423 test_lb_s d7, a1
424 movem.l (sp)+, d2-d7
9d39a80e 425 rts
6c839579 426
e71680d5 427.macro ymwrite areg, dreg addr dat
428 move.b \addr, (\areg) /* 12 addr */
429 nbcd d0 /* 6 delay to reach 17 ym cycles (M/7) */
430 move.b \dat, (\dreg) /* 12 data */
431.endm
432
433.global test_ym_stopped_tick
434test_ym_stopped_tick:
435 movem.l a2-a3, -(sp)
436 movea.l #0xa04000, a0
437 movea.l #0xa04001, a1
438 movea.l #0xc00007, a2
439 movea.l #0xfff000, a3
440
441 ymwrite a0, a1, #0x27, #0x30 /* 30 disable, clear */
442 ymwrite a0, a1, #0x26, #0xff /* 30 timer b shortest interval */
443 move.b #0x27, (a0) /* 12 addr prep */
4440:
445 btst #3, (a2)
446 beq 0b /* not blanking */
4470:
448 btst #3, (a2)
449 bne 0b /* blanking */
450
451 addq.l #1, a2
4520:
453 tst.b (a2)
454 bne 0b /* not line 0 - waiting for sequential vcnt */
455
456 move.b #0x0a, (a1) /* 12 start timer b */
457 moveq.l #0, d0
458 moveq.l #2, d1
4590:
460 move.b (a0), d0
461 and.b d1, d0
462 beq 0b
4630:
464# move.w (a2), (a3)+ /* 12 save hvcnt */
465 move.b (a2), d0
466 cmp.b (a2), d0
467 bne 0b
468 move.w d0, (a3)+
469 move.b #0x30, (a1) /* 12 stop b, clear */
470
471 move.w #(1900/10-1), d0 /* waste cycles */
4720:
473 dbra d0, 0b
474 moveq.l #0, d0
475
476 move.w (a0), (a3)+ /* 12 save status */
477 move.b #0x0a, (a1) /* 12 start b */
4780:
479 move.b (a0), d0
480 and.b d1, d0
481 beq 0b
482
4830:
484# move.w (a2), (a3)+ /* 12 save hvcnt */
485 move.b (a2), d1
486 cmp.b (a2), d1
487 bne 0b
488 move.w d1, (a3)+
489 move.w d0, (a3)+ /* 12 save status */
490
491 movem.l (sp)+, a2-a3
492 rts
493
494.global test_ym_ab_sync
495test_ym_ab_sync:
496 movea.l #0xa04000, a0
497 movea.l #0xa04001, a1
498
499 ymwrite a0, a1, #0x27, #0x30 /* 30 disable, clear */
500 ymwrite a0, a1, #0x24, #0xfc /* 30 timer a */
635f2450 501 ymwrite a0, a1, #0x25, #0x01 /* 30 =15 */
e71680d5 502 ymwrite a0, a1, #0x26, #0xff /* 30 timer b shortest interval */
503 move.b #0x27, (a0) /* 12 addr prep */
504 nop
505 nop
506
507 move.b #0x0a, (a1) /* 12 start timer b */
508 moveq.l #0, d0
509 moveq.l #2, d1
5100:
511 move.b (a0), d0 /* 8 */
512 and.b d1, d0 /* 4 */
513 beq 0b /* 10|8 */
635f2450 514
e71680d5 515 move.b #0x3f, (a1) /* 12 start a, clear */
438648dc 516
635f2450 517 move.w #(488/10), d0 /* waste cycles */
5180: dbra d0, 0b
519
520 ymwrite a0, a1, #0x24, #0xf0 /* 30 show that rewriting count */
521 ymwrite a0, a1, #0x25, #0x00 /* 30 does nothing until timer expires */
522
523 move.w #(488*2/10), d0 /* waste cycles */
5240: dbra d0, 0b
525
526 ymwrite a0, a1, #0x26, #0xfc /* 30 same for timer b */
438648dc 527 ymwrite a0, a1, #0x27, #0x0f /* 30 setting already set bits too */
528 moveq.l #0, d0
529 moveq.l #3, d1
e71680d5 5300:
531 move.b (a0), d0
532 and.b d1, d0
533 beq 0b
534 move.b (a0), d0 /* re-read, else very occasionally get 1 */
535 rts
536
635f2450 537.global test_ym_ab_sync2
538test_ym_ab_sync2:
539 movea.l #0xa04000, a0
540 movea.l #0xa04001, a1
541
3d80f940 542 move.b #0x0f, (a1) /* 12 enable */
635f2450 543 moveq.l #0, d0
544 moveq.l #3, d1
545 nop /* 4 need ~12c to clear */
5460:
547 move.b (a0), d0 /* 8 */
548 and.b d1, d0 /* 4 */
549 beq 0b /* 10|8 */
550 move.b (a0), d0 /* re-read */
3d80f940 551 move.b #0x3c, (a1) /* 12 clear, disable */
635f2450 552 rts
553
5073ab5a 554.global x32x_switch_rv
555x32x_switch_rv:
556 ldargw 0, 0, d0
557 move.l (sp)+, d1
558 movea.l #0xa15106, a0
559 btst #0, d0
560 bne 0f
561 move.w #0, (a0)
562 or.l #0x880000, d1
563 bra 1f
5640:
565 move.w #1, (a0)
566 and.l #0x07ffff, d1
5671:
568 movea.l d1, a1
569 jmp (a1)
570.global x32x_switch_rv_end
571x32x_switch_rv_end:
572
ffd4b35c 573# vim:filetype=asmM68k:ts=4:sw=4:expandtab