SMW Save routine
From SnesLab
The Super Mario World save routine is the routine that, well, saves the game. The routine begins at $009BC9. The documentation here was done by p4plus2.
The Routine
save: ;
PHB ;\ Switch to current data bank
PHK ; |
PLB ;/
LDX.w $010A ; Load save game
LDA.w high_byte,X ;\ Get SRAM index
XBA ; |
LDA.w low_byte,X ; |
REP #$10 ; |
TAX ;/ Transfer to X
.write_file ;
LDY.w #$0000 ; Initalize the buffer index to 0
STY $8A ; Zero the checksum counter
.copy_buffer ;
LDA.w $1F49,Y ;\ Copy one byte over
STA.l $700000,X ;/
CLC ;\ Add the value of the mirror to the checksum
ADC $8A ; |
STA $8A ; |
BCC .no_carry ; | Handle overflow
INC $8B ;/
.no_carry ;
INX ; Increment the SRAM index
INY ; Increment the save buffer index
CPY.w #$008D ;\ Check if the entire buffer is copied
BCC .copy_buffer ;/ Loop again if not
REP #$20 ; 16 bit A
LDA.w #$5A5A ; Load the default checksum value
SEC ;\ Subtract to get the correct complement
SBC $8A ; |
STA.l $700000,X ;/
CPX.w #$01AD ;\ If at the end of SRAM
BCS .return ;/
TXA ;\ Offset the file and duplicate it
ADC.w #$0120 ; |
TAX ;/
SEP #$20 ; 8 bit A
BRA .write_file ; Duplicate file(used to finish the checksum)
;
.return ;
SEP #$30 ;\ Restore data banks and return
PLB ; |
RTL ;/
high_byte:
db $00,$00,$01
low_byte:
db $00,$8F,$1E
Explanation
Get the file index. Index a table to get the SRAM address. Copy the SRAM buffer to SRAM ($1F49, which is actually a mirror of $7E:1EA2-$7E:1F2E). While doing this it keeps a sum of the buffers contents, this is used to calculate the check sum complement.($8D contains the sum). The check sum is subtracted from #$5A5A (the default checksum value) and written to SRAM as the last byte of the file. Make a duplicate copy of the file, presumably this was to ensure data integrity. (Basically repeated from step 3, however 288 bytes are added to the SRAM index).