Mercurial > repos > blastem
comparison z80_to_x86.c @ 895:13388ab6d78a
Get Z80 core sort of working again post alignment change
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 25 Nov 2015 20:18:34 -0800 |
parents | a7774fc2de4b |
children | 2f1157f00dc6 |
comparison
equal
deleted
inserted
replaced
894:a7774fc2de4b | 895:13388ab6d78a |
---|---|
2374 mov_rr(code, RAX, options->gen.scratch1, SZ_PTR); | 2374 mov_rr(code, RAX, options->gen.scratch1, SZ_PTR); |
2375 pop_r(code, options->gen.context_reg); | 2375 pop_r(code, options->gen.context_reg); |
2376 call(code, options->gen.load_context); | 2376 call(code, options->gen.load_context); |
2377 retn(code); | 2377 retn(code); |
2378 | 2378 |
2379 uint32_t tmp_stack_off; | |
2380 | |
2379 options->gen.handle_cycle_limit = code->cur; | 2381 options->gen.handle_cycle_limit = code->cur; |
2380 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.cycles, SZ_D); | 2382 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.cycles, SZ_D); |
2381 code_ptr no_sync = code->cur+1; | 2383 code_ptr no_sync = code->cur+1; |
2382 jcc(code, CC_B, no_sync); | 2384 jcc(code, CC_B, no_sync); |
2383 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, pc), SZ_W); | 2385 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, pc), SZ_W); |
2384 call(code, options->save_context_scratch); | 2386 call(code, options->save_context_scratch); |
2387 tmp_stack_off = code->stack_off; | |
2385 pop_r(code, RAX); //return address in read/write func | 2388 pop_r(code, RAX); //return address in read/write func |
2389 add_ir(code, 16-sizeof(void *), RSP, SZ_PTR); | |
2386 pop_r(code, RBX); //return address in translated code | 2390 pop_r(code, RBX); //return address in translated code |
2391 add_ir(code, 16-sizeof(void *), RSP, SZ_PTR); | |
2387 sub_ir(code, 5, RAX, SZ_PTR); //adjust return address to point to the call that got us here | 2392 sub_ir(code, 5, RAX, SZ_PTR); //adjust return address to point to the call that got us here |
2388 mov_rrdisp(code, RBX, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); | 2393 mov_rrdisp(code, RBX, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); |
2389 mov_rrind(code, RAX, options->gen.context_reg, SZ_PTR); | 2394 mov_rrind(code, RAX, options->gen.context_reg, SZ_PTR); |
2390 restore_callee_save_regs(code); | 2395 restore_callee_save_regs(code); |
2391 *no_sync = code->cur - (no_sync + 1); | 2396 *no_sync = code->cur - (no_sync + 1); |
2392 //return to caller of z80_run | 2397 //return to caller of z80_run |
2393 retn(code); | 2398 retn(code); |
2399 code->stack_off = tmp_stack_off; | |
2394 | 2400 |
2395 options->gen.handle_code_write = (code_ptr)z80_handle_code_write; | 2401 options->gen.handle_code_write = (code_ptr)z80_handle_code_write; |
2396 | 2402 |
2397 options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, &options->read_8_noinc); | 2403 options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, &options->read_8_noinc); |
2398 options->write_8 = gen_mem_fun(&options->gen, chunks, num_chunks, WRITE_8, &options->write_8_noinc); | 2404 options->write_8 = gen_mem_fun(&options->gen, chunks, num_chunks, WRITE_8, &options->write_8_noinc); |
2399 | 2405 |
2406 code_ptr skip_int = code->cur; | |
2407 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.cycles, SZ_D); | |
2408 code_ptr skip_sync = code->cur + 1; | |
2409 jcc(code, CC_B, skip_sync); | |
2410 //save PC | |
2411 mov_rrdisp(code, options->gen.scratch1, options->gen.context_reg, offsetof(z80_context, pc), SZ_D); | |
2412 options->do_sync = code->cur; | |
2413 call(code, options->gen.save_context); | |
2414 tmp_stack_off = code->stack_off; | |
2415 //pop return address off the stack and save for resume later | |
2416 pop_rind(code, options->gen.context_reg); | |
2417 add_ir(code, 16-sizeof(void *), RSP, SZ_PTR); | |
2418 //restore callee saved registers | |
2419 restore_callee_save_regs(code); | |
2420 //return to caller of z80_run | |
2421 *skip_sync = code->cur - (skip_sync+1); | |
2422 retn(code); | |
2423 code->stack_off = tmp_stack_off; | |
2424 | |
2400 options->gen.handle_cycle_limit_int = code->cur; | 2425 options->gen.handle_cycle_limit_int = code->cur; |
2401 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, int_cycle), options->gen.cycles, SZ_D); | 2426 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, int_cycle), options->gen.cycles, SZ_D); |
2402 code_ptr skip_int = code->cur+1; | |
2403 jcc(code, CC_B, skip_int); | 2427 jcc(code, CC_B, skip_int); |
2404 //set limit to the cycle limit | 2428 //set limit to the cycle limit |
2405 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.limit, SZ_D); | 2429 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.limit, SZ_D); |
2406 //disable interrupts | 2430 //disable interrupts |
2407 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); | 2431 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); |
2426 shr_ir(code, 8, options->gen.scratch1, SZ_W); | 2450 shr_ir(code, 8, options->gen.scratch1, SZ_W); |
2427 check_cycles(&options->gen); | 2451 check_cycles(&options->gen); |
2428 cycles(&options->gen, 3); | 2452 cycles(&options->gen, 3); |
2429 call(code, options->write_8_noinc); | 2453 call(code, options->write_8_noinc); |
2430 //dispose of return address as we'll be jumping somewhere else | 2454 //dispose of return address as we'll be jumping somewhere else |
2431 pop_r(code, options->gen.scratch2); | 2455 add_ir(code, 16, RSP, SZ_PTR); |
2432 //TODO: Support interrupt mode 0 and 2 | 2456 //TODO: Support interrupt mode 0 and 2 |
2433 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); | 2457 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); |
2434 call(code, options->native_addr); | 2458 call(code, options->native_addr); |
2435 mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR); | 2459 mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR); |
2460 tmp_stack_off = code->stack_off; | |
2436 restore_callee_save_regs(code); | 2461 restore_callee_save_regs(code); |
2437 //return to caller of z80_run to sync | 2462 //return to caller of z80_run to sync |
2438 retn(code); | 2463 retn(code); |
2439 *skip_int = code->cur - (skip_int+1); | 2464 code->stack_off = tmp_stack_off; |
2440 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.cycles, SZ_D); | |
2441 code_ptr skip_sync = code->cur + 1; | |
2442 jcc(code, CC_B, skip_sync); | |
2443 //save PC | |
2444 mov_rrdisp(code, options->gen.scratch1, options->gen.context_reg, offsetof(z80_context, pc), SZ_D); | |
2445 options->do_sync = code->cur; | |
2446 call(code, options->gen.save_context); | |
2447 pop_rind(code, options->gen.context_reg); | |
2448 //restore callee saved registers | |
2449 restore_callee_save_regs(code); | |
2450 //return to caller of z80_run | |
2451 *skip_sync = code->cur - (skip_sync+1); | |
2452 retn(code); | |
2453 | 2465 |
2454 //HACK | 2466 //HACK |
2455 options->gen.address_size = SZ_D; | 2467 options->gen.address_size = SZ_D; |
2456 options->gen.address_mask = 0xFF; | 2468 options->gen.address_mask = 0xFF; |
2457 options->read_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, READ_8, NULL); | 2469 options->read_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, READ_8, NULL); |
2515 //TODO: Check if we can get away with TCO here | 2527 //TODO: Check if we can get away with TCO here |
2516 call(code, options->write_8_noinc); | 2528 call(code, options->write_8_noinc); |
2517 retn(code); | 2529 retn(code); |
2518 | 2530 |
2519 options->retrans_stub = code->cur; | 2531 options->retrans_stub = code->cur; |
2532 tmp_stack_off = code->stack_off; | |
2520 //pop return address | 2533 //pop return address |
2521 pop_r(code, options->gen.scratch2); | 2534 pop_r(code, options->gen.scratch2); |
2535 add_ir(code, 16-sizeof(void*), RSP, SZ_PTR); | |
2536 code->stack_off = tmp_stack_off; | |
2522 call(code, options->gen.save_context); | 2537 call(code, options->gen.save_context); |
2523 //adjust pointer before move and call instructions that got us here | 2538 //adjust pointer before move and call instructions that got us here |
2524 sub_ir(code, options->gen.scratch1 >= R8 ? 11 : 10, options->gen.scratch2, SZ_PTR); | 2539 sub_ir(code, options->gen.scratch1 >= R8 ? 11 : 10, options->gen.scratch2, SZ_PTR); |
2525 push_r(code, options->gen.context_reg); | 2540 push_r(code, options->gen.context_reg); |
2526 call_args(code, (code_ptr)z80_retranslate_inst, 3, options->gen.scratch1, options->gen.context_reg, options->gen.scratch2); | 2541 call_args(code, (code_ptr)z80_retranslate_inst, 3, options->gen.scratch1, options->gen.context_reg, options->gen.scratch2); |
2528 mov_rr(code, RAX, options->gen.scratch1, SZ_PTR); | 2543 mov_rr(code, RAX, options->gen.scratch1, SZ_PTR); |
2529 call(code, options->gen.load_context); | 2544 call(code, options->gen.load_context); |
2530 jmp_r(code, options->gen.scratch1); | 2545 jmp_r(code, options->gen.scratch1); |
2531 | 2546 |
2532 options->run = (z80_run_fun)code->cur; | 2547 options->run = (z80_run_fun)code->cur; |
2548 tmp_stack_off = code->stack_off; | |
2533 save_callee_save_regs(code); | 2549 save_callee_save_regs(code); |
2534 #ifdef X86_64 | 2550 #ifdef X86_64 |
2535 mov_rr(code, RDI, options->gen.context_reg, SZ_PTR); | 2551 mov_rr(code, RDI, options->gen.context_reg, SZ_PTR); |
2536 #else | 2552 #else |
2537 mov_rdispr(code, RSP, 5 * sizeof(int32_t), options->gen.context_reg, SZ_PTR); | 2553 mov_rdispr(code, RSP, 5 * sizeof(int32_t), options->gen.context_reg, SZ_PTR); |
2542 jcc(code, CC_Z, no_extra); | 2558 jcc(code, CC_Z, no_extra); |
2543 push_rdisp(code, options->gen.context_reg, offsetof(z80_context, extra_pc)); | 2559 push_rdisp(code, options->gen.context_reg, offsetof(z80_context, extra_pc)); |
2544 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); | 2560 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); |
2545 *no_extra = code->cur - (no_extra + 1); | 2561 *no_extra = code->cur - (no_extra + 1); |
2546 jmp_rind(code, options->gen.context_reg); | 2562 jmp_rind(code, options->gen.context_reg); |
2563 code->stack_off = tmp_stack_off; | |
2547 } | 2564 } |
2548 | 2565 |
2549 void init_z80_context(z80_context * context, z80_options * options) | 2566 void init_z80_context(z80_context * context, z80_options * options) |
2550 { | 2567 { |
2551 memset(context, 0, sizeof(*context)); | 2568 memset(context, 0, sizeof(*context)); |