Skip to content

Commit c081555

Browse files
committed
Clean up memory and some other classes
1 parent 668e8aa commit c081555

20 files changed

+1247
-1351
lines changed

src/bios.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ int Bios::execute(uint8_t vector, uint32_t **registers)
105105
void Bios::checkWaitFlags()
106106
{
107107
// Read the BIOS interrupt flags from memory
108-
uint32_t address = arm7 ? 0x3FFFFF8 : (core->cp15.getDtcmAddr() + 0x3FF8);
108+
uint32_t address = arm7 ? 0x3FFFFF8 : (core->cp15.dtcmAddr + 0x3FF8);
109109
uint32_t flags = core->memory.read<uint32_t>(arm7, address);
110110

111111
// If a flag being waited for is set, clear it and stop waiting

src/cartridge.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ bool CartridgeGba::loadRom()
11101110
core->rtc.enableGpRtc();
11111111

11121112
// Update the memory maps at the GBA ROM locations
1113-
core->memory.updateMap9<false>(0x08000000, 0x0A000000);
1113+
core->memory.updateMap9(0x08000000, 0x0A000000);
11141114
core->memory.updateMap7(0x08000000, 0x0D000000);
11151115

11161116
// If the save size is unknown, try to detect it

src/core.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Core::Core(std::string ndsRom, std::string gbaRom, int id, int ndsRomFd,
7777
schedule(NDS_SPU_SAMPLE, 512 * 2);
7878

7979
// Initialize the memory and CPUs
80-
memory.updateMap9<false>(0x00000000, 0xFFFFFFFF);
80+
memory.updateMap9(0x00000000, 0xFFFFFFFF);
8181
memory.updateMap7(0x00000000, 0xFFFFFFFF);
8282
interpreter[0].init();
8383
interpreter[1].init();

src/cp15.cpp

+27-45
Original file line numberDiff line numberDiff line change
@@ -42,91 +42,73 @@ void Cp15::loadState(FILE *file)
4242
write(9, 1, 1, itcm);
4343
}
4444

45-
uint32_t Cp15::read(int cn, int cm, int cp)
45+
uint32_t Cp15::read(uint8_t cn, uint8_t cm, uint8_t cp)
4646
{
4747
// Read a value from a CP15 register
4848
switch ((cn << 16) | (cm << 8) | (cp << 0))
4949
{
5050
case 0x000000: return 0x41059461; // Main ID
5151
case 0x000001: return 0x0F0D2112; // Cache type
52-
case 0x010000: return ctrlReg; // Control
53-
case 0x090100: return dtcmReg; // Data TCM base/size
54-
case 0x090101: return itcmReg; // Instruction TCM size
52+
case 0x010000: return ctrlReg; // Control
53+
case 0x090100: return dtcmReg; // Data TCM base/size
54+
case 0x090101: return itcmReg; // Instruction TCM size
5555

5656
default:
57-
{
5857
LOG("Unknown CP15 register read: C%d,C%d,%d\n", cn, cm, cp);
5958
return 0;
60-
}
6159
}
6260
}
6361

64-
void Cp15::write(int cn, int cm, int cp, uint32_t value)
62+
void Cp15::write(uint8_t cn, uint8_t cm, uint8_t cp, uint32_t value)
6563
{
6664
// Write a value to a CP15 register
65+
uint32_t oldAddr, oldSize;
6766
switch ((cn << 16) | (cm << 8) | (cp << 0))
6867
{
6968
case 0x010000: // Control
70-
{
71-
// Some control bits are read only, so only set the writeable ones
72-
ctrlReg = (ctrlReg & ~0x000FF085) | (value & 0x000FF085);
69+
// Set writable control bits and update their state values
70+
ctrlReg = (ctrlReg & ~0xFF085) | (value & 0xFF085);
7371
exceptionAddr = (ctrlReg & BIT(13)) ? 0xFFFF0000 : 0x00000000;
74-
dtcmReadEnabled = (ctrlReg & BIT(16)) && !(ctrlReg & BIT(17));
75-
dtcmWriteEnabled = (ctrlReg & BIT(16));
76-
itcmReadEnabled = (ctrlReg & BIT(18)) && !(ctrlReg & BIT(19));
77-
itcmWriteEnabled = (ctrlReg & BIT(18));
72+
dtcmCanRead = (ctrlReg & BIT(16)) && !(ctrlReg & BIT(17));
73+
dtcmCanWrite = (ctrlReg & BIT(16));
74+
itcmCanRead = (ctrlReg & BIT(18)) && !(ctrlReg & BIT(19));
75+
itcmCanWrite = (ctrlReg & BIT(18));
7876

7977
// Update the memory map at the current TCM locations
80-
core->memory.updateMap9<true>(dtcmAddr, dtcmAddr + dtcmSize);
81-
core->memory.updateMap9<true>(0x00000000, itcmSize);
82-
78+
core->memory.updateMap9(dtcmAddr, dtcmAddr + dtcmSize, true);
79+
core->memory.updateMap9(0x00000000, itcmSize, true);
8380
return;
84-
}
8581

8682
case 0x090100: // Data TCM base/size
87-
{
88-
uint32_t dtcmAddrOld = dtcmAddr;
89-
uint32_t dtcmSizeOld = dtcmSize;
90-
91-
// DTCM size is calculated as 512 shifted left N bits, with a minimum of 4KB
83+
// Set the DTCM register and update its address and size
9284
dtcmReg = value;
85+
oldAddr = dtcmAddr;
86+
oldSize = dtcmSize;
9387
dtcmAddr = dtcmReg & 0xFFFFF000;
94-
dtcmSize = 0x200 << ((dtcmReg & 0x0000003E) >> 1);
95-
if (dtcmSize < 0x1000) dtcmSize = 0x1000;
96-
97-
// Update the memory map at the old and new DTCM locations
98-
core->memory.updateMap9<true>(dtcmAddrOld, dtcmAddrOld + dtcmSizeOld);
99-
core->memory.updateMap9<true>(dtcmAddr, dtcmAddr + dtcmSize);
88+
dtcmSize = std::max(0x1000, 0x200 << ((dtcmReg >> 1) & 0x1F)); // Min 4KB
10089

90+
// Update the memory map at the old and new DTCM areas
91+
core->memory.updateMap9(oldAddr, oldAddr + oldSize, true);
92+
core->memory.updateMap9(dtcmAddr, dtcmAddr + dtcmSize, true);
10193
return;
102-
}
10394

10495
case 0x070004: case 0x070802: // Wait for interrupt
105-
{
96+
// Halt the CPU
10697
core->interpreter[0].halt(0);
10798
return;
108-
}
10999

110100
case 0x090101: // Instruction TCM size
111-
{
112-
uint32_t itcmSizeOld = itcmSize;
113-
114-
// ITCM base is fixed, so that part of the value is unused
115-
// ITCM size is calculated as 512 shifted left N bits, with a minimum of 4KB
101+
// Set the ITCM register and update its size
116102
itcmReg = value;
117-
itcmSize = 0x200 << ((itcmReg & 0x0000003E) >> 1);
118-
if (itcmSize < 0x1000) itcmSize = 0x1000;
119-
120-
// Update the memory map at the old and new ITCM locations
121-
core->memory.updateMap9<true>(0x00000000, std::max(itcmSizeOld, itcmSize));
103+
oldSize = itcmSize;
104+
itcmSize = std::max(0x1000, 0x200 << ((itcmReg >> 1) & 0x1F)); // Min 4KB
122105

106+
// Update the memory map at the old and new ITCM areas
107+
core->memory.updateMap9(0x00000000, std::max(oldSize, itcmSize), true);
123108
return;
124-
}
125109

126110
default:
127-
{
128111
LOG("Unknown CP15 register write: C%d,C%d,%d\n", cn, cm, cp);
129112
return;
130-
}
131113
}
132114
}

src/cp15.h

+11-21
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,24 @@ class Core;
2828
class Cp15
2929
{
3030
public:
31+
uint32_t exceptionAddr = 0;
32+
bool dtcmCanRead = false, dtcmCanWrite = false;
33+
bool itcmCanRead = false, itcmCanWrite = false;
34+
uint32_t dtcmAddr = 0, dtcmSize = 0;
35+
uint32_t itcmSize = 0;
36+
3137
Cp15(Core *core): core(core) {}
3238
void saveState(FILE *file);
3339
void loadState(FILE *file);
3440

35-
uint32_t read(int cn, int cm, int cp);
36-
void write(int cn, int cm, int cp, uint32_t value);
37-
38-
uint32_t getExceptionAddr() { return exceptionAddr; }
39-
bool getDtcmReadEnabled() { return dtcmReadEnabled; }
40-
bool getDtcmWriteEnabled() { return dtcmWriteEnabled; }
41-
bool getItcmReadEnabled() { return itcmReadEnabled; }
42-
bool getItcmWriteEnabled() { return itcmWriteEnabled; }
43-
uint32_t getDtcmAddr() { return dtcmAddr; }
44-
uint32_t getDtcmSize() { return dtcmSize; }
45-
uint32_t getItcmSize() { return itcmSize; }
41+
uint32_t read(uint8_t cn, uint8_t cm, uint8_t cp);
42+
void write(uint8_t cn, uint8_t cm, uint8_t cp, uint32_t value);
4643

4744
private:
4845
Core *core;
49-
50-
uint32_t ctrlReg = 0x00000078;
51-
uint32_t dtcmReg = 0x00000000;
52-
uint32_t itcmReg = 0x00000000;
53-
54-
uint32_t exceptionAddr = 0;
55-
bool dtcmReadEnabled = false, dtcmWriteEnabled = false;
56-
bool itcmReadEnabled = false, itcmWriteEnabled = false;
57-
uint32_t dtcmAddr = 0, dtcmSize = 0;
58-
uint32_t itcmSize = 0;
46+
uint32_t ctrlReg = 0x78;
47+
uint32_t dtcmReg = 0x00;
48+
uint32_t itcmReg = 0x00;
5949
};
6050

6151
#endif // CP15_H

src/div_sqrt.cpp

+21-30
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,27 @@ void DivSqrt::loadState(FILE *file)
5050

5151
void DivSqrt::divide()
5252
{
53-
// Set the division by zero error bit
54-
// The bit only gets set if the full 64-bit denominator is zero, even in 32-bit mode
55-
if (divDenom == 0) divCnt |= BIT(14); else divCnt &= ~BIT(14);
53+
// Set the division by zero bit based on the full 64-bit denominator, even in 32-bit mode
54+
divDenom ? (divCnt &= ~BIT(14)) : (divCnt |= BIT(14));
5655

5756
// Calculate the division result and remainder
58-
switch (divCnt & 0x0003) // Division mode
57+
switch (divCnt & 0x3) // Division mode
5958
{
6059
case 0: // 32-bit / 32-bit
6160
{
6261
if ((int32_t)divNumer == INT32_MIN && (int32_t)divDenom == -1) // Overflow
6362
{
64-
divResult = (int32_t)divNumer ^ (0xFFFFFFFFULL << 32);
63+
divResult = (int32_t)divNumer ^ (0xFFFFFFFFULL << 32);
6564
divRemResult = 0;
6665
}
6766
else if ((int32_t)divDenom != 0)
6867
{
69-
divResult = (int32_t)divNumer / (int32_t)divDenom;
68+
divResult = (int32_t)divNumer / (int32_t)divDenom;
7069
divRemResult = (int32_t)divNumer % (int32_t)divDenom;
7170
}
7271
else // Division by 0
7372
{
74-
divResult = (((int32_t)divNumer < 0) ? 1 : -1) ^ (0xFFFFFFFFULL << 32);
73+
divResult = (((int32_t)divNumer < 0) ? 1 : -1) ^ (0xFFFFFFFFULL << 32);
7574
divRemResult = (int32_t)divNumer;
7675
}
7776
break;
@@ -81,17 +80,17 @@ void DivSqrt::divide()
8180
{
8281
if (divNumer == INT64_MIN && (int32_t)divDenom == -1) // Overflow
8382
{
84-
divResult = divNumer;
83+
divResult = divNumer;
8584
divRemResult = 0;
8685
}
8786
else if ((int32_t)divDenom != 0)
8887
{
89-
divResult = divNumer / (int32_t)divDenom;
88+
divResult = divNumer / (int32_t)divDenom;
9089
divRemResult = divNumer % (int32_t)divDenom;
9190
}
9291
else // Division by 0
9392
{
94-
divResult = (divNumer < 0) ? 1 : -1;
93+
divResult = (divNumer < 0) ? 1 : -1;
9594
divRemResult = divNumer;
9695
}
9796
break;
@@ -101,17 +100,17 @@ void DivSqrt::divide()
101100
{
102101
if (divNumer == INT64_MIN && divDenom == -1) // Overflow
103102
{
104-
divResult = divNumer;
103+
divResult = divNumer;
105104
divRemResult = 0;
106105
}
107106
else if (divDenom != 0)
108107
{
109-
divResult = divNumer / divDenom;
108+
divResult = divNumer / divDenom;
110109
divRemResult = divNumer % divDenom;
111110
}
112111
else // Division by 0
113112
{
114-
divResult = (divNumer < 0) ? 1 : -1;
113+
divResult = (divNumer < 0) ? 1 : -1;
115114
divRemResult = divNumer;
116115
}
117116
break;
@@ -122,7 +121,7 @@ void DivSqrt::divide()
122121
void DivSqrt::squareRoot()
123122
{
124123
// Calculate the square root result
125-
switch (sqrtCnt & 0x0001) // Square root mode
124+
switch (sqrtCnt & 0x1) // Square root mode
126125
{
127126
case 0: // 32-bit
128127
sqrtResult = sqrt((uint32_t)sqrtParam);
@@ -136,66 +135,58 @@ void DivSqrt::squareRoot()
136135

137136
void DivSqrt::writeDivCnt(uint16_t mask, uint16_t value)
138137
{
139-
// Write to the DIVCNT register
138+
// Write to the DIVCNT register and update the division result
140139
mask &= 0x0003;
141140
divCnt = (divCnt & ~mask) | (value & mask);
142-
143141
divide();
144142
}
145143

146144
void DivSqrt::writeDivNumerL(uint32_t mask, uint32_t value)
147145
{
148-
// Write to the DIVNUMER register
146+
// Write to the DIVNUMER register and update the division result
149147
divNumer = (divNumer & ~((uint64_t)mask)) | (value & mask);
150-
151148
divide();
152149
}
153150

154151
void DivSqrt::writeDivNumerH(uint32_t mask, uint32_t value)
155152
{
156-
// Write to the DIVNUMER register
153+
// Write to the DIVNUMER register and update the division result
157154
divNumer = (divNumer & ~((uint64_t)mask << 32)) | ((uint64_t)(value & mask) << 32);
158-
159155
divide();
160156
}
161157

162158
void DivSqrt::writeDivDenomL(uint32_t mask, uint32_t value)
163159
{
164-
// Write to the DIVDENOM register
160+
// Write to the DIVDENOM register and update the division result
165161
divDenom = (divDenom & ~((uint64_t)mask)) | (value & mask);
166-
167162
divide();
168163
}
169164

170165
void DivSqrt::writeDivDenomH(uint32_t mask, uint32_t value)
171166
{
172-
// Write to the DIVDENOM register
167+
// Write to the DIVDENOM register and update the division result
173168
divDenom = (divDenom & ~((uint64_t)mask << 32)) | ((uint64_t)(value & mask) << 32);
174-
175169
divide();
176170
}
177171

178172
void DivSqrt::writeSqrtCnt(uint16_t mask, uint16_t value)
179173
{
180-
// Write to the SQRTCNT register
174+
// Write to the SQRTCNT register and update the square root result
181175
mask &= 0x0001;
182176
sqrtCnt = (sqrtCnt & ~mask) | (value & mask);
183-
184177
squareRoot();
185178
}
186179

187180
void DivSqrt::writeSqrtParamL(uint32_t mask, uint32_t value)
188181
{
189-
// Write to the DIVDENOM register
182+
// Write to the DIVDENOM register and update the square root result
190183
sqrtParam = (sqrtParam & ~((uint64_t)mask)) | (value & mask);
191-
192184
squareRoot();
193185
}
194186

195187
void DivSqrt::writeSqrtParamH(uint32_t mask, uint32_t value)
196188
{
197-
// Write to the SQRTPARAM register
189+
// Write to the SQRTPARAM register and update the square root result
198190
sqrtParam = (sqrtParam & ~((uint64_t)mask << 32)) | ((uint64_t)(value & mask) << 32);
199-
200191
squareRoot();
201192
}

src/div_sqrt.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@ class DivSqrt
3232
void saveState(FILE *file);
3333
void loadState(FILE *file);
3434

35-
uint16_t readDivCnt() { return divCnt; }
36-
uint32_t readDivNumerL() { return divNumer; }
37-
uint32_t readDivNumerH() { return divNumer >> 32; }
38-
uint32_t readDivDenomL() { return divDenom; }
39-
uint32_t readDivDenomH() { return divDenom >> 32; }
40-
uint32_t readDivResultL() { return divResult; }
41-
uint32_t readDivResultH() { return divResult >> 32; }
42-
uint32_t readDivRemResultL() { return divRemResult; }
35+
uint16_t readDivCnt() { return divCnt; }
36+
uint32_t readDivNumerL() { return divNumer; }
37+
uint32_t readDivNumerH() { return divNumer >> 32; }
38+
uint32_t readDivDenomL() { return divDenom; }
39+
uint32_t readDivDenomH() { return divDenom >> 32; }
40+
uint32_t readDivResultL() { return divResult; }
41+
uint32_t readDivResultH() { return divResult >> 32; }
42+
uint32_t readDivRemResultL() { return divRemResult; }
4343
uint32_t readDivRemResultH() { return divRemResult >> 32; }
44-
uint16_t readSqrtCnt() { return sqrtCnt; }
45-
uint32_t readSqrtResult() { return sqrtResult; }
46-
uint32_t readSqrtParamL() { return sqrtParam; }
47-
uint32_t readSqrtParamH() { return sqrtParam >> 32; }
44+
uint16_t readSqrtCnt() { return sqrtCnt; }
45+
uint32_t readSqrtResult() { return sqrtResult; }
46+
uint32_t readSqrtParamL() { return sqrtParam; }
47+
uint32_t readSqrtParamH() { return sqrtParam >> 32; }
4848

4949
void writeDivCnt(uint16_t mask, uint16_t value);
5050
void writeDivNumerL(uint32_t mask, uint32_t value);

0 commit comments

Comments
 (0)