2 # --register-prefix-optional --bitwise-or
3 # reminder: d2-d7/a2-a6 are callee-save
5 .macro ldarg arg, stacksz, reg
6 move.l (4 + \arg * 4 + \stacksz)(%sp), \reg
9 # args are always 4 bytes in stack, caller restores sp
10 .macro ldargw arg, stacksz, reg
11 move.w (4 + \arg * 4 + 2 + \stacksz)(%sp), \reg
14 .global burn10 /* u16 val */
19 dbra d0, 0b /* 10|14 */
22 .global write16_x16 /* u32 a, u16 count, u16 d */
43 # read single phase from controller
50 move.b #0x40,(0xa10003)
55 move.b #0x00,(0xa10003)
56 andi.w #0x3f,d1 /* 00CB RLDU */
60 andi.w #0xc0,d0 /* SA00 0000 */
66 eor.w d0,d1 /* changed btns */
67 move.w d0,d7 /* old val */
69 and.w d0,d1 /* what changed now */
80 move.b (a0), d0 /* 8 d2 = vcnt */
81 cmp.b (a0), d0 /* 8 reread for super-rare corruption (torn read) */
85 .global write_and_read1 /* u32 a, u16 d, void *dst */
92 /* different timing due to extra fetch of offset, */
93 /* less troulesome to emulate */
106 .global move_sr /* u16 sr */
112 .global move_sr_and_read /* u16 sr, u32 a */
125 .global memcpy_ /* void *dst, const void *src, u16 size */
132 move.b (a1)+, (a0)+ /* not in a hurry */
136 .global memset_ /* void *dst, int d, u16 size */
143 move.b d1, (a0)+ /* not in a hurry */
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 */
158 move.l #1<<(3+16), d7 /* d7 = SR_VB */
161 beq 0b /* not blanking */
164 bne 0b /* blanking */
169 bne 0b /* not line 0 */
173 move.l d6, (a2)+ /* d0 = old */
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? */
181 move.l (a0), d0 /* 12 */
185 addq.l #1, d4 /* count++ */
188 bne 2f /* vcnt == vcnt_expect + 1 */
191 and.l d7, d1 /* (old ^ val) & vb */
193 move.l d0, d6 /* old = val */
196 2: /* 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 */
206 bne 1b /* still in VB */
208 move.l d0, (a2)+ /* *ram++ = val */
209 move.l d4, (a2)+ /* *ram++ = count */
211 movem.l (sp)+, d2-d7/a2
214 .global test_vcnt_loops
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 */
224 beq 0b /* not blanking */
227 bne 0b /* blanking */
231 addq.w #1, d1 /* 4 */
232 cmp.b (a0), d0 /* 8 vcnt changed? */
235 move.w d0, (a1)+ /* 8 save */
237 move.b (a0), d0 /* 8 new vcnt */
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 */
251 move.w d0, (0xf002).w /* 12 */
253 move.w d0, (0xf004).w /* 12 */
254 move.w (sp)+, d0 /* 8 */
256 .global test_hint_end
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 */
266 move.w d0, (0xf00a).w /* 12 */
268 move.w d0, (0xf00c).w /* 12 */
269 move.w (sp)+, d0 /* 8 */
271 .global test_vint_end
276 movea.l #0xa15100, a0
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
285 move.w #3, (a0) /* ADEN, nRES */
287 move.w #0xffff, d0 /* waste some cycles */
289 beq 0b /* master BIOS busy */
291 0: /* 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 */
295 or.w #1, 6(a0) /* RV */
297 .global x32x_enable_end
302 movea.l #0xa15100, a0
303 move.w #1, (a0) /* ADEN (reset sh2) */
304 move.w #0, (a0) /* adapter disable, reset sh2 */
308 move.w #2, (a0) /* nRES - sh2s should see no ADEN and sleep */
310 .global x32x_disable_end
313 .global test_32x_b_c0
317 jsr (0xc0).l /* move.b d0, (a1); RV=0 */
318 bset #0, (0xa15107).l /* RV=1 */
320 .global test_32x_b_c0_end
323 # some nastyness from Fatal Rewind
327 move.w #0x8014, (0xFFC00004).l
328 move.w #0x8164, (0xFFC00004).l
338 movea.l #0xc00004, a0
341 move.w #480/2/10-1, d0
344 move.w #0x8164, (0xFFC00004).l
345 move.w #0x8014, (0xFFC00004).l
353 .global test_f_vint_end
358 movea.l #0xc00005, a0
359 movea.l #0xc00004, a1
367 movem.l d2-d7/a2, -(sp)
375 movea.l #0xff0000, a0
378 .macro test_lb_s sr, dr
389 movem.l (sp)+, d2-d7/a2
395 movea.l #0xc00004, a0
396 movea.l #0xc00008, a1
407 movea.l #0xff0000, a1
408 movea.l #0xff0000, a1
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 */
433 .global test_ym_stopped_tick
434 test_ym_stopped_tick:
436 movea.l #0xa04000, a0
437 movea.l #0xa04001, a1
438 movea.l #0xc00007, a2
439 movea.l #0xfff000, a3
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 */
446 beq 0b /* not blanking */
449 bne 0b /* blanking */
454 bne 0b /* not line 0 - waiting for sequential vcnt */
456 move.b #0x0a, (a1) /* 12 start timer b */
464 # move.w (a2), (a3)+ /* 12 save hvcnt */
469 move.b #0x30, (a1) /* 12 stop b, clear */
471 move.w #(1900/10-1), d0 /* waste cycles */
476 move.w (a0), (a3)+ /* 12 save status */
477 move.b #0x0a, (a1) /* 12 start b */
484 # move.w (a2), (a3)+ /* 12 save hvcnt */
489 move.w d0, (a3)+ /* 12 save status */
494 .global test_ym_ab_sync
496 movea.l #0xa04000, a0
497 movea.l #0xa04001, a1
499 ymwrite a0, a1, #0x27, #0x30 /* 30 disable, clear */
500 ymwrite a0, a1, #0x24, #0xfc /* 30 timer a */
501 ymwrite a0, a1, #0x25, #0x01 /* 30 =15 */
502 ymwrite a0, a1, #0x26, #0xff /* 30 timer b shortest interval */
503 move.b #0x27, (a0) /* 12 addr prep */
507 move.b #0x0a, (a1) /* 12 start timer b */
511 move.b (a0), d0 /* 8 */
515 move.b #0x3f, (a1) /* 12 start a, clear */
517 move.w #(488/10), d0 /* waste cycles */
520 ymwrite a0, a1, #0x24, #0xf0 /* 30 show that rewriting count */
521 ymwrite a0, a1, #0x25, #0x00 /* 30 does nothing until timer expires */
523 move.w #(488*2/10), d0 /* waste cycles */
526 ymwrite a0, a1, #0x26, #0xfc /* 30 same for timer b */
527 ymwrite a0, a1, #0x27, #0x0f /* 30 setting already set bits too */
534 move.b (a0), d0 /* re-read, else very occasionally get 1 */
537 .global test_ym_ab_sync2
539 movea.l #0xa04000, a0
540 movea.l #0xa04001, a1
542 move.b #0x0f, (a1) /* 12 enable */
545 nop /* 4 need ~12c to clear */
547 move.b (a0), d0 /* 8 */
550 move.b (a0), d0 /* re-read */
551 move.b #0x3c, (a1) /* 12 clear, disable */
554 .global x32x_switch_rv
558 movea.l #0xa15106, a0
570 .global x32x_switch_rv_end
573 # vim:filetype=asmM68k:ts=4:sw=4:expandtab