We've just updated MediaWiki and its underlying software. If anything doesn't look or work quite right, please mention it to us. --RanAS

SMW Save routine

From SnesLab
Jump to: navigation, search

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).