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));