comparison m68k_core_x86.c @ 667:30ccf56842d6

All cycle counters are now based off the master clock. This seems to have messed up Z80 interrupt timing (music in Sonic 2 is too slow for instance), but things are generally working
author Michael Pavone <pavone@retrodev.com>
date Sat, 03 Jan 2015 16:08:23 -0800
parents d0943769353b
children 7ed1dbb48f61
comparison
equal deleted inserted replaced
666:b68039895627 667:30ccf56842d6
1010 if (inst->src.addr_mode == MODE_UNUSED) { 1010 if (inst->src.addr_mode == MODE_UNUSED) {
1011 cycles(&opts->gen, BUS); 1011 cycles(&opts->gen, BUS);
1012 //Memory shift 1012 //Memory shift
1013 shift_ir(code, 1, dst_op->base, SZ_W); 1013 shift_ir(code, 1, dst_op->base, SZ_W);
1014 } else { 1014 } else {
1015 cycles(&opts->gen, inst->extra.size == OPSIZE_LONG ? 8 : 6);
1016 if (src_op->mode == MODE_IMMED) { 1015 if (src_op->mode == MODE_IMMED) {
1016 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + 2 * src_op->disp);
1017 if (src_op->disp != 1 && inst->op == M68K_ASL) { 1017 if (src_op->disp != 1 && inst->op == M68K_ASL) {
1018 set_flag(opts, 0, FLAG_V); 1018 set_flag(opts, 0, FLAG_V);
1019 for (int i = 0; i < src_op->disp; i++) { 1019 for (int i = 0; i < src_op->disp; i++) {
1020 if (dst_op->mode == MODE_REG_DIRECT) { 1020 if (dst_op->mode == MODE_REG_DIRECT) {
1021 shift_ir(code, 1, dst_op->base, inst->extra.size); 1021 shift_ir(code, 1, dst_op->base, inst->extra.size);
1035 shift_irdisp(code, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); 1035 shift_irdisp(code, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size);
1036 } 1036 }
1037 set_flag_cond(opts, CC_O, FLAG_V); 1037 set_flag_cond(opts, CC_O, FLAG_V);
1038 } 1038 }
1039 } else { 1039 } else {
1040 cycles(&opts->gen, inst->extra.size == OPSIZE_LONG ? 8 : 6);
1040 if (src_op->base != RCX) { 1041 if (src_op->base != RCX) {
1041 if (src_op->mode == MODE_REG_DIRECT) { 1042 if (src_op->mode == MODE_REG_DIRECT) {
1042 mov_rr(code, src_op->base, RCX, SZ_B); 1043 mov_rr(code, src_op->base, RCX, SZ_B);
1043 } else { 1044 } else {
1044 mov_rdispr(code, src_op->base, src_op->disp, RCX, SZ_B); 1045 mov_rdispr(code, src_op->base, src_op->disp, RCX, SZ_B);
1064 } 1065 }
1065 z_off = code->cur + 1; 1066 z_off = code->cur + 1;
1066 jmp(code, code->cur + 2); 1067 jmp(code, code->cur + 2);
1067 *nz_off = code->cur - (nz_off + 1); 1068 *nz_off = code->cur - (nz_off + 1);
1068 //add 2 cycles for every bit shifted 1069 //add 2 cycles for every bit shifted
1069 add_rr(code, RCX, opts->gen.cycles, SZ_D); 1070 mov_ir(code, 2 * opts->gen.clock_divider, opts->gen.scratch2, SZ_D);
1070 add_rr(code, RCX, opts->gen.cycles, SZ_D); 1071 imul_rr(code, RCX, opts->gen.scratch2, SZ_D);
1072 add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D);
1071 if (inst->op == M68K_ASL) { 1073 if (inst->op == M68K_ASL) {
1072 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB 1074 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB
1073 //Easiest way to deal with this is to shift one bit at a time 1075 //Easiest way to deal with this is to shift one bit at a time
1074 set_flag(opts, 0, FLAG_V); 1076 set_flag(opts, 0, FLAG_V);
1075 check_alloc_code(code, 5*MAX_INST_LEN); 1077 check_alloc_code(code, 5*MAX_INST_LEN);
1863 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_B); 1865 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_B);
1864 } 1866 }
1865 and_ir(code, 63, opts->gen.scratch1, SZ_D); 1867 and_ir(code, 63, opts->gen.scratch1, SZ_D);
1866 code_ptr zero_off = code->cur + 1; 1868 code_ptr zero_off = code->cur + 1;
1867 jcc(code, CC_Z, code->cur + 2); 1869 jcc(code, CC_Z, code->cur + 2);
1868 add_rr(code, opts->gen.scratch1, opts->gen.cycles, SZ_D); 1870 //add 2 cycles for every bit shifted
1869 add_rr(code, opts->gen.scratch1, opts->gen.cycles, SZ_D); 1871 mov_ir(code, 2 * opts->gen.clock_divider, opts->gen.scratch2, SZ_D);
1872 imul_rr(code, RCX, opts->gen.scratch2, SZ_D);
1873 add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D);
1870 cmp_ir(code, 32, opts->gen.scratch1, SZ_B); 1874 cmp_ir(code, 32, opts->gen.scratch1, SZ_B);
1871 code_ptr norm_off = code->cur + 1; 1875 code_ptr norm_off = code->cur + 1;
1872 jcc(code, CC_L, code->cur + 2); 1876 jcc(code, CC_L, code->cur + 2);
1873 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { 1877 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) {
1874 flag_to_carry(opts, FLAG_X); 1878 flag_to_carry(opts, FLAG_X);
2184 } else { 2188 } else {
2185 call(&native, bp_stub); 2189 call(&native, bp_stub);
2186 } 2190 }
2187 } 2191 }
2188 2192
2189 void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) 2193 void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider)
2190 { 2194 {
2191 memset(opts, 0, sizeof(*opts)); 2195 memset(opts, 0, sizeof(*opts));
2192 opts->gen.memmap = memmap; 2196 opts->gen.memmap = memmap;
2193 opts->gen.memmap_chunks = num_chunks; 2197 opts->gen.memmap_chunks = num_chunks;
2194 opts->gen.address_size = SZ_D; 2198 opts->gen.address_size = SZ_D;
2195 opts->gen.address_mask = 0xFFFFFF; 2199 opts->gen.address_mask = 0xFFFFFF;
2196 opts->gen.byte_swap = 1; 2200 opts->gen.byte_swap = 1;
2197 opts->gen.max_address = 0x1000000; 2201 opts->gen.max_address = 0x1000000;
2198 opts->gen.bus_cycles = BUS; 2202 opts->gen.bus_cycles = BUS;
2203 opts->gen.clock_divider = clock_divider;
2199 opts->gen.mem_ptr_off = offsetof(m68k_context, mem_pointers); 2204 opts->gen.mem_ptr_off = offsetof(m68k_context, mem_pointers);
2200 opts->gen.ram_flags_off = offsetof(m68k_context, ram_code_flags); 2205 opts->gen.ram_flags_off = offsetof(m68k_context, ram_code_flags);
2201 opts->gen.ram_flags_shift = 11; 2206 opts->gen.ram_flags_shift = 11;
2202 for (int i = 0; i < 8; i++) 2207 for (int i = 0; i < 8; i++)
2203 { 2208 {
2306 retn(code); 2311 retn(code);
2307 2312
2308 opts->native_addr_and_sync = code->cur; 2313 opts->native_addr_and_sync = code->cur;
2309 call(code, opts->gen.save_context); 2314 call(code, opts->gen.save_context);
2310 push_r(code, opts->gen.scratch1); 2315 push_r(code, opts->gen.scratch1);
2311 2316
2312 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_D); 2317 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_D);
2313 call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1); 2318 call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1);
2314 pop_r(code, RSI); //restore saved address from opts->gen.scratch1 2319 pop_r(code, RSI); //restore saved address from opts->gen.scratch1
2315 push_r(code, RAX); //save context pointer for later 2320 push_r(code, RAX); //save context pointer for later
2316 call_args(code, (code_ptr)get_native_address_trans, 2, RAX, RSI); 2321 call_args(code, (code_ptr)get_native_address_trans, 2, RAX, RSI);