comparison z80_to_x86.c @ 366:836585d389b8

Partial implementation of Z80 debugger
author Mike Pavone <pavone@retrodev.com>
date Fri, 31 May 2013 19:43:13 -0700
parents c708dea45f8b
children f20562f2a570
comparison
equal deleted inserted replaced
365:3ba3b6656fff 366:836585d389b8
34 void z80_handle_cycle_limit_int(); 34 void z80_handle_cycle_limit_int();
35 void z80_retrans_stub(); 35 void z80_retrans_stub();
36 void z80_io_read(); 36 void z80_io_read();
37 void z80_io_write(); 37 void z80_io_write();
38 void z80_halt(); 38 void z80_halt();
39 void z80_save_context();
40 void z80_load_context();
39 41
40 uint8_t z80_size(z80inst * inst) 42 uint8_t z80_size(z80inst * inst)
41 { 43 {
42 uint8_t reg = (inst->reg & 0x1F); 44 uint8_t reg = (inst->reg & 0x1F);
43 if (reg != Z80_UNUSED && reg != Z80_USE_IMMED) { 45 if (reg != Z80_UNUSED && reg != Z80_USE_IMMED) {
1951 context->iff1 = context->iff2 = 0; 1953 context->iff1 = context->iff2 = 0;
1952 context->native_pc = z80_get_native_address_trans(context, 0); 1954 context->native_pc = z80_get_native_address_trans(context, 0);
1953 context->extra_pc = NULL; 1955 context->extra_pc = NULL;
1954 } 1956 }
1955 1957
1956 1958 void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_handler)
1959 {
1960 static uint8_t * bp_stub = NULL;
1961 uint8_t * native = z80_get_native_address_trans(context, address);
1962 uint8_t * start_native = native;
1963 native = mov_ir(native, address, SCRATCH1, SZ_W);
1964 if (!bp_stub) {
1965 x86_z80_options * opts = context->options;
1966 uint8_t * dst = opts->cur_code;
1967 uint8_t * dst_end = opts->code_end;
1968 if (dst_end - dst < 128) {
1969 size_t size = 1024*1024;
1970 dst = alloc_code(&size);
1971 opts->code_end = dst_end = dst + size;
1972 }
1973 bp_stub = dst;
1974 native = call(native, bp_stub);
1975
1976 //Calculate length of prologue
1977 dst = z80_check_cycles_int(dst, address);
1978 int check_int_size = dst-bp_stub;
1979 dst = bp_stub;
1980
1981 //Save context and call breakpoint handler
1982 dst = call(dst, (uint8_t *)z80_save_context);
1983 dst = push_r(dst, SCRATCH1);
1984 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
1985 dst = mov_rr(dst, SCRATCH1, RSI, SZ_W);
1986 dst = call(dst, bp_handler);
1987 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
1988 //Restore context
1989 dst = call(dst, (uint8_t *)z80_load_context);
1990 dst = pop_r(dst, SCRATCH1);
1991 //do prologue stuff
1992 dst = cmp_rr(dst, ZCYCLES, ZLIMIT, SZ_D);
1993 uint8_t * jmp_off = dst+1;
1994 dst = jcc(dst, CC_NC, dst + 7);
1995 dst = call(dst, (uint8_t *)z80_handle_cycle_limit_int);
1996 *jmp_off = dst - (jmp_off+1);
1997 //jump back to body of translated instruction
1998 dst = pop_r(dst, SCRATCH1);
1999 dst = add_ir(dst, check_int_size - (native-start_native), SCRATCH1, SZ_Q);
2000 dst = jmp_r(dst, SCRATCH1);
2001 opts->cur_code = dst;
2002 } else {
2003 native = call(native, bp_stub);
2004 }
2005 }
2006
2007 void zremove_breakpoint(z80_context * context, uint16_t address)
2008 {
2009 uint8_t * native = z80_get_native_address(context, address);
2010 z80_check_cycles_int(native, address);
2011 }
2012
2013