Mercurial > repos > blastem
diff z80_to_x86.c @ 2053:3414a4423de1 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Jan 2022 13:15:21 -0800 |
parents | 6fdac0108e47 |
children | 3e591869d135 |
line wrap: on
line diff
--- a/z80_to_x86.c Sat Jan 05 00:58:08 2019 -0800 +++ b/z80_to_x86.c Sat Jan 15 13:15:21 2022 -0800 @@ -355,6 +355,8 @@ } if (inst->reg == Z80_I || inst->ea_reg == Z80_I || inst->reg == Z80_R || inst->ea_reg == Z80_R) { num_cycles += 1; + } else if (inst->reg == Z80_USE_IMMED) { + num_cycles += 3; } break; case Z80_IMMED: @@ -874,7 +876,7 @@ } else if(inst->addr_mode == Z80_IMMED) { num_cycles += 3; } else if(z80_size(inst) == SZ_W) { - num_cycles += 4; + num_cycles += 7; } cycles(&opts->gen, num_cycles); translate_z80_reg(inst, &dst_op, opts); @@ -942,7 +944,7 @@ } else if(inst->addr_mode == Z80_IMMED) { num_cycles += 3; } else if(z80_size(inst) == SZ_W) { - num_cycles += 4; + num_cycles += 7; } cycles(&opts->gen, num_cycles); translate_z80_reg(inst, &dst_op, opts); @@ -1073,7 +1075,7 @@ } else if(inst->addr_mode == Z80_IMMED) { num_cycles += 3; } else if(z80_size(inst) == SZ_W) { - num_cycles += 4; + num_cycles += 7; } cycles(&opts->gen, num_cycles); translate_z80_reg(inst, &dst_op, opts); @@ -1261,6 +1263,10 @@ case Z80_DEC: if(z80_size(inst) == SZ_W) { num_cycles += 2; + } else if (inst->addr_mode == Z80_REG_INDIRECT) { + num_cycles += 1; + } else if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { + num_cycles += 9; } cycles(&opts->gen, num_cycles); translate_z80_reg(inst, &dst_op, opts); @@ -1853,7 +1859,7 @@ break; case Z80_BIT: { if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { - num_cycles += 8; + num_cycles += 4; } cycles(&opts->gen, num_cycles); uint8_t bit; @@ -1914,7 +1920,7 @@ } case Z80_SET: { if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { - num_cycles += 8; + num_cycles += 4; } cycles(&opts->gen, num_cycles); uint8_t bit; @@ -1983,7 +1989,7 @@ } case Z80_RES: { if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { - num_cycles += 8; + num_cycles += 4; } cycles(&opts->gen, num_cycles); uint8_t bit; @@ -2321,7 +2327,7 @@ if (inst->addr_mode == Z80_IMMED_INDIRECT) { mov_ir(code, inst->immed, opts->gen.scratch1, SZ_B); } else { - zreg_to_native(opts, Z80_C, opts->gen.scratch2); + zreg_to_native(opts, Z80_C, opts->gen.scratch1); } call(code, opts->read_io); if (inst->addr_mode != Z80_IMMED_INDIRECT) { @@ -2593,7 +2599,7 @@ break; } case Z80_OUT: - if (inst->reg == Z80_A) { + if (inst->addr_mode == Z80_IMMED_INDIRECT) { num_cycles += 3; } cycles(&opts->gen, num_cycles);//T States: 4 3/4 @@ -2658,7 +2664,6 @@ setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); break; case Z80_OTIR: { - code_ptr start = code->cur; cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 //read from (HL) zreg_to_native(opts, Z80_HL, opts->gen.scratch1); @@ -2758,7 +2763,6 @@ setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); break; case Z80_OTDR: { - code_ptr start = code->cur; cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 //read from (HL) zreg_to_native(opts, Z80_HL, opts->gen.scratch1); @@ -3409,6 +3413,9 @@ add_rdispr(code, options->gen.context_reg, offsetof(z80_context, target_cycle), options->gen.cycles, SZ_D); cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, int_cycle), options->gen.cycles, SZ_D); jcc(code, CC_B, skip_int); + //check that we are not past the end of interrupt pulse + cmp_rrdisp(code, options->gen.cycles, options->gen.context_reg, offsetof(z80_context, int_pulse_end), SZ_D); + jcc(code, CC_B, skip_int); //set limit to the cycle limit mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.scratch2, SZ_D); mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, target_cycle), SZ_D); @@ -3420,14 +3427,15 @@ jcc(code, CC_NZ, is_nmi); mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); + cycles(&options->gen, 6); //interupt ack cycle code_ptr after_int_disable = code->cur + 1; jmp(code, after_int_disable); *is_nmi = code->cur - (is_nmi + 1); mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, iff1), options->gen.scratch2, SZ_B); mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); + cycles(&options->gen, 5); //NMI processing cycles *after_int_disable = code->cur - (after_int_disable + 1); - cycles(&options->gen, 7); //save return address (in scratch1) to Z80 stack sub_ir(code, 2, options->regs[Z80_SP], SZ_W); mov_rr(code, options->regs[Z80_SP], options->gen.scratch2, SZ_W); @@ -3453,7 +3461,6 @@ 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); - 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 @@ -3461,6 +3468,7 @@ code_ptr im2 = code->cur + 1; jcc(code, CC_Z, im2); mov_ir(code, 0x38, options->gen.scratch1, SZ_W); + cycles(&options->gen, 1); //total time for mode 0/1 is 13 t-states code_ptr after_int_dest = code->cur + 1; jmp(code, after_int_dest); *im2 = code->cur - (im2 + 1); @@ -3501,10 +3509,12 @@ //HACK options->gen.address_size = SZ_D; options->gen.address_mask = io_address_mask; + options->gen.bus_cycles = 4; options->read_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, READ_8, NULL); options->write_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, WRITE_8, NULL); options->gen.address_size = SZ_W; options->gen.address_mask = 0xFFFF; + options->gen.bus_cycles = 3; options->read_16 = code->cur; cycles(&options->gen, 3); @@ -3594,7 +3604,7 @@ tmp_stack_off = code->stack_off; save_callee_save_regs(code); #ifdef X86_64 - mov_rr(code, RDI, options->gen.context_reg, SZ_PTR); + mov_rr(code, FIRST_ARG_REG, options->gen.context_reg, SZ_PTR); #else mov_rdispr(code, RSP, 5 * sizeof(int32_t), options->gen.context_reg, SZ_PTR); #endif