]> git.sesse.net Git - pistorm/blobdiff - m68kcpu.c
Add Meson build files.
[pistorm] / m68kcpu.c
index 49c65a0c5ed0dd0e48f05c0755741cff700bf204..5b494ad58d8c913563e441d322a0e4eac4ac0eb9 100644 (file)
--- a/m68kcpu.c
+++ b/m68kcpu.c
@@ -676,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;
@@ -696,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);
@@ -721,7 +724,8 @@ void m68k_set_reg(m68k_register_t regnum, unsigned int value)
                case M68K_REG_CAAR:     REG_CAAR = MASK_OUT_ABOVE_32(value); return;
                case M68K_REG_PPC:      REG_PPC = MASK_OUT_ABOVE_32(value); return;
                case M68K_REG_IR:       REG_IR = MASK_OUT_ABOVE_16(value); return;
-               case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return;
+               case M68K_REG_CPU_TYPE:
+                       m68k_set_cpu_type(state, value); return;
                default:                        return;
        }
 }
@@ -778,7 +782,7 @@ void m68k_set_instr_hook_callback(void  (*callback)(unsigned int pc))
 }
 
 /* Set the CPU type. */
-void m68k_set_cpu_type(unsigned int cpu_type)
+void m68k_set_cpu_type(struct m68ki_cpu_core *state, unsigned int cpu_type)
 {
        switch(cpu_type)
        {
@@ -801,7 +805,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
                        HAS_FPU          = 0;
                        return;
                case M68K_CPU_TYPE_SCC68070:
-                       m68k_set_cpu_type(M68K_CPU_TYPE_68010);
+                       m68k_set_cpu_type(state, M68K_CPU_TYPE_68010);
                        CPU_ADDRESS_MASK = 0xffffffff;
                        CPU_TYPE         = CPU_TYPE_SCC070;
                        return;
@@ -934,26 +938,26 @@ void m68k_set_cpu_type(unsigned int cpu_type)
                case M68K_CPU_TYPE_68LC040:
                        CPU_TYPE         = CPU_TYPE_LC040;
                        CPU_ADDRESS_MASK = 0xffffffff;
-                       m68ki_cpu.sr_mask          = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
-                       m68ki_cpu.cyc_instruction  = m68ki_cycles[4];
-                       m68ki_cpu.cyc_exception    = m68ki_exception_cycle_table[4];
-                       m68ki_cpu.cyc_bcc_notake_b = -2;
-                       m68ki_cpu.cyc_bcc_notake_w = 0;
-                       m68ki_cpu.cyc_dbcc_f_noexp = 0;
-                       m68ki_cpu.cyc_dbcc_f_exp   = 4;
-                       m68ki_cpu.cyc_scc_r_true   = 0;
-                       m68ki_cpu.cyc_movem_w      = 2;
-                       m68ki_cpu.cyc_movem_l      = 2;
-                       m68ki_cpu.cyc_shift        = 0;
-                       m68ki_cpu.cyc_reset        = 518;
+                       state->sr_mask          = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
+                       state->cyc_instruction  = m68ki_cycles[4];
+                       state->cyc_exception    = m68ki_exception_cycle_table[4];
+                       state->cyc_bcc_notake_b = -2;
+                       state->cyc_bcc_notake_w = 0;
+                       state->cyc_dbcc_f_noexp = 0;
+                       state->cyc_dbcc_f_exp   = 4;
+                       state->cyc_scc_r_true   = 0;
+                       state->cyc_movem_w      = 2;
+                       state->cyc_movem_l      = 2;
+                       state->cyc_shift        = 0;
+                       state->cyc_reset        = 518;
                        HAS_PMMU         = 1;
                        HAS_FPU          = 0;
                        return;
        }
 }
 
-uint m68k_get_address_mask() {
-       return m68ki_cpu.address_mask;
+uint m68k_get_address_mask(m68ki_cpu_core *state) {
+       return state->address_mask;
 }
 
 /* Execute some instructions until we use up num_cycles clock cycles */
@@ -980,7 +984,7 @@ int m68k_execute(m68ki_cpu_core *state, int num_cycles)
        if(!CPU_STOPPED)
        {
                /* Return point if we had an address error */
-               m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
+               m68ki_set_address_error_trap(state); /* auto-disable (see m68kcpu.h) */
 
 #ifdef M68K_BUSERR_THING
                m68ki_check_bus_error_trap();
@@ -1124,12 +1128,12 @@ void m68k_pulse_bus_error(m68ki_cpu_core *state)
 void m68k_pulse_reset(m68ki_cpu_core *state)
 {
        /* Disable the PMMU/HMMU on reset, if any */
-       m68ki_cpu.pmmu_enabled = 0;
-//     m68ki_cpu.hmmu_enabled = 0;
+       state->pmmu_enabled = 0;
+//     state->hmmu_enabled = 0;
 
-       m68ki_cpu.mmu_tc = 0;
-       m68ki_cpu.mmu_tt0 = 0;
-       m68ki_cpu.mmu_tt1 = 0;
+       state->mmu_tc = 0;
+       state->mmu_tt0 = 0;
+       state->mmu_tt1 = 0;
 
        /* Clear all stop levels and eat up all remaining cycles */
        CPU_STOPPED = 0;
@@ -1144,11 +1148,11 @@ void m68k_pulse_reset(m68ki_cpu_core *state)
        /* Interrupt mask to level 7 */
        FLAG_INT_MASK = 0x0700;
        CPU_INT_LEVEL = 0;
-       m68ki_cpu.virq_state = 0;
+       state->virq_state = 0;
        /* 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
@@ -1157,10 +1161,10 @@ void m68k_pulse_reset(m68ki_cpu_core *state)
 #endif /* M68K_EMULATE_PREFETCH */
 
        /* Read the initial stack pointer and program counter */
-       m68ki_jump(0);
+       m68ki_jump(state, 0);
        REG_SP = m68ki_read_imm_32(state);
        REG_PC = m68ki_read_imm_32(state);
-       m68ki_jump(REG_PC);
+       m68ki_jump(state, REG_PC);
 
        CPU_RUN_MODE = RUN_MODE_NORMAL;
 
@@ -1204,9 +1208,9 @@ void m68k_set_context(void* src)
 /* Read data immediately following the PC */
 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 < 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]);
+       for (int i = 0; i < state->read_ranges; i++) {
+               if(address >= state->read_addr[i] && address < state->read_upper[i]) {
+                       return be16toh(((unsigned short *)(state->read_data[i] + (address - state->read_addr[i])))[0]);
                }
        }
 #endif
@@ -1215,9 +1219,9 @@ inline unsigned int m68k_read_immediate_16(m68ki_cpu_core *state, unsigned int a
 }
 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 < 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]);
+       for (int i = 0; i < state->read_ranges; i++) {
+               if(address >= state->read_addr[i] && address < state->read_upper[i]) {
+                       return be32toh(((unsigned int *)(state->read_data[i] + (address - state->read_addr[i])))[0]);
                }
        }
 #endif
@@ -1227,27 +1231,27 @@ inline unsigned int m68k_read_immediate_32(m68ki_cpu_core *state, unsigned int a
 
 /* Read data relative to the PC */
 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]];
+       for (int i = 0; i < state->read_ranges; i++) {
+               if(address >= state->read_addr[i] && address < state->read_upper[i]) {
+                       return state->read_data[i][address - state->read_addr[i]];
                }
        }
 
        return m68k_read_memory_8(address);
 }
 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]);
+       for (int i = 0; i < state->read_ranges; i++) {
+               if(address >= state->read_addr[i] && address < state->read_upper[i]) {
+                       return be16toh(((unsigned short *)(state->read_data[i] + (address - state->read_addr[i])))[0]);
                }
        }
 
        return m68k_read_memory_16(address);
 }
 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]);
+       for (int i = 0; i < state->read_ranges; i++) {
+               if(address >= state->read_addr[i] && address < state->read_upper[i]) {
+                       return be32toh(((unsigned int *)(state->read_data[i] + (address - state->read_addr[i])))[0]);
                }
        }
 
@@ -1260,21 +1264,21 @@ uint m68ki_read_imm16_addr_slowpath(m68ki_cpu_core *state, uint32_t pc, address_
 {
     uint32_t address = ADDRESS_68K(pc);
     uint32_t pc_address_diff = pc - address;
-       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;
+       for (int i = 0; i < state->read_ranges; i++) {
+               if(address >= state->read_addr[i] && address < state->read_upper[i]) {
+                       cache->lower = state->read_addr[i] + pc_address_diff;
+                       cache->upper = state->read_upper[i] + pc_address_diff;
+                       cache->offset = state->read_data[i] - cache->lower;
                        REG_PC += 2;
-                       return be16toh(((unsigned short *)(m68ki_cpu.read_data[i] + (address - m68ki_cpu.read_addr[i])))[0]);
+                       return be16toh(((unsigned short *)(state->read_data[i] + (address - state->read_addr[i])))[0]);
                }
        }
 
        m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
-       m68ki_cpu.mmu_tmp_fc = FLAG_S | FUNCTION_CODE_USER_PROGRAM;
-       m68ki_cpu.mmu_tmp_rw = 1;
-       m68ki_cpu.mmu_tmp_sz = M68K_SZ_WORD;
-       m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
+       state->mmu_tmp_fc = FLAG_S | FUNCTION_CODE_USER_PROGRAM;
+       state->mmu_tmp_rw = 1;
+       state->mmu_tmp_sz = M68K_SZ_WORD;
+       m68ki_check_address_error(state, REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
 
 #if M68K_EMULATE_PREFETCH
 {
@@ -1282,16 +1286,16 @@ uint m68ki_read_imm16_addr_slowpath(m68ki_cpu_core *state, uint32_t pc, address_
        if(REG_PC != CPU_PREF_ADDR)
        {
                CPU_PREF_DATA = m68ki_ic_readimm16(state, REG_PC);
-               CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
+               CPU_PREF_ADDR = state->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) {
+       if (!state->mmu_tmp_buserror_occurred) {
                // prefetch only if no bus error occurred in opcode fetch
                CPU_PREF_DATA = m68ki_ic_readimm16(state, REG_PC);
-               CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
+               CPU_PREF_ADDR = state->mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
                // ignore bus error on prefetch
-               m68ki_cpu.mmu_tmp_buserror_occurred = 0;
+               state->mmu_tmp_buserror_occurred = 0;
        }
        return result;
 }
@@ -1312,8 +1316,12 @@ void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
                return;
 
        for (int i = 0; i < m68ki_cpu.write_ranges; i++) {
-               if (m68ki_cpu.write_addr[i] == addr) {
+               if (m68ki_cpu.write_addr[i] == addr || m68ki_cpu.write_data[i] == ptr) {
                        uint8_t changed = 0;
+                       if (m68ki_cpu.write_addr[i] != addr) {
+                               m68ki_cpu.write_addr[i] = addr;
+                               changed = 1;
+                       }
                        if (m68ki_cpu.write_upper[i] != upper) {
                                m68ki_cpu.write_upper[i] = upper;
                                changed = 1;
@@ -1359,8 +1367,12 @@ void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
                return;
 
        for (int i = 0; i < m68ki_cpu.read_ranges; i++) {
-               if (m68ki_cpu.read_addr[i] == addr) {
+               if (m68ki_cpu.read_addr[i] == addr  || m68ki_cpu.read_data[i] == ptr) {
                        uint8_t changed = 0;
+                       if (m68ki_cpu.read_addr[i] != addr) {
+                               m68ki_cpu.read_addr[i] = addr;
+                               changed = 1;
+                       }
                        if (m68ki_cpu.read_upper[i] != upper) {
                                m68ki_cpu.read_upper[i] = upper;
                                changed = 1;
@@ -1388,6 +1400,49 @@ void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
        }
 }
 
+void m68k_remove_range(unsigned char *ptr) {
+       if (!ptr) {
+               return;
+       }
+
+       m68ki_cpu.code_translation_cache.lower = 0;
+       m68ki_cpu.code_translation_cache.upper = 0;
+
+       // FIXME: Replace the 8 with a #define, such as MAX_MUSASHI_RANGES
+       for (int i = 0; i < 8; i++) {
+               if (m68ki_cpu.read_data[i] == ptr) {
+                       m68ki_cpu.read_data[i] = NULL;
+                       m68ki_cpu.read_addr[i] = 0;
+                       m68ki_cpu.read_upper[i] = 0;
+                       printf("[MUSASHI] Unmapped read range %d.\n", i);
+                       for (int j = i; j < 8 - 1; j++) {
+                               m68ki_cpu.read_data[j] = m68ki_cpu.read_data[j + 1];
+                               m68ki_cpu.read_addr[j] = m68ki_cpu.read_addr[j + 1];
+                               m68ki_cpu.read_upper[j] = m68ki_cpu.read_upper[j + 1];
+                       }
+                       m68ki_cpu.read_data[8 - 1] = NULL;
+                       m68ki_cpu.read_addr[8 - 1] = 0;
+                       m68ki_cpu.read_upper[8 - 1] = 0;
+                       m68ki_cpu.read_ranges--;
+               }
+               if (m68ki_cpu.write_data[i] == ptr) {
+                       m68ki_cpu.write_data[i] = NULL;
+                       m68ki_cpu.write_addr[i] = 0;
+                       m68ki_cpu.write_upper[i] = 0;
+                       printf("[MUSASHI] Unmapped write range %d.\n", i);
+                       for (int j = i; j < 8 - 1; j++) {
+                               m68ki_cpu.write_data[j] = m68ki_cpu.write_data[j + 1];
+                               m68ki_cpu.write_addr[j] = m68ki_cpu.write_addr[j + 1];
+                               m68ki_cpu.write_upper[j] = m68ki_cpu.write_upper[j + 1];
+                       }
+                       m68ki_cpu.write_data[8 - 1] = NULL;
+                       m68ki_cpu.write_addr[8 - 1] = 0;
+                       m68ki_cpu.write_upper[8 - 1] = 0;
+                       m68ki_cpu.write_ranges--;
+               }
+       }
+}
+
 void m68k_clear_ranges()
 {
        printf("[MUSASHI] Clearing all reads/write memory ranges.\n");