comparison z80_to_x86.c @ 735:539d12fa6a4d

Add a define in both the source and Makefile for enabling logging of z80 instruction address/cycle counts. Fix Z80 in/out instructions to eliminate assumptions about which registers are stored in native regs. Fix read_16 to not corrupt the low byte when the read has to call into a C function.
author Michael Pavone <pavone@retrodev.com>
date Mon, 25 May 2015 18:56:22 -0700
parents e21c274a008e
children 043393b79e28
comparison
equal deleted inserted replaced
734:e21c274a008e 735:539d12fa6a4d
340 if (!interp) { 340 if (!interp) {
341 check_cycles_int(&opts->gen, address); 341 check_cycles_int(&opts->gen, address);
342 if (context->breakpoint_flags[address / sizeof(uint8_t)] & (1 << (address % sizeof(uint8_t)))) { 342 if (context->breakpoint_flags[address / sizeof(uint8_t)] & (1 << (address % sizeof(uint8_t)))) {
343 zbreakpoint_patch(context, address, start); 343 zbreakpoint_patch(context, address, start);
344 } 344 }
345 //log_address(&opts->gen, address, "Z80: %X @ %d\n"); 345 #ifdef Z80_LOG_ADDRESS
346 log_address(&opts->gen, address, "Z80: %X @ %d\n");
347 #endif
346 } 348 }
347 switch(inst->op) 349 switch(inst->op)
348 { 350 {
349 case Z80_LD: 351 case Z80_LD:
350 size = z80_size(inst); 352 size = z80_size(inst);
1895 } else { 1897 } else {
1896 mov_rr(code, opts->regs[Z80_C], opts->gen.scratch1, SZ_B); 1898 mov_rr(code, opts->regs[Z80_C], opts->gen.scratch1, SZ_B);
1897 } 1899 }
1898 call(code, opts->read_io); 1900 call(code, opts->read_io);
1899 translate_z80_reg(inst, &dst_op, opts); 1901 translate_z80_reg(inst, &dst_op, opts);
1900 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_B); 1902 if (dst_op.mode == MODE_REG_DIRECT) {
1903 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_B);
1904 } else {
1905 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_B);
1906 }
1901 z80_save_reg(inst, opts); 1907 z80_save_reg(inst, opts);
1902 break; 1908 break;
1903 /*case Z80_INI: 1909 /*case Z80_INI:
1904 case Z80_INIR: 1910 case Z80_INIR:
1905 case Z80_IND: 1911 case Z80_IND:
1907 case Z80_OUT: 1913 case Z80_OUT:
1908 cycles(&opts->gen, inst->reg == Z80_A ? 7 : 8);//T States: 4 3/4 1914 cycles(&opts->gen, inst->reg == Z80_A ? 7 : 8);//T States: 4 3/4
1909 if ((inst->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) { 1915 if ((inst->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) {
1910 mov_ir(code, inst->immed, opts->gen.scratch2, SZ_B); 1916 mov_ir(code, inst->immed, opts->gen.scratch2, SZ_B);
1911 } else { 1917 } else {
1918 zreg_to_native(opts, Z80_C, opts->gen.scratch2);
1912 mov_rr(code, opts->regs[Z80_C], opts->gen.scratch2, SZ_B); 1919 mov_rr(code, opts->regs[Z80_C], opts->gen.scratch2, SZ_B);
1913 } 1920 }
1914 translate_z80_reg(inst, &src_op, opts); 1921 translate_z80_reg(inst, &src_op, opts);
1915 mov_rr(code, dst_op.base, opts->gen.scratch1, SZ_B); 1922 if (src_op.mode == MODE_REG_DIRECT) {
1923 mov_rr(code, src_op.base, opts->gen.scratch1, SZ_B);
1924 } else if (src_op.mode == MODE_IMMED) {
1925 mov_ir(code, src_op.disp, opts->gen.scratch1, SZ_B);
1926 } else {
1927 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_B);
1928 }
1916 call(code, opts->write_io); 1929 call(code, opts->write_io);
1917 z80_save_reg(inst, opts); 1930 z80_save_reg(inst, opts);
1918 break; 1931 break;
1919 /*case Z80_OUTI: 1932 /*case Z80_OUTI:
1920 case Z80_OTIR: 1933 case Z80_OTIR:
2457 //TODO: figure out how to handle the extra wait state for word reads to bank area 2470 //TODO: figure out how to handle the extra wait state for word reads to bank area
2458 //may also need special handling to avoid too much stack depth when access is blocked 2471 //may also need special handling to avoid too much stack depth when access is blocked
2459 push_r(code, options->gen.scratch1); 2472 push_r(code, options->gen.scratch1);
2460 call(code, options->read_8_noinc); 2473 call(code, options->read_8_noinc);
2461 mov_rr(code, options->gen.scratch1, options->gen.scratch2, SZ_B); 2474 mov_rr(code, options->gen.scratch1, options->gen.scratch2, SZ_B);
2475 #ifndef X86_64
2476 //scratch 2 is a caller save register in 32-bit builds and may be clobbered by something called from the read8 fun
2477 mov_rrdisp(code, options->gen.scratch1, options->gen.context_reg, offsetof(z80_context, scratch2), SZ_B);
2478 #endif
2462 pop_r(code, options->gen.scratch1); 2479 pop_r(code, options->gen.scratch1);
2463 add_ir(code, 1, options->gen.scratch1, SZ_W); 2480 add_ir(code, 1, options->gen.scratch1, SZ_W);
2464 cycles(&options->gen, 3); 2481 cycles(&options->gen, 3);
2465 check_cycles(&options->gen); 2482 check_cycles(&options->gen);
2466 call(code, options->read_8_noinc); 2483 call(code, options->read_8_noinc);
2467 shl_ir(code, 8, options->gen.scratch1, SZ_W); 2484 shl_ir(code, 8, options->gen.scratch1, SZ_W);
2485 #ifdef X86_64
2468 mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_B); 2486 mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_B);
2487 #else
2488 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, scratch2), options->gen.scratch1, SZ_B);
2489 #endif
2469 retn(code); 2490 retn(code);
2470 2491
2471 options->write_16_highfirst = code->cur; 2492 options->write_16_highfirst = code->cur;
2472 cycles(&options->gen, 3); 2493 cycles(&options->gen, 3);
2473 check_cycles(&options->gen); 2494 check_cycles(&options->gen);