comparison z80_to_x86.c @ 1471:2e6320d261ff

Implemented Z80 IM 2 and attempted correct intack cycle delay
author Michael Pavone <pavone@retrodev.com>
date Thu, 19 Oct 2017 03:21:24 -0700
parents 9327c1dc3791
children 5a6339e46917
comparison
equal deleted inserted replaced
1470:1e3e0205640f 1471:2e6320d261ff
3452 //dispose of return address as we'll be jumping somewhere else 3452 //dispose of return address as we'll be jumping somewhere else
3453 add_ir(code, 16, RSP, SZ_PTR); 3453 add_ir(code, 16, RSP, SZ_PTR);
3454 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); 3454 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B);
3455 is_nmi = code->cur + 1; 3455 is_nmi = code->cur + 1;
3456 jcc(code, CC_NZ, is_nmi); 3456 jcc(code, CC_NZ, is_nmi);
3457 //TODO: Support interrupt mode 0 and 2 3457 cycles(&options->gen, 6); //interupt ack cycle
3458 //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack
3459 //which is conveniently rst $38, i.e. the same thing that im 1 does
3460 //check interrupt mode
3461 cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B);
3462 code_ptr im2 = code->cur + 1;
3463 jcc(code, CC_Z, im2);
3458 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); 3464 mov_ir(code, 0x38, options->gen.scratch1, SZ_W);
3459 code_ptr after_int_dest = code->cur + 1; 3465 code_ptr after_int_dest = code->cur + 1;
3460 jmp(code, after_int_dest); 3466 jmp(code, after_int_dest);
3467 *im2 = code->cur - (im2 + 1);
3468 //read vector address from I << 8 | vector
3469 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B);
3470 shl_ir(code, 8, options->gen.scratch1, SZ_W);
3471 movzx_rdispr(code, options->gen.context_reg, offsetof(z80_context, im2_vector), options->gen.scratch2, SZ_B, SZ_W);
3472 or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W);
3473 push_r(code, options->gen.scratch1);
3474 cycles(&options->gen, 3);
3475 call(code, options->read_8_noinc);
3476 pop_r(code, options->gen.scratch2);
3477 push_r(code, options->gen.scratch1);
3478 mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W);
3479 add_ir(code, 1, options->gen.scratch1, SZ_W);
3480 cycles(&options->gen, 3);
3481 call(code, options->read_8_noinc);
3482 pop_r(code, options->gen.scratch2);
3483 shl_ir(code, 8, options->gen.scratch1, SZ_W);
3484 movzx_rr(code, options->gen.scratch2, options->gen.scratch2, SZ_B, SZ_W);
3485 or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W);
3486 code_ptr after_int_dest2 = code->cur + 1;
3487 jmp(code, after_int_dest2);
3461 *is_nmi = code->cur - (is_nmi + 1); 3488 *is_nmi = code->cur - (is_nmi + 1);
3462 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); 3489 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); 3490 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); 3491 mov_ir(code, 0x66, options->gen.scratch1, SZ_W);
3465 *after_int_dest = code->cur - (after_int_dest + 1); 3492 *after_int_dest = code->cur - (after_int_dest + 1);
3493 *after_int_dest2 = code->cur - (after_int_dest2 + 1);
3466 call(code, options->native_addr); 3494 call(code, options->native_addr);
3467 mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR); 3495 mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR);
3468 tmp_stack_off = code->stack_off; 3496 tmp_stack_off = code->stack_off;
3469 restore_callee_save_regs(code); 3497 restore_callee_save_regs(code);
3470 //return to caller of z80_run to sync 3498 //return to caller of z80_run to sync