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