Mercurial > repos > blastem
comparison 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 |
comparison
equal
deleted
inserted
replaced
1504:95b3a1a8b26c | 1692:5dacaef602a7 |
---|---|
2073 jmp_r(code, opts->gen.scratch1); | 2073 jmp_r(code, opts->gen.scratch1); |
2074 } | 2074 } |
2075 break; | 2075 break; |
2076 } | 2076 } |
2077 case Z80_JPCC: { | 2077 case Z80_JPCC: { |
2078 cycles(&opts->gen, num_cycles + 3);//T States: 4,3 | 2078 cycles(&opts->gen, num_cycles + 6);//T States: 4,3,3 |
2079 uint8_t cond = CC_Z; | 2079 uint8_t cond = CC_Z; |
2080 switch (inst->reg) | 2080 switch (inst->reg) |
2081 { | 2081 { |
2082 case Z80_CC_NZ: | 2082 case Z80_CC_NZ: |
2083 cond = CC_NZ; | 2083 cond = CC_NZ; |
2100 cmp_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_S), SZ_B); | 2100 cmp_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_S), SZ_B); |
2101 break; | 2101 break; |
2102 } | 2102 } |
2103 uint8_t *no_jump_off = code->cur+1; | 2103 uint8_t *no_jump_off = code->cur+1; |
2104 jcc(code, cond, code->cur+2); | 2104 jcc(code, cond, code->cur+2); |
2105 cycles(&opts->gen, 5);//T States: 5 | |
2106 uint16_t dest_addr = inst->immed; | 2105 uint16_t dest_addr = inst->immed; |
2107 code_ptr call_dst = z80_get_native_address(context, dest_addr); | 2106 code_ptr call_dst = z80_get_native_address(context, dest_addr); |
2108 if (!call_dst) { | 2107 if (!call_dst) { |
2109 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); | 2108 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); |
2110 //fake address to force large displacement | 2109 //fake address to force large displacement |
3452 //dispose of return address as we'll be jumping somewhere else | 3451 //dispose of return address as we'll be jumping somewhere else |
3453 add_ir(code, 16, RSP, SZ_PTR); | 3452 add_ir(code, 16, RSP, SZ_PTR); |
3454 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); | 3453 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); |
3455 is_nmi = code->cur + 1; | 3454 is_nmi = code->cur + 1; |
3456 jcc(code, CC_NZ, is_nmi); | 3455 jcc(code, CC_NZ, is_nmi); |
3457 //TODO: Support interrupt mode 0 and 2 | 3456 cycles(&options->gen, 6); //interupt ack cycle |
3457 //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack | |
3458 //which is conveniently rst $38, i.e. the same thing that im 1 does | |
3459 //check interrupt mode | |
3460 cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B); | |
3461 code_ptr im2 = code->cur + 1; | |
3462 jcc(code, CC_Z, im2); | |
3458 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); | 3463 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); |
3459 code_ptr after_int_dest = code->cur + 1; | 3464 code_ptr after_int_dest = code->cur + 1; |
3460 jmp(code, after_int_dest); | 3465 jmp(code, after_int_dest); |
3466 *im2 = code->cur - (im2 + 1); | |
3467 //read vector address from I << 8 | vector | |
3468 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B); | |
3469 shl_ir(code, 8, options->gen.scratch1, SZ_W); | |
3470 movzx_rdispr(code, options->gen.context_reg, offsetof(z80_context, im2_vector), options->gen.scratch2, SZ_B, SZ_W); | |
3471 or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W); | |
3472 push_r(code, options->gen.scratch1); | |
3473 cycles(&options->gen, 3); | |
3474 call(code, options->read_8_noinc); | |
3475 pop_r(code, options->gen.scratch2); | |
3476 push_r(code, options->gen.scratch1); | |
3477 mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W); | |
3478 add_ir(code, 1, options->gen.scratch1, SZ_W); | |
3479 cycles(&options->gen, 3); | |
3480 call(code, options->read_8_noinc); | |
3481 pop_r(code, options->gen.scratch2); | |
3482 shl_ir(code, 8, options->gen.scratch1, SZ_W); | |
3483 movzx_rr(code, options->gen.scratch2, options->gen.scratch2, SZ_B, SZ_W); | |
3484 or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W); | |
3485 code_ptr after_int_dest2 = code->cur + 1; | |
3486 jmp(code, after_int_dest2); | |
3461 *is_nmi = code->cur - (is_nmi + 1); | 3487 *is_nmi = code->cur - (is_nmi + 1); |
3462 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); | 3488 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); |
3463 mov_irdisp(code, CYCLE_NEVER, options->gen.context_reg, offsetof(z80_context, nmi_start), SZ_D); | 3489 mov_irdisp(code, CYCLE_NEVER, options->gen.context_reg, offsetof(z80_context, nmi_start), SZ_D); |
3464 mov_ir(code, 0x66, options->gen.scratch1, SZ_W); | 3490 mov_ir(code, 0x66, options->gen.scratch1, SZ_W); |
3465 *after_int_dest = code->cur - (after_int_dest + 1); | 3491 *after_int_dest = code->cur - (after_int_dest + 1); |
3492 *after_int_dest2 = code->cur - (after_int_dest2 + 1); | |
3466 call(code, options->native_addr); | 3493 call(code, options->native_addr); |
3467 mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR); | 3494 mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR); |
3468 tmp_stack_off = code->stack_off; | 3495 tmp_stack_off = code->stack_off; |
3469 restore_callee_save_regs(code); | 3496 restore_callee_save_regs(code); |
3470 //return to caller of z80_run to sync | 3497 //return to caller of z80_run to sync |
3642 } | 3669 } |
3643 } | 3670 } |
3644 | 3671 |
3645 void z80_options_free(z80_options *opts) | 3672 void z80_options_free(z80_options *opts) |
3646 { | 3673 { |
3674 for (uint32_t address = 0; address < opts->gen.address_mask; address += NATIVE_CHUNK_SIZE) | |
3675 { | |
3676 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | |
3677 if (opts->gen.native_code_map[chunk].base) { | |
3678 free(opts->gen.native_code_map[chunk].offsets); | |
3679 } | |
3680 } | |
3647 free(opts->gen.native_code_map); | 3681 free(opts->gen.native_code_map); |
3682 uint32_t ram_inst_slots = ram_size(&opts->gen) / 1024; | |
3683 for (uint32_t i = 0; i < ram_inst_slots; i++) | |
3684 { | |
3685 free(opts->gen.ram_inst_sizes[i]); | |
3686 } | |
3648 free(opts->gen.ram_inst_sizes); | 3687 free(opts->gen.ram_inst_sizes); |
3649 free(opts); | 3688 free(opts); |
3650 } | 3689 } |
3651 | 3690 |
3652 void z80_assert_reset(z80_context * context, uint32_t cycle) | 3691 void z80_assert_reset(z80_context * context, uint32_t cycle) |