@@ -88,10 +88,10 @@ static const std::map<uint32_t, std::string_view> s_knownBioses = {
88
88
PCSX::Memory::Memory () : m_listener(g_system->m_eventBus) {
89
89
m_listener.listen <Events::ExecutionFlow::Reset>([this ](auto &) {
90
90
free (m_msanRAM);
91
- free (m_msanBitmap );
91
+ free (m_msanUsableBitmap );
92
92
free (m_msanWrittenBitmap);
93
93
m_msanRAM = nullptr ;
94
- m_msanBitmap = nullptr ;
94
+ m_msanUsableBitmap = nullptr ;
95
95
m_msanWrittenBitmap = nullptr ;
96
96
m_msanAllocs.clear ();
97
97
});
@@ -264,10 +264,10 @@ void PCSX::Memory::shutdown() {
264
264
free (m_writeLUT);
265
265
266
266
free (m_msanRAM);
267
- free (m_msanBitmap );
267
+ free (m_msanUsableBitmap );
268
268
free (m_msanWrittenBitmap);
269
269
m_msanRAM = nullptr ;
270
- m_msanBitmap = nullptr ;
270
+ m_msanUsableBitmap = nullptr ;
271
271
m_msanWrittenBitmap = nullptr ;
272
272
m_msanAllocs.clear ();
273
273
}
@@ -279,19 +279,18 @@ uint8_t PCSX::Memory::read8(uint32_t address) {
279
279
const bool pioConnected = g_emulator->settings .get <Emulator::SettingPIOConnected>().value ;
280
280
281
281
if (msanInitialized () && inMsanRange (address)) {
282
- uint32_t msanAddress = address - c_msanStart;
283
- if ((m_msanWrittenBitmap[msanAddress / 8 ] & (1 << (msanAddress % 8 ))) == 0 ) {
284
- g_system->log (LogClass::CPU, _ (" 8-bit read from usable but uninitialized msan memory: %8.8lx\n " ), address);
285
- g_system->pause ();
286
- return 0 ;
287
- }
288
- if (m_msanBitmap[msanAddress / 8 ] & (1 << (msanAddress % 8 ))) {
289
- return m_msanRAM[msanAddress];
290
- } else {
291
- g_system->log (LogClass::CPU, _ (" 8-bit read from unusable msan memory: %8.8lx\n " ), address);
292
- g_system->pause ();
293
- return 0 ;
282
+ switch (msanGetStatus (address, 1 )) {
283
+ case MsanStatus::UNINITIALIZED:
284
+ g_system->log (LogClass::CPU, _ (" 8-bit read from usable but uninitialized msan memory: %8.8lx\n " ), address);
285
+ break ;
286
+ case MsanStatus::UNUSABLE:
287
+ g_system->log (LogClass::CPU, _ (" 8-bit read from unusable msan memory: %8.8lx\n " ), address);
288
+ break ;
289
+ case MsanStatus::OK:
290
+ return m_msanRAM[address - c_msanStart];
294
291
}
292
+ g_system->pause ();
293
+ return 0 ;
295
294
} else if (pointer != nullptr ) {
296
295
const uint32_t offset = address & 0xffff ;
297
296
return *(pointer + offset);
@@ -328,22 +327,18 @@ uint16_t PCSX::Memory::read16(uint32_t address) {
328
327
const bool pioConnected = g_emulator->settings .get <Emulator::SettingPIOConnected>().value ;
329
328
330
329
if (msanInitialized () && inMsanRange (address)) {
331
- uint32_t msanAddress = address - c_msanStart;
332
- for (unsigned offset = 0 ; offset < 2 ; offset++) {
333
- if ((m_msanWrittenBitmap[(msanAddress + offset) / 8 ] & (1 << ((msanAddress + offset) % 8 ))) == 0 ) {
334
- g_system->log (LogClass::CPU, _ (" 16-bit read from usable but uninitialized msan memory: %8.8lx\n " ),
335
- address);
336
- g_system->pause ();
337
- return 0 ;
338
- }
339
- }
340
- if (m_msanBitmap[msanAddress / 8 ] & (1 << (msanAddress % 8 ))) {
341
- return *(uint16_t *)&m_msanRAM[msanAddress];
342
- } else {
343
- g_system->log (LogClass::CPU, _ (" 16-bit read from unusable msan memory: %8.8lx\n " ), address);
344
- g_system->pause ();
345
- return 0 ;
330
+ switch (msanGetStatus (address, 2 )) {
331
+ case MsanStatus::UNINITIALIZED:
332
+ g_system->log (LogClass::CPU, _ (" 16-bit read from usable but uninitialized msan memory: %8.8lx\n " ), address);
333
+ break ;
334
+ case MsanStatus::UNUSABLE:
335
+ g_system->log (LogClass::CPU, _ (" 16-bit read from unusable msan memory: %8.8lx\n " ), address);
336
+ break ;
337
+ case MsanStatus::OK:
338
+ return *(uint16_t *)&m_msanRAM[address - c_msanStart];
346
339
}
340
+ g_system->pause ();
341
+ return 0 ;
347
342
} else if (pointer != nullptr ) {
348
343
const uint32_t offset = address & 0xffff ;
349
344
return SWAP_LEu16 (*(uint16_t *)(pointer + offset));
@@ -377,22 +372,18 @@ uint32_t PCSX::Memory::read32(uint32_t address, ReadType readType) {
377
372
const bool pioConnected = g_emulator->settings .get <Emulator::SettingPIOConnected>().value ;
378
373
379
374
if (msanInitialized () && inMsanRange (address)) {
380
- uint32_t msanAddress = address - c_msanStart;
381
- for (unsigned offset = 0 ; offset < 4 ; offset++) {
382
- if ((m_msanWrittenBitmap[(msanAddress + offset) / 8 ] & (1 << ((msanAddress + offset) % 8 ))) == 0 ) {
383
- g_system->log (LogClass::CPU, _ (" 32-bit read from usable but uninitialized msan memory: %8.8lx\n " ),
384
- address);
385
- g_system->pause ();
386
- return 0 ;
387
- }
388
- }
389
- if (m_msanBitmap[msanAddress / 8 ] & (1 << (msanAddress % 8 ))) {
390
- return *(uint32_t *)&m_msanRAM[msanAddress];
391
- } else {
392
- g_system->log (LogClass::CPU, _ (" 32-bit read from unusable msan memory: %8.8lx\n " ), address);
393
- g_system->pause ();
394
- return 0 ;
375
+ switch (msanGetStatus (address, 4 )) {
376
+ case MsanStatus::UNINITIALIZED:
377
+ g_system->log (LogClass::CPU, _ (" 32-bit read from usable but uninitialized msan memory: %8.8lx\n " ), address);
378
+ break ;
379
+ case MsanStatus::UNUSABLE:
380
+ g_system->log (LogClass::CPU, _ (" 32-bit read from unusable msan memory: %8.8lx\n " ), address);
381
+ break ;
382
+ case MsanStatus::OK:
383
+ return *(uint32_t *)&m_msanRAM[address - c_msanStart];
395
384
}
385
+ g_system->pause ();
386
+ return 0 ;
396
387
} else if (pointer != nullptr ) {
397
388
const uint32_t offset = address & 0xffff ;
398
389
return SWAP_LEu32 (*(uint32_t *)(pointer + offset));
@@ -502,10 +493,8 @@ void PCSX::Memory::write8(uint32_t address, uint32_t value) {
502
493
const bool pioConnected = g_emulator->settings .get <Emulator::SettingPIOConnected>().value ;
503
494
504
495
if (msanInitialized () && inMsanRange (address)) {
505
- uint32_t msanAddress = address - c_msanStart;
506
- if (m_msanBitmap[msanAddress / 8 ] & (1 << (msanAddress % 8 ))) {
507
- m_msanWrittenBitmap[msanAddress / 8 ] |= (1 << (msanAddress % 8 ));
508
- m_msanRAM[msanAddress] = value;
496
+ if (msanValidateWrite (address, 1 )) {
497
+ m_msanRAM[address - c_msanStart] = value;
509
498
} else {
510
499
g_system->log (LogClass::CPU, _ (" 8-bit write to unusable msan memory: %8.8lx\n " ), address);
511
500
g_system->pause ();
@@ -539,12 +528,8 @@ void PCSX::Memory::write16(uint32_t address, uint32_t value) {
539
528
const bool pioConnected = g_emulator->settings .get <Emulator::SettingPIOConnected>().value ;
540
529
541
530
if (msanInitialized () && inMsanRange (address)) {
542
- uint32_t msanAddress = address - c_msanStart;
543
- if (m_msanBitmap[msanAddress / 8 ] & (1 << (msanAddress % 8 ))) {
544
- for (unsigned offset = 0 ; offset < 2 ; offset++) {
545
- m_msanWrittenBitmap[(msanAddress + offset) / 8 ] |= (1 << ((msanAddress + offset) % 8 ));
546
- }
547
- *(uint16_t *)&m_msanRAM[msanAddress] = value;
531
+ if (msanValidateWrite (address, 2 )) {
532
+ *(uint16_t *)&m_msanRAM[address - c_msanStart] = SWAP_LEu16 (value);
548
533
} else {
549
534
g_system->log (LogClass::CPU, _ (" 16-bit write to unusable msan memory: %8.8lx\n " ), address);
550
535
g_system->pause ();
@@ -579,12 +564,8 @@ void PCSX::Memory::write32(uint32_t address, uint32_t value) {
579
564
const bool pioConnected = g_emulator->settings .get <Emulator::SettingPIOConnected>().value ;
580
565
581
566
if (msanInitialized () && inMsanRange (address)) {
582
- uint32_t msanAddress = address - c_msanStart;
583
- if (m_msanBitmap[msanAddress / 8 ] & (1 << (msanAddress % 8 ))) {
584
- for (unsigned offset = 0 ; offset < 4 ; offset++) {
585
- m_msanWrittenBitmap[(msanAddress + offset) / 8 ] |= (1 << ((msanAddress + offset) % 8 ));
586
- }
587
- *(uint32_t *)&m_msanRAM[msanAddress] = value;
567
+ if (msanValidateWrite (address, 4 )) {
568
+ *(uint32_t *)&m_msanRAM[address - c_msanStart] = SWAP_LEu32 (value);
588
569
} else {
589
570
g_system->log (LogClass::CPU, _ (" 32-bit write to unusable msan memory: %8.8lx\n " ), address);
590
571
g_system->pause ();
@@ -820,10 +801,10 @@ void PCSX::Memory::MemoryAsFile::writeBlock(const void *src, size_t size, size_t
820
801
void PCSX::Memory::initMsan (bool reset) {
821
802
if (reset) {
822
803
free (m_msanRAM);
823
- free (m_msanBitmap );
804
+ free (m_msanUsableBitmap );
824
805
free (m_msanWrittenBitmap);
825
806
m_msanRAM = nullptr ;
826
- m_msanBitmap = nullptr ;
807
+ m_msanUsableBitmap = nullptr ;
827
808
m_msanWrittenBitmap = nullptr ;
828
809
m_msanAllocs.clear ();
829
810
m_msanChainRegistry.clear ();
@@ -836,7 +817,7 @@ void PCSX::Memory::initMsan(bool reset) {
836
817
837
818
// 1.5GB of RAM, with 384MB worth of bitmap, between 0x20000000 and 0x80000000
838
819
m_msanRAM = (uint8_t *)calloc (c_msanSize, 1 );
839
- m_msanBitmap = (uint8_t *)calloc (c_msanSize / 8 , 1 );
820
+ m_msanUsableBitmap = (uint8_t *)calloc (c_msanSize / 8 , 1 );
840
821
m_msanWrittenBitmap = (uint8_t *)calloc (c_msanSize / 8 , 1 );
841
822
m_msanPtr = 1024 ;
842
823
for (uint32_t segment = c_msanStart; segment < c_msanEnd; segment += 0x10000 ) {
@@ -864,7 +845,7 @@ uint32_t PCSX::Memory::msanAlloc(uint32_t size) {
864
845
m_msanPtr += actualSize;
865
846
// Mark the allocation as usable.
866
847
for (uint32_t i = 0 ; i < size; i++) {
867
- m_msanBitmap [(ptr + i) / 8 ] |= 1 << ((ptr + i) % 8 );
848
+ m_msanUsableBitmap [(ptr + i) / 8 ] |= 1 << ((ptr + i) % 8 );
868
849
}
869
850
870
851
// Insert the allocation into the list of allocations.
@@ -891,7 +872,7 @@ void PCSX::Memory::msanFree(uint32_t ptr) {
891
872
}
892
873
// Mark the allocation as unusable.
893
874
for (uint32_t i = 0 ; i < m_msanAllocs[ptr]; i++) {
894
- m_msanBitmap [(ptr + i) / 8 ] &= ~(1 << ((ptr + i) % 8 ));
875
+ m_msanUsableBitmap [(ptr + i) / 8 ] &= ~(1 << ((ptr + i) % 8 ));
895
876
}
896
877
// Remove the allocation from the list of allocations.
897
878
m_msanAllocs.erase (ptr);
@@ -930,7 +911,7 @@ uint32_t PCSX::Memory::msanRealloc(uint32_t ptr, uint32_t size) {
930
911
931
912
// Mark the old allocation as unusable
932
913
for (uint32_t i = 0 ; i < oldSize; i++) {
933
- m_msanBitmap [(ptr + i) / 8 ] &= ~(1 << ((ptr + i) % 8 ));
914
+ m_msanUsableBitmap [(ptr + i) / 8 ] &= ~(1 << ((ptr + i) % 8 ));
934
915
}
935
916
// Mark the new allocation as written to
936
917
auto toCopy = std::min (size, oldSize);
@@ -942,6 +923,30 @@ uint32_t PCSX::Memory::msanRealloc(uint32_t ptr, uint32_t size) {
942
923
return newPtr + c_msanStart;
943
924
}
944
925
926
+ PCSX::MsanStatus PCSX::Memory::msanGetStatus (uint32_t addr, uint32_t size) const {
927
+ uint32_t msanAddr = addr - c_msanStart;
928
+ if (!(m_msanUsableBitmap[msanAddr / 8 ] & (1 << msanAddr % 8 ))) {
929
+ return PCSX::MsanStatus::UNUSABLE;
930
+ }
931
+ for (uint32_t checkAddr = msanAddr; checkAddr < msanAddr + size; checkAddr++) {
932
+ if (!(m_msanWrittenBitmap[checkAddr / 8 ] & (1 << checkAddr % 8 ))) {
933
+ return PCSX::MsanStatus::UNINITIALIZED;
934
+ }
935
+ }
936
+ return PCSX::MsanStatus::OK;
937
+ }
938
+
939
+ bool PCSX::Memory::msanValidateWrite (uint32_t addr, uint32_t size) {
940
+ uint32_t msanAddr = addr - c_msanStart;
941
+ if (!(m_msanUsableBitmap[msanAddr / 8 ] & (1 << msanAddr % 8 ))) {
942
+ return false ;
943
+ }
944
+ for (uint32_t checkAddr = msanAddr; checkAddr < msanAddr + size; checkAddr++) {
945
+ m_msanWrittenBitmap[checkAddr / 8 ] |= 1 << checkAddr % 8 ;
946
+ }
947
+ return true ;
948
+ }
949
+
945
950
uint32_t PCSX::Memory::msanSetChainPtr (uint32_t headerAddr, uint32_t nextPtr, uint32_t wordCount) {
946
951
if (!inMsanRange (headerAddr)) {
947
952
headerAddr &= 0xffffff ;
0 commit comments