summaryrefslogtreecommitdiff
path: root/z80_to_x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'z80_to_x86.c')
-rw-r--r--z80_to_x86.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/z80_to_x86.c b/z80_to_x86.c
index f2ead45..56b10ec 100644
--- a/z80_to_x86.c
+++ b/z80_to_x86.c
@@ -36,6 +36,8 @@ void z80_retrans_stub();
void z80_io_read();
void z80_io_write();
void z80_halt();
+void z80_save_context();
+void z80_load_context();
uint8_t z80_size(z80inst * inst)
{
@@ -1953,4 +1955,59 @@ void z80_reset(z80_context * context)
context->extra_pc = NULL;
}
+void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_handler)
+{
+ static uint8_t * bp_stub = NULL;
+ uint8_t * native = z80_get_native_address_trans(context, address);
+ uint8_t * start_native = native;
+ native = mov_ir(native, address, SCRATCH1, SZ_W);
+ if (!bp_stub) {
+ x86_z80_options * opts = context->options;
+ uint8_t * dst = opts->cur_code;
+ uint8_t * dst_end = opts->code_end;
+ if (dst_end - dst < 128) {
+ size_t size = 1024*1024;
+ dst = alloc_code(&size);
+ opts->code_end = dst_end = dst + size;
+ }
+ bp_stub = dst;
+ native = call(native, bp_stub);
+
+ //Calculate length of prologue
+ dst = z80_check_cycles_int(dst, address);
+ int check_int_size = dst-bp_stub;
+ dst = bp_stub;
+
+ //Save context and call breakpoint handler
+ dst = call(dst, (uint8_t *)z80_save_context);
+ dst = push_r(dst, SCRATCH1);
+ dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
+ dst = mov_rr(dst, SCRATCH1, RSI, SZ_W);
+ dst = call(dst, bp_handler);
+ dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
+ //Restore context
+ dst = call(dst, (uint8_t *)z80_load_context);
+ dst = pop_r(dst, SCRATCH1);
+ //do prologue stuff
+ dst = cmp_rr(dst, ZCYCLES, ZLIMIT, SZ_D);
+ uint8_t * jmp_off = dst+1;
+ dst = jcc(dst, CC_NC, dst + 7);
+ dst = call(dst, (uint8_t *)z80_handle_cycle_limit_int);
+ *jmp_off = dst - (jmp_off+1);
+ //jump back to body of translated instruction
+ dst = pop_r(dst, SCRATCH1);
+ dst = add_ir(dst, check_int_size - (native-start_native), SCRATCH1, SZ_Q);
+ dst = jmp_r(dst, SCRATCH1);
+ opts->cur_code = dst;
+ } else {
+ native = call(native, bp_stub);
+ }
+}
+
+void zremove_breakpoint(z80_context * context, uint16_t address)
+{
+ uint8_t * native = z80_get_native_address(context, address);
+ z80_check_cycles_int(native, address);
+}
+