# HG changeset patch # User Michael Pavone # Date 1508408484 25200 # Node ID 2e6320d261ffad163640d9f0b46124eb074cf99f # Parent 1e3e0205640f92017e6b5ee9d333b7930b04de00 Implemented Z80 IM 2 and attempted correct intack cycle delay diff -r 1e3e0205640f -r 2e6320d261ff genesis.c --- a/genesis.c Sat Oct 14 05:03:38 2017 -0700 +++ b/genesis.c Thu Oct 19 03:21:24 2017 -0700 @@ -242,6 +242,7 @@ genesis_context * gen = z_context->system; z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp); z_context->int_pulse_end = z_context->int_pulse_start + Z80_INT_PULSE_MCLKS; + z_context->im2_vector = 0xFF; } static void sync_z80(z80_context * z_context, uint32_t mclks) diff -r 1e3e0205640f -r 2e6320d261ff z80_to_x86.c --- a/z80_to_x86.c Sat Oct 14 05:03:38 2017 -0700 +++ b/z80_to_x86.c Thu Oct 19 03:21:24 2017 -0700 @@ -3454,15 +3454,43 @@ cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); is_nmi = code->cur + 1; jcc(code, CC_NZ, is_nmi); - //TODO: Support interrupt mode 0 and 2 + cycles(&options->gen, 6); //interupt ack cycle + //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack + //which is conveniently rst $38, i.e. the same thing that im 1 does + //check interrupt mode + cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B); + code_ptr im2 = code->cur + 1; + jcc(code, CC_Z, im2); mov_ir(code, 0x38, options->gen.scratch1, SZ_W); code_ptr after_int_dest = code->cur + 1; jmp(code, after_int_dest); + *im2 = code->cur - (im2 + 1); + //read vector address from I << 8 | vector + mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B); + shl_ir(code, 8, options->gen.scratch1, SZ_W); + movzx_rdispr(code, options->gen.context_reg, offsetof(z80_context, im2_vector), options->gen.scratch2, SZ_B, SZ_W); + or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W); + push_r(code, options->gen.scratch1); + cycles(&options->gen, 3); + call(code, options->read_8_noinc); + pop_r(code, options->gen.scratch2); + push_r(code, options->gen.scratch1); + mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W); + add_ir(code, 1, options->gen.scratch1, SZ_W); + cycles(&options->gen, 3); + call(code, options->read_8_noinc); + pop_r(code, options->gen.scratch2); + shl_ir(code, 8, options->gen.scratch1, SZ_W); + movzx_rr(code, options->gen.scratch2, options->gen.scratch2, SZ_B, SZ_W); + or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W); + code_ptr after_int_dest2 = code->cur + 1; + jmp(code, after_int_dest2); *is_nmi = code->cur - (is_nmi + 1); mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); mov_irdisp(code, CYCLE_NEVER, options->gen.context_reg, offsetof(z80_context, nmi_start), SZ_D); mov_ir(code, 0x66, options->gen.scratch1, SZ_W); *after_int_dest = code->cur - (after_int_dest + 1); + *after_int_dest2 = code->cur - (after_int_dest2 + 1); call(code, options->native_addr); mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR); tmp_stack_off = code->stack_off; diff -r 1e3e0205640f -r 2e6320d261ff z80_to_x86.h --- a/z80_to_x86.h Sat Oct 14 05:03:38 2017 -0700 +++ b/z80_to_x86.h Thu Oct 19 03:21:24 2017 -0700 @@ -87,6 +87,7 @@ uint8_t busreq; uint8_t busack; uint8_t int_is_nmi; + uint8_t im2_vector; uint8_t ram_code_flags[]; };