comparison z80_to_x86.c @ 668:5439ae7946ca

Made the Z80 core more contained by refactoring some code in blastem.c into z80_to_x86.c
author Michael Pavone <pavone@retrodev.com>
date Sat, 03 Jan 2015 18:23:04 -0800
parents 30ccf56842d6
children f4f3e74b0ce6
comparison
equal deleted inserted replaced
667:30ccf56842d6 668:5439ae7946ca
1775 uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address); 1775 uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address);
1776 if (inst_start != INVALID_INSTRUCTION_START) { 1776 if (inst_start != INVALID_INSTRUCTION_START) {
1777 code_ptr dst = z80_get_native_address(context, inst_start); 1777 code_ptr dst = z80_get_native_address(context, inst_start);
1778 code_info code = {dst, dst+16}; 1778 code_info code = {dst, dst+16};
1779 z80_options * opts = context->options; 1779 z80_options * opts = context->options;
1780 dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code, inst_start, address); 1780 dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code.cur, inst_start, address);
1781 mov_ir(&code, inst_start, opts->gen.scratch1, SZ_D); 1781 mov_ir(&code, inst_start, opts->gen.scratch1, SZ_D);
1782 call(&code, opts->retrans_stub); 1782 call(&code, opts->retrans_stub);
1783 } 1783 }
1784 return context; 1784 return context;
1785 } 1785 }
2224 context->static_code_map->offsets = malloc(sizeof(int32_t) * 0x2000); 2224 context->static_code_map->offsets = malloc(sizeof(int32_t) * 0x2000);
2225 memset(context->static_code_map->offsets, 0xFF, sizeof(int32_t) * 0x2000); 2225 memset(context->static_code_map->offsets, 0xFF, sizeof(int32_t) * 0x2000);
2226 context->banked_code_map = malloc(sizeof(native_map_slot)); 2226 context->banked_code_map = malloc(sizeof(native_map_slot));
2227 memset(context->banked_code_map, 0, sizeof(native_map_slot)); 2227 memset(context->banked_code_map, 0, sizeof(native_map_slot));
2228 context->options = options; 2228 context->options = options;
2229 context->int_cycle = 0xFFFFFFFF; 2229 context->int_cycle = CYCLE_NEVER;
2230 context->int_pulse_start = 0xFFFFFFFF; 2230 context->int_pulse_start = CYCLE_NEVER;
2231 context->int_pulse_end = 0xFFFFFFFF; 2231 context->int_pulse_end = CYCLE_NEVER;
2232 context->run = options->run; 2232 }
2233 } 2233
2234 2234 void z80_run(z80_context * context, uint32_t target_cycle)
2235 void z80_reset(z80_context * context) 2235 {
2236 { 2236 if (context->reset || context->busack) {
2237 context->im = 0; 2237 context->current_cycle = target_cycle;
2238 context->iff1 = context->iff2 = 0; 2238 } else {
2239 context->native_pc = z80_get_native_address_trans(context, 0); 2239 if (context->current_cycle < target_cycle) {
2240 context->extra_pc = NULL; 2240 //busreq is sampled at the end of an m-cycle
2241 //we can approximate that by running for a single m-cycle after a bus request
2242 context->sync_cycle = context->busreq ? context->current_cycle + 3*context->options->gen.clock_divider : target_cycle;
2243 if (!context->native_pc) {
2244 context->native_pc = z80_get_native_address_trans(context, context->pc);
2245 }
2246 while (context->current_cycle < context->sync_cycle)
2247 {
2248 if (context->int_pulse_end < context->current_cycle || context->int_pulse_end == CYCLE_NEVER) {
2249 z80_next_int_pulse(context);
2250 }
2251 if (context->iff1) {
2252 context->int_cycle = context->int_pulse_start < context->int_enable_cycle ? context->int_enable_cycle : context->int_pulse_start;
2253 } else {
2254 context->int_cycle = CYCLE_NEVER;
2255 }
2256 context->target_cycle = context->sync_cycle < context->int_cycle ? context->sync_cycle : context->int_cycle;
2257 dprintf("Running Z80 from cycle %d to cycle %d. Int cycle: %d\n", context->current_cycle, context->sync_cycle, context->int_cycle);
2258 context->options->run(context);
2259 dprintf("Z80 ran to cycle %d\n", context->current_cycle);
2260 }
2261 if (context->busreq) {
2262 context->busack = 1;
2263 context->current_cycle = target_cycle;
2264 }
2265 }
2266 }
2267 }
2268
2269 void z80_assert_reset(z80_context * context, uint32_t cycle)
2270 {
2271 z80_run(context, cycle);
2272 context->reset = 1;
2273 }
2274
2275 void z80_clear_reset(z80_context * context, uint32_t cycle)
2276 {
2277 z80_run(context, cycle);
2278 if (context->reset) {
2279 //TODO: Handle case where reset is not asserted long enough
2280 context->im = 0;
2281 context->iff1 = context->iff2 = 0;
2282 context->native_pc = NULL;
2283 context->extra_pc = NULL;
2284 context->pc = 0;
2285 context->reset = 0;
2286 }
2287 }
2288
2289 void z80_assert_busreq(z80_context * context, uint32_t cycle)
2290 {
2291 z80_run(context, cycle);
2292 context->busreq = 1;
2293 }
2294
2295 void z80_clear_busreq(z80_context * context, uint32_t cycle)
2296 {
2297 z80_run(context, cycle);
2298 context->busreq = 0;
2299 context->busack = 0;
2300 }
2301
2302 uint8_t z80_get_busack(z80_context * context, uint32_t cycle)
2303 {
2304 z80_run(context, cycle);
2305 return context->busack;
2306 }
2307
2308 void z80_adjust_cycles(z80_context * context, uint32_t deduction)
2309 {
2310 if (context->current_cycle < deduction) {
2311 fprintf(stderr, "WARNING: Deduction of %u cycles when Z80 cycle counter is only %u\n", deduction, context->current_cycle);
2312 context->current_cycle = 0;
2313 } else {
2314 context->current_cycle -= deduction;
2315 }
2316 if (context->int_enable_cycle != CYCLE_NEVER) {
2317 if (context->int_enable_cycle < deduction) {
2318 context->int_enable_cycle = 0;
2319 } else {
2320 context->int_enable_cycle -= deduction;
2321 }
2322 }
2323 if (context->int_pulse_start != CYCLE_NEVER) {
2324 if (context->int_pulse_end < deduction) {
2325 context->int_pulse_start = context->int_pulse_end = CYCLE_NEVER;
2326 } else {
2327 context->int_pulse_end -= deduction;
2328 if (context->int_pulse_start < deduction) {
2329 context->int_pulse_start = 0;
2330 } else {
2331 context->int_pulse_start -= deduction;
2332 }
2333 }
2334 }
2241 } 2335 }
2242 2336
2243 uint32_t zbreakpoint_patch(z80_context * context, uint16_t address, code_ptr dst) 2337 uint32_t zbreakpoint_patch(z80_context * context, uint16_t address, code_ptr dst)
2244 { 2338 {
2245 code_info code = {dst, dst+16}; 2339 code_info code = {dst, dst+16};