Mercurial > repos > blastem
diff z80_to_x86.c @ 1692:5dacaef602a7 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 05 Jan 2019 00:58:08 -0800 |
parents | 31effaadf877 |
children | 873a1330c3a9 |
line wrap: on
line diff
--- a/z80_to_x86.c Tue Dec 19 00:49:13 2017 -0800 +++ b/z80_to_x86.c Sat Jan 05 00:58:08 2019 -0800 @@ -2075,7 +2075,7 @@ break; } case Z80_JPCC: { - cycles(&opts->gen, num_cycles + 3);//T States: 4,3 + cycles(&opts->gen, num_cycles + 6);//T States: 4,3,3 uint8_t cond = CC_Z; switch (inst->reg) { @@ -2102,7 +2102,6 @@ } uint8_t *no_jump_off = code->cur+1; jcc(code, cond, code->cur+2); - cycles(&opts->gen, 5);//T States: 5 uint16_t dest_addr = inst->immed; code_ptr call_dst = z80_get_native_address(context, dest_addr); if (!call_dst) { @@ -3454,15 +3453,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; @@ -3644,7 +3671,19 @@ void z80_options_free(z80_options *opts) { + for (uint32_t address = 0; address < opts->gen.address_mask; address += NATIVE_CHUNK_SIZE) + { + uint32_t chunk = address / NATIVE_CHUNK_SIZE; + if (opts->gen.native_code_map[chunk].base) { + free(opts->gen.native_code_map[chunk].offsets); + } + } free(opts->gen.native_code_map); + uint32_t ram_inst_slots = ram_size(&opts->gen) / 1024; + for (uint32_t i = 0; i < ram_inst_slots; i++) + { + free(opts->gen.ram_inst_sizes[i]); + } free(opts->gen.ram_inst_sizes); free(opts); }