X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=m68kcpu.c;h=1b1f44fbf724c2c9e5b4ae0c7da811c039460339;hb=514f1d4e24f7e938c0a0d79330f8a6ef5a2eb5fa;hp=da84aed0067dc887330ceae83e1185e279f45a0d;hpb=a48402ce6c111bf22c084e885c30aa6f3f524c72;p=pistorm diff --git a/m68kcpu.c b/m68kcpu.c index da84aed..1b1f44f 100644 --- a/m68kcpu.c +++ b/m68kcpu.c @@ -37,12 +37,11 @@ /* ======================================================================== */ /* ================================ INCLUDES ============================== */ /* ======================================================================== */ - -extern void m68040_fpu_op0(void); -extern void m68040_fpu_op1(void); -extern void m68851_mmu_ops(); +struct m68ki_cpu_core; +extern void m68040_fpu_op0(struct m68ki_cpu_core *state); +extern void m68040_fpu_op1(struct m68ki_cpu_core *state); +extern void m68851_mmu_ops(struct m68ki_cpu_core *state); extern unsigned char m68ki_cycles[][0x10000]; -extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */ extern void m68ki_build_opcode_table(void); #include "m68kops.h" @@ -677,8 +676,9 @@ unsigned int m68k_get_reg(void* context, m68k_register_t regnum) return 0; } -void m68k_set_reg(m68k_register_t regnum, unsigned int value) +void m68k_set_reg(void *context, m68k_register_t regnum, unsigned int value) { + m68ki_cpu_core* state = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu; switch(regnum) { case M68K_REG_D0: REG_D[0] = MASK_OUT_ABOVE_32(value); return; @@ -697,8 +697,10 @@ void m68k_set_reg(m68k_register_t regnum, unsigned int value) case M68K_REG_A5: REG_A[5] = MASK_OUT_ABOVE_32(value); return; case M68K_REG_A6: REG_A[6] = MASK_OUT_ABOVE_32(value); return; case M68K_REG_A7: REG_A[7] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_PC: m68ki_jump(MASK_OUT_ABOVE_32(value)); return; - case M68K_REG_SR: m68ki_set_sr_noint_nosp(value); return; + case M68K_REG_PC: + m68ki_jump(state, MASK_OUT_ABOVE_32(value)); return; + case M68K_REG_SR: + m68ki_set_sr_noint_nosp(state, value); return; case M68K_REG_SP: REG_SP = MASK_OUT_ABOVE_32(value); return; case M68K_REG_USP: if(FLAG_S) REG_USP = MASK_OUT_ABOVE_32(value); @@ -959,7 +961,7 @@ uint m68k_get_address_mask() { /* Execute some instructions until we use up num_cycles clock cycles */ /* ASG: removed per-instruction interrupt checks */ -int m68k_execute(int num_cycles) +int m68k_execute(m68ki_cpu_core *state, int num_cycles) { /* eat up any reset cycles */ if (RESET_CYCLES) { @@ -975,7 +977,7 @@ int m68k_execute(int num_cycles) m68ki_initial_cycles = num_cycles; /* See if interrupts came in */ - m68ki_check_interrupts(); + m68ki_check_interrupts(state); /* Make sure we're not stopped */ if(!CPU_STOPPED) @@ -990,7 +992,7 @@ int m68k_execute(int num_cycles) /* Main loop. Keep going until we run out of clock cycles */ do { - /* Set tracing accodring to T1. (T0 is done inside instruction) */ + /* Set tracing according to T1. (T0 is done inside instruction) */ m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */ /* Set the address space for reads */ @@ -1011,8 +1013,8 @@ int m68k_execute(int num_cycles) #endif /* Read an instruction and call its handler */ - REG_IR = m68ki_read_imm_16(); - m68ki_instruction_jump_table[REG_IR](); + REG_IR = m68ki_read_imm_16(state); + m68ki_instruction_jump_table[REG_IR](state); USE_CYCLES(CYC_INSTRUCTION[REG_IR]); /* Trace m68k_exception, if necessary */ @@ -1116,13 +1118,13 @@ void m68k_init(void) } /* Trigger a Bus Error exception */ -void m68k_pulse_bus_error(void) +void m68k_pulse_bus_error(m68ki_cpu_core *state) { - m68ki_exception_bus_error(); + m68ki_exception_bus_error(state); } /* Pulse the RESET line on the CPU */ -void m68k_pulse_reset(void) +void m68k_pulse_reset(m68ki_cpu_core *state) { /* Disable the PMMU/HMMU on reset, if any */ m68ki_cpu.pmmu_enabled = 0; @@ -1149,7 +1151,7 @@ void m68k_pulse_reset(void) /* Reset VBR */ REG_VBR = 0; /* Go to supervisor mode */ - m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR); + m68ki_set_sm_flag(state, SFLAG_SET | MFLAG_CLEAR); /* Invalidate the prefetch queue */ #if M68K_EMULATE_PREFETCH @@ -1158,22 +1160,22 @@ void m68k_pulse_reset(void) #endif /* M68K_EMULATE_PREFETCH */ /* Read the initial stack pointer and program counter */ - m68ki_jump(0); - REG_SP = m68ki_read_imm_32(); - REG_PC = m68ki_read_imm_32(); - m68ki_jump(REG_PC); + m68ki_jump(state, 0); + REG_SP = m68ki_read_imm_32(state); + REG_PC = m68ki_read_imm_32(state); + m68ki_jump(state, REG_PC); CPU_RUN_MODE = RUN_MODE_NORMAL; RESET_CYCLES = CYC_EXCEPTION[EXCEPTION_RESET]; /* flush the MMU's cache */ - pmmu_atc_flush(); + pmmu_atc_flush(state); if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { // clear instruction cache - m68ki_ic_clear(); + m68ki_ic_clear(state); } } @@ -1203,22 +1205,22 @@ void m68k_set_context(void* src) #if M68K_SEPARATE_READS /* Read data immediately following the PC */ -inline unsigned int m68k_read_immediate_16(unsigned int address) { +inline unsigned int m68k_read_immediate_16(m68ki_cpu_core *state, unsigned int address) { #if M68K_EMULATE_PREFETCH == OPT_ON - for (int i = 0; i < read_ranges; i++) { - if(address >= read_addr[i] && address < read_upper[i]) { - return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]); + for (int i = 0; i < m68ki_cpu.read_ranges; i++) { + if(address >= m68ki_cpu.read_addr[i] && address < m68ki_cpu.read_upper[i]) { + return be16toh(((unsigned short *)(m68ki_cpu.read_data[i] + (address - m68ki_cpu.read_addr[i])))[0]); } } #endif return m68k_read_memory_16(address); } -inline unsigned int m68k_read_immediate_32(unsigned int address) { +inline unsigned int m68k_read_immediate_32(m68ki_cpu_core *state, unsigned int address) { #if M68K_EMULATE_PREFETCH == OPT_ON - for (int i = 0; i < read_ranges; i++) { - if(address >= read_addr[i] && address < read_upper[i]) { - return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]); + for (int i = 0; i < m68ki_cpu.read_ranges; i++) { + if(address >= m68ki_cpu.read_addr[i] && address < m68ki_cpu.read_upper[i]) { + return be32toh(((unsigned int *)(m68ki_cpu.read_data[i] + (address - m68ki_cpu.read_addr[i])))[0]); } } #endif @@ -1227,28 +1229,28 @@ inline unsigned int m68k_read_immediate_32(unsigned int address) { } /* Read data relative to the PC */ -inline unsigned int m68k_read_pcrelative_8(unsigned int address) { - for (int i = 0; i < read_ranges; i++) { - if(address >= read_addr[i] && address < read_upper[i]) { - return read_data[i][address - read_addr[i]]; +inline unsigned int m68k_read_pcrelative_8(m68ki_cpu_core *state, unsigned int address) { + for (int i = 0; i < m68ki_cpu.read_ranges; i++) { + if(address >= m68ki_cpu.read_addr[i] && address < m68ki_cpu.read_upper[i]) { + return m68ki_cpu.read_data[i][address - m68ki_cpu.read_addr[i]]; } } return m68k_read_memory_8(address); } -inline unsigned int m68k_read_pcrelative_16(unsigned int address) { - for (int i = 0; i < read_ranges; i++) { - if(address >= read_addr[i] && address < read_upper[i]) { - return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]); +inline unsigned int m68k_read_pcrelative_16(m68ki_cpu_core *state, unsigned int address) { + for (int i = 0; i < m68ki_cpu.read_ranges; i++) { + if(address >= m68ki_cpu.read_addr[i] && address < m68ki_cpu.read_upper[i]) { + return be16toh(((unsigned short *)(m68ki_cpu.read_data[i] + (address - m68ki_cpu.read_addr[i])))[0]); } } return m68k_read_memory_16(address); } -inline unsigned int m68k_read_pcrelative_32(unsigned int address) { - for (int i = 0; i < read_ranges; i++) { - if(address >= read_addr[i] && address < read_upper[i]) { - return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]); +inline unsigned int m68k_read_pcrelative_32(m68ki_cpu_core *state, unsigned int address) { + for (int i = 0; i < m68ki_cpu.read_ranges; i++) { + if(address >= m68ki_cpu.read_addr[i] && address < m68ki_cpu.read_upper[i]) { + return be32toh(((unsigned int *)(m68ki_cpu.read_data[i] + (address - m68ki_cpu.read_addr[i])))[0]); } } @@ -1257,17 +1259,17 @@ inline unsigned int m68k_read_pcrelative_32(unsigned int address) { #endif -uint m68ki_read_imm6_addr_slowpath(uint32_t pc, address_translation_cache *cache) +uint m68ki_read_imm16_addr_slowpath(m68ki_cpu_core *state, uint32_t pc, address_translation_cache *cache) { uint32_t address = ADDRESS_68K(pc); uint32_t pc_address_diff = pc - address; - for (int i = 0; i < read_ranges; i++) { - if(address >= read_addr[i] && address < read_upper[i]) { - cache->lower = read_addr[i] + pc_address_diff; - cache->upper = read_upper[i] + pc_address_diff; - cache->data = read_data[i]; + for (int i = 0; i < m68ki_cpu.read_ranges; i++) { + if(address >= m68ki_cpu.read_addr[i] && address < m68ki_cpu.read_upper[i]) { + cache->lower = m68ki_cpu.read_addr[i] + pc_address_diff; + cache->upper = m68ki_cpu.read_upper[i] + pc_address_diff; + cache->offset = m68ki_cpu.read_data[i] - cache->lower; REG_PC += 2; - return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]); + return be16toh(((unsigned short *)(m68ki_cpu.read_data[i] + (address - m68ki_cpu.read_addr[i])))[0]); } } @@ -1282,14 +1284,14 @@ uint m68ki_read_imm6_addr_slowpath(uint32_t pc, address_translation_cache *cache uint result; if(REG_PC != CPU_PREF_ADDR) { - CPU_PREF_DATA = m68ki_ic_readimm16(REG_PC); + CPU_PREF_DATA = m68ki_ic_readimm16(state, REG_PC); CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC; } result = MASK_OUT_ABOVE_16(CPU_PREF_DATA); REG_PC += 2; if (!m68ki_cpu.mmu_tmp_buserror_occurred) { // prefetch only if no bus error occurred in opcode fetch - CPU_PREF_DATA = m68ki_ic_readimm16(REG_PC); + CPU_PREF_DATA = m68ki_ic_readimm16(state, REG_PC); CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC; // ignore bus error on prefetch m68ki_cpu.mmu_tmp_buserror_occurred = 0; @@ -1307,45 +1309,45 @@ uint m68ki_read_imm6_addr_slowpath(uint32_t pc, address_translation_cache *cache void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr) { - code_translation_cache.lower = 0; - code_translation_cache.upper = 0; + m68ki_cpu.code_translation_cache.lower = 0; + m68ki_cpu.code_translation_cache.upper = 0; if ((addr == 0 && upper == 0) || upper < addr) return; - for (int i = 0; i < write_ranges; i++) { - if (write_addr[i] == addr) { + for (int i = 0; i < m68ki_cpu.write_ranges; i++) { + if (m68ki_cpu.write_addr[i] == addr) { uint8_t changed = 0; - if (write_upper[i] != upper) { - write_upper[i] = upper; + if (m68ki_cpu.write_upper[i] != upper) { + m68ki_cpu.write_upper[i] = upper; changed = 1; } - if (write_data[i] != ptr) { - write_data[i] = ptr; + if (m68ki_cpu.write_data[i] != ptr) { + m68ki_cpu.write_data[i] = ptr; changed = 1; } if (changed) { - printf("[MUSASHI] Adjusted mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr); + printf("[MUSASHI] Adjusted mapped write range %d: %.8X-%.8X (%p)\n", m68ki_cpu.write_ranges, addr, upper, ptr); } return; } } - if (read_ranges + 1 < 8) { - read_addr[read_ranges] = addr; - read_upper[read_ranges] = upper; - read_data[read_ranges] = ptr; - read_ranges++; - printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr); + if (m68ki_cpu.read_ranges + 1 < 8) { + m68ki_cpu.read_addr[m68ki_cpu.read_ranges] = addr; + m68ki_cpu.read_upper[m68ki_cpu.read_ranges] = upper; + m68ki_cpu.read_data[m68ki_cpu.read_ranges] = ptr; + m68ki_cpu.read_ranges++; + printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", m68ki_cpu.read_ranges, addr, upper, ptr); } else { printf("Can't Musashi map more than eight RAM/ROM read ranges.\n"); } - if (write_ranges + 1 < 8) { - write_addr[write_ranges] = addr; - write_upper[write_ranges] = upper; - write_data[write_ranges] = ptr; - write_ranges++; - printf("[MUSASHI] Mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr); + if (m68ki_cpu.write_ranges + 1 < 8) { + m68ki_cpu.write_addr[m68ki_cpu.write_ranges] = addr; + m68ki_cpu.write_upper[m68ki_cpu.write_ranges] = upper; + m68ki_cpu.write_data[m68ki_cpu.write_ranges] = ptr; + m68ki_cpu.write_ranges++; + printf("[MUSASHI] Mapped write range %d: %.8X-%.8X (%p)\n", m68ki_cpu.write_ranges, addr, upper, ptr); } else { printf("Can't Musashi map more than eight RAM write ranges.\n"); @@ -1354,35 +1356,35 @@ void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr) void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr) { - code_translation_cache.lower = 0; - code_translation_cache.upper = 0; + m68ki_cpu.code_translation_cache.lower = 0; + m68ki_cpu.code_translation_cache.upper = 0; if ((addr == 0 && upper == 0) || upper < addr) return; - for (int i = 0; i < read_ranges; i++) { - if (read_addr[i] == addr) { + for (int i = 0; i < m68ki_cpu.read_ranges; i++) { + if (m68ki_cpu.read_addr[i] == addr) { uint8_t changed = 0; - if (read_upper[i] != upper) { - read_upper[i] = upper; + if (m68ki_cpu.read_upper[i] != upper) { + m68ki_cpu.read_upper[i] = upper; changed = 1; } - if (read_data[i] != ptr) { - read_data[i] = ptr; + if (m68ki_cpu.read_data[i] != ptr) { + m68ki_cpu.read_data[i] = ptr; changed = 1; } if (changed) { - printf("[MUSASHI] Adjusted mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr); + printf("[MUSASHI] Adjusted mapped read range %d: %.8X-%.8X (%p)\n", m68ki_cpu.read_ranges, addr, upper, ptr); } return; } } - if (read_ranges + 1 < 8) { - read_addr[read_ranges] = addr; - read_upper[read_ranges] = upper; - read_data[read_ranges] = ptr; - read_ranges++; - printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr); + if (m68ki_cpu.read_ranges + 1 < 8) { + m68ki_cpu.read_addr[m68ki_cpu.read_ranges] = addr; + m68ki_cpu.read_upper[m68ki_cpu.read_ranges] = upper; + m68ki_cpu.read_data[m68ki_cpu.read_ranges] = ptr; + m68ki_cpu.read_ranges++; + printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", m68ki_cpu.read_ranges, addr, upper, ptr); } else { printf("Can't Musashi map more than eight RAM/ROM read ranges.\n"); @@ -1393,15 +1395,17 @@ void m68k_clear_ranges() { printf("[MUSASHI] Clearing all reads/write memory ranges.\n"); for (int i = 0; i < 8; i++) { - read_upper[i] = 0; - read_addr[i] = 0; - read_data[i] = NULL; - write_upper[i] = 0; - write_addr[i] = 0; - write_data[i] = NULL; + m68ki_cpu.read_upper[i] = 0; + m68ki_cpu.read_addr[i] = 0; + m68ki_cpu.read_data[i] = NULL; + m68ki_cpu.write_upper[i] = 0; + m68ki_cpu.write_addr[i] = 0; + m68ki_cpu.write_data[i] = NULL; } - write_ranges = 0; - read_ranges = 0; + m68ki_cpu.write_ranges = 0; + m68ki_cpu.read_ranges = 0; + m68ki_cpu.code_translation_cache.lower = 0; + m68ki_cpu.code_translation_cache.upper = 0; } /* ======================================================================== */