;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Alternate Yoshi Coin Counter, by imamelia ;; ;; This patch installs a numerical Yoshi coin counter on the status bar that replaces ;; the normal one. It is 3 digits, so it can go up to 999. The coins also save to SRAM, ;; so each coin can be collected only once. But please read the readme. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; header lorom !Freespace = $1A8000 !RAM_TotalYCoins = $7F9C80 ; the total number of Yoshi coins that have been collected (16-bit) !SRAM_TotalYCoins = $7003FA ; SRAM for the total number of Yoshi coins that have been collected (6 bytes) !RAM_CoinFlags = $7FB600 ; flags for each individual coin, 0x600 bytes' worth of free RAM !SRAM_CoinFlags = $700E00 ; SRAM for the coin flags, 0x600 bytes per file (0x1200 bytes total) !OWLevel = $13BF ; the current overworld level ; (should be changed only if you are using the Extra Overworld Level RAM patch) !Points = $0A ; the points/lives to give for each Yoshi coin before the last !Points2 = $0D ; the points/lives to give for the last Yoshi coin ; 00 = 0, 01 = 10, 02 = 20, 03 = 40, 04 = 80, 05 = 100, 06 = 200, 07 = 400, 08 = 800, 09 = 1000, ; 0A = 2000, 0B = 4000, 0C = 8000, 0D = 1-Up, 0E = 2-Up, 0F = 3-Up, 10 = 5-Up (may glitch) !SBDigit1 = $0F01 ; the position of the ones digit on the status bar (can be 24-bit) !SBDigit10 = $0F00 ; the position of the tens digit on the status bar (can be 24-bit) !SBDigit100 = $0EFF ; the position of the hundreds digit on the status bar (can be 24-bit) !SBCoin = $0EFE ; the position of the coin symbol on the status bar (can be 24-bit) org $008FD8 ; the routine that draws Yoshi coins onto the status bar JML YCoinStatusBar ; org $00F343 ; the routine that increments the Yoshi coin counter and resets it if necessary JML YCoinNumber ; org $00F377 ; the routine that gives you an extra life when you have enough Yoshi coins JML YCoinLives ; org $0DB2CA ; the routine that creates the Yoshi coin object in the first place JML YCoinObject ; org $009D22 ; part of the load game routine JML LoadCoinFlags ; org $009BD2 ; part of the save game routine JML SaveCoinFlags ; org $00A5F3 JML ClearSRAM ; clear the coin flags in SRAM NOP #2 ; org $00FFD8 ; SRAM size db $08 ; expand the SRAM to $700000-$701FFF org !Freespace reset bytes db "STAR" dw EndCode-StartCode-$01 dw EndCode-StartCode-$01^$FFFF StartCode: YCoinStatusBar: REP #$20 ; set A to 16-bit mode LDA !RAM_TotalYCoins ; take the total number of Yoshi coins collected PHX ; PHY ; JSR HexToDecLong ; and convert it to decimal STA !SBDigit1 ; store the ones digit CPX #$00 ; if the hundreds digit is 0... BNE NotZero ; LDX #$FC ; make it a space instead CPY #$00 ; if the tens digit is 0... BNE NotZero ; LDY #$FC ; make it a space instead NotZero: ; TYA ; STA !SBDigit10 ; store the tens digit TXA ; STA !SBDigit100 ; store the hundreds digit PLY ; PLX ; LDA #$2E ; store the coin symbol STA !SBCoin ; (you can comment out these two lines if you don't want it there) JML $008FF9 ; YCoinLives: ; PHX ; preserve the contents of X PHY ; and Y PHB ; PHK ; PLB ; LDY #!Points ; default point value LDX !OWLevel ; load the overworld level LDA $1422 ; check the current number of Yoshi coins collected CMP TotalNumber,x ; if it has not reached the total number in the level... BCC LessThanTotal ; use the default point value LDY #!Points2 ; if all of them have been collected, use the other point value LessThanTotal: ; CPY #$00 ; if the point value is 0... BEQ NoPoints ; don't give any points TYA ; PLB PLY PLX JML $00F38A ; jump back to the rest of the normal routine NoPoints: ; PLY PLX PLB ; JML $00F3B1 ; YCoinNumber: ; INC $1422 ; increment the coins collected in the current level REP #$20 ; set A to 16-bit mode LDA !RAM_TotalYCoins ; check the total number of coins collected CMP #$03E7 ; if it has reached 999... BEQ NoIncTotal ; don't let it go any higher INC ; STA !RAM_TotalYCoins ; NoIncTotal: ; SEP #$20 ; PHX ; LDA $9A ; X position of contact with the block AND #$70 ; in terms of 8 tiles LSR #4 ; STA $06 ; X position on the screen = *bit* index (00-07) LDA $5B ; check whether the level is vertical or horizontal LSR ; if bit 0 of $5B is set... BCS Vertical ; then the level is vertical LDA $9B ; base the high byte on the player's X position BRA StoreHighByte ; Vertical: ; if the level is vertical... LDA $99 ; base the high byte on the player's Y position StoreHighByte: ; AND #$0F ; 4 bits for the screen number (the 5th bit is cleared) STA $07 ; STZ $08 ; clear the next byte LDA !OWLevel ; overworld level REP #$20 ; AND.w #$00FF ; clear the high byte of A ASL #4 ; ORA $07 ; overworld level + low 4 bits of screen number STA $07 ; = resulting *byte* index SEP #$20 ; LDX $06 ; load the index from the player's X position LDA $028000,x ; set a particular coin flag (bitwise) REP #$10 ; set X to 16-bit as well LDX $07 ; get an index from 0-600 based on the level number and screen number ORA !RAM_CoinFlags,x ; STA !RAM_CoinFlags,x ; SEP #$10 ; PLX ; JML $00F358 ; finish up with the regular code YCoinObject: LDA $1BA1 ; the current screen the loading routine is on AND #$0F ; STA $06 ; STZ $07 ; LDA !OWLevel ; REP #$30 ; AND.w #$00FF ; ASL #4 ; get the overworld level x16 ORA $06 ; add in the screen bits TAX ; SEP #$20 ; LDA !RAM_CoinFlags,x ; check a particular byte of coin flags SEP #$10 ; PHA ; LDA $57 ; check the object's position within the subscreen AND #$07 ; TAX ; PLA ; AND $028000,x ; check a single flag to see if it is set or not BNE YCoinCollected ; if set, the coin has already been collected LDY $57 ; LDA #$2D ; STA [$6B],y ; LDA #$00 ; STA [$6E],y ; TYA ; CLC ; ADC #$10 ; TAY ; LDA #$2E ; STA [$6B],y ; LDA #$00 ; STA [$6E],y ; YCoinCollected: ; JML $0DB335 ; SaveCoinFlags: XBA ; LDA $009CCE,x ; restore hijacked code PHA ; preserve this to prevent it getting overwritten PHX ; PHY ; PHP ; REP #$30 ; PHX ; TXA ; ASL ; TAX ; LDA !RAM_TotalYCoins ; STA !SRAM_TotalYCoins,x ; PLX ; LDA.w #$05FE ; DEX ; BMI $06 ; CLC ; ADC #$0600 ; BRA $F7 ; TAX ; LDA.w #!RAM_CoinFlags ; STA $00 ; LDA.w #!RAM_CoinFlags/$10000 ; set up a pointer STA $02 ; LDY #$05FE ; SaveLoop: ; LDA [$00],y ; STA !SRAM_CoinFlags,x ; DEX ; DEX ; DEY ; DEY ; BPL SaveLoop PLP ; PLY ; PLX ; PLA ; JML $009BD6 ; LoadCoinFlags: ; SEP #$10 ; LDY #$12 ; restore hijacked code PHY PHP ; REP #$30 ; LDA $010A ; AND.w #$00FF ; PHA ; ASL ; TAX ; LDA !SRAM_TotalYCoins,x ; STA !RAM_TotalYCoins ; PLA ; TAX ; LDA #$05FE ; DEX ; BMI $06 ; CLC ; ADC #$0600 ; BRA $F7 ; TAX ; LDA.w #!RAM_CoinFlags ; STA $00 ; LDA.w #!RAM_CoinFlags/$10000 ; set up a pointer STA $02 ; LDY #$05FE ; LoadLoop: ; LDA !SRAM_CoinFlags,x ; STA [$00],y ; DEX ; DEX ; DEY ; DEY ; BPL LoadLoop PLP ; PLY ; JML $009D26 ; ClearSRAM: PHP ; SEP #$30 ; LDA $0109 ; CMP #$E9 ; BNE NoClear ; PHX ; preserve the value of X PHY ; and Y LDA $010A ; save file number ASL ; x2 STA $00 ; into scratch ASL ; x4 CLC ; ADC $00 ; x6 XBA ; REP #$30 ; AND #$FF00 ; save file x600 CLC ; ADC #$05FE ; TAX ; LDA.w #!RAM_CoinFlags ; STA $00 ; LDA.w #!RAM_CoinFlags/$10000 ; set up a pointer STA $02 ; LDY #$05FE ; 0x600 bytes to clear LDA.w #$0000 ; SRAMClearLoop: ; STA !SRAM_CoinFlags,x ; set the coin flags to zero STA [$00],y ; DEX ; DEX ; DEY ; DEY ; BPL SRAMClearLoop ; loop if Y hasn't dropped below zero STA !RAM_TotalYCoins ; SEP #$30 ; PLY ; PLX ; NoClear: ; PLP ; PEA $93F3 ; JML $008494 ; HexToDecLong: ; LDX #$00 LDY #$00 HexDecLoop1: CMP.w #$0064 BCC HexDecLoop2 SBC.w #$0064 INX BRA HexDecLoop1 HexDecLoop2: CMP.w #$000A BCC EndHexDec SBC.w #$000A INY BRA HexDecLoop2 EndHexDec: SEP #$20 RTS TotalNumber: ; the total number of Yoshi coins in each level db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 ; levels 0-F db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 ; levels 10-1F db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 ; levels 20-24 and 101-10B db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 ; levels 10C-11B db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 ; levels 11C-12B db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 ; levels 12C-13B print "This patch uses ",bytes," bytes." EndCode: