@@ -92,14 +92,16 @@ sfcRom::sfcRom(const string& path) {
9292 {
9393 if ((mode & 0xe0 ) != 0x20 ) {
9494 correctedMode = headerLocation >= 0x8000 ? 0x21 : 0x20 ;
95- hasLegalMode = false ;
9695 hasSevereIssues = true ;
9796 ++issues;
97+ } else {
98+ hasLegalMode = true ;
9899 }
99100
100101 if (mapperName.empty ()) {
101- hasKnownMapper = false ;
102102 ++issues;
103+ } else {
104+ hasKnownMapper = true ;
103105 }
104106 }
105107
@@ -124,17 +126,20 @@ sfcRom::sfcRom(const string& path) {
124126 // Check RAM size
125127 {
126128 if ((hasRam && ramSize > 0x0f ) || (!hasRam && ramSize != 0 )) {
127- hasCorrectRamSize = false ;
128129 ++issues;
130+ } else {
131+ hasCorrectRamSize = true ;
129132 }
130133 }
131134
132135 // Calculate checksum
133136 {
134137 correctedChecksum = calculateChecksum ();
135138 correctedComplement = ~correctedChecksum;
136- if (checksum != correctedChecksum) {
139+ if (( checksum != correctedChecksum) || complement != correctedComplement ) {
137140 ++issues;
141+ } else {
142+ hasCorrectChecksum = true ;
138143 }
139144 }
140145
@@ -246,7 +251,7 @@ string sfcRom::description(bool silent) const {
246251 os << " RAM size should be 0x00" << ' \n ' ;
247252 }
248253 }
249- if (checksum != correctedChecksum || complement != correctedComplement ) {
254+ if (!hasCorrectChecksum ) {
250255 os << " Checksum/complement should be 0x" << setw (4 ) << correctedChecksum << " /0x" << setw (4 ) << correctedComplement
251256 << ' \n ' ;
252257 }
@@ -621,58 +626,53 @@ void sfcRom::getHeaderInfo(const vector<uint8_t>& header) {
621626}
622627
623628uint16_t sfcRom::calculateChecksum () const {
624- size_t imageSize = image.size ();
625- size_t mappedSize;
629+ vector<uint8_t > img = image;
630+ putWord (img, headerLocation + 0x2c , 0xffff );
631+ putWord (img, headerLocation + 0x2e , 0x0000 );
626632
627- // Base and mask for out of bounds mirroring
628- uint32_t base = 0 ;
629- uint32_t offsetMask = 0xffffffff ;
630- uint32_t offsetMod = 0xffffffff ;
633+ size_t imageSize = img.size ();
634+ size_t mappedSize;
631635
632636 if (mapper == 0x0a && chipset == 0xf9 && chipsetSubtype == 0x00 ) {
633637 // Extended HiROM/SPC7110+RTC+Battery
634638 mappedSize = imageSize;
635639 } else if (mapper == 0x0a && chipset == 0xf5 && chipsetSubtype == 0x00 ) {
636640 // Extended HiROM/SPC7110+Battery
637641 mappedSize = imageSize > 0x200000 ? imageSize << 1 : imageSize;
638- offsetMod = imageSize;
642+ while (mappedSize > img.size ()) {
643+ size_t remaining = mappedSize - img.size ();
644+ if (remaining > image.size ()) {
645+ remaining = image.size ();
646+ }
647+ if ((remaining + img.size ()) > mappedSize) {
648+ remaining = mappedSize - img.size ();
649+ }
650+ vector<uint8_t > mirror (img.begin (), img.begin () + remaining);
651+ img.insert (img.end (), mirror.begin (), mirror.end ());
652+ }
639653 } else {
654+ // Standard mapping
640655 mappedSize = 1 << (correctedRomSize != 0 ? correctedRomSize + 10 : romSize + 10 );
641- uint32_t mask = 1 ;
642- uint32_t t = imageSize;
643- while (t >>= 1 ) {
644- mask <<= 1 ;
645- mask += 1 ;
656+ while (mappedSize > img.size ()) {
657+ vector<uint8_t > mirror (img.begin () + (mappedSize >> 1 ), img.end ());
658+ img.insert (img.end (), mirror.begin (), mirror.end ());
646659 }
647- mask >>= 1 ;
648- base = mask + 1 ;
649- offsetMask = imageSize - base - 1 ;
650660 }
651661
652- // Add sum
653- auto img = image;
654- putWord (img, headerLocation + 0x2c , 0xffff );
655- putWord (img, headerLocation + 0x2e , 0x0000 );
656662 uint16_t sum = 0 ;
657-
658- for (size_t offset = 0 ; offset < mappedSize; ++offset) {
659- size_t imgOffset = offset % offsetMod;
660- if (imgOffset < imageSize) {
661- sum += img[imgOffset];
662- } else {
663- size_t mirrorOffset = base + (imgOffset & offsetMask);
664- sum += img[mirrorOffset];
665- }
663+ size_t length = img.size ();
664+ for (size_t offset = 0 ; offset < length; ++offset) {
665+ sum += img[offset];
666666 }
667667 return sum;
668668}
669669
670-
671- // Get/put little endian word
670+ // Get little endian word
672671uint16_t getWord (const vector<uint8_t >& vec, size_t offset) {
673672 return (uint16_t )((vec[offset]) + ((uint8_t )(vec[offset + 1 ]) << 8 ));
674673}
675674
675+ // Put little endian word
676676void putWord (vector<uint8_t >& vec, size_t offset, uint16_t value) {
677677 vec[offset] = (uint8_t )(value & 0xff );
678678 vec[offset + 1 ] = (uint8_t )(value >> 8 );
0 commit comments