+static const u8 hcnt2tm[] =
+{
+ 0x0a, 0x1d, 0x31, 0x44, 0x58, 0x6b, 0x7f, 0x92,
+ 0xa6, 0xb9, 0xcc, 0x00, 0x00, 0x00, 0xe2, 0xf6
+};
+
+static int t_tim_ym_timer_z80(int is_b)
+{
+ u8 pal = read8(0xa10001) & 0x40;
+ u8 *zram = (u8 *)0xa00000;
+ u8 *z80 = zram;
+ u16 _68k_loops = 3420*(302+5+1)/7/10; // ~ (72*1024*2)/(3420./7)
+ u16 start, end, diff;
+ int ok = 1;
+
+ zram[0x1000] = 4 + is_b; // ym2612 timer a/b test
+ zram[0x1100] = zram[0x1101] = zram[0x1102] = zram[0x1103] = 0;
+ mem_barrier();
+
+ vdp_wait_for_line_0();
+ write16(0xa11100, 0x000);
+
+ burn10(_68k_loops + (Z80_C_DISPATCH + Z80_C_END_VCNT) * 15 / 7 / 10);
+
+ write16(0xa11100, 0x100);
+ while (read16(0xa11100) & 0x100)
+ ;
+ mem_barrier();
+ expect(ok, zram[0x1000], 0);
+ (void)hcnt2tm;
+ //start = ((u16)zram[0x1102] << 8) | hcnt2tm[zram[0x1103] >> 4];
+ //end = ((u16)zram[0x1100] << 8) | hcnt2tm[zram[0x1101] >> 4];
+ start = zram[0x1102];
+ end = zram[0x1100];
+ diff = end - start;
+ if (pal)
+ expect_range(ok, diff, 0xf4, 0xf6);
+ else
+ expect_range(ok, diff, 0x27, 0x29);
+ write8(&z80[0x4001], 0); // stop, but should keep the flag
+ mem_barrier();
+ burn10(32*6/10); // busy bit, 32 FM ticks (M/7/6)
+ if (is_b) {
+ expect(ok, z80[0x4000], 2);
+ write8(&z80[0x4001], 0x20); // reset flag (reg 0x27, set up by z80)
+ }
+ else {
+ expect(ok, z80[0x4000], 1);
+ write8(&z80[0x4001], 0x10);
+ }
+ mem_barrier();
+ burn10(32*6/10);
+ expect(ok, z80[0x4000], 0);
+ return ok;
+}
+
+static int t_tim_ym_timera_z80(void)
+{
+ return t_tim_ym_timer_z80(0);
+}
+
+static int t_tim_ym_timerb_z80(void)
+{
+ return t_tim_ym_timer_z80(1);
+}
+
+static int t_tim_ym_timerb_stop(void)
+{
+ const struct {
+ //u8 vcnt_start;
+ //u8 hcnt_start;
+ u16 vcnt_start;
+ u16 stat0;
+ //u8 vcnt_end;
+ //u8 hcnt_end;
+ u16 vcnt_end;
+ u16 stat1;
+ } *t = (void *)0xfff000;
+ u8 *z80 = (u8 *)0xa00000;
+ u16 diff;
+ int ok = 1;
+ write16(0xa11100, 0x100);
+ while (read16(0xa11100) & 0x100)
+ ;
+ test_ym_stopped_tick();
+ mem_barrier();
+ //start = ((u16)t->vcnt_start << 8) | hcnt2tm[t->hcnt_start >> 4];
+ //end = ((u16)t->vcnt_end << 8) | hcnt2tm[t->hcnt_end >> 4];
+ //diff = end - start;
+ diff = t->vcnt_end - t->vcnt_start;
+ //expect_range(ok, diff, 0x492, 0x5c2); // why so much variation?
+ expect_range(ok, diff, 4, 5);
+ expect(ok, t->stat0, 0);
+ expect(ok, t->stat1, 2);
+ expect(ok, z80[0x4000], 2);
+ write8(&z80[0x4001], 0x30);
+ return ok;
+}
+
+static int t_tim_ym_timer_ab_sync(void)
+{
+ u16 v = test_ym_ab_sync();
+ int ok = 1;
+ expect(ok, v, 3);
+ return ok;
+}
+