From cfe88ce0d79d2d6d58799cfc20edd85ebc0ed02c Mon Sep 17 00:00:00 2001 From: rogerman Date: Tue, 31 Aug 2021 10:23:04 -0700 Subject: [PATCH] Core: Silence the 1000+ compiler warnings about using offsetof() on a non-POD type... again. --- desmume/src/NDSSystem.cpp | 26 +- desmume/src/arm_instructions.cpp | 64 ++--- desmume/src/arm_jit.cpp | 4 +- desmume/src/armcpu.cpp | 74 +++--- desmume/src/armcpu.h | 42 +-- desmume/src/cp15.cpp | 397 ++++++++++++++++------------- desmume/src/cp15.h | 67 ++--- desmume/src/debug.cpp | 4 +- desmume/src/saves.cpp | 8 +- desmume/src/thumb_instructions.cpp | 6 +- 10 files changed, 350 insertions(+), 342 deletions(-) diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 1d64f72af..36224a1f5 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2008-2019 DeSmuME team + Copyright (C) 2008-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -176,14 +176,14 @@ int NDS_Init() } armcpu_new(&NDS_ARM9,0); - NDS_ARM9.SetBaseMemoryInterface(&arm9_base_memory_iface); - NDS_ARM9.SetBaseMemoryInterfaceData(NULL); - NDS_ARM9.ResetMemoryInterfaceToBase(); + armcpu_SetBaseMemoryInterface(&NDS_ARM9, &arm9_base_memory_iface); + armcpu_SetBaseMemoryInterfaceData(&NDS_ARM9, NULL); + armcpu_ResetMemoryInterfaceToBase(&NDS_ARM9); armcpu_new(&NDS_ARM7,1); - NDS_ARM7.SetBaseMemoryInterface(&arm7_base_memory_iface); - NDS_ARM7.SetBaseMemoryInterfaceData(NULL); - NDS_ARM7.ResetMemoryInterfaceToBase(); + armcpu_SetBaseMemoryInterface(&NDS_ARM7, &arm7_base_memory_iface); + armcpu_SetBaseMemoryInterfaceData(&NDS_ARM7, NULL); + armcpu_ResetMemoryInterfaceToBase(&NDS_ARM7); delete GPU; GPU = new GPUSubsystem; @@ -1921,8 +1921,9 @@ static /*donotinline*/ std::pair armInnerLoop( { // breakpoint handling #if defined(HOST_WINDOWS) && !defined(TARGET_INTERFACE) - for (int i = 0; i < NDS_ARM9.breakPoints.size(); ++i) { - if (NDS_ARM9.instruct_adr == NDS_ARM9.breakPoints[i] && !NDS_ARM9.debugStep) { + const std::vector *breakpointList9 = NDS_ARM9.breakPoints; + for (int i = 0; i < breakpointList9->size(); ++i) { + if (NDS_ARM9.instruct_adr == (*breakpointList9)[i] && !NDS_ARM9.debugStep) { emu_paused = true; paused = true; execute = false; @@ -1932,8 +1933,9 @@ static /*donotinline*/ std::pair armInnerLoop( return std::make_pair(arm9, arm7); } } - for (int i = 0; i < NDS_ARM7.breakPoints.size(); ++i) { - if (NDS_ARM7.instruct_adr == NDS_ARM7.breakPoints[i] && !NDS_ARM7.debugStep) { + const std::vector *breakpointList7 = NDS_ARM7.breakPoints; + for (int i = 0; i < breakpointList7->size(); ++i) { + if (NDS_ARM7.instruct_adr == (*breakpointList7)[i] && !NDS_ARM7.debugStep) { emu_paused = true; paused = true; execute = false; @@ -2717,7 +2719,7 @@ void NDS_Reset() //initialize CP15 specially for this platform //TODO - how much of this is necessary for firmware boot? //(only ARM9 has CP15) - reconstruct(&cp15); + armcp15_init(&cp15); MMU.ARM9_RW_MODE = BIT7(cp15.ctrl); NDS_ARM9.intVector = 0xFFFF0000 * (BIT13(cp15.ctrl)); NDS_ARM9.LDTBit = !BIT15(cp15.ctrl); //TBit diff --git a/desmume/src/arm_instructions.cpp b/desmume/src/arm_instructions.cpp index dbac8c2e7..fd2634fc6 100644 --- a/desmume/src/arm_instructions.cpp +++ b/desmume/src/arm_instructions.cpp @@ -1,7 +1,7 @@ -/* +/* Copyright (C) 2006 yopyop Copyright (C) 2006-2007 shash - Copyright (C) 2008-2016 DeSmuME team + Copyright (C) 2008-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -279,7 +279,7 @@ TEMPLATE static u32 FASTCALL OP_UND(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -418,7 +418,7 @@ TEMPLATE static u32 FASTCALL OP_AND_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -557,7 +557,7 @@ TEMPLATE static u32 FASTCALL OP_EOR_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -706,7 +706,7 @@ TEMPLATE static u32 FASTCALL OP_SUB_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -855,7 +855,7 @@ TEMPLATE static u32 FASTCALL OP_RSB_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1004,7 +1004,7 @@ TEMPLATE static u32 FASTCALL OP_ADD_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1164,7 +1164,7 @@ TEMPLATE static u32 FASTCALL OP_ADC_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1324,7 +1324,7 @@ TEMPLATE static u32 FASTCALL OP_SBC_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1754,7 +1754,7 @@ TEMPLATE static u32 FASTCALL OP_CMN_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1894,7 +1894,7 @@ TEMPLATE static u32 FASTCALL OP_ORR_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -2040,7 +2040,7 @@ TEMPLATE static u32 FASTCALL OP_MOV_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -2179,7 +2179,7 @@ TEMPLATE static u32 FASTCALL OP_BIC_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ - cpu->changeCPSR(); \ + armcpu_changeCPSR(); \ cpu->R[15] &= (0xFFFFFFFC|(((u32)cpu->CPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -2990,7 +2990,7 @@ TEMPLATE static u32 FASTCALL OP_MRS_SPSR(const u32 i) if(cpu->CPSR.bits.mode != USR && BIT16(i)) \ { armcpu_switchMode(cpu, operand & 0x1F); } \ cpu->CPSR.val = (cpu->CPSR.val & ~byte_mask) | (operand & byte_mask); \ - cpu->changeCPSR(); + armcpu_changeCPSR(); #define OP_MSR_SPSR_(operand) \ if(cpu->CPSR.bits.mode == USR || cpu->CPSR.bits.mode == SYS) return 1; \ @@ -2999,7 +2999,7 @@ TEMPLATE static u32 FASTCALL OP_MRS_SPSR(const u32 i) (BIT18(i)?0x00FF0000:0x00000000) | \ (BIT19(i)?0xFF000000:0x00000000); \ cpu->SPSR.val = (cpu->SPSR.val & ~byte_mask) | (operand & byte_mask); \ - cpu->changeCPSR(); + armcpu_changeCPSR(); //#define __NEW_MSR #ifdef __NEW_MSR @@ -5177,7 +5177,7 @@ TEMPLATE static u32 FASTCALL OP_LDMIA2(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); //start += 4; cpu->next_instruction = cpu->R[15]; c += MMU_memAccessCycles(start); @@ -5239,7 +5239,7 @@ TEMPLATE static u32 FASTCALL OP_LDMIB2(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->next_instruction = registres[15]; c += MMU_memAccessCycles(start); @@ -5276,7 +5276,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2(const u32 i) u32 tmp = READ32(cpu->mem_if->data, start); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); c += MMU_memAccessCycles(start); start -= 4; cpu->next_instruction = registres[15]; @@ -5313,7 +5313,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2(const u32 i) Status_Reg SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); } return MMU_aluMemCycles(2, c); @@ -5341,7 +5341,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2(const u32 i) tmp = READ32(cpu->mem_if->data, start); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->next_instruction = registres[15]; c += MMU_memAccessCycles(start); @@ -5377,7 +5377,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2(const u32 i) Status_Reg SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); } return MMU_aluMemCycles(2, c); @@ -5432,7 +5432,7 @@ TEMPLATE static u32 FASTCALL OP_LDMIA2_W(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->next_instruction = registres[15]; c += MMU_memAccessCycles(start); @@ -5487,12 +5487,12 @@ TEMPLATE static u32 FASTCALL OP_LDMIB2_W(const u32 i) tmp = READ32(cpu->mem_if->data, start + 4); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->next_instruction = registres[15]; SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); c += MMU_memAccessCycles(start); return MMU_aluMemCycles(2, c); @@ -5553,7 +5553,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2_W(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); return MMU_aluMemCycles(2, c); } @@ -5583,7 +5583,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2_W(const u32 i) c += MMU_memAccessCycles(start); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->next_instruction = registres[15]; } @@ -5615,7 +5615,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2_W(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->changeCPSR(); + armcpu_changeCPSR(); return MMU_aluMemCycles(2, c); } @@ -6207,7 +6207,7 @@ TEMPLATE static u32 FASTCALL OP_MCR(const u32 i) return 2; } - cp15.moveARM2CP(cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&0x7, (i>>5)&0x7); + armcp15_moveARM2CP(&cp15, cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&0x7, (i>>5)&0x7); return 2; } @@ -6238,7 +6238,7 @@ TEMPLATE static u32 FASTCALL OP_MRC(const u32 i) // Rd = data u32 data = 0; - cp15.moveCP2ARM(&data, REG_POS(i, 16), REG_POS(i, 0), (i>>21)&0x7, (i>>5)&0x7); + armcp15_moveCP2ARM(&cp15, &data, REG_POS(i, 16), REG_POS(i, 0), (i>>21)&0x7, (i>>5)&0x7); if (REG_POS(i, 12) == 15) { cpu->CPSR.bits.N = BIT31(data); @@ -6292,7 +6292,7 @@ TEMPLATE static u32 FASTCALL OP_SWI(const u32 i) cpu->SPSR = tmp; /* save old CPSR as new SPSR */ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ cpu->CPSR.bits.I = 1; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->R[15] = cpu->intVector + 0x08; cpu->next_instruction = cpu->R[15]; return 3; @@ -6339,7 +6339,7 @@ TEMPLATE static u32 FASTCALL OP_BKPT(const u32 i) cpu->SPSR = tmp; // save old CPSR as new SPSR cpu->CPSR.bits.T = 0; // handle as ARM32 code cpu->CPSR.bits.I = 1; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->R[15] = cpu->intVector + 0x0C; cpu->next_instruction = cpu->R[15]; return 4; diff --git a/desmume/src/arm_jit.cpp b/desmume/src/arm_jit.cpp index e7b1151d6..e4272dbd3 100644 --- a/desmume/src/arm_jit.cpp +++ b/desmume/src/arm_jit.cpp @@ -2513,7 +2513,7 @@ static void maskPrecalc(u32 _num) mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \ } \ } \ - cp15.setSingleRegionAccess(num, mask, set) ; \ + armcp15_setSingleRegionAccess(&cp15, num, mask, set) ; \ } switch(_num) { @@ -2686,7 +2686,7 @@ static int OP_MCR(const u32 i) bUnknown = true; break; case 9: - if((opcode1==0)) + if(opcode1==0) { switch(CRm) { diff --git a/desmume/src/armcpu.cpp b/desmume/src/armcpu.cpp index b3182045a..66bf9c7c3 100644 --- a/desmume/src/armcpu.cpp +++ b/desmume/src/armcpu.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2009-2017 DeSmuME team + Copyright (C) 2009-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -138,90 +138,92 @@ int armcpu_new( armcpu_t *armcpu, u32 id) armcpu->base_mem_if.write32 = NULL; armcpu->base_mem_if.data = NULL; - armcpu->SetControlInterface(&arm_default_ctrl_iface); - armcpu->SetControlInterfaceData(armcpu); - armcpu->SetCurrentMemoryInterface(NULL); - armcpu->SetCurrentMemoryInterfaceData(NULL); + armcpu_SetControlInterface(armcpu, &arm_default_ctrl_iface); + armcpu_SetControlInterfaceData(armcpu, armcpu); + armcpu_SetCurrentMemoryInterface(armcpu, NULL); + armcpu_SetCurrentMemoryInterfaceData(armcpu, NULL); armcpu->post_ex_fn = NULL; armcpu->post_ex_fn_data = NULL; + armcpu->breakPoints = new std::vector; + armcpu_init(armcpu, 0); return 0; } -void armcpu_t::SetControlInterface(const armcpu_ctrl_iface *theControlInterface) +void armcpu_SetControlInterface(armcpu_t *armcpu, const armcpu_ctrl_iface *theControlInterface) { - this->ctrl_iface = *theControlInterface; + armcpu->ctrl_iface = *theControlInterface; } -armcpu_ctrl_iface* armcpu_t::GetControlInterface() +armcpu_ctrl_iface* armcpu_GetControlInterface(armcpu_t *armcpu) { - return &this->ctrl_iface; + return &armcpu->ctrl_iface; } -void armcpu_t::SetControlInterfaceData(void *theData) +void armcpu_SetControlInterfaceData(armcpu_t *armcpu, void *theData) { - this->ctrl_iface.data = theData; + armcpu->ctrl_iface.data = theData; } -void* armcpu_t::GetControlInterfaceData() +void* armcpu_GetControlInterfaceData(const armcpu_t *armcpu) { - return this->ctrl_iface.data; + return armcpu->ctrl_iface.data; } -void armcpu_t::SetCurrentMemoryInterface(armcpu_memory_iface *theMemoryInterface) +void armcpu_SetCurrentMemoryInterface(armcpu_t *armcpu, armcpu_memory_iface *theMemoryInterface) { - this->mem_if = theMemoryInterface; + armcpu->mem_if = theMemoryInterface; } -armcpu_memory_iface* armcpu_t::GetCurrentMemoryInterface() +armcpu_memory_iface* armcpu_GetCurrentMemoryInterface(const armcpu_t *armcpu) { - return this->mem_if; + return armcpu->mem_if; } -void armcpu_t::SetCurrentMemoryInterfaceData(void *theData) +void armcpu_SetCurrentMemoryInterfaceData(armcpu_t *armcpu, void *theData) { - if (this->mem_if != NULL) + if (armcpu->mem_if != NULL) { - this->mem_if->data = theData; + armcpu->mem_if->data = theData; } } -void* armcpu_t::GetCurrentMemoryInterfaceData() +void* armcpu_GetCurrentMemoryInterfaceData(const armcpu_t *armcpu) { - return (this->mem_if != NULL) ? this->mem_if->data : NULL; + return (armcpu->mem_if != NULL) ? armcpu->mem_if->data : NULL; } -void armcpu_t::SetBaseMemoryInterface(const armcpu_memory_iface *theMemInterface) +void armcpu_SetBaseMemoryInterface(armcpu_t *armcpu, const armcpu_memory_iface *theMemInterface) { - this->base_mem_if = *theMemInterface; + armcpu->base_mem_if = *theMemInterface; } -armcpu_memory_iface* armcpu_t::GetBaseMemoryInterface() +armcpu_memory_iface* armcpu_GetBaseMemoryInterface(armcpu_t *armcpu) { - return &this->base_mem_if; + return &armcpu->base_mem_if; } -void armcpu_t::SetBaseMemoryInterfaceData(void *theData) +void armcpu_SetBaseMemoryInterfaceData(armcpu_t *armcpu, void *theData) { - this->base_mem_if.data = theData; + armcpu->base_mem_if.data = theData; } -void* armcpu_t::GetBaseMemoryInterfaceData() +void* armcpu_GetBaseMemoryInterfaceData(const armcpu_t *armcpu) { - return this->base_mem_if.data; + return armcpu->base_mem_if.data; } -void armcpu_t::ResetMemoryInterfaceToBase() +void armcpu_ResetMemoryInterfaceToBase(armcpu_t *armcpu) { - this->SetCurrentMemoryInterface(this->GetBaseMemoryInterface()); - this->SetCurrentMemoryInterfaceData(this->GetBaseMemoryInterfaceData()); + armcpu_SetCurrentMemoryInterface(armcpu, armcpu_GetBaseMemoryInterface(armcpu)); + armcpu_SetCurrentMemoryInterfaceData(armcpu, armcpu_GetBaseMemoryInterfaceData(armcpu)); } //call this whenever CPSR is changed (other than CNVZQ or T flags); interrupts may need to be unleashed -void armcpu_t::changeCPSR() +void armcpu_changeCPSR() { //but all it does is give them a chance to unleash by forcing an immediate reschedule //TODO - we could actually set CPSR through here and look for a change in the I bit @@ -379,7 +381,7 @@ u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode) } armcpu->CPSR.bits.mode = mode & 0x1F; - armcpu->changeCPSR(); + armcpu_changeCPSR(); return oldmode; } @@ -512,7 +514,7 @@ void armcpu_exception(armcpu_t *cpu, u32 number) cpu->SPSR = tmp; //save old CPSR as new SPSR cpu->CPSR.bits.T = 0; //handle as ARM32 code cpu->CPSR.bits.I = 1; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->R[15] = cpu->intVector + number; cpu->next_instruction = cpu->R[15]; printf("armcpu_exception!\n"); diff --git a/desmume/src/armcpu.h b/desmume/src/armcpu.h index b9d77c6b8..4369fa09e 100644 --- a/desmume/src/armcpu.h +++ b/desmume/src/armcpu.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2006-2017 DeSmuME team + Copyright (C) 2006-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -264,25 +264,6 @@ struct armcpu_t u32 R[16]; //16 Status_Reg CPSR; //80 Status_Reg SPSR; - - void SetControlInterface(const armcpu_ctrl_iface *theCtrlInterface); - armcpu_ctrl_iface* GetControlInterface(); - void SetControlInterfaceData(void *theData); - void* GetControlInterfaceData(); - - void SetCurrentMemoryInterface(armcpu_memory_iface *theMemInterface); - armcpu_memory_iface* GetCurrentMemoryInterface(); - void SetCurrentMemoryInterfaceData(void *theData); - void* GetCurrentMemoryInterfaceData(); - - void SetBaseMemoryInterface(const armcpu_memory_iface *theMemInterface); - armcpu_memory_iface* GetBaseMemoryInterface(); - void SetBaseMemoryInterfaceData(void *theData); - void* GetBaseMemoryInterfaceData(); - - void ResetMemoryInterfaceToBase(); - - void changeCPSR(); u32 R13_usr, R14_usr; u32 R13_svc, R14_svc; @@ -332,10 +313,29 @@ struct armcpu_t int runToRetTmp; bool runToRet; int stepOverBreak; - std::vector breakPoints; + std::vector *breakPoints; bool debugStep; }; +void armcpu_SetControlInterface(armcpu_t *armcpu, const armcpu_ctrl_iface *theCtrlInterface); +armcpu_ctrl_iface* armcpu_GetControlInterface(armcpu_t *armcpu); +void armcpu_SetControlInterfaceData(armcpu_t *armcpu, void *theData); +void* armcpu_GetControlInterfaceData(const armcpu_t *armcpu); + +void armcpu_SetCurrentMemoryInterface(armcpu_t *armcpu, armcpu_memory_iface *theMemInterface); +armcpu_memory_iface* armcpu_GetCurrentMemoryInterface(const armcpu_t *armcpu); +void armcpu_SetCurrentMemoryInterfaceData(armcpu_t *armcpu, void *theData); +void* armcpu_GetCurrentMemoryInterfaceData(const armcpu_t *armcpu); + +void armcpu_SetBaseMemoryInterface(armcpu_t *armcpu, const armcpu_memory_iface *theMemInterface); +armcpu_memory_iface* armcpu_GetBaseMemoryInterface(armcpu_t *armcpu); +void armcpu_SetBaseMemoryInterfaceData(armcpu_t *armcpu, void *theData); +void* armcpu_GetBaseMemoryInterfaceData(const armcpu_t *armcpu); + +void armcpu_ResetMemoryInterfaceToBase(armcpu_t *armcpu); + +void armcpu_changeCPSR(); + int armcpu_new( armcpu_t *armcpu, u32 id); void armcpu_init(armcpu_t *armcpu, u32 adr); u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode); diff --git a/desmume/src/cp15.cpp b/desmume/src/cp15.cpp index 7faf1ba98..60cce8f0b 100644 --- a/desmume/src/cp15.cpp +++ b/desmume/src/cp15.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2006-2017 DeSmuME team + Copyright (C) 2006-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,11 +28,50 @@ armcp15_t cp15; +void armcp15_init(armcp15_t *armcp15) +{ + armcp15->IDCode = 0x41059461; + armcp15->cacheType = 0x0F0D2112; + armcp15->TCMSize = 0x00140180; + armcp15->ctrl = 0x00012078; + armcp15->DCConfig = 0; + armcp15->ICConfig = 0; + armcp15->writeBuffCtrl = 0; + armcp15->und = 0; + armcp15->DaccessPerm = 0x22222222; + armcp15->IaccessPerm = 0x22222222; + armcp15->cacheOp = 0; + armcp15->DcacheLock = 0; + armcp15->IcacheLock = 0; + armcp15->ITCMRegion = 0x0C; + armcp15->DTCMRegion = 0x0080000A; + armcp15->processID = 0; + armcp15->RAM_TAG = 0; + armcp15->testState = 0; + armcp15->cacheDbg = 0; + + //printf("CP15 Reset\n"); + memset(&armcp15->protectBaseSize[0], 0, sizeof(armcp15->protectBaseSize)); + memset(&armcp15->regionWriteMask_USR[0], 0, sizeof(armcp15->regionWriteMask_USR)); + memset(&armcp15->regionWriteMask_SYS[0], 0, sizeof(armcp15->regionWriteMask_SYS)); + memset(&armcp15->regionReadMask_USR[0], 0, sizeof(armcp15->regionReadMask_USR)); + memset(&armcp15->regionReadMask_SYS[0], 0, sizeof(armcp15->regionReadMask_SYS)); + memset(&armcp15->regionExecuteMask_USR[0], 0, sizeof(armcp15->regionExecuteMask_USR)); + memset(&armcp15->regionExecuteMask_SYS[0], 0, sizeof(armcp15->regionExecuteMask_SYS)); + memset(&armcp15->regionWriteSet_USR[0], 0, sizeof(armcp15->regionWriteSet_USR)); + memset(&armcp15->regionWriteSet_SYS[0], 0, sizeof(armcp15->regionWriteSet_SYS)); + memset(&armcp15->regionReadSet_USR[0], 0, sizeof(armcp15->regionReadSet_USR)); + memset(&armcp15->regionReadSet_SYS[0], 0, sizeof(armcp15->regionReadSet_SYS)); + memset(&armcp15->regionExecuteSet_USR[0], 0, sizeof(armcp15->regionExecuteSet_USR)); + memset(&armcp15->regionExecuteSet_SYS[0], 0, sizeof(armcp15->regionExecuteSet_SYS)); +} + #define CP15_ACCESSTYPE(val, n) (((val) >> (4*n)) & 0x0F) /* sets the precalculated regions to mask,set for the affected accesstypes */ -void armcp15_t::setSingleRegionAccess(u8 num, u32 mask, u32 set) { +void armcp15_setSingleRegionAccess(armcp15_t *armcp15, u8 num, u32 mask, u32 set) +{ - switch (CP15_ACCESSTYPE(DaccessPerm, num)) { + switch (CP15_ACCESSTYPE(armcp15->DaccessPerm, num)) { case 4: /* UNP */ case 7: /* UNP */ case 8: /* UNP */ @@ -44,67 +83,67 @@ void armcp15_t::setSingleRegionAccess(u8 num, u32 mask, u32 set) { case 14: /* UNP */ case 15: /* UNP */ case 0: /* no access at all */ - regionWriteMask_USR[num] = 0 ; - regionWriteSet_USR[num] = 0xFFFFFFFF ; - regionReadMask_USR[num] = 0 ; - regionReadSet_USR[num] = 0xFFFFFFFF ; - regionWriteMask_SYS[num] = 0 ; - regionWriteSet_SYS[num] = 0xFFFFFFFF ; - regionReadMask_SYS[num] = 0 ; - regionReadSet_SYS[num] = 0xFFFFFFFF ; + armcp15->regionWriteMask_USR[num] = 0 ; + armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_USR[num] = 0 ; + armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionWriteMask_SYS[num] = 0 ; + armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_SYS[num] = 0 ; + armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ; break ; case 1: /* no access at USR, all to sys */ - regionWriteMask_USR[num] = 0 ; - regionWriteSet_USR[num] = 0xFFFFFFFF ; - regionReadMask_USR[num] = 0 ; - regionReadSet_USR[num] = 0xFFFFFFFF ; - regionWriteMask_SYS[num] = mask ; - regionWriteSet_SYS[num] = set ; - regionReadMask_SYS[num] = mask ; - regionReadSet_SYS[num] = set ; + armcp15->regionWriteMask_USR[num] = 0 ; + armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_USR[num] = 0 ; + armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionWriteMask_SYS[num] = mask ; + armcp15->regionWriteSet_SYS[num] = set ; + armcp15->regionReadMask_SYS[num] = mask ; + armcp15->regionReadSet_SYS[num] = set ; break ; case 2: /* read at USR, all to sys */ - regionWriteMask_USR[num] = 0 ; - regionWriteSet_USR[num] = 0xFFFFFFFF ; - regionReadMask_USR[num] = mask ; - regionReadSet_USR[num] = set ; - regionWriteMask_SYS[num] = mask ; - regionWriteSet_SYS[num] = set ; - regionReadMask_SYS[num] = mask ; - regionReadSet_SYS[num] = set ; + armcp15->regionWriteMask_USR[num] = 0 ; + armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_USR[num] = mask ; + armcp15->regionReadSet_USR[num] = set ; + armcp15->regionWriteMask_SYS[num] = mask ; + armcp15->regionWriteSet_SYS[num] = set ; + armcp15->regionReadMask_SYS[num] = mask ; + armcp15->regionReadSet_SYS[num] = set ; break ; case 3: /* all to USR, all to sys */ - regionWriteMask_USR[num] = mask ; - regionWriteSet_USR[num] = set ; - regionReadMask_USR[num] = mask ; - regionReadSet_USR[num] = set ; - regionWriteMask_SYS[num] = mask ; - regionWriteSet_SYS[num] = set ; - regionReadMask_SYS[num] = mask ; - regionReadSet_SYS[num] = set ; + armcp15->regionWriteMask_USR[num] = mask ; + armcp15->regionWriteSet_USR[num] = set ; + armcp15->regionReadMask_USR[num] = mask ; + armcp15->regionReadSet_USR[num] = set ; + armcp15->regionWriteMask_SYS[num] = mask ; + armcp15->regionWriteSet_SYS[num] = set ; + armcp15->regionReadMask_SYS[num] = mask ; + armcp15->regionReadSet_SYS[num] = set ; break ; case 5: /* no access at USR, read to sys */ - regionWriteMask_USR[num] = 0 ; - regionWriteSet_USR[num] = 0xFFFFFFFF ; - regionReadMask_USR[num] = 0 ; - regionReadSet_USR[num] = 0xFFFFFFFF ; - regionWriteMask_SYS[num] = 0 ; - regionWriteSet_SYS[num] = 0xFFFFFFFF ; - regionReadMask_SYS[num] = mask ; - regionReadSet_SYS[num] = set ; + armcp15->regionWriteMask_USR[num] = 0 ; + armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_USR[num] = 0 ; + armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionWriteMask_SYS[num] = 0 ; + armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_SYS[num] = mask ; + armcp15->regionReadSet_SYS[num] = set ; break ; case 6: /* read at USR, read to sys */ - regionWriteMask_USR[num] = 0 ; - regionWriteSet_USR[num] = 0xFFFFFFFF ; - regionReadMask_USR[num] = mask ; - regionReadSet_USR[num] = set ; - regionWriteMask_SYS[num] = 0 ; - regionWriteSet_SYS[num] = 0xFFFFFFFF ; - regionReadMask_SYS[num] = mask ; - regionReadSet_SYS[num] = set ; + armcp15->regionWriteMask_USR[num] = 0 ; + armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_USR[num] = mask ; + armcp15->regionReadSet_USR[num] = set ; + armcp15->regionWriteMask_SYS[num] = 0 ; + armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; + armcp15->regionReadMask_SYS[num] = mask ; + armcp15->regionReadSet_SYS[num] = set ; break ; } - switch (CP15_ACCESSTYPE(IaccessPerm, num)) { + switch (CP15_ACCESSTYPE(armcp15->IaccessPerm, num)) { case 4: /* UNP */ case 7: /* UNP */ case 8: /* UNP */ @@ -116,43 +155,43 @@ void armcp15_t::setSingleRegionAccess(u8 num, u32 mask, u32 set) { case 14: /* UNP */ case 15: /* UNP */ case 0: /* no access at all */ - regionExecuteMask_USR[num] = 0 ; - regionExecuteSet_USR[num] = 0xFFFFFFFF ; - regionExecuteMask_SYS[num] = 0 ; - regionExecuteSet_SYS[num] = 0xFFFFFFFF ; + armcp15->regionExecuteMask_USR[num] = 0 ; + armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionExecuteMask_SYS[num] = 0 ; + armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ; break ; case 1: - regionExecuteMask_USR[num] = 0 ; - regionExecuteSet_USR[num] = 0xFFFFFFFF ; - regionExecuteMask_SYS[num] = mask ; - regionExecuteSet_SYS[num] = set ; + armcp15->regionExecuteMask_USR[num] = 0 ; + armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ; + armcp15->regionExecuteMask_SYS[num] = mask ; + armcp15->regionExecuteSet_SYS[num] = set ; break ; case 2: case 3: case 6: - regionExecuteMask_USR[num] = mask ; - regionExecuteSet_USR[num] = set ; - regionExecuteMask_SYS[num] = mask ; - regionExecuteSet_SYS[num] = set ; + armcp15->regionExecuteMask_USR[num] = mask ; + armcp15->regionExecuteSet_USR[num] = set ; + armcp15->regionExecuteMask_SYS[num] = mask ; + armcp15->regionExecuteSet_SYS[num] = set ; break ; } } ; /* precalculate region masks/sets from cp15 register */ -void armcp15_t::maskPrecalc() +void armcp15_maskPrecalc(armcp15_t *armcp15) { #define precalc(num) { \ - u32 mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \ - if (BIT_N(protectBaseSize[num],0)) /* if region is enabled */ \ + u32 mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is always false (disabled) */ \ + if (BIT_N(armcp15->protectBaseSize[num],0)) /* if region is enabled */ \ { /* reason for this define: naming includes var */ \ - mask = CP15_MASKFROMREG(protectBaseSize[num]) ; \ - set = CP15_SETFROMREG(protectBaseSize[num]) ; \ - if (CP15_SIZEIDENTIFIER(protectBaseSize[num])==0x1F) \ + mask = CP15_MASKFROMREG(armcp15->protectBaseSize[num]) ; \ + set = CP15_SETFROMREG(armcp15->protectBaseSize[num]) ; \ + if (CP15_SIZEIDENTIFIER(armcp15->protectBaseSize[num])==0x1F) \ { /* for the 4GB region, u32 suffers wraparound */ \ - mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \ + mask = 0 ; set = 0 ; /* (x & 0) == 0 is always true (enabled) */ \ } \ } \ - setSingleRegionAccess(num, mask, set) ; \ + armcp15_setSingleRegionAccess(armcp15, num, mask, set) ; \ } precalc(0) ; precalc(1) ; @@ -165,29 +204,29 @@ void armcp15_t::maskPrecalc() #undef precalc } -BOOL armcp15_t::isAccessAllowed(u32 address,u32 access) +BOOL armcp15_isAccessAllowed(armcp15_t *armcp15, u32 address,u32 access) { int i ; - if (!(ctrl & 1)) return TRUE ; /* protection checking is not enabled */ + if (!(armcp15->ctrl & 1)) return TRUE ; /* protection checking is not enabled */ for (i=0;i<8;i++) { switch (access) { case CP15_ACCESS_WRITEUSR: - if ((address & regionWriteMask_USR[i]) == regionWriteSet_USR[i]) return TRUE ; + if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return TRUE ; break ; case CP15_ACCESS_WRITESYS: - if ((address & regionWriteMask_SYS[i]) == regionWriteSet_SYS[i]) return TRUE ; + if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return TRUE ; break ; case CP15_ACCESS_READUSR: - if ((address & regionReadMask_USR[i]) == regionReadSet_USR[i]) return TRUE ; + if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return TRUE ; break ; case CP15_ACCESS_READSYS: - if ((address & regionReadMask_SYS[i]) == regionReadSet_SYS[i]) return TRUE ; + if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return TRUE ; break ; case CP15_ACCESS_EXECUSR: - if ((address & regionExecuteMask_USR[i]) == regionExecuteSet_USR[i]) return TRUE ; + if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return TRUE ; break ; case CP15_ACCESS_EXECSYS: - if ((address & regionExecuteMask_SYS[i]) == regionExecuteSet_SYS[i]) return TRUE ; + if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return TRUE ; break ; } } @@ -195,25 +234,25 @@ BOOL armcp15_t::isAccessAllowed(u32 address,u32 access) return FALSE ; } -BOOL armcp15_t::dataProcess(u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) +BOOL armcp15_dataProcess(armcp15_t *armcp15, u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { LOG("Unsupported CP15 operation : DataProcess\n"); return FALSE; } -BOOL armcp15_t::load(u8 CRd, u8 adr) +BOOL armcp15_load(armcp15_t *armcp15, u8 CRd, u8 adr) { LOG("Unsupported CP15 operation : Load\n"); return FALSE; } -BOOL armcp15_t::store(u8 CRd, u8 adr) +BOOL armcp15_store(armcp15_t *armcp15, u8 CRd, u8 adr) { LOG("Unsupported CP15 operation : Store\n"); return FALSE; } -BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) +BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { if(NDS_ARM9.CPSR.bits.mode == USR) return FALSE; @@ -225,13 +264,13 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 1: - *R = cacheType; + *R = armcp15->cacheType; return TRUE; case 2: - *R = TCMSize; + *R = armcp15->TCMSize; return TRUE; default: - *R = IDCode; + *R = armcp15->IDCode; return TRUE; } } @@ -239,7 +278,7 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) case 1: if((opcode1==0) && (opcode2==0) && (CRm==0)) { - *R = ctrl; + *R = armcp15->ctrl; //LOG("CP15: CPtoARM ctrl %08X\n", ctrl); return TRUE; } @@ -251,10 +290,10 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 0: - *R = DCConfig; + *R = armcp15->DCConfig; return TRUE; case 1: - *R = ICConfig; + *R = armcp15->ICConfig; return TRUE; default: return FALSE; @@ -264,7 +303,7 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) case 3: if((opcode1==0) && (opcode2==0) && (CRm==0)) { - *R = writeBuffCtrl; + *R = armcp15->writeBuffCtrl; //LOG("CP15: CPtoARM writeBuffer ctrl %08X\n", writeBuffCtrl); return TRUE; } @@ -275,10 +314,10 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 2: - *R = DaccessPerm; + *R = armcp15->DaccessPerm; return TRUE; case 3: - *R = IaccessPerm; + *R = armcp15->IaccessPerm; return TRUE; default: return FALSE; @@ -290,7 +329,7 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { if (CRm < 8) { - *R = protectBaseSize[CRm]; + *R = armcp15->protectBaseSize[CRm]; return TRUE; } } @@ -304,10 +343,10 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 0: - *R = DcacheLock; + *R = armcp15->DcacheLock; return TRUE; case 1: - *R = IcacheLock; + *R = armcp15->IcacheLock; return TRUE; default: return FALSE; @@ -316,10 +355,10 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 0: - *R = DTCMRegion; + *R = armcp15->DTCMRegion; return TRUE; case 1: - *R = ITCMRegion; + *R = armcp15->ITCMRegion; return TRUE; default: return FALSE; @@ -333,7 +372,7 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) } } -BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) +BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { if(NDS_ARM9.CPSR.bits.mode == USR) return FALSE; @@ -344,7 +383,7 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { //On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero. - ctrl = (val & 0x000FF085) | 0x00000078; + armcp15->ctrl = (val & 0x000FF085) | 0x00000078; MMU.ARM9_RW_MODE = BIT7(val); //zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek NDS_ARM9.intVector = 0xFFFF0000 * (BIT13(val)); @@ -359,10 +398,10 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 0: - DCConfig = val; + armcp15->DCConfig = val; return TRUE; case 1: - ICConfig = val; + armcp15->ICConfig = val; return TRUE; default: return FALSE; @@ -372,7 +411,7 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) case 3: if((opcode1==0) && (opcode2==0) && (CRm==0)) { - writeBuffCtrl = val; + armcp15->writeBuffCtrl = val; //LOG("CP15: ARMtoCP writeBuffer ctrl %08X\n", writeBuffCtrl); return TRUE; } @@ -383,12 +422,12 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 2: - DaccessPerm = val; - maskPrecalc(); + armcp15->DaccessPerm = val; + armcp15_maskPrecalc(armcp15); return TRUE; case 3: - IaccessPerm = val; - maskPrecalc(); + armcp15->IaccessPerm = val; + armcp15_maskPrecalc(armcp15); return TRUE; default: return FALSE; @@ -400,8 +439,8 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { if (CRm < 8) { - protectBaseSize[CRm] = val; - maskPrecalc(); + armcp15->protectBaseSize[CRm] = val; + armcp15_maskPrecalc(armcp15); return TRUE; } } @@ -424,10 +463,10 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 0: - DcacheLock = val; + armcp15->DcacheLock = val; return TRUE; case 1: - IcacheLock = val; + armcp15->IcacheLock = val; return TRUE; default: return FALSE; @@ -436,10 +475,10 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) switch(opcode2) { case 0: - MMU.DTCMRegion = DTCMRegion = val & 0x0FFFF000; + MMU.DTCMRegion = armcp15->DTCMRegion = val & 0x0FFFF000; return TRUE; case 1: - ITCMRegion = val; + armcp15->ITCMRegion = val; //ITCM base is not writeable! MMU.ITCMRegion = 0; return TRUE; @@ -455,76 +494,76 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) } // Save state -void armcp15_t::saveone(EMUFILE &os) +void armcp15_saveone(armcp15_t *armcp15, EMUFILE &os) { - os.write_32LE(IDCode); - os.write_32LE(cacheType); - os.write_32LE(TCMSize); - os.write_32LE(ctrl); - os.write_32LE(DCConfig); - os.write_32LE(ICConfig); - os.write_32LE(writeBuffCtrl); - os.write_32LE(und); - os.write_32LE(DaccessPerm); - os.write_32LE(IaccessPerm); - for (int i=0;i<8;i++) os.write_32LE(protectBaseSize[i]); - os.write_32LE(cacheOp); - os.write_32LE(DcacheLock); - os.write_32LE(IcacheLock); - os.write_32LE(ITCMRegion); - os.write_32LE(DTCMRegion); - os.write_32LE(processID); - os.write_32LE(RAM_TAG); - os.write_32LE(testState); - os.write_32LE(cacheDbg); - for (int i=0;i<8;i++) os.write_32LE(regionWriteMask_USR[i]); - for (int i=0;i<8;i++) os.write_32LE(regionWriteMask_SYS[i]); - for (int i=0;i<8;i++) os.write_32LE(regionReadMask_USR[i]); - for (int i=0;i<8;i++) os.write_32LE(regionReadMask_SYS[i]); - for (int i=0;i<8;i++) os.write_32LE(regionExecuteMask_USR[i]); - for (int i=0;i<8;i++) os.write_32LE(regionExecuteMask_SYS[i]); - for (int i=0;i<8;i++) os.write_32LE(regionWriteSet_USR[i]); - for (int i=0;i<8;i++) os.write_32LE(regionWriteSet_SYS[i]); - for (int i=0;i<8;i++) os.write_32LE(regionReadSet_USR[i]); - for (int i=0;i<8;i++) os.write_32LE(regionReadSet_SYS[i]); - for (int i=0;i<8;i++) os.write_32LE(regionExecuteSet_USR[i]); - for (int i=0;i<8;i++) os.write_32LE(regionExecuteSet_SYS[i]); + os.write_32LE(armcp15->IDCode); + os.write_32LE(armcp15->cacheType); + os.write_32LE(armcp15->TCMSize); + os.write_32LE(armcp15->ctrl); + os.write_32LE(armcp15->DCConfig); + os.write_32LE(armcp15->ICConfig); + os.write_32LE(armcp15->writeBuffCtrl); + os.write_32LE(armcp15->und); + os.write_32LE(armcp15->DaccessPerm); + os.write_32LE(armcp15->IaccessPerm); + for (int i=0;i<8;i++) os.write_32LE(armcp15->protectBaseSize[i]); + os.write_32LE(armcp15->cacheOp); + os.write_32LE(armcp15->DcacheLock); + os.write_32LE(armcp15->IcacheLock); + os.write_32LE(armcp15->ITCMRegion); + os.write_32LE(armcp15->DTCMRegion); + os.write_32LE(armcp15->processID); + os.write_32LE(armcp15->RAM_TAG); + os.write_32LE(armcp15->testState); + os.write_32LE(armcp15->cacheDbg); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionWriteMask_USR[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionWriteMask_SYS[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionReadMask_USR[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionReadMask_SYS[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionExecuteMask_USR[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionExecuteMask_SYS[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionWriteSet_USR[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionWriteSet_SYS[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionReadSet_USR[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionReadSet_SYS[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionExecuteSet_USR[i]); + for (int i=0;i<8;i++) os.write_32LE(armcp15->regionExecuteSet_SYS[i]); } -bool armcp15_t::loadone(EMUFILE &is) +bool armcp15_loadone(armcp15_t *armcp15, EMUFILE &is) { - if (!is.read_32LE(IDCode)) return false; - if (!is.read_32LE(cacheType)) return false; - if (!is.read_32LE(TCMSize)) return false; - if (!is.read_32LE(ctrl)) return false; - if (!is.read_32LE(DCConfig)) return false; - if (!is.read_32LE(ICConfig)) return false; - if (!is.read_32LE(writeBuffCtrl)) return false; - if (!is.read_32LE(und)) return false; - if (!is.read_32LE(DaccessPerm)) return false; - if (!is.read_32LE(IaccessPerm)) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(protectBaseSize[i])) return false; - if (!is.read_32LE(cacheOp)) return false; - if (!is.read_32LE(DcacheLock)) return false; - if (!is.read_32LE(IcacheLock)) return false; - if (!is.read_32LE(ITCMRegion)) return false; - if (!is.read_32LE(DTCMRegion)) return false; - if (!is.read_32LE(processID)) return false; - if (!is.read_32LE(RAM_TAG)) return false; - if (!is.read_32LE(testState)) return false; - if (!is.read_32LE(cacheDbg)) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteMask_USR[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteMask_SYS[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionReadMask_USR[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionReadMask_SYS[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteMask_USR[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteMask_SYS[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteSet_USR[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteSet_SYS[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionReadSet_USR[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionReadSet_SYS[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteSet_USR[i])) return false; - for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteSet_SYS[i])) return false; + if (!is.read_32LE(armcp15->IDCode)) return false; + if (!is.read_32LE(armcp15->cacheType)) return false; + if (!is.read_32LE(armcp15->TCMSize)) return false; + if (!is.read_32LE(armcp15->ctrl)) return false; + if (!is.read_32LE(armcp15->DCConfig)) return false; + if (!is.read_32LE(armcp15->ICConfig)) return false; + if (!is.read_32LE(armcp15->writeBuffCtrl)) return false; + if (!is.read_32LE(armcp15->und)) return false; + if (!is.read_32LE(armcp15->DaccessPerm)) return false; + if (!is.read_32LE(armcp15->IaccessPerm)) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->protectBaseSize[i])) return false; + if (!is.read_32LE(armcp15->cacheOp)) return false; + if (!is.read_32LE(armcp15->DcacheLock)) return false; + if (!is.read_32LE(armcp15->IcacheLock)) return false; + if (!is.read_32LE(armcp15->ITCMRegion)) return false; + if (!is.read_32LE(armcp15->DTCMRegion)) return false; + if (!is.read_32LE(armcp15->processID)) return false; + if (!is.read_32LE(armcp15->RAM_TAG)) return false; + if (!is.read_32LE(armcp15->testState)) return false; + if (!is.read_32LE(armcp15->cacheDbg)) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionWriteMask_USR[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionWriteMask_SYS[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionReadMask_USR[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionReadMask_SYS[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionExecuteMask_USR[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionExecuteMask_SYS[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionWriteSet_USR[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionWriteSet_SYS[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionReadSet_USR[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionReadSet_SYS[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionExecuteSet_USR[i])) return false; + for (int i=0;i<8;i++) if (!is.read_32LE(armcp15->regionExecuteSet_SYS[i])) return false; return true; } diff --git a/desmume/src/cp15.h b/desmume/src/cp15.h index f42a2576d..5bc594288 100644 --- a/desmume/src/cp15.h +++ b/desmume/src/cp15.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2006-2017 DeSmuME team + Copyright (C) 2006-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,7 +41,6 @@ class EMUFILE; struct armcp15_t { -public: u32 IDCode; u32 cacheType; u32 TCMSize; @@ -76,56 +75,22 @@ public: u32 regionReadSet_SYS[8] ; u32 regionExecuteSet_USR[8] ; u32 regionExecuteSet_SYS[8] ; - - void setSingleRegionAccess(u8 num, u32 mask, u32 set); - void maskPrecalc(); - -public: - armcp15_t() : IDCode(0x41059461), - cacheType(0x0F0D2112), - TCMSize(0x00140180), - ctrl(0x00012078), - DCConfig(0), - ICConfig(0), - writeBuffCtrl(0), - und(0), - DaccessPerm(0x22222222), - IaccessPerm(0x22222222), - cacheOp(0), - DcacheLock(0), - IcacheLock(0), - ITCMRegion(0x0C), - DTCMRegion(0x0080000A), - processID(0), - RAM_TAG(0), - testState(0), - cacheDbg(0) - { - //printf("CP15 Reset\n"); - memset(&protectBaseSize[0], 0, sizeof(protectBaseSize)); - memset(®ionWriteMask_USR[0], 0, sizeof(regionWriteMask_USR)); - memset(®ionWriteMask_SYS[0], 0, sizeof(regionWriteMask_SYS)); - memset(®ionReadMask_USR[0], 0, sizeof(regionReadMask_USR)); - memset(®ionReadMask_SYS[0], 0, sizeof(regionReadMask_SYS)); - memset(®ionExecuteMask_USR[0], 0, sizeof(regionExecuteMask_USR)); - memset(®ionExecuteMask_SYS[0], 0, sizeof(regionExecuteMask_SYS)); - memset(®ionWriteSet_USR[0], 0, sizeof(regionWriteSet_USR)); - memset(®ionWriteSet_SYS[0], 0, sizeof(regionWriteSet_SYS)); - memset(®ionReadSet_USR[0], 0, sizeof(regionReadSet_USR)); - memset(®ionReadSet_SYS[0], 0, sizeof(regionReadSet_SYS)); - memset(®ionExecuteSet_USR[0], 0, sizeof(regionExecuteSet_USR)); - memset(®ionExecuteSet_SYS[0], 0, sizeof(regionExecuteSet_SYS)); - } - BOOL dataProcess(u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2); - BOOL load(u8 CRd, u8 adr); - BOOL store(u8 CRd, u8 adr); - BOOL moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2); - BOOL moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2); - BOOL isAccessAllowed(u32 address,u32 access); - // savestate - void saveone(EMUFILE &os); - bool loadone(EMUFILE &is); }; +void armcp15_init(armcp15_t *armcp15); + +void armcp15_setSingleRegionAccess(armcp15_t *armcp15, u8 num, u32 mask, u32 set); +void armcp15_maskPrecalc(armcp15_t *armcp15); + +BOOL armcp15_dataProcess(armcp15_t *armcp15, u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2); +BOOL armcp15_load(armcp15_t *armcp15, u8 CRd, u8 adr); +BOOL armcp15_store(armcp15_t *armcp15, u8 CRd, u8 adr); +BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 *R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2); +BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2); +BOOL armcp15_isAccessAllowed(armcp15_t *armcp15, u32 address, u32 access); +// savestate +void armcp15_saveone(armcp15_t *armcp15, EMUFILE &os); +bool armcp15_loadone(armcp15_t *armcp15, EMUFILE &is); + extern armcp15_t cp15; #endif /* __CP15_H__*/ diff --git a/desmume/src/debug.cpp b/desmume/src/debug.cpp index 9ba04fcbd..5eaa27a41 100644 --- a/desmume/src/debug.cpp +++ b/desmume/src/debug.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 Guillaume Duhamel - Copyright (C) 2006-2016 DeSmuME team + Copyright (C) 2006-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -52,7 +52,7 @@ static bool acl_check_access(u32 adr, u32 access) { if(NDS_ARM9.CPSR.bits.mode != USR) access |= 1; - if (cp15.isAccessAllowed(adr,access)==FALSE) { + if (armcp15_isAccessAllowed(&cp15, adr,access)==FALSE) { HandleDebugEvent(DEBUG_EVENT_ACL_EXCEPTION); } return true; diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index 9fecb1a6b..9280cd961 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -2,7 +2,7 @@ Copyright (C) 2006 Normmatt Copyright (C) 2006 Theo Berkau Copyright (C) 2007 Pascal Giard - Copyright (C) 2008-2017 DeSmuME team + Copyright (C) 2008-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -607,7 +607,7 @@ static void cp15_savestate(EMUFILE &os) //version os.write_32LE(1); - cp15.saveone(os); + armcp15_saveone(&cp15, os); //ARM7 not have coprocessor //cp15_saveone((armcp15_t *)NDS_ARM7.coproc[15],os); } @@ -619,12 +619,12 @@ static bool cp15_loadstate(EMUFILE &is, int size) if (is.read_32LE(version) != 1) return false; if (version > 1) return false; - if (!cp15.loadone(is)) return false; + if (!armcp15_loadone(&cp15, is)) return false; if (version == 0) { //ARM7 not have coprocessor - if (!cp15.loadone(is)) + if (!armcp15_loadone(&cp15, is)) return false; } diff --git a/desmume/src/thumb_instructions.cpp b/desmume/src/thumb_instructions.cpp index 2a6ed6869..6077ba416 100644 --- a/desmume/src/thumb_instructions.cpp +++ b/desmume/src/thumb_instructions.cpp @@ -1,7 +1,7 @@ /* Copyright (C) 2006 yopyop Copyright (C) 2008 shash - Copyright (C) 2008-2016 DeSmuME team + Copyright (C) 2008-2021 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1001,7 +1001,7 @@ TEMPLATE static u32 FASTCALL OP_BKPT_THUMB(const u32 i) cpu->SPSR = tmp; // save old CPSR as new SPSR cpu->CPSR.bits.T = 0; // handle as ARM32 code cpu->CPSR.bits.I = 1; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->R[15] = cpu->intVector + 0x0C; cpu->next_instruction = cpu->R[15]; return 1; @@ -1047,7 +1047,7 @@ TEMPLATE static u32 FASTCALL OP_SWI_THUMB(const u32 i) cpu->SPSR = tmp; /* save old CPSR as new SPSR */ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ cpu->CPSR.bits.I = 1; - cpu->changeCPSR(); + armcpu_changeCPSR(); cpu->R[15] = cpu->intVector + 0x08; cpu->next_instruction = cpu->R[15]; return 3;