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