Core: Silence the 1000+ compiler warnings about using offsetof() on a non-POD type... again.

This commit is contained in:
rogerman 2021-08-31 10:23:04 -07:00
parent 3f47c4ad7d
commit cfe88ce0d7
10 changed files with 350 additions and 342 deletions

View File

@ -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<s32,s32> 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<int> *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<s32,s32> 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<int> *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

View File

@ -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<PROCNUM,32,MMU_AD_READ>(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<PROCNUM,32,MMU_AD_READ>(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<PROCNUM,32,MMU_AD_READ>(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<PROCNUM>(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<PROCNUM,32,MMU_AD_READ>(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<PROCNUM>(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<PROCNUM,32,MMU_AD_READ>(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<PROCNUM,32,MMU_AD_READ>(start);
return MMU_aluMemCycles<PROCNUM>(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<PROCNUM>(2, c);
}
@ -5583,7 +5583,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2_W(const u32 i)
c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(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<PROCNUM>(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;

View File

@ -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)
{

View File

@ -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<int>;
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");

View File

@ -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<int> breakPoints;
std::vector<int> *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);

View File

@ -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;
}

View File

@ -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(&regionWriteMask_USR[0], 0, sizeof(regionWriteMask_USR));
memset(&regionWriteMask_SYS[0], 0, sizeof(regionWriteMask_SYS));
memset(&regionReadMask_USR[0], 0, sizeof(regionReadMask_USR));
memset(&regionReadMask_SYS[0], 0, sizeof(regionReadMask_SYS));
memset(&regionExecuteMask_USR[0], 0, sizeof(regionExecuteMask_USR));
memset(&regionExecuteMask_SYS[0], 0, sizeof(regionExecuteMask_SYS));
memset(&regionWriteSet_USR[0], 0, sizeof(regionWriteSet_USR));
memset(&regionWriteSet_SYS[0], 0, sizeof(regionWriteSet_SYS));
memset(&regionReadSet_USR[0], 0, sizeof(regionReadSet_USR));
memset(&regionReadSet_SYS[0], 0, sizeof(regionReadSet_SYS));
memset(&regionExecuteSet_USR[0], 0, sizeof(regionExecuteSet_USR));
memset(&regionExecuteSet_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__*/

View File

@ -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;

View File

@ -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;
}

View File

@ -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;