comparison m68k_core_x86.c @ 846:98d7b6073163

Implement interrupt latency. Fixes Sesame Street: Counting Cafe and gives accurate results in my test ROM
author Michael Pavone <pavone@retrodev.com>
date Sat, 31 Oct 2015 22:17:50 -0700
parents 4556818b6847
children 7decd421cdc8
comparison
equal deleted inserted replaced
845:3a18b5f63afc 846:98d7b6073163
2008 //leave supervisor mode 2008 //leave supervisor mode
2009 swap_ssp_usp(opts); 2009 swap_ssp_usp(opts);
2010 } 2010 }
2011 if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700) 2011 if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700)
2012 || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) { 2012 || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) {
2013 if (inst->op == M68K_ANDI_SR) {
2014 //set int pending flag in case we trigger an interrupt as a result of the mask change
2015 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2016 }
2013 call(code, opts->do_sync); 2017 call(code, opts->do_sync);
2014 } 2018 }
2015 } 2019 }
2016 } 2020 }
2017 2021
2033 xor_flag(opts, 1, FLAG_N); 2037 xor_flag(opts, 1, FLAG_N);
2034 } 2038 }
2035 if (inst->src.params.immed & 0x10) { 2039 if (inst->src.params.immed & 0x10) {
2036 xor_flag(opts, 1, FLAG_X); 2040 xor_flag(opts, 1, FLAG_X);
2037 } 2041 }
2038 if (inst->op == M68K_ORI_SR) { 2042 if (inst->op == M68K_EORI_SR) {
2039 xor_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2043 xor_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2040 if (inst->src.params.immed & 0x700) { 2044 if (inst->src.params.immed & 0x700) {
2045 //set int pending flag in case we trigger an interrupt as a result of the mask change
2046 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2041 call(code, opts->do_sync); 2047 call(code, opts->do_sync);
2042 } 2048 }
2043 } 2049 }
2044 } 2050 }
2045 2051
2062 if (inst->op == M68K_MOVE_SR) { 2068 if (inst->op == M68K_MOVE_SR) {
2063 mov_irdisp(code, (src_op->disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2069 mov_irdisp(code, (src_op->disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2064 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 2070 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
2065 //leave supervisor mode 2071 //leave supervisor mode
2066 swap_ssp_usp(opts); 2072 swap_ssp_usp(opts);
2073 }
2074 if (((src_op->disp >> 8) & 7) < 7) {
2075 //set int pending flag in case we trigger an interrupt as a result of the mask change
2076 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2067 } 2077 }
2068 call(code, opts->do_sync); 2078 call(code, opts->do_sync);
2069 } 2079 }
2070 cycles(&opts->gen, 12); 2080 cycles(&opts->gen, 12);
2071 } else { 2081 } else {
2464 } 2474 }
2465 } 2475 }
2466 } 2476 }
2467 shr_ir(code, 8, opts->gen.scratch1, SZ_W); 2477 shr_ir(code, 8, opts->gen.scratch1, SZ_W);
2468 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2478 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2479 //set int pending flag in case we trigger an interrupt as a result of the mask change
2480 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2469 retn(code); 2481 retn(code);
2470 2482
2471 opts->set_ccr = code->cur; 2483 opts->set_ccr = code->cur;
2472 for (int flag = FLAG_C; flag >= FLAG_X; flag--) 2484 for (int flag = FLAG_C; flag >= FLAG_X; flag--)
2473 { 2485 {
2497 mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); 2509 mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR);
2498 jmp(code, opts->gen.load_context); 2510 jmp(code, opts->gen.load_context);
2499 *skip_sync = code->cur - (skip_sync+1); 2511 *skip_sync = code->cur - (skip_sync+1);
2500 retn(code); 2512 retn(code);
2501 *do_int = code->cur - (do_int+1); 2513 *do_int = code->cur - (do_int+1);
2514 //implement 1 instruction latency
2515 cmp_irdisp(code, 0, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2516 do_int = code->cur + 1;
2517 jcc(code, CC_NZ, do_int);
2518 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2519 retn(code);
2520 *do_int = code->cur - (do_int + 1);
2502 //set target cycle to sync cycle 2521 //set target cycle to sync cycle
2503 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.limit, SZ_D); 2522 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.limit, SZ_D);
2504 //swap USP and SSP if not already in supervisor mode 2523 //swap USP and SSP if not already in supervisor mode
2505 check_user_mode_swap_ssp_usp(opts); 2524 check_user_mode_swap_ssp_usp(opts);
2506 //save PC 2525 //save PC