SNES ROM Checksums.

Re: Game Genie

snes game genie and par codes CANNOT be converted to each other. the game genie modifies a byte in the snes rom, meaning you're changing the asm code or a value permanently stored in the rom. it's like taking a rom and changing a byte with a hex editor.

par codes modify memory, they force a value in memory to always be the same. rom is not covered in this memory area, only ram.

so how can there be infinite lives codes for both game genie and par? well par will take the value stored in memory, and always force it to say 3. game genie will modify the rom so the dec mem:area is overwritten with nop. there's no correlation between the location of asm code in a rom and the address it modifies.


so what's this par 2 gg code converter I found on the internet? well game code will somtimes take the easy way out and simply decrement a memory location. the asm command for this is dec xxxx, so this program will search through the entire rom looking for asm code which decrements a memory location. it only worked like once for me.
 
Re: Game Genie

> so what's this par 2 gg code converter I found on the
> internet? well game code will somtimes take the easy way out
> and simply decrement a memory location. the asm command for
> this is dec xxxx, so this program will search through the
> entire rom looking for asm code which decrements a memory
> location. it only worked like once for me.

I'm pretty sure you're wrong. My program I just wrote correctly converts between PAR and GG codes.

Game Genie codes and PAR codes both modify CPU addresses, not ROM addresses. Goldfinger codes, however, modify ROM addresses and can't address RAM, so PAR codes that address 7E0000-7FFFFF can't work. I've just made a program that can convert any code that's Game Genie, PAR, or Goldfinger into a valid code in all formats (except Goldfinger, in which case it must be in ROM and within the first 8Mbit of the ROM). However, it could be that ZSNES's emulation allows invalid Game Genie codes to work, because otherwise I can't explain codes I've converted from PAR to GG and GG to PAR having the exact same effect. I don't have a real Game Genie to test it out on.
 
Re: Game Genie

found a few sites with some information.

http://64.233.187.104/search?q=cache:3TC7KHLn_AIJ:65.110.43.80/~gshi/faqs/PAR_to_GG.html+snes+par+codes+7f&hl=en

http://www.videogamesource.com/boards/showthread.php?t=18396

zsnes (snes9x also) doesn't check for rom/ram limitations in codes, it simply takes them and applies them to zsnes's variables. rom is mapped very close to ram in the cpu, so a par code can access it through improper emulation. in the end you're basing your program off the results of a quick hack job in an emulator. zsnes emulates the snes, not the par or gg, it just converts their codes to work. so if you're gonna have a program to create codes for gg then you mine as well make sure they work on a real gg. read up some more. I have a par and have 'converted' codes that don't work on it but do in zsnes. goldfinger works the same way as gg but has less addressable rom area. you can't base results on incompletely emulated devices, your goal should be the hardware.
 
Re: Game Genie

> found a few sites with some information.
>

Thanks for the clarifications. Apparently, according to the one document you posted, and PAR codes I've seen before, the PAR can affect both RAM and ROM, which means that any Game Genie code can be converted to work on the PAR, but only PAR codes which affect ROM can be converted to work on the GG. So:

if ((codeadr>=0x7E0000)&&(codeadr<=0x7FFFFF)) printf("Code affects RAM, invalid Game Genie code\n");

would solve the problem?
 
Re: Game Genie

http://einsteinsbreakfast.com/snes/docs/rom/SNES%20memory%20mapping.txt

read that document. game genie can only affect rom, which means all those addresses that don't say rom cannot be converted from par to gg. this can change depending if the game is hirom or lorom, meaning now your program has to access the actual rom for which the codes are made to give an accurate conversion. I don't know the range the par or gg can cover, but there are limitations on them. as you can see you're barking up the wrong tree again. conversion of these codes is a cool process but you don't have enough information without actual hardware to test. if you went out and got hardware and documented all this then that'd be one thing, but releasing a program that converts codes back and forth is useless when you can just use the original code in the emu, but it will also screw the person who tries it on hardware wondering why the converted code doesn't work.

I'll whip out the old par and see what areas of memory it can alter. I have a game genie somewhere but it's dysfunctional.
 
So do you apply Data AND $FFFF after each addition? Or do you do all additions and then perform AND $FFFF the final sum? Please explain what's going on here.
 
I've recently gotten into ROM hacking and am developing a SNES rom editor/game maker. Checksum was of course one of the first hurdles. I took a gander at the ZSNES source code. There's a few things in there I am not currently familiar with (specifically where the SPC7100 enabled bit comes from). But my code calculates the correct checksum for 99% of the ROMs I have. VB rocks, so I program in VB.NET 2010. There's a lot of explanation as to how the mirroring works.

Public Function CalcCheckSum(ByRef pROMData() As Byte) As CheckSumType
Dim cst As CheckSumType
Dim CheckSum As Long = 0
Dim Sum1 As Long = 0
Dim Sum2 As Long = 0

'Make sure the ROM's byte data length is an exact power of 2.
'This is necessary for the checksum value to be calculated correctly
mirror_rom(pROMData, 0, pROMData.Length)

'The checksum is simply the sum of all the ROM's byte data (after mirroring) anded with &HFFFF
For i As Integer = 0 To UBound(pROMData)
CheckSum = CheckSum + pROMData(i)
Next i

cst.CheckSum = CInt(CheckSum And &HFFFF)
cst.ComplementCheck = (cst.CheckSum Xor &HFFFF)
Return cst
End Function

''' <summary>
''' Used to mirror a SNES ROM's byte data up to a single power of two
''' </summary>
''' <param name="pROMData">The temporary ROM byte data used in calculating the Checksum</param>
''' <param name="srcLoc">The starting array index from which memory is to be copied (using rom_memcpy)</param>
''' <param name="length">The total number of bytes being copied</param>
''' <returns>The starting point for mirroring ROM data</returns>
''' <remarks></remarks>
Private Function mirror_rom(ByRef pROMData() As Byte, ByVal srcLoc As Long, ByVal length As Long) As Integer
Dim mask As Long = &H800000

Do While ((length And mask) = 0)
mask = mask / 2
If mask = 0 Then Exit Do
Loop

length = length - mask 'subtract off the first power of two found
If length <> 0 Then 'If there are any bytes remaining in the ROM's data, the data needs to be mirrored to calculate the check sum properly
srcLoc = srcLoc + mask 'Place the ROM's cursor at the start of the extra passed a total power of 2 length

'Run this routine again to see if the extra data found is indeed a power of 2, or if there's more data
'(e.g. size = 0000 0000 0100 0001 0000 0010 0000 0000 bytes) - all three 1s need to be found and the cooresponding data mirrored up
length = mirror_rom(pROMData, srcLoc, length)

'This while loop will first execute when the last mirror_rom routine finished and length+mask is returned.
'
'Length will be the value of the last mask bit found (e.g. for size above, this is 0010 0000 0000 = 512 [first time through])
'The mask will be the value of the preceeding mask (e.g. for size above, this is 0001 0000 0000 0000 0000 = 65536 [first time through])
'This loop mirrors the extra rom data up to the net full power of two.
Do While (length <> mask) ' length is small extra data size, mask is next power of 2 ROM data size
rom_memcpy(pROMData, srcLoc, length) 'append the extra data to the end of the ROM's data
length += length 'increment to the next power of two
Loop
End If

Return (length + mask)
End Function

''' <summary>
''' Resizes temporary ROM data used for Checksum calculation and mirrors data upward
''' </summary>
''' <param name="pROMData">The temporary ROM byte data used in calculating the Checksum</param>
''' <param name="srcLoc">The beginning index in the ROM data array at which to begin copying</param>
''' <param name="length">The total number of bytes to copy/mirror</param>
''' <remarks></remarks>
Private Sub rom_memcpy(ByRef pROMData() As Byte, ByVal srcLoc As Long, ByVal length As Long)
ReDim Preserve pROMData(srcLoc + 2 * length) 'Resize the temporary ROM data size to allow the new data to be copied

'Copy/mirror the extra data in the ROM upward towards the next full power of two
For i As Integer = 0 To length - 1
pROMData(srcLoc + length + i) = pROMData(srcLoc + i) 'mirror data upward
Next i
End Sub
 
Back
Top Bottom