Skip to content

Commit 9212bd1

Browse files
author
Bim Overbohm
committed
Make ROM speed testing work
1 parent adf4a0f commit 9212bd1

File tree

7 files changed

+66
-47
lines changed

7 files changed

+66
-47
lines changed

112.png

-88.9 KB
Loading

336.png

-102 KB
Loading

MemTestGBA.gba

2.05 KB
Binary file not shown.

MemTestGBA.png

-30.9 KB
Loading

src/cmake/CompilerFlagsGBA.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ set(COMPILERFLAGS "-save-temps -Wall -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame
1818
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--warn -x assembler-with-cpp ${ARCH}")
1919
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH} ${COMPILERFLAGS} -std=c11")
2020
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -Og -g")
21-
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O2")
22-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH} ${COMPILERFLAGS} -std=c++17 -fconserve-space -fno-threadsafe-statics -fno-rtti -fno-exceptions")
21+
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3")
22+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH} ${COMPILERFLAGS} -std=c++17 -fno-threadsafe-statics -fno-rtti -fno-exceptions")
2323
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -Og -g")
24-
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O")
24+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3")
2525
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ARCH}")
2626
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}")
2727
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS} -s")

src/main.cpp

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct alignas(4) TestConfig
2222
struct alignas(4) SpeedResult
2323
{
2424
int32_t romTime = 0;
25+
uint32_t bytesPerRomTest = 0;
2526
int32_t readTime = 0;
2627
int32_t writeTime = 0;
2728
int32_t setTime = 0;
@@ -30,26 +31,33 @@ struct alignas(4) SpeedResult
3031
int32_t copyFromTime = 0;
3132
int32_t copyToDMATime = 0;
3233
int32_t copyFromDMATime = 0;
33-
uint32_t bytesPerTest = 0;
34+
uint32_t bytesPerRamTest = 0;
3435
};
3536

3637
// define all functions here, so we can put them into IWRAM
38+
#define NOINLINE __attribute__((noinline))
39+
3740
void printSpeed(int32_t time, uint32_t bytes, uint16_t x, uint16_t y, TUI::Color backColor, TUI::Color textColor) IWRAM_CODE;
3841
template <typename F>
3942
void runBlockwise(F func, const TestConfig &config) IWRAM_CODE;
40-
void readBlock(void *source, uint32_t value, uint32_t nrOfWords) IWRAM_CODE;
43+
void readBlock(const void *source, uint32_t value, uint32_t nrOfWords) IWRAM_CODE;
4144
void writeBlock(void *destination, uint32_t value, uint32_t nrOfWords) IWRAM_CODE;
4245
template <typename F>
4346
int32_t runFunctionBlockwise(F func, const TestConfig &config, uint32_t nrOfCycles) IWRAM_CODE;
4447
template <typename F>
45-
int32_t runFunction(F func, const TestConfig &config, uint32_t nrOfCycles) IWRAM_CODE;
48+
int32_t runFunctionOnSrc(F func, const TestConfig &config, uint32_t nrOfCycles) IWRAM_CODE;
49+
template <typename F>
50+
int32_t runFunctionOnDest(F func, const TestConfig &config, uint32_t nrOfCycles) IWRAM_CODE;
4651
SpeedResult runSpeedTest(const TestConfig &config, uint32_t nrOfCycles) IWRAM_CODE;
4752
uint32_t testPattern(uint32_t index) IWRAM_CODE;
4853
uint32_t runErrorTest(const TestConfig &config, uint32_t nrOfCycles, uint32_t pattern) IWRAM_CODE;
49-
int32_t getTime() IWRAM_CODE;
50-
void updateTime() IWRAM_CODE;
54+
int32_t getTime() NOINLINE IWRAM_CODE;
55+
void updateTime() NOINLINE IWRAM_CODE;
5156
void updateBlinkState() IWRAM_CODE;
5257
void updateInput() IWRAM_CODE;
58+
void printTestState() IWRAM_CODE;
59+
void printRamTimings() IWRAM_CODE;
60+
void printRomWaitStates() IWRAM_CODE;
5361
int main() IWRAM_CODE;
5462

5563
// ------------------------------------------------------------------------------------------------
@@ -85,7 +93,7 @@ void runBlockwise(F func, const TestConfig &config)
8593
}
8694
}
8795

88-
void readBlock(void *source, uint32_t value, uint32_t nrOfWords)
96+
void readBlock(const void *source, uint32_t value, uint32_t nrOfWords)
8997
{
9098
uint32_t v = value;
9199
auto src32 = reinterpret_cast<const uint32_t *>(source);
@@ -121,7 +129,18 @@ int32_t runFunctionBlockwise(F func, const TestConfig &config, uint32_t nrOfCycl
121129
}
122130

123131
template <typename F>
124-
int32_t runFunction(F func, const TestConfig &config, uint32_t nrOfCycles)
132+
int32_t runFunctionOnSrc(F func, const TestConfig &config, uint32_t nrOfCycles)
133+
{
134+
auto startTime = getTime();
135+
for (uint32_t cycle = 0; cycle < nrOfCycles; cycle++)
136+
{
137+
func(config.src, 0x12345678, config.srcSize >> 2);
138+
}
139+
return getTime() - startTime;
140+
}
141+
142+
template <typename F>
143+
int32_t runFunctionOnDest(F func, const TestConfig &config, uint32_t nrOfCycles)
125144
{
126145
auto startTime = getTime();
127146
for (uint32_t cycle = 0; cycle < nrOfCycles; cycle++)
@@ -133,16 +152,16 @@ int32_t runFunction(F func, const TestConfig &config, uint32_t nrOfCycles)
133152

134153
SpeedResult runSpeedTest(const TestConfig &config, uint32_t nrOfCycles)
135154
{
136-
SpeedResult result = {0, 0, 0, 0, 0, 0, 0, 0, 0, config.destSize * nrOfCycles};
155+
SpeedResult result = {0, ROM_DATA_SIZE * 4 * nrOfCycles, 0, 0, 0, 0, 0, 0, 0, 0, config.destSize * nrOfCycles};
137156
auto rom = config;
138157
rom.src = reinterpret_cast<const uint8_t *>(ROM_DATA);
139158
rom.srcSize = ROM_DATA_SIZE * 4;
140-
result.romTime = runFunction(readBlock, rom, nrOfCycles);
159+
result.romTime = runFunctionOnSrc(readBlock, rom, nrOfCycles);
141160
auto to = config;
142-
result.readTime = runFunction(readBlock, to, nrOfCycles);
143-
result.writeTime = runFunction(writeBlock, to, nrOfCycles);
144-
result.setTime = runFunction(Memory::memset32, to, nrOfCycles);
145-
result.setDMATime = runFunction(DMA::dma_fill32, to, nrOfCycles);
161+
result.readTime = runFunctionOnDest(readBlock, to, nrOfCycles);
162+
result.writeTime = runFunctionOnDest(writeBlock, to, nrOfCycles);
163+
result.setTime = runFunctionOnDest(Memory::memset32, to, nrOfCycles);
164+
result.setDMATime = runFunctionOnDest(DMA::dma_fill32, to, nrOfCycles);
146165
TestConfig from = {const_cast<uint8_t *>(config.src), config.srcSize, config.dest, config.destSize};
147166
result.copyFromTime = runFunctionBlockwise(Memory::memcpy32, from, nrOfCycles);
148167
result.copyToTime = runFunctionBlockwise(Memory::memcpy32, to, nrOfCycles);
@@ -240,12 +259,6 @@ void updateTime()
240259
TimerTicks += TimerIncrement;
241260
}
242261

243-
void printTestState()
244-
{
245-
TUI::printString("Error test", 4, 16, TUI::Color::LightGray, !testSpeed && blinkState ? TUI::Color::Red : TUI::Color::Blue);
246-
TUI::printString("Speed test", 20, 16, TUI::Color::LightGray, testSpeed && blinkState ? TUI::Color::Red : TUI::Color::Blue);
247-
}
248-
249262
void updateBlinkState()
250263
{
251264
// blink UI elements
@@ -254,13 +267,19 @@ void updateBlinkState()
254267
printTestState();
255268
}
256269

257-
void updateRamTimings()
270+
void printTestState()
271+
{
272+
TUI::printString("Error test", 4, 16, TUI::Color::LightGray, !testSpeed && blinkState ? TUI::Color::Red : TUI::Color::Blue);
273+
TUI::printString("Speed test", 20, 16, TUI::Color::LightGray, testSpeed && blinkState ? TUI::Color::Red : TUI::Color::Blue);
274+
}
275+
276+
void printRamTimings()
258277
{
259278
TUI::printString(RamWaitStateStrings[ramWaitStateIndex], 15, 3, TUI::Color::Blue, TUI::Color::White);
260279
TUI::printString(RamWaitStateOptionStrings[ramWaitStateIndex], 0, 17, TUI::Color::LightGray, TUI::Color::Blue);
261280
}
262281

263-
void updateRomWaitStates()
282+
void printRomWaitStates()
264283
{
265284
TUI::printString(RomWaitStateStrings[romWaitStateIndex], 26, 3, TUI::Color::Blue, TUI::Color::White);
266285
TUI::printString(RomWaitStateOptionStrings[romWaitStateIndex], 0, 18, TUI::Color::LightGray, TUI::Color::Blue);
@@ -283,7 +302,7 @@ void updateInput()
283302
if (ramWaitStateIndex != ramWaitStateIndexBefore)
284303
{
285304
Memory::RegWaitEwram = RamWaitStates[ramWaitStateIndex];
286-
updateRamTimings();
305+
printRamTimings();
287306
}
288307
// check if need to change ROM wait states
289308
auto romWaitStateIndexBefore = romWaitStateIndex;
@@ -298,7 +317,7 @@ void updateInput()
298317
if (romWaitStateIndex != romWaitStateIndexBefore)
299318
{
300319
Memory::RegWaitCnt = RomWaitStates[romWaitStateIndex];
301-
updateRomWaitStates();
320+
printRomWaitStates();
302321
}
303322
// check if we need to change the test mode
304323
auto testSpeedBefore = testSpeed;
@@ -350,11 +369,11 @@ int main()
350369
TUI::printString(RamWaitStateOptionStrings[ramWaitStateIndex], 0, 17, TUI::Color::LightGray, TUI::Color::Blue);
351370
TUI::printString(RomWaitStateOptionStrings[romWaitStateIndex], 0, 18, TUI::Color::LightGray, TUI::Color::Blue);
352371
TUI::printString(" (START) Reboot ", 0, 19, TUI::Color::LightGray, TUI::Color::Blue);
353-
updateRamTimings();
354-
updateRomWaitStates();
372+
printRamTimings();
373+
printRomWaitStates();
355374
// start wall clock
356375
irqInit();
357-
// set up time to increase time every ~5ms
376+
// set up time to increase time every ~2.5ms
358377
irqSet(irqMASKS::IRQ_TIMER3, updateTime);
359378
irqEnable(irqMASKS::IRQ_TIMER3);
360379
REG_TM3CNT_L = 65536 - TimerIncrement;
@@ -378,15 +397,15 @@ int main()
378397
if (testSpeed)
379398
{
380399
auto result = runSpeedTest(testConfig, CyclesSpeed);
381-
printSpeed(result.romTime, result.bytesPerTest, 15, 5, TUI::Color::Blue, TUI::Color::White);
382-
printSpeed(result.readTime, result.bytesPerTest, 15, 6, TUI::Color::Blue, TUI::Color::White);
383-
printSpeed(result.writeTime, result.bytesPerTest, 15, 7, TUI::Color::Blue, TUI::Color::White);
384-
printSpeed(result.setTime, result.bytesPerTest, 15, 8, TUI::Color::Blue, TUI::Color::White);
385-
printSpeed(result.setDMATime, result.bytesPerTest, 15, 9, TUI::Color::Blue, TUI::Color::White);
386-
printSpeed(result.copyFromTime, result.bytesPerTest, 15, 10, TUI::Color::Blue, TUI::Color::White);
387-
printSpeed(result.copyToTime, result.bytesPerTest, 15, 11, TUI::Color::Blue, TUI::Color::White);
388-
printSpeed(result.copyFromDMATime, result.bytesPerTest, 18, 12, TUI::Color::Blue, TUI::Color::White);
389-
printSpeed(result.copyToDMATime, result.bytesPerTest, 18, 13, TUI::Color::Blue, TUI::Color::White);
400+
printSpeed(result.romTime, result.bytesPerRomTest, 15, 5, TUI::Color::Blue, TUI::Color::White);
401+
printSpeed(result.readTime, result.bytesPerRamTest, 15, 6, TUI::Color::Blue, TUI::Color::White);
402+
printSpeed(result.writeTime, result.bytesPerRamTest, 15, 7, TUI::Color::Blue, TUI::Color::White);
403+
printSpeed(result.setTime, result.bytesPerRamTest, 15, 8, TUI::Color::Blue, TUI::Color::White);
404+
printSpeed(result.setDMATime, result.bytesPerRamTest, 15, 9, TUI::Color::Blue, TUI::Color::White);
405+
printSpeed(result.copyFromTime, result.bytesPerRamTest, 15, 10, TUI::Color::Blue, TUI::Color::White);
406+
printSpeed(result.copyToTime, result.bytesPerRamTest, 15, 11, TUI::Color::Blue, TUI::Color::White);
407+
printSpeed(result.copyFromDMATime, result.bytesPerRamTest, 18, 12, TUI::Color::Blue, TUI::Color::White);
408+
printSpeed(result.copyToDMATime, result.bytesPerRamTest, 18, 13, TUI::Color::Blue, TUI::Color::White);
390409
}
391410
else
392411
{

src/memory.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,24 @@ namespace Memory
2020
extern uint8_t EWRAM_BLOCK[EWRAM_ALLOC_SIZE] EWRAM_DATA;
2121

2222
/// @brief Register for Game Pak SRAM and ROM wait states
23-
constexpr reg_t<uint16_t, REG_BASE + 0x0204> RegWaitCnt;
23+
constexpr reg_t<uint32_t, REG_BASE + 0x0204> RegWaitCnt;
2424

25-
/// @brief Minimum wait states possible for Game Pak ROM (2,1) and faster SRAM wait states (4)
25+
/// @brief Minimum wait states possible for Game Pak ROM (2,1 / 2,1 / 2,1) and faster SRAM wait states (4)
2626
/// See: http://problemkaputt.de/gbatek.htm#gbasystemcontrol
27-
constexpr uint16_t WaitCntFast = 0x46D8;
27+
constexpr uint32_t WaitCntFast = 0x46D8;
2828

29-
/// @brief Regular wait states possible for Game Pak ROM (3,1) and maximum SRAM wait states (8)
29+
/// @brief Regular wait states possible for Game Pak ROM (3,1 / 3,1 / 3,1) and maximum SRAM wait states (8)
3030
/// This is what most commercial carts use.
3131
/// See: http://problemkaputt.de/gbatek.htm#gbasystemcontrol
32-
constexpr uint16_t WaitCntNormal = 0x4317;
32+
constexpr uint32_t WaitCntNormal = 0x45B7;
3333

34-
/// @brief Slower wait states possible for Game Pak ROM (4,2) and maximum SRAM wait states (8)
34+
/// @brief Slower wait states possible for Game Pak ROM (4,2 / 4,4 / 4,8) and maximum SRAM wait states (8)
3535
/// See: http://problemkaputt.de/gbatek.htm#gbasystemcontrol
36-
constexpr uint16_t WaitCntSlow = 0x4303;
36+
constexpr uint32_t WaitCntSlow = 0x4003;
3737

38-
/// @brief Maximum wait states possible for Game Pak ROM (8,2) and maximum SRAM wait states (8)
38+
/// @brief Maximum wait states possible for Game Pak ROM (8,2 / 8,4 / 8,8) and maximum SRAM wait states (8)
3939
/// See: http://problemkaputt.de/gbatek.htm#gbasystemcontrol
40-
constexpr uint16_t WaitCntSlowest = 0x430F;
40+
constexpr uint32_t WaitCntSlowest = 0x436F;
4141

4242
/// @brief Register for EWRAM wait states
4343
constexpr reg_t<uint32_t, REG_BASE + 0x0800> RegWaitEwram;

0 commit comments

Comments
 (0)