If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!
Notes:Pokémon Gold and Silver/Memory Game Disassembly
Jump to navigation
Jump to search
This is a sub-page of Notes:Pokémon Gold and Silver.
This is the commented disassembly for the Unused Memory game found in Pokémon Gold and Silver, Japanese v1.0 ROM, at 38:667A.
Disassembly
;; Memory Game Routine entry ;; 38:667A call @6686 ; init call $032E ; wait for screen to come back on @6680: call @66DA ; main loop jr nc, @6680 ret ;; Init @6686: call $0432 ; Disable screen ld b, $08 call $34E5 ; load palette ld hl, $4F99 ld a, $23 rst $8 ; init OAM sprite routine ld hl, $6A46 ld de, $9000 call $0AE9 ; load background gfx ld hl, $48BC ; data source: commented-out gfx ld de, $8000 ld bc, $0040 ld a, $38 call $0DB6 ; copy 0x40 bytes (0x04 tiles) for selector sprite ld a, $08 ld hl, $C508 ldi [hl], a ; OAM sprite tile base select ld [hl], $00 ; OAM sprite group 0x08 based at 0x00 ld hl, $C3A0 ld bc, $0168 xor a, a call $3108 ; clear bg map xor a, a ld [$FF00 + $D2], a ; set X scroll ld [$FF00 + $D1], a ; set Y scroll ld [$FF00 + $4A], a ; hide window ld [$CE57], a ; init main loop state to 0x00 ld a, $01 ld [$FF00 + $D6], a ; set screen update to C3A0 region ld a, $E3 ld [$FF00 + $40], a ; LCD control ld a, $E4 call $0C4A ; bg palettes ld a, $E0 call $0C8F ; obj palettes ret ;; main loop @66DA: ld a, [$CE57] bit 7, a jr nz, @66EF ; exit condition = b7 set call @66F1 ; call subroutines ld hl, $4FAF ld a, $23 rst $8 ; animate OAM sprites call $032E and a, a ; don't exit game ret @66EF: scf ; exit game ret ;; subroutines @66F1: ld a, [$CE57] ld e, a ld d, $00 ld hl, @6700 add hl, de add hl, de ldi a, [hl] ld h, [hl] ld l, a jp [hl] ; jump to pointer [$CE57] in list @6700 @6700: dw @6712 dw @671A dw @673B dw @6761 dw @6780 dw @67AA dw @67D9 dw @67EB dw @681F ;; subroutine 0x00 ;; init @6712: call @6977 ; init field ld hl, $CE57 inc [hl] ; next subroutine ret ;; subroutine 0x01 ;; coin question @671A: call $48BC ; "Bet how many coins?" routine should be here jr nc, @6725 ; but is commented out. ld hl, $CE57 set 7, [hl] ret ;; play game (cont'd 0x01) ;; randomize field @6725: call @68C2 ; randomize field ld hl, $CE57 inc [hl] ; next subroutine xor a, a ld [$C608], a ; clear RAM C603 - C609 ld hl, $C603 ldi [hl], a ; RAM map: [slot1][slot2][slot3][slot4][slot5][counter][taken card offset counter] ldi [hl], a ; taken card offset counter counts in tiles ldi [hl], a ldi [hl], a ld [hl], a ld [$C609], a ;; subroutine 0x02 ;; draw cards @673B: ld hl, $C608 ld a, [hl] cp a, $2D jr nc, @674F inc [hl] call $69A8 ; get card bg offset xor a, a ld [$C5FD], a ; card 0x00 call @694D ; draw card tiles ret ;; finished drawing all cards @674F: ld de, $341C ; coordinates X = 0x1C Y = 0x34 ld a, $1E ; sprite number 0x1E call $3C4C ; load OAM sprite ld a, $05 ld [$C602], a ; load number of turns ld hl, $CE57 inc [hl] ; next subroutine ret ;; subroutine 0x03 ;; current turn @6761: ld a, [$C602] ld hl, $C3B1 add a, $F6 ld [hl], a ; number of turns + Tile 0xF6 ld hl, $C602 ld a, [hl] and a, a jr nz, @6777 ld a, $07 ; no turns left ld [$CE57], a ; goto subroutine 0x07 ret ;; turns left @6777: dec [hl] ; decrease turns left xor a, a ld [$CE58], a ; init card select index to 0x00 ld hl, $CE57 inc [hl] ; next subroutine ;; subroutine 0x04 ;; select first card ld a, [$CE58] and a, a ret z ; exit if no card selected dec a ld e, a ld d, $00 ld hl, $C5D0 add hl, de ld a, [hl] cp a, $FF ret z ; exit if empty spot selected ld [$C5FD], a ; card to draw ld [$C5FE], a ; first selected card ld a, e ld [$C600], a ; first selected card's slot call $69A8 ; get card bg offset call @694D ; draw card xor a, a ld [$CE58], a ; clear selection ld hl, $CE57 inc [hl] ; next subroutine ret ;; subroutine 0x05 ;; select second card ld a, [$CE58] and a, a ret z ; exit if no card selected dec a ld hl, $C600 cp a, [hl] ret z ; exit if first select card's slot selected ld e, a ld d, $00 ld hl, $C5D0 add hl, de ld a, [hl] cp a, $FF ret z ; exit if empty spot selected ld [$C5FD], a ; card to draw ld [$C5FF], a ; second selected card ld a, e ld [$C601], a ; second selected card's slot call $69A8 ; get card bg offset call @694D ; draw card ld a, $40 ld [$C608], a ; delay ld hl, $CE57 inc [hl] ; next subroutine ;; subroutine 0x06 ;; check cards ld hl, $C608 ld a, [hl] and a, a jr z, @67E2 dec [hl] ret ;; end of delay @67E2: call @682F ; check cards ld a, $03 ld [$CE57], a ; return to current turn ret ;; subroutine 0x07 ;; no turns left ;; draw all cards ld a, [$FF00 + $A5] and a, $01 ret z ; wait for A button press xor a, a ld [$C608], a ; clear counter @67F4: ld hl, $C608 ld a, [hl] cp a, $2D jr nc, @6818 inc [hl] push af call $69A8 ; get card bg offset pop af push hl ld e, a ld d, $00 ld hl, $C5D0 add hl, de ld a, [hl] ; get card number pop hl cp a, $FF jr z, @67F4 ; skip empty slots ld [$C5FD], a ; store card number call @694D ; draw card jr @67F4 ;; all cards drawn @6818: call $0A26 ; wait for keypress ld hl, $CE57 inc [hl] ; next subroutine ;; subroutine 0x08 call $48BC ; "Play again?" routine should be here jr nc, @682A ; but is commented out. ld hl, $CE57 set 7, [hl] ; exit game ret ;; new round @682A: xor a, a ld [$CE57], a ; reset game ret ;; check cards @682F: ld hl, $C5FE ldi a, [hl] cp a, [hl] jr nz, @6885 ; cards don't match ld a, [$C600] call $69A8 ; get first selected card's bg offset call @6967 ; erase card ld a, [$C601] call $69A8 ; get second selected card's bg offset call @6967 ; erase card ld a, [$C600] ld e, a ld d, $00 ld hl, $C5D0 add hl, de ld [hl], $FF ; empty first selected card's slot ld a, [$C601] ld e, a ld d, $00 ld hl, $C5D0 add hl, de ld [hl], $FF ; empty second selected card's slot ld hl, $C603 @6863: ldi a, [hl] and a, a jr nz, @6863 dec hl ld a, [$C5FE] ; get current card number ld [hl], a ; write card to taken slot ld [$C5FD], a @686F: ld hl, $C609 ld e, [hl] inc [hl] inc [hl] ld d, $00 ld hl, $C3A5 add hl, de ; get taken card bg offset call @694D ; draw card ld hl, @68A2 call $0F30 ; message win ret ;; cards don't match @6885: xor a, a ld [$C5FD], a ; card 0x00 ld a, [$C600] call $69A8 ; get first selected card's bg offset call @694D ; draw card ld a, [$C601] call $69A8 ; get second selected card's bg offset call @694D ; draw card ld hl, @68BA call $0F30 ; message lose ret ;; messages @68A2: db $08 ; message ASM push bc ld hl, $C4A6 call $694D ; draw card in text box ld hl, @68B2 ; message offset pop bc inc bc inc bc inc bc ; skip 0x03 tiles in message ret @68B2: db $00 ; message 「CARD いただき!」 "CARD, yeah!" db $7F db $B2 db $C0 db $30 db $B7 db $E7 db $57 @68BA: db $00 ; message 「ざんねん…」 "Darn..." db $2B db $DE db $C8 db $DE db $75 db $75 db $57 ;; randomize field @68C2: ld hl, $C5D0 ld bc, $002D xor a, a call $3108 ; clear field call @6926 ; get card distribution ld c, $02 ld b, [hl] call @690A ; card 0x02 ld c, $08 ld b, [hl] call @690A ; card 0x08 ld c, $04 ld b, [hl] call @690A ; card 0x04 ld c, $07 ld b, [hl] call @690A ; card 0x07 ld c, $03 ld b, [hl] call @690A ; card 0x03 ld c, $06 ld b, [hl] call @690A ; card 0x06 ld c, $01 ld b, [hl] call @690A ; card 0x01 ld c, $05 ld hl, $C5D0 ld b, $2D @6900: ld a, [hl] and a, a jr nz, @6905 ld [hl], c ; make rest card 0x05 @6905: inc hl dec b jr nz, @6900 ret ;; set b cards @690A: push hl ld de, $C5D0 @690E: call $305E ; get random index and a, $3F cp a, $2D jr nc, @690E ld l, a ld h, $00 add hl, de ld a, [hl] and a, a jr nz, @690E ; put card if empty ld [hl], c ; else get random index again dec b jr nz, @690E pop hl inc hl ret ;; card distribution @6926: ld a, [$CF14] dec a ld l, a ld h, $00 add hl, hl add hl, hl add hl, hl ld de, @6935 add hl, de ret @6935: db $02 ; begin data 1 coin db $03 db $06 db $06 db $06 db $08 db $08 db $06 db $02 ; begin data 2 coins db $02 db $04 db $06 db $06 db $08 db $08 db $09 db $02 ; begin data 3 coins db $02 db $02 db $04 db $07 db $08 db $08 db $0C ;; draw single card [$C5FD] @694D: ld a, [$C5FD] sla a sla a add a, $04 ; card tile base = 0x04 ldi [hl], a inc a ldd [hl], a ; draw top two tiles inc a ld bc, $0014 add hl, bc ldi [hl], a inc a ld [hl], a ; draw bottom two tiles ld c, $03 call $033C ret ;; erase single card at hl @6967: ld a, $01 ; tile 0x01 = background ldi [hl], a ldd [hl], a ; erase top two tiles ld bc, $0014 add hl, bc ldi [hl], a ld [hl], a ; erase bottom two tiles ld c, $03 call $033C ret ;; init field @6977: ld hl, $C3A0 ld bc, $0168 ld a, $01 call $3108 ; fill map with 0x01 ld hl, $C3A0 ld de, @699C call $0F46 ; string upper left corner ld hl, $C3AF ld de, @69A2 call $0F46 ; string upper right corner ld hl, @699B call $0F30 ; show message ret @699B: db $50 ; empty message @699C: db $C4 ; 「とったもの」 "[Cards] taken" db $DF db $C0 db $D3 db $C9 db $50 @69A2: db $B1 ; 「あとNかい」 "N more turns" db $C4 db $7F db $B6 db $B2 db $50 ;; get card bg offset @69A8: ld d, $00 @69AA: sub a, $09 jr c, @69B1 inc d jr @69AA ; d = a \ 9 @69B1: add a, $09 ; a = a % 9 ld e, a ld hl, $C3C9 ld bc, $0028 @69BA: ld a, d and a, a jr z, @69C2 add hl, bc dec d jr @69BA @69C2: sla e add hl, de ; hl = 0xC328 + 0x0028 * row + 2 * column ret ;; Selector code entry ;; 38:69C6 ld a, [$CE57] cp a, $07 jr nc, @69ED call $09FD ; Read keys ld hl, $FFA5 ld a, [hl] and a, $01 jr nz, @69F4 ; A button ld a, [hl] and a, $20 jr nz, @69FE ; D-pad LEFT ld a, [hl] and a, $10 jr nz, @6A0E ; D-pad RIGHT ld a, [hl] and a, $40 jr nz, @6A1F ; D-pad UP ld a, [hl] and a, $80 jr nz, @6A32 ; D-pad DOWN ret ;; Subroutine ≧0x07 active @69ED: ld hl, $0000 add hl, bc ld [hl], $00 ; Delete OAM sprite ret ;; A button pressed @69F4: ld hl, $000C add hl, bc ld a, [hl] ; load selected slot index to inc a ld [$CE58], a ; card select index register ret ;; D-pad LEFT pressed @69FE: ld hl, $0006 add hl, bc ld a, [hl] and a, a ret z ; exit if already at left edge sub a, $10 ld [hl], a ld hl, $000C add hl, bc dec [hl] ; selected slot index-- ret ;; D-pad RIGHT pressed @6A0E: ld hl, $0006 add hl, bc ld a, [hl] cp a, $80 ret z ; exit if already at right edge add a, $10 ld [hl], a ld hl, $000C add hl, bc inc [hl] ; selected slot index++ ret ;; D-pad UP pressed @6A1F: ld hl, $0007 add hl, bc ld a, [hl] and a, a ret z ; exit if already at top edge sub a, $10 ld [hl], a ld hl, $000C add hl, bc ld a, [hl] sub a, $09 ld [hl], a ; selected slot index - 0x09 (one row) ret ;; D-pad DOWN pressed @6A32: ld hl, $0007 add hl, bc ld a, [hl] cp a, $40 ret z ; exit if already at bottom edge add a, $10 ld [hl], a ld hl, $000C add hl, bc ld a, [hl] add a, $09 ld [hl], a ; selected slot index + 0x09 (one row) ret
Notice
The actual card selection is handled by the OAM selector sprite code, which calls 38:69C6.