move.l (4 + \arg * 4 + \stacksz)(%sp), \reg
.endm
+.macro ldargw arg, stacksz, reg
+ move.w (4 + \arg * 4 + 2 + \stacksz)(%sp), \reg
+.endm
+
.global burn10 /* u16 val */
burn10:
ldarg 0, 0, d0
.endif
rts
+.global write_and_read1 /* u32 a, u16 d, void *dst */
+write_and_read1:
+ ldarg 0, 0, a0
+ ldargw 1, 0, d0
+ ldarg 2, 0, a1
+ move.w d0, (a0)
+ move.l (a0), d0
+ move.l (a0), d1
+ move.l d0, (a1)+
+ move.l d1, (a1)+
+ rts
+
+.global move_sr /* u16 sr */
+move_sr:
+ ldargw 0, 0, d0
+ move.w d0, sr
+ rts
+
+.global move_sr_and_read /* u16 sr, u32 a */
+move_sr_and_read:
+ ldargw 0, 0, d0
+ ldarg 1, 0, a0
+ move.w d0, sr
+ move.w (a0), d0
+ rts
+
+.global memcpy_ /* void *dst, const void *src, u16 size */
+memcpy_:
+ ldarg 0, 0, a0
+ ldarg 1, 0, a1
+ ldargw 2, 0, d0
+ subq.w #1, d0
+0:
+ move.b (a1)+, (a0)+ /* not in a hurry */
+ dbra d0, 0b
+ rts
+
+.global memset_ /* void *dst, int d, u16 size */
+memset_:
+ ldarg 0, 0, a0
+ ldargw 1, 0, d1
+ ldargw 2, 0, d0
+ subq.w #1, d0
+0:
+ move.b d1, (a0)+ /* not in a hurry */
+ dbra d0, 0b
+ rts
+
+# tests
+
.global do_vcnt_vb
do_vcnt_vb:
movem.l d2-d7/a2, -(sp)
movem.l (sp)+, d2-d7/a2
rts
+.global test_hint
+test_hint:
+ move.w d0, -(sp) /* 8 */
+ move.w (0xc00008).l, d0 /* 16 */
+ addq.w #1, (0xf000).w /* 16 */
+ tst.w (0xf002).w /* 12 */
+ bne 0f /* 10 */
+ move.w d0, (0xf002).w /* 12 */
+0:
+ move.w d0, (0xf004).w /* 12 */
+ move.w (sp)+, d0 /* 8 */
+ rte /* 20 114 */
+.global test_hint_end
+test_hint_end:
+
+.global test_vint
+test_vint:
+ move.w d0, -(sp) /* 8 */
+ move.w (0xc00008).l, d0 /* 16 */
+ addq.w #1, (0xf008).w /* 16 */
+ tst.w (0xf00a).w /* 12 */
+ bne 0f /* 10 */
+ move.w d0, (0xf00a).w /* 12 */
+0:
+ move.w d0, (0xf00c).w /* 12 */
+ move.w (sp)+, d0 /* 8 */
+ rte /* 20 114 */
+.global test_vint_end
+test_vint_end:
+
+
# vim:filetype=asmM68k:ts=4:sw=4:expandtab
return ok;
}
+static int t_irq_hint(void)
+{
+ u16 *ram = (u16 *)0xfff000;
+ u8 *ram8 = (u8 *)0xfff000;
+ u16 v_p, cnt_p;
+ int ok = 1;
+
+ // for more fun, disable the display
+ VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
+
+ ram[0] = ram[1] = ram[2] = 0;
+ memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
+ VDP_setReg(10, 0);
+ while (read8(VDP_HV_COUNTER) != 100)
+ ;
+ while (read8(VDP_HV_COUNTER) != 229)
+ ;
+ // take the pending irq
+ VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
+ move_sr(0x2000);
+ burn10(488 * 2 / 10);
+ move_sr(0x2700);
+ v_p = ram8[2];
+ cnt_p = ram[0];
+ ram[0] = ram[1] = ram[2] = 0;
+ // count irqs
+ move_sr(0x2000);
+ while (read8(VDP_HV_COUNTER) != 3)
+ ;
+ while (read8(VDP_HV_COUNTER) != 228)
+ ;
+ move_sr(0x2700);
+ VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
+ VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
+
+ expect(ok, v_p, 229); // pending irq trigger
+ expect(ok, cnt_p, 1);
+ expect(ok, ram[0], 225); // count
+ expect(ok, ram8[2], 0); // first line
+ expect(ok, ram8[4], 224); // last line
+ return ok;
+}
+
+static int t_irq_ack_v_h(void)
+{
+ u16 *ram = (u16 *)0xfff000;
+ u8 *ram8 = (u8 *)0xfff000;
+ u16 s0, s1, s2;
+ int ok = 1;
+
+ ram[0] = ram[1] = ram[2] =
+ ram[4] = ram[5] = ram[6] = 0;
+ memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
+ memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
+ VDP_setReg(10, 0);
+ VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
+ VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0);
+ while (read8(VDP_HV_COUNTER) != 100)
+ ;
+ while (read8(VDP_HV_COUNTER) != 226)
+ ;
+ s0 = read16(VDP_CTRL_PORT);
+ s1 = move_sr_and_read(0x2500, VDP_CTRL_PORT);
+ burn10(666 / 10);
+ s2 = move_sr_and_read(0x2000, VDP_CTRL_PORT);
+ burn10(488 / 10);
+ move_sr(0x2700);
+ VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
+ VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
+
+ expect(ok, ram[4], 1); // vint count
+ expect(ok, ram8[10], 226); // vint line
+ expect(ok, ram[0], 1); // hint count
+ expect(ok, ram8[2], 228); // hint line
+ expect_bits(ok, s0, SR_F, SR_F);
+ expect_bits(ok, s1, 0, SR_F);
+ expect_bits(ok, s2, 0, SR_F);
+ return ok;
+}
+
+static int t_irq_ack_h_v(void)
+{
+ u16 *ram = (u16 *)0xfff000;
+ u8 *ram8 = (u8 *)0xfff000;
+ u16 s0, s1, s[4];
+ int ok = 1;
+
+ ram[0] = ram[1] = ram[2] =
+ ram[4] = ram[5] = ram[6] = 0;
+ memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
+ memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
+ VDP_setReg(10, 0);
+ while (read8(VDP_HV_COUNTER) != 100)
+ ;
+ while (read8(VDP_HV_COUNTER) != 226)
+ ;
+ s0 = read16(VDP_CTRL_PORT);
+ VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
+ move_sr(0x2000);
+ burn10(666 / 10);
+ s1 = read16(VDP_CTRL_PORT);
+ write_and_read1(VDP_CTRL_PORT, 0x8000 | (VDP_MODE2 << 8)
+ | VDP_MODE2_MD | VDP_MODE2_IE0, s);
+ burn10(488 / 10);
+ move_sr(0x2700);
+ VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
+ VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
+
+ expect(ok, ram[0], 1); // hint count
+ expect(ok, ram8[2], 226); // hint line
+ expect(ok, ram[4], 1); // vint count
+ expect(ok, ram8[10], 228); // vint line
+ expect_bits(ok, s0, SR_F, SR_F);
+ expect_bits(ok, s1, SR_F, SR_F);
+ expect_bits(ok, s[0], SR_F, SR_F);
+ expect_bits(ok, s[1], SR_F, SR_F);
+ expect_bits(ok, s[2], 0, SR_F);
+ expect_bits(ok, s[3], 0, SR_F);
+ return ok;
+}
+
static const struct {
int (*test)(void);
const char *name;
{ t_tim_vcnt, "time V counter" },
{ t_tim_vdp_as_vram_w, "time vdp vram w" },
{ t_tim_vdp_as_cram_w, "time vdp cram w" },
+ { t_irq_hint, "irq4 / line" },
+ { t_irq_ack_v_h, "irq ack v-h" },
+ { t_irq_ack_h_v, "irq ack h-v" },
};
static void setup_z80(void)
dc.l 0, 0x200, exc02, exc03, exc04, exc05, exc06, exc07\r
dc.l exc08, exc09, exc0a, exc0b, exc0c, exc0d, exc0e, exc0f\r
dc.l exc10, exc11, exc12, exc13, exc14, exc15, exc16, exc17\r
- dc.l exc18, exc19, exc1a, exc1b, HBL, exc1d, VBL, exc1f\r
+ dc.l exc18, exc19, exc1a, exc1b, 0xff0100, exc1d, 0xff0140, exc1f\r
dc.l exc20, exc21, exc22, exc23, exc24, exc25, exc26, exc27\r
dc.l exc28, exc29, exc2a, exc2b, exc2c, exc2d, exc2e, exc2f\r
dc.l exc30, exc31, exc32, exc33, exc34, exc35, exc3e, exc37\r