Notes:Pokémon Gold and Silver/Memory Game Disassembly

This is the commented disassembly for the Unused Memory game found in Pokémon Gold and Silver, Japanese v1.0 ROM, at.

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

@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
 * Init


 * 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, 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

@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 more turns" db $C4 db $7F db $B6 db $B2 db $50
 * init field


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