Mercurial > repos > blastem
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}; |