comparison m68k_core_x86.c @ 1303:208803173ebc

Implemented M68K trace mode. Some edge cases/SR update paths still need work
author Michael Pavone <pavone@retrodev.com>
date Tue, 28 Mar 2017 00:13:35 -0700
parents 71b1a080b30c
children 5b90d7669eee
comparison
equal deleted inserted replaced
1302:d2cb97ab3cff 1303:208803173ebc
2195 if (inst->op == M68K_ANDI_SR && !(inst->src.params.immed & (1 << (BIT_SUPERVISOR + 8)))) { 2195 if (inst->op == M68K_ANDI_SR && !(inst->src.params.immed & (1 << (BIT_SUPERVISOR + 8)))) {
2196 //leave supervisor mode 2196 //leave supervisor mode
2197 swap_ssp_usp(opts); 2197 swap_ssp_usp(opts);
2198 } 2198 }
2199 if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700) 2199 if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700)
2200 || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) { 2200 || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x8700)) {
2201 if (inst->op == M68K_ANDI_SR) { 2201 if (inst->op == M68K_ANDI_SR) {
2202 //set int pending flag in case we trigger an interrupt as a result of the mask change 2202 //set int pending flag in case we trigger an interrupt as a result of the mask change
2203 mov_irdisp(code, INT_PENDING_SR_CHANGE, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); 2203 mov_irdisp(code, INT_PENDING_SR_CHANGE, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2204 } 2204 }
2205 call(code, opts->do_sync); 2205 call(code, opts->do_sync);
2927 opts->gen.handle_cycle_limit_int = code->cur; 2927 opts->gen.handle_cycle_limit_int = code->cur;
2928 //calculate stack adjust size 2928 //calculate stack adjust size
2929 add_ir(code, 16-sizeof(void*), RSP, SZ_PTR); 2929 add_ir(code, 16-sizeof(void*), RSP, SZ_PTR);
2930 uint32_t adjust_size = code->cur - opts->gen.handle_cycle_limit_int; 2930 uint32_t adjust_size = code->cur - opts->gen.handle_cycle_limit_int;
2931 code->cur = opts->gen.handle_cycle_limit_int; 2931 code->cur = opts->gen.handle_cycle_limit_int;
2932 2932 bt_irdisp(code, 7, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2933 code_ptr no_trace = code->cur + 1;
2934 jcc(code, CC_NC, no_trace);
2935 cmp_irdisp(code, 0, opts->gen.context_reg, offsetof(m68k_context, trace_pending), SZ_B);
2936 code_ptr do_trace = code->cur + 1;
2937 jcc(code, CC_NZ, do_trace);
2938 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, trace_pending), SZ_B);
2939 *no_trace = code->cur - (no_trace + 1);
2933 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D); 2940 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D);
2934 code_ptr do_int = code->cur + 1; 2941 code_ptr do_int = code->cur + 2;
2935 jcc(code, CC_NC, code->cur + 2); 2942 jcc(code, CC_NC, do_int+512);//force 32-bit displacement
2936 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.cycles, SZ_D); 2943 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.cycles, SZ_D);
2937 skip_sync = code->cur + 1; 2944 skip_sync = code->cur + 1;
2938 jcc(code, CC_C, code->cur + 2); 2945 jcc(code, CC_C, code->cur + 2);
2939 call(code, opts->gen.save_context); 2946 call(code, opts->gen.save_context);
2940 call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1); 2947 call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1);
2953 add_ir(code, adjust_size, opts->gen.scratch1, SZ_PTR); 2960 add_ir(code, adjust_size, opts->gen.scratch1, SZ_PTR);
2954 //save return address for restoring later 2961 //save return address for restoring later
2955 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, resume_pc), SZ_PTR); 2962 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, resume_pc), SZ_PTR);
2956 retn(code); 2963 retn(code);
2957 code->stack_off = tmp_stack_off; 2964 code->stack_off = tmp_stack_off;
2958 *do_int = code->cur - (do_int+1); 2965 *do_trace = code->cur - (do_trace + 1);
2966 //clear out trace pending flag
2967 mov_irdisp(code, 0, opts->gen.context_reg, offsetof(m68k_context, trace_pending), SZ_B);
2968 //save PC as stored in scratch1 for later
2969 push_r(code, opts->gen.scratch1);
2970 //swap USP and SSP if not already in supervisor mode
2971 check_user_mode_swap_ssp_usp(opts);
2972 //save status register
2973 subi_areg(opts, 6, 7);
2974 call(code, opts->get_sr);
2975 cycles(&opts->gen, 6);
2976 //save SR to stack
2977 areg_to_native(opts, 7, opts->gen.scratch2);
2978 call(code, opts->write_16);
2979 //update the status register
2980 and_irdisp(code, 0x7F, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2981 or_irdisp(code, 0x20, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2982 //save PC
2983 areg_to_native(opts, 7, opts->gen.scratch2);
2984 add_ir(code, 2, opts->gen.scratch2, SZ_D);
2985 pop_r(code, opts->gen.scratch1);
2986 call(code, opts->write_32_lowfirst);
2987 //read vector
2988 mov_ir(code, 0x24, opts->gen.scratch1, SZ_D);
2989 call(code, opts->read_32);
2990 call(code, opts->native_addr_and_sync);
2991 //2 prefetch bus operations + 2 idle bus cycles
2992 cycles(&opts->gen, 10);
2993 //discard function return address
2994 pop_r(code, opts->gen.scratch2);
2995 add_ir(code, 16-sizeof(void *), RSP, SZ_PTR);
2996 jmp_r(code, opts->gen.scratch1);
2997
2998 code->stack_off = tmp_stack_off;
2999
3000 *((uint32_t *)do_int) = code->cur - (do_int+4);
2959 //implement 1 instruction latency 3001 //implement 1 instruction latency
2960 cmp_irdisp(code, INT_PENDING_NONE, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); 3002 cmp_irdisp(code, INT_PENDING_NONE, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2961 do_int = code->cur + 1; 3003 do_int = code->cur + 1;
2962 jcc(code, CC_NZ, do_int); 3004 jcc(code, CC_NZ, do_int);
2963 //store current interrupt number so it doesn't change before we start processing the vector 3005 //store current interrupt number so it doesn't change before we start processing the vector