# HG changeset patch # User Michael Pavone # Date 1419626081 28800 # Node ID 086de86929327ecbfca5491528b531b3021f18f2 # Parent 5ef3fe516da9242dd7019539cbc8fee3eb94f243 Add in missing generated Z80 helper functions. Fix a small bug in Z80_HALT. Fix generation of save and load context for Z80 diff -r 5ef3fe516da9 -r 086de8692932 gen_x86.h --- a/gen_x86.h Mon Dec 22 20:55:10 2014 -0800 +++ b/gen_x86.h Fri Dec 26 12:34:41 2014 -0800 @@ -38,6 +38,7 @@ CC_C, CC_B = CC_C, CC_NC, + CC_NB = CC_NC, CC_Z, CC_NZ, CC_BE, diff -r 5ef3fe516da9 -r 086de8692932 z80_to_x86.c --- a/z80_to_x86.c Mon Dec 22 20:55:10 2014 -0800 +++ b/z80_to_x86.c Fri Dec 26 12:34:41 2014 -0800 @@ -870,7 +870,7 @@ add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D); cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); code_ptr skip_last = code->cur+1; - jcc(code, CC_B, opts->gen.handle_cycle_limit_int); + jcc(code, CC_NB, code->cur+2); cycles(&opts->gen, 4); *skip_last = code->cur - (skip_last+1); call(code, opts->gen.handle_cycle_limit_int); @@ -1953,10 +1953,8 @@ int reg; uint8_t size; if (i < Z80_I) { - reg = i /2 + Z80_BC; + reg = i /2 + Z80_BC + (i > Z80_H ? 2 : 0); size = SZ_W; - i++; - } else { reg = i; size = SZ_B; @@ -1964,6 +1962,9 @@ if (options->regs[reg] >= 0) { mov_rrdisp(code, options->regs[reg], options->gen.context_reg, offsetof(z80_context, regs) + i, size); } + if (size == SZ_W) { + i++; + } } if (options->regs[Z80_SP] >= 0) { mov_rrdisp(code, options->regs[Z80_SP], options->gen.context_reg, offsetof(z80_context, sp), SZ_W); @@ -1983,9 +1984,8 @@ int reg; uint8_t size; if (i < Z80_I) { - int reg = i /2 + Z80_BC; + reg = i /2 + Z80_BC + (i > Z80_H ? 2 : 0); size = SZ_W; - } else { reg = i; size = SZ_B; @@ -1993,6 +1993,9 @@ if (options->regs[reg] >= 0) { mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + i, options->regs[reg], size); } + if (size == SZ_W) { + i++; + } } if (options->regs[Z80_SP] >= 0) { mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sp), options->regs[Z80_SP], SZ_W); @@ -2035,8 +2038,10 @@ *no_sync = code->cur - no_sync; //return to caller of z80_run retn(code); + + options->gen.handle_code_write = (code_ptr)z80_handle_code_write; - options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, NULL); + options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, &options->read_8_noinc); options->write_8 = gen_mem_fun(&options->gen, chunks, num_chunks, WRITE_8, &options->write_8_noinc); options->gen.handle_cycle_limit_int = code->cur; @@ -2105,6 +2110,55 @@ check_cycles(&options->gen); cycles(&options->gen, 4); retn(code); + + options->read_16 = code->cur; + cycles(&options->gen, 3); + check_cycles(&options->gen); + //TODO: figure out how to handle the extra wait state for word reads to bank area + //may also need special handling to avoid too much stack depth when acces is blocked + push_r(code, options->gen.scratch1); + call(code, options->read_8_noinc); + mov_rr(code, options->gen.scratch1, options->gen.scratch2, SZ_B); + pop_r(code, options->gen.scratch1); + add_ir(code, 1, options->gen.scratch1, SZ_W); + cycles(&options->gen, 3); + check_cycles(&options->gen); + call(code, options->read_8_noinc); + shl_ir(code, 8, options->gen.scratch1, SZ_W); + mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_B); + retn(code); + + options->write_16_highfirst = code->cur; + cycles(&options->gen, 3); + check_cycles(&options->gen); + push_r(code, options->gen.scratch2); + push_r(code, options->gen.scratch1); + add_ir(code, 1, options->gen.scratch2, SZ_W); + shr_ir(code, 8, options->gen.scratch1, SZ_W); + call(code, options->write_8_noinc); + pop_r(code, options->gen.scratch1); + pop_r(code, options->gen.scratch2); + cycles(&options->gen, 3); + check_cycles(&options->gen); + //TODO: Check if we can get away with TCO here + call(code, options->write_8_noinc); + retn(code); + + options->write_16_lowfirst = code->cur; + cycles(&options->gen, 3); + check_cycles(&options->gen); + push_r(code, options->gen.scratch2); + push_r(code, options->gen.scratch1); + call(code, options->write_8_noinc); + pop_r(code, options->gen.scratch1); + pop_r(code, options->gen.scratch2); + add_ir(code, 1, options->gen.scratch2, SZ_W); + shr_ir(code, 8, options->gen.scratch1, SZ_W); + cycles(&options->gen, 3); + check_cycles(&options->gen); + //TODO: Check if we can get away with TCO here + call(code, options->write_8_noinc); + retn(code); options->retrans_stub = code->cur; //pop return address @@ -2130,6 +2184,7 @@ push_r(code, R14); push_r(code, R15); mov_rr(code, RDI, options->gen.context_reg, SZ_PTR); + call(code, options->load_context_scratch); cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); code_ptr no_extra = code->cur+1; jcc(code, CC_Z, no_extra); diff -r 5ef3fe516da9 -r 086de8692932 z80_to_x86.h --- a/z80_to_x86.h Mon Dec 22 20:55:10 2014 -0800 +++ b/z80_to_x86.h Fri Dec 26 12:34:41 2014 -0800 @@ -32,6 +32,7 @@ code_ptr do_sync; code_ptr read_8; code_ptr write_8; + code_ptr read_8_noinc; code_ptr write_8_noinc; code_ptr read_16; code_ptr write_16_highfirst;