Language…
18 users online:  AmperSam,  Anorakun, CharlieUltra, Courage2006, DanMario24YT, Dennsen86, elegist, GamesInTweed, Golden Yoshi, Green Jerry, GRIMMKIN, Metal-Yoshi94, Nayfal, PuffleDreemurr, signature_steve, slopcore, TheXander, Tulip Time Scholarship Games - Guests: 303 - Bots: 444
Users: 64,795 (2,370 active)
Latest user: mathew

Yoshi's Island Disassembly Project v2.0

Resource

A few months ago, I had the urge to start disassembling Yoshi's Island. I couldn't take on such a big project alone, so I enlisted Raidenthequick (who comes from the YI speedrunning community) and we started to work.

We're nowhere near done yet, but I've been tossing around the idea of making a thread to document our progress for a while now; I figured now would be as good of a time as any!

Git repository: Contains up-to-date full disassembly.

Progress spreadsheet

Verbose progress report (updated constantly)

Disassembly data dump wikia
My personal findings/progress thus far:

Mostly sprite-related. I have fully disassembled bank 03, which is kind of the "main sprite bank" and I'm pretty sure it's good/correct though I'd like a review if anyone would be so kind. (Disassembly/bank03.txt) Currently duking out all the sprites in these tables, which spans multiple banks and will take a while. Me and Alex decided to go half and half on them, though of course I got the half with all the bosses :3

Speaking of, I figured out Hookbill's AI and I documented all of my findings for anyone curious (in bank 01 pretty much at the beginning).

Beyond that, helped figure out the level header layout / copying routine (at $108B05 for the curious) and lots of other random junk.
The stuff I've done thus far is pretty scattered, but:

I've almost completely finished disassembling bank $00. There's some tables in there that I'm unsure of, but I'll iron those out soon. The stuff in there is mostly init routines and such. I started working on plowing through the posts in the offset thread to see what's already been documented, and disassembling them. As a result, I've documented a lot of things across a lot of banks (banks $17, $3F, $0F, $0A and $08 come to mind).

As raiden said, we've been churning out sprites in tandem. I don't know how many he's done exactly, but between us we have in the ballpark of 50 sprites fully disassembled. The sprite I'm working on at this very second is the shy-guys on stilts.

Additionally, I recently started disassembling some of the GSU (super fx) routines in banks $08, $09, $0A and $0B. I've only done a couple thus far, but we've been logging every GSU call that we come across (see the list here).

Over the past few weeks I've also been trying to figure out level data. I haven't moved onto sprites quite yet, but the objects in a level are laid out thusly:

Code
OOOOOOOO YYYYXXXX yyyyxxxx LLLLLLLL HHHHHHHH
OOOOOOOO = object number
YYYYyyyy = y-position
XXXXxxxx = x-position
LLLLLLLL = length
HHHHHHHH = height
objects that cannot be extended in a certain direction omit the last byte


Some minor stuff I've done here and there: some palette and tilemap documentation, a few level modes disassembled, and some graphics.

e: also you can view how the level header is compressed here
In fact, the header as you noted it down in the document is not quite correct anymore; at least some bits of there aren't as unknown anymore as they were back in the EggVine-Days; I'll try and post an updated table of the header bits later on.

On a side note, do any of you happen to know, how to know whether a GFX File is compressed or not?

A bit of background: There is a table at headered PC 0x37B1F, SNES $06:F71F with 0x1D9 entries, 3 byte/entry; ending at headered PC 0x380A9, SNES $06:FEA9.
Each entry is a pointer to one of the GFX files. Some of them are compressed, some of them are not.
The address is calculated as follows: Take an entry, for example entry 0x159, found at headered PC 0x37B1F + 3*0x159 = 0x37F2A, SNES $06:FD2A; there are three bytes there: [4A F8 5C].
Now these are little-endian, so you revert them: [5C F8 4A].
Getting their headered PC addresses is easy now, you subtract 0x400000 and add 0x200 => 0x5CF84A - 0x400000 + 0x200 = 0x1CFA4A
So, by retrieving the addresses on their own, I don't see how it's possible to tell whether the data is compressed or not.

On another note, what kind of compression is used? I have found something about the LC_LZ2 compression, which is used for SMW, but it could be, that some other stuff is used as well. Also, the GFX Files are either 4BBP, 2BBP or Tilemap-Format; is there a way to find out, which?


Yeah, that's a lot of questions, but I hope at least the most important one can be answered (finding out whether a GFX File is compressed or uncompressed)
NEW! SMW2 Yoshi's Island is done!
Last update: 2012-12-31
I'll answer the rest later but

Originally posted by Yoshis Fan
In fact, the header as you noted it down in the document is not quite correct anymore; at least some bits of there aren't as unknown anymore as they were back in the EggVine-Days; I'll try and post an updated table of the header bits later on.

That would be fantastic.

e: to figure out if a GFX file is compressed, try compressing it again; if it shrinks by any noticeable amount, it's not compressed. This works even for unknown compression methods.

I'll figure out which compression method is used later
Sadly, that isn't exactly helpful; there is only one tool, which is able to decompress/compress graphics from/to a ROM, and that is YCompress. The problem is, that I want to write an application, which is able to decompress the graphics and I was hoping for a table or something like that, which tells the game, what method (if any) of decompression it has to use for each graphics file.

Anyways, as for the Level Header, this is what I've come up with:

Code
                //    TYPE              LEN      BYTE:BIT
		// BG Color              5       0:0 - 0:4
		// BG 1 Tileset          4       0:5 - 1:0
		// BG 1 Palette          5       1:1 - 1:5
		// BG 2 Tileset          5       1:6 - 2:2
		// BG 2 Palette          6       2:3 - 3:0
		// BG 3 Tileset          6       3:1 - 3:6
		// BG 3 Palette          6       3:7 - 4:4
		// Sprite Tileset        7       4:5 - 5:3
		// Sprite Palette        4       5:4 - 5:7
		// Level Mode            5       6:0 - 6:4
		// Animation Tileset     6       6:5 - 7:2
		// Animation Palette     5       7:3 - 7:7
		// BG Scrolling          5       8:0 - 8:4
		// Music                 4       8:5 - 9:0
		// Item Memory           2       9:1 - 9:2
		// Unused                5       9:3 - 9:7

NEW! SMW2 Yoshi's Island is done!
Last update: 2012-12-31
Looking around for such a table right now. In the meantime, YI uses LC_LZ2 and LC_LZ16. The latter is a gsu routine located at $0A8000. I'll disassemble that routine in a minute.

Thanks for the header info!

e: you can see how LC_LZ16 works here.
Sadly LC_LZ16 is not as well-documented as LC_LZ2 and I have no idea how the decompression works by reading this post... :/
The LC_LZ2 was easy to understand and to implement, because we have an Article about it here in the Wiki. Maybe you disassembling that routine can shed some light?

Edit:
I have used DotPeek for disassembling Golden Egg at least partially, it's a mess without comments...
Anyway, I think I have found the Class, which is responsible for decompressing the GFX and by the looks of it he's just translated the SNES Assembly into C# code ^^
Decompress.cs
I'll see if I can get any new insights from this.
Romi must return and release the source of GE, it's better than EggVine, but there are still many things to improve.
NEW! SMW2 Yoshi's Island is done!
Last update: 2012-12-31
Originally posted by Yoshis Fan
Maybe you disassembling that routine can shed some light?

Probably will. Figuring it out right now.

e: Raidenthequick and I have discussed the possibility of making an editor. It's still up in the air, and certainly won't begin until we finish the disassembly, but it's a possibility.
Level data format for sprites

Code
IIIIIIII YYYYYYYY XXXXXXXX

IIIIIIII = sprite ID
YYYYYYYY = y-position
XXXXXXXX = x-position
y-position is shifted right one bit in golden egg
e.g. 01101010 -> 00110101


Sprites are organized by room. The end of the room is marked with two $FF's.

Warning: Opinions expressed by Lexie or others in this post do not necessarily reflect the views, opinions, or position of Lexie himself on the matter(s) being discussed therein.


Yoshi's Island Disassembly C3 Thread
SPASM - LevelASM for Yoshi's Island!
Yoshi's Island Disassembly Data Dump Wiki
There's no need to post that, it is already exactly known how to read Level Data, you can just ask me =P



Code
Level Header is 10 Bytes

5-Byte Objects:
 IIIIIIII	ID (can't be 00/FF)
 XXXXYYYY	High X and High Y
 xxxxyyyy	Low X and Low Y
 WWWWWWWW	Width - 1, signed
 HHHHHHHH	Height - 1, signed

01 76 45 03 04 => Object 01 at (74|65) with Width 4, Height 5

4-Byte Objects:
 IIIIIIII	ID (can't be 00/FF)
 XXXXYYYY	High X and High Y
 xxxxyyyy	Low X and Low Y
 LLLLLLLL	Length - 1, signed

3C 73 48 FE => Object 3C at (74|38) with length -3

4-Byte Xtended Objects
 00000000	This Byte is always zero
 XXXXYYYY	High X and High Y
 xxxxyyyy	Low X and Low Y
 IIIIIIII	ID

00 70 F0 FF => Xtended Object FF at (7F|00)

Sprites (3 Bytes each)
 iiiiiiii	Low ID
 YYYYYYYI	High ID and Y-Coordinate
 XXXXXXXX	X-Coordinate

3D A9 78 => Sprite 0x13D at (78|54)

Screen Exits (Level-Warp, 5 Bytes each)
 TTTTTTTT	Target page (between 00 and 7F)
 LLLLLLLL	Destination Level (between 00 and DD)
 XXXXXXXX	Destination X-Coordinate
 YYYYYYYY	Destination Y-Coordinate
 EEEEEEEE	Destination Entrance Type (between 00 and 0A)

70 00 0A 77 05 => At Screen Position (0|7), leads to Level 0, X-Coordinate 0A, Y-Coordinate 77, exits Pipe

Screen Exits (Minibattle, Entrance Type = 0, 5 Bytes each)
 TTTTTTTT	Target page (between 00 and 7F)
 MMMMMMMM	Destination Minibattle (between DE and E9)
 XXXXXXXX	Return X-Coordinate
 YYYYYYYY	Return Y-Coordinate
 LLLLLLLL	Return Level (between 00 and E9)

70 DF 0A 77 05 => At Screen Position (0|7), leads to Minibattle 2, returns at X-Coordinate 0A, Y-Coordinate 77, Level 05, exits Door


How to read Level Data:
Code
currentOffset = objectDataOffset
levelObjects = new List<Object>
screenExits = new List<Screenexit>

levelHeader = GenerateLevelHeader(rom, currentOffset)
currentOffset += 10

//An FF is no Object, it's the end of Object Data
while(rom[currentOffset] != FF):
  levelObjects.append(GenerateObject(rom, currentOffset))
  currentOffset += levelObjects.Last().GetLength() //Either 4 or 5

//Must be incremented or you're stuck at the first FF
currentOffset++

//An FF is no Target Page, it's the end of Screen Exit Data
while(rom[currentOffset] != FF):
  screenExits.append(GenerateScreenExit(rom, currentOffset))
  currentOffset += 5


currentOffset = spriteDataOffset
sprites = new List<Sprite>
//Two consecutive FF-bytes mark the end of Sprite Data
while(rom[currentOffset] != FF && rom[currentOffset+1] != FF):
  sprites.append(GenerateSprite(rom, currentOffset)
  currentOffset += 3

NEW! SMW2 Yoshi's Island is done!
Last update: 2012-12-31
u shittin me

I spent so long figuring this out ARGH

oh well, thank you anyway

Warning: Opinions expressed by Lexie or others in this post do not necessarily reflect the views, opinions, or position of Lexie himself on the matter(s) being discussed therein.


Yoshi's Island Disassembly C3 Thread
SPASM - LevelASM for Yoshi's Island!
Yoshi's Island Disassembly Data Dump Wiki
Hello good friends,

I spent some time on Raphael tonight and figured out why sometimes he doesn't move at the beginning. Sharing my findings here:

http://pastebin.com/iYgKVSWf

I am also more than halfway done disassembling him and have several RAM addresses of his documented. Fun times.
Nice finds. Raphael is definitely one of the more complex bosses in the game with the moon sequence and all that.

Hopefully we can get those maps up soon (still not sure what we're waiting on at this point...)
<p4plus2> Lexie: I've been busy
<p4plus2> I'll get to it when I can

Warning: Opinions expressed by Lexie or others in this post do not necessarily reflect the views, opinions, or position of Lexie himself on the matter(s) being discussed therein.


Yoshi's Island Disassembly C3 Thread
SPASM - LevelASM for Yoshi's Island!
Yoshi's Island Disassembly Data Dump Wiki
Figured out the local and sram high score saving routines

Code
; save high score loop
$01/BE9D 20 E4 BE    JSR $BEE4  [$00:BEE4]   ;
$01/BEA0 A5 36       LDA $36    [$00:0036]   ;
$01/BEA2 05 35       ORA $35    [$00:0035]   ;
$01/BEA4 29 F0       AND #$F0                ;
$01/BEA6 F0 3B       BEQ $3B    [$BEE3]      ;
$01/BEA8 22 B7 B2 01 JSL $01B2B7[$01:B2B7]   ;
$01/BEAC A2 1F       LDX #$1F                ;
$01/BEAE AD 85 03    LDA $0385  [$00:0385]   ;\
$01/BEB1 10 05       BPL $05    [$BEB8]      ; |
$01/BEB3 20 38 BF    JSR $BF38  [$00:BF38]   ; | if bonus, go to bonus game
$01/BEB6 A2 29       LDX #$29                ; |
$01/BEB8 8E 18 01    STX $0118  [$00:0118]   ;/ 
$01/BEBB A9 F1       LDA #$F1                ;
$01/BEBD 85 4D       STA $4D    [$00:004D]   ;
$01/BEBF EE 20 02    INC $0220  [$00:0220]   ;
$01/BEC2 AE 1A 02    LDX $021A  [$00:021A]   ; load level ID
$01/BEC5 AD 0C 03    LDA $030C  [$00:030C]   ; load current or high score (whichever is higher)
$01/BEC8 DD B8 02    CMP $02B8,x[$00:02B8]   ;\ compare to high score
$01/BECB F0 13       BEQ $13    [$BEE0]      ; | branch if you didn't get a high score
$01/BECD 90 11       BCC $11    [$BEE0]      ;/
$01/BECF 48          PHA                     ; push high score
$01/BED0 BD 22 02    LDA $0222,x[$00:0222]   ;\
$01/BED3 29 7F       AND #$7F                ; | branch if you have beat the level before
$01/BED5 F0 08       BEQ $08    [$BEDF]      ;/
$01/BED7 BD B8 02    LDA $02B8,x[$00:02B8]   ;\
$01/BEDA 09 80       ORA #$80                ; | store old score for the overworld score change (when you get a new high score)
$01/BEDC 8D 20 02    STA $0220  [$00:0220]   ;/
$01/BEDF 68          PLA                     ; pull high score
$01/BEE0 9D B8 02    STA $02B8,x[$00:02B8]   ; store new high score
$01/BEE3 60          RTS                     ; return


Code
; high score sram save loop
$10/82B3 A0 00       LDY #$00                ;
$10/82B5 B9 22 02    LDA $0222,y[$10:0222]   ;\
$10/82B8 29 01       AND #$01                ; | branch if you've beaten the level
$10/82BA F0 07       BEQ $07    [$82C3]      ;/
$10/82BC B9 B8 02    LDA $02B8,y[$10:02B8]   ;\
$10/82BF 09 80       ORA #$80                ; | sets the high bit of the high score address to indicate the level has been beaten
$10/82C1 87 00       STA [$00]  [$50:0342]   ;/ store high score for the level in RAM
$10/82C3 C2 20       REP #$20                ;
$10/82C5 E6 00       INC $00    [$00:0000]   ;
$10/82C7 E2 20       SEP #$20                ;
$10/82C9 C8          INY                     ;
$10/82CA C0 48       CPY #$48                ;
$10/82CC 90 E7       BCC $E7    [$82B5]      ;


relevant addresses:

$7E021A level ID

$7E0220 old score for the overworld score change (when you get a new high score)

$7E0222,x log of your history in the level, indexed by level ID
format: X------Y (X = unlocked but not beaten; Y = beaten level)
if none of the bits are set, you haven't unlocked the level yet

$7E02B8,x table of high scores, indexed by level ID

$7E030C current or high score (whichever is higher)

Additionally, I found the bonus item sram save routine:

Code
; bonus item sram save loop
$10/82CE A0 00       LDY #$00                ;\
$10/82D0 B9 57 03    LDA $0357,y[$10:0357]   ; |
$10/82D3 87 00       STA [$00]  [$50:0342]   ; |
$10/82D5 C2 20       REP #$20                ; |
$10/82D7 E6 00       INC $00    [$00:0000]   ; | save all of your bonus items to sram
$10/82D9 E2 20       SEP #$20                ; |
$10/82DB C8          INY                     ; |
$10/82DC C0 1B       CPY #$1B                ; |
$10/82DE 90 F0       BCC $F0    [$82D0]      ;/
$10/82E0 C2 20       REP #$20                ;
$10/82E2 AD 82 60    LDA $6082  [$10:6082]   ;
$10/82E5 87 00       STA [$00]  [$50:0342]   ;
$10/82E7 E6 00       INC $00    [$00:0000]   ;
$10/82E9 AD 72 03    LDA $0372  [$10:0372]   ;
$10/82EC 87 00       STA [$00]  [$50:0342]   ;
$10/82EE E2 20       SEP #$20                ;
$10/82F0 C2 20       REP #$20                ;


Incidentally, when the game saves your high score to sram, it makes a duplicate table and gets the checksum of it before and after a new high score is added. The process is done thusly:

Code
$10/82F2 DA          PHX                     ;\
$10/82F3 DA          PHX                     ; |
$10/82F4 BD 12 80    LDA $8012,x[$10:8012]   ; |
$10/82F7 8D 14 30    STA $3014  [$10:3014]   ; | get high score checksum before a new high score is added
$10/82FA A2 08       LDX #$08                ; |
$10/82FC A9 83 DE    LDA #$DE83              ; |
$10/82FF 22 44 DE 7E JSL $7EDE44[$7E:DE44]   ;/ GSU init

$10/8303 FA          PLX                     ;
$10/8304 AD 00 30    LDA $3000  [$10:3000]   ;\
$10/8307 9F 70 7E 70 STA $707E70,x[$70:7E70] ;/ store high score checksum

$10/830B BD 12 80    LDA $8012,x[$10:8012]   ;\
$10/830E 8D 02 30    STA $3002  [$10:3002]   ; |
$10/8311 BD 3A 80    LDA $803A,x[$10:803A]   ; |
$10/8314 8D 14 30    STA $3014  [$10:3014]   ; | store high scores and get new checksum
$10/8317 A2 08       LDX #$08                ; |
$10/8319 A9 73 DE    LDA #$DE73              ; |
$10/831C 22 44 DE 7E JSL $7EDE44[$7E:DE44]   ;/ GSU init

$10/8320 FA          PLX                     ;
$10/8321 AD 00 30    LDA $3000  [$10:3000]   ;\
$10/8324 9F 76 7E 70 STA $707E76,x[$70:7E76] ;/ store new high score checksum
$10/8328 E2 20       SEP #$20                ;
$10/832A AB          PLB                     ;
$10/832B 6B          RTL                     ;


I've documented the GSU routine as well:

Code
; r1 = source table (dw $7C00, $7C68, $7CD0)
; r10 = desination table (dw $7D38, $7DA0, $7E08)
; indexed by save file
0008:DE73 2A 12        move  r2,r10		; move desination into r2
0008:DE75 02           cache			;\ table copy loop
0008:DE76 FC 34 00     iwt   r12,#0034 		; | load number of high scores to save (number of levels total)
0008:DE79 FD 7C DE     iwt   r13,#DE7C 		; | set loop address
0008:DE7C 41           ldw   (r1)		; |\ copy high score from source table to desination table
0008:DE7D 32           stw   (r2)		; |/
0008:DE7E D1           inc   r1 		; |\
0008:DE7F D1           inc   r1 		; | | loop until every high score is saved
0008:DE80 D2           inc   r2 		; | |
0008:DE81 3C           loop 			; |/
0008:DE82 D2           inc   r2 		;/

; r10 = destination 
0008:DE83 02           cache			;\ checksum loop
0008:DE84 FC 34 00     iwt   r12,#0034 		; | load number of high scores
0008:DE87 FD 8C DE     iwt   r13,#DE8C 		; | set loop address
0008:DE8A A1 00        ibt   r1,#00 		; |
0008:DE8C 4A           ldw   (r10)		; | load destination table
0008:DE8D 11 51        add   r1 		; | add score to r1
0008:DE8F DA           inc   r10 		; |\
0008:DE90 3C           loop 			; | | loop through every index ($34 times)
0008:DE91 DA           inc   r10 		;/ /
0008:DE92 F0 77 77     iwt   r0,#7777 		;\ compute checksum
0008:DE95 61           sub   r1 		;/ r0 = final checksum
0008:DE96 00           stop			;\ halt gsu processing
0008:DE97 01           nop 			;/


The checksum of the duplicate table before the copy is stored to $707E70,x; the checksum of the table after the copy is stored to $707E76,x. Both are indexed with the save file.

Warning: Opinions expressed by Lexie or others in this post do not necessarily reflect the views, opinions, or position of Lexie himself on the matter(s) being discussed therein.


Yoshi's Island Disassembly C3 Thread
SPASM - LevelASM for Yoshi's Island!
Yoshi's Island Disassembly Data Dump Wiki
Figured out how the game checks the high score checksum:

Code
CODE_108000:        8B            PHB                       ;
CODE_108001:        4B            PHK                       ;
CODE_108002:        AB            PLB                       ;
CODE_108003:        C2 20         REP #$20                  ;
CODE_108005:        A2 04         LDX #$04                  ;\
CODE_108007:        20 18 80      JSR CODE_108018           ; |
CODE_10800A:        CA            DEX                       ; | check checksums loop
CODE_10800B:        CA            DEX                       ; |
CODE_10800C:        10 F9         BPL CODE_108007           ;/
CODE_10800E:        E2 20         SEP #$20                  ;
CODE_108010:        AB            PLB                       ;
CODE_108011:        6B            RTL                       ;

DATA_108012:        dw $7C00, $7C68, $7CD0

CODE_108018:        86 0E         STX $0E                   ; store save file number
CODE_10801A:        BD 12 80      LDA $8012,x               ;\
CODE_10801D:        8D 14 30      STA $3014                 ;/ load high score table index into r10
CODE_108020:        A2 08         LDX #$08                  ;\
CODE_108022:        A9 83 DE      LDA #$DE83                ; | generate checksum
CODE_108025:        22 44 DE 7E   JSL CODE_7EDE44           ;/ GSU init

CODE_108029:        A6 0E         LDX $0E                   ; load save file
CODE_10802B:        AD 00 30      LDA $3000                 ;\
CODE_10802E:        DF 70 7E 70   CMP $707E70,x             ; | check if checksum is correct
CODE_108032:        F0 05         BEQ CODE_108039           ;/ return if it is
CODE_108034:        20 A8 80      JSR CODE_1080A8           ; if not, double-check checksum with the table copy
CODE_108037:        80 DF         BRA CODE_108018           ; generate new checksum

CODE_108039:        60            RTS                       ; return

DATA_10803A:        dw $7D38, $7DA0, $7E08

; initialization state for high scores saved in sram
DATA_108040:         dw $0003, $0080, $0000, $0000
DATA_108048:         dw $0000, $0000, $8000, $0080
DATA_108050:         dw $0000, $0000, $0000, $0000
DATA_108058:         dw $8000, $0080, $0000, $0000
DATA_108060:         dw $0000, $0000, $8000, $0080
DATA_108068:         dw $0000, $0000, $0000, $0000
DATA_108070:         dw $8000, $0080, $0000, $0000
DATA_108078:         dw $0000, $0000, $8000, $0080
DATA_108080:         dw $0000, $0000, $0000, $0000
DATA_108088:         dw $8000, $0080, $0000, $0000
DATA_108090:         dw $0000, $0000, $0000, $0000
DATA_108098:         dw $0000, $0000, $0000, $0000
DATA_1080A0:         dw $0000, $0000, $0000, $0000

CODE_1080A8:        BD 3A 80      LDA $803A,x               ;\ load high score table copy into r10
CODE_1080AB:        8D 14 30      STA $3014                 ;/
CODE_1080AE:        A2 08         LDX #$08                  ;\
CODE_1080B0:        A9 83 DE      LDA #$DE83                ; | generate checksum
CODE_1080B3:        22 44 DE 7E   JSL CODE_7EDE44           ;/ GSU init

CODE_1080B7:        A6 0E         LDX $0E                   ; load save file
CODE_1080B9:        AD 00 30      LDA $3000                 ;\
CODE_1080BC:        DF 76 7E 70   CMP $707E76,x             ; | check if checksum is correct
CODE_1080C0:        F0 29         BEQ CODE_1080EB           ;/ branch if it is

CODE_1080C2:        A9 40 80      LDA #$8040                ;\
CODE_1080C5:        8D 02 30      STA $3002                 ; |
CODE_1080C8:        A9 10 00      LDA #$0010                ; |
CODE_1080CB:        29 FF 00      AND #$00FF                ; |
CODE_1080CE:        8D 04 30      STA $3004                 ; | clears high scores and generates a new checksum
CODE_1080D1:        BD 3A 80      LDA $803A,x               ; |
CODE_1080D4:        8D 14 30      STA $3014                 ; |
CODE_1080D7:        A2 08         LDX #$08                  ; |
CODE_1080D9:        A9 59 DE      LDA #$DE59                ; |
CODE_1080DC:        22 44 DE 7E   JSL CODE_7EDE44           ;/ GSU init

CODE_1080E0:        A6 0E         LDX $0E                   ; load save file
CODE_1080E2:        AD 00 30      LDA $3000                 ;\
CODE_1080E5:        9F 76 7E 70   STA $707E76,x             ;/ store new checksum
CODE_1080E9:        80 BD         BRA CODE_1080A8           ; check checksum again

CODE_1080EB:        BD 3A 80      LDA $803A,x               ;\
CODE_1080EE:        8D 02 30      STA $3002                 ; |
CODE_1080F1:        BD 12 80      LDA $8012,x               ; | copy the high score table and generate a new checksum
CODE_1080F4:        8D 14 30      STA $3014                 ; |
CODE_1080F7:        A2 08         LDX #$08                  ; |
CODE_1080F9:        A9 73 DE      LDA #$DE73                ; |
CODE_1080FC:        22 44 DE 7E   JSL CODE_7EDE44           ;/ GSU init

CODE_108100:        A6 0E         LDX $0E                   ; load save file
CODE_108102:        AD 00 30      LDA $3000                 ;\
CODE_108105:        9F 70 7E 70   STA $707E70,x             ;/ store new checksum
CODE_108109:        60            RTS                       ;


If a checksum gets corrupted, this routine re-initializes that save file:

Code
; r1 = table of init high scores ($108040)
; r2 = ROM data bank ($10)
; r10 = table of all high scores
0008:DE59 02           cache			;\ clear high scores from SRAM
0008:DE5A FC 34 00     iwt   r12,#0034 		; |\ load number of high scores
0008:DE5D FD 67 DE     iwt   r13,#DE67 		; | | set loop address
0008:DE60 B2 3F DF     romb			; | | set the ROM data bank to $10
0008:DE63 2A 12        move  r2,r10 		; | | move the address of r10 into r2
0008:DE65 21 1E        move  r14,r1 		; |/ set ROM buffer address register
0008:DE67 EF           getb 			; |\
0008:DE68 DE           inc   r14 		; | | load data from $108040
0008:DE69 3D EF        getbh 			; |/
0008:DE6B DE           inc   r14 		; |\
0008:DE6C 32           stw   (r2) 		; | | store re-initialized high score
0008:DE6D D2           inc   r2 		; | | loop until every high score is re-initialized
0008:DE6E 3C           loop 			; | |
0008:DE6F D2           inc   r2 		;/ /
0008:DE70 05 11        bra   DE83 		;\ get new checksum
0008:DE72 01           nop 			;/



on an related note: the word checksum is forever etched into my eyeballs now

e: this is all done shortly after reset

Warning: Opinions expressed by Lexie or others in this post do not necessarily reflect the views, opinions, or position of Lexie himself on the matter(s) being discussed therein.


Yoshi's Island Disassembly C3 Thread
SPASM - LevelASM for Yoshi's Island!
Yoshi's Island Disassembly Data Dump Wiki
I'm curious! What will be the use of this disassembly? :)


Originally posted by niamek
I'm curious! What will be the use of this disassembly? :)

Basically if you want to get anything nice done ASM-wise with a game, you need a disassembly so you can see exactly how the game handles doing a given thing.

Warning: Opinions expressed by Lexie or others in this post do not necessarily reflect the views, opinions, or position of Lexie himself on the matter(s) being discussed therein.


Yoshi's Island Disassembly C3 Thread
SPASM - LevelASM for Yoshi's Island!
Yoshi's Island Disassembly Data Dump Wiki

Resource