Disassemble the BLUEMONS.GB debug ROM

This commit is contained in:
Rangi 2020-07-15 13:35:39 -04:00
parent 87f24a885d
commit 4b4ad9894e
25 changed files with 364 additions and 81 deletions

View file

@ -1,4 +1,4 @@
roms := pokered.gbc pokeblue.gbc
roms := pokered.gbc pokeblue.gbc pokeblue_debug.gbc
rom_obj := \
audio.o \
@ -13,6 +13,7 @@ gfx/tilesets.o
pokered_obj := $(rom_obj:.o=_red.o)
pokeblue_obj := $(rom_obj:.o=_blue.o)
pokeblue_debug_obj := $(rom_obj:.o=_blue_debug.o)
### Build tools
@ -36,19 +37,20 @@ RGBLINK ?= $(RGBDS)rgblink
.SECONDEXPANSION:
.PRECIOUS:
.SECONDARY:
.PHONY: all red blue clean tidy compare tools
.PHONY: all red blue blue_debug clean tidy compare tools
all: $(roms)
red: pokered.gbc
blue: pokeblue.gbc
blue_debug: pokeblue_debug.gbc
clean:
rm -f $(roms) $(pokered_obj) $(pokeblue_obj) $(roms:.gbc=.map) $(roms:.gbc=.sym) rgbdscheck.o
rm -f $(roms) $(pokered_obj) $(pokeblue_obj) $(pokeblue_debug_obj) $(roms:.gbc=.map) $(roms:.gbc=.sym) rgbdscheck.o
find gfx \( -iname '*.1bpp' -o -iname '*.2bpp' -o -iname '*.pic' \) -delete
$(MAKE) clean -C tools/
tidy:
rm -f $(roms) $(pokered_obj) $(pokeblue_obj) $(roms:.gbc=.map) $(roms:.gbc=.sym) rgbdscheck.o
rm -f $(roms) $(pokered_obj) $(pokeblue_obj) $(pokeblue_debug_obj) $(roms:.gbc=.map) $(roms:.gbc=.sym) rgbdscheck.o
$(MAKE) clean -C tools/
compare: $(roms)
@ -66,6 +68,7 @@ endif
$(pokered_obj): RGBASMFLAGS += -D _RED
$(pokeblue_obj): RGBASMFLAGS += -D _BLUE
$(pokeblue_debug_obj): RGBASMFLAGS += -D _BLUE -D _DEBUG
rgbdscheck.o: rgbdscheck.asm
$(RGBASM) -o $@ $<
@ -87,18 +90,25 @@ $(info $(shell $(MAKE) -C tools))
# Dependencies for objects (drop _red and _blue from asm file basenames)
$(foreach obj, $(pokered_obj), $(eval $(call DEP,$(obj),$(obj:_red.o=.asm))))
$(foreach obj, $(pokeblue_obj), $(eval $(call DEP,$(obj),$(obj:_blue.o=.asm))))
$(foreach obj, $(pokeblue_debug_obj), $(eval $(call DEP,$(obj),$(obj:_blue_debug.o=.asm))))
endif
%.asm: ;
pokered_opt = -jsv -k 01 -l 0x33 -m 0x13 -p 0 -r 03 -t "POKEMON RED"
pokeblue_opt = -jsv -k 01 -l 0x33 -m 0x13 -p 0 -r 03 -t "POKEMON BLUE"
pokered_pad = 0x00
pokeblue_pad = 0x00
pokeblue_debug_pad = 0xff
pokered_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON RED"
pokeblue_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON BLUE"
pokeblue_debug_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON BLUE"
%.gbc: $$(%_obj) layout.link
$(RGBLINK) -d -m $*.map -n $*.sym -l layout.link -o $@ $(filter %.o,$^)
$(RGBFIX) $($*_opt) $@
$(RGBLINK) -p $($*_pad) -d -m $*.map -n $*.sym -l layout.link -o $@ $(filter %.o,$^)
$(RGBFIX) -p $($*_pad) $($*_opt) $@
### Misc file-specific graphics rules

View file

@ -6,6 +6,7 @@ It builds the following ROMs:
- Pokemon Red (UE) [S][!].gb `sha1: ea9bcae617fdf159b045185467ae58b2e4a48b9a`
- Pokemon Blue (UE) [S][!].gb `sha1: d7037c83e1ae5b39bde3c30787637ba1d4c48ce2`
- BLUEMONS.GB (debug build) `sha1: 5b1456177671b79b263c614ea0e7cc9ac542e9c4`
To set up the repository, see [**INSTALL.md**](INSTALL.md).

View file

@ -87,7 +87,7 @@ PredefPointers::
add_predef LoadTownMap_Nest
add_predef PrintMonType
add_predef EmotionBubble
add_predef EmptyFunc3; return immediately
add_predef EmptyFunc ; return immediately
add_predef AskName
add_predef PewterGuys
add_predef SaveSAVtoSRAM2

115
engine/debug/debug_menu.asm Normal file
View file

@ -0,0 +1,115 @@
DebugMenu:
IF DEF(_DEBUG)
call ClearScreen
ld hl, DebugPlayerName
ld de, wPlayerName
ld bc, NAME_LENGTH
call CopyData
ld hl, DebugRivalName
ld de, wRivalName
ld bc, NAME_LENGTH
call CopyData
call LoadFontTilePatterns
call LoadHpBarAndStatusTilePatterns
call ClearSprites
call RunDefaultPaletteCommand
hlcoord 5, 6
ld b, 3
ld c, 9
call TextBoxBorder
hlcoord 7, 7
ld de, DebugMenuOptions
call PlaceString
ld a, 3 ; medium speed
ld [wOptions], a
ld a, A_BUTTON | B_BUTTON | START
ld [wMenuWatchedKeys], a
xor a
ld [wMenuJoypadPollCount], a
inc a
ld [wMaxMenuItem], a
ld a, 7
ld [wTopMenuItemY], a
dec a
ld [wTopMenuItemX], a
xor a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld [wMenuWatchMovingOutOfBounds], a
call HandleMenuInput
bit BIT_B_BUTTON, a
jp nz, DisplayTitleScreen
ld a, [wCurrentMenuItem]
and a ; FIGHT?
jp z, TestBattle
; DEBUG
ld hl, wd732
set 1, [hl]
jp StartNewGameDebug
DebugPlayerName:
db "Tom@"
DebugRivalName:
db "Juerry@"
DebugMenuOptions:
db "FIGHT"
next "DEBUG@"
ELSE
ret
ENDC
TestBattle:
.loop
call GBPalNormal
; Don't mess around
; with obedience.
ld a, 1 << BIT_EARTHBADGE
ld [wObtainedBadges], a
ld hl, wFlags_D733
set BIT_TEST_BATTLE, [hl]
; Reset the party.
ld hl, wPartyCount
xor a
ld [hli], a
dec a
ld [hl], a
; Give the player a
; level 20 Rhydon.
ld a, RHYDON
ld [wcf91], a
ld a, 20
ld [wCurEnemyLVL], a
xor a
ld [wMonDataLocation], a
ld [wCurMap], a
call AddPartyMon
; Fight against a
; level 20 Rhydon.
ld a, RHYDON
ld [wCurOpponent], a
predef InitOpponent
; When the battle ends,
; do it all again.
ld a, 1
ld [wUpdateSpritesEnabled], a
ldh [hAutoBGTransferEnabled], a
jr .loop

View file

@ -1,5 +1,4 @@
; This function appears to never be used.
; It is likely a debugging feature to give the player Tsunekazu Ishihara's
; This function is a debugging feature to give the player Tsunekazu Ishihara's
; favorite Pokemon. This is indicated by the overpowered Exeggutor, which
; Ishihara (president of Creatures Inc.) said was his favorite Pokemon in an ABC
; interview on February 8, 2000.
@ -11,7 +10,7 @@ SetIshiharaTeam:
ld de, IshiharaTeam
.loop
ld a, [de]
cp $ff
cp -1
ret z
ld [wcf91], a
inc de
@ -23,11 +22,138 @@ SetIshiharaTeam:
IshiharaTeam:
db EXEGGUTOR, 90
IF DEF(_DEBUG)
db MEW, 5
ELSE
db MEW, 20
ENDC
db JOLTEON, 56
db DUGTRIO, 56
db ARTICUNO, 57
db $FF
IF DEF(_DEBUG)
db PIKACHU, 5
ENDC
db -1 ; end
DebugStart:
IF DEF(_DEBUG)
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
; Fly anywhere.
dec a ; $ff
ld [wTownVisitedFlag], a
ld [wTownVisitedFlag + 1], a
; Get all badges except Earth Badge.
ld a, $ff ^ (1 << BIT_EARTHBADGE)
ld [wObtainedBadges], a
call SetIshiharaTeam
; Exeggutor gets four HM moves.
ld hl, wPartyMon1Moves
ld a, FLY
ld [hli], a
ld a, CUT
ld [hli], a
ld a, SURF
ld [hli], a
ld a, STRENGTH
ld [hl], a
ld hl, wPartyMon1PP
ld a, 15
ld [hli], a
ld a, 30
ld [hli], a
ld a, 15
ld [hli], a
ld [hl], a
; Jolteon gets Thunderbolt.
ld hl, wPartyMon3Moves + 3
ld a, THUNDERBOLT
ld [hl], a
ld hl, wPartyMon3PP + 3
ld a, 15
ld [hl], a
; Articuno gets Fly.
ld hl, wPartyMon5Moves
ld a, FLY
ld [hl], a
ld hl, wPartyMon5PP
ld a, 15
ld [hl], a
; Pikachu gets Surf.
ld hl, wPartyMon6Moves + 2
ld a, SURF
ld [hl], a
ld hl, wPartyMon6PP + 2
ld a, 15
ld [hl], a
; Get some debug items.
ld hl, wNumBagItems
ld de, DebugItemsList
.items_loop
ld a, [de]
cp -1
jr z, .items_end
ld [wcf91], a
inc de
ld a, [de]
inc de
ld [wItemQuantity], a
call AddItemToInventory
jr .items_loop
.items_end
; Complete the Pokédex.
ld hl, wPokedexOwned
call DebugSetPokedexEntries
ld hl, wPokedexSeen
call DebugSetPokedexEntries
SetEvent EVENT_GOT_POKEDEX
; Rival chose Squirtle,
; Player chose Charmander.
ld hl, wRivalStarter
ld a, STARTER2
ld [hli], a
inc hl ; hl = wPlayerStarter
ld a, STARTER1
ld [hl], a
EmptyFunc:
ret
DebugSetPokedexEntries:
ld b, wPokedexOwnedEnd - wPokedexOwned - 1
ld a, %11111111
.loop
ld [hli], a
dec b
jr nz, .loop
ld [hl], %01111111
ret
DebugItemsList:
db BICYCLE, 1
db FULL_RESTORE, 99
db FULL_HEAL, 99
db ESCAPE_ROPE, 99
db RARE_CANDY, 99
db MASTER_BALL, 99
db TOWN_MAP, 1
db SECRET_KEY, 1
db CARD_KEY, 1
db S_S_TICKET, 1
db LIFT_KEY, 1
db -1 ; end
DebugUnusedList:
db -1 ; end
ELSE
ret
ENDC

View file

@ -1,45 +0,0 @@
TestBattle:
ret
.loop
call GBPalNormal
; Don't mess around
; with obedience.
ld a, 1 << BIT_EARTHBADGE
ld [wObtainedBadges], a
ld hl, wFlags_D733
set BIT_TEST_BATTLE, [hl]
; Reset the party.
ld hl, wPartyCount
xor a
ld [hli], a
dec a
ld [hl], a
; Give the player a
; level 20 Rhydon.
ld a, RHYDON
ld [wcf91], a
ld a, 20
ld [wCurEnemyLVL], a
xor a
ld [wMonDataLocation], a
ld [wCurMap], a
call AddPartyMon
; Fight against a
; level 20 Rhydon.
ld a, RHYDON
ld [wCurOpponent], a
predef InitOpponent
; When the battle ends,
; do it all again.
ld a, 1
ld [wUpdateSpritesEnabled], a
ldh [hAutoBGTransferEnabled], a
jr .loop

View file

@ -7,6 +7,10 @@ SafariZoneCheck::
jr SafariZoneGameStillGoing
SafariZoneCheckSteps::
IF DEF(_DEBUG)
call DebugPressedOrHeldB
ret nz
ENDC
ld a, [wSafariSteps]
ld b, a
ld a, [wSafariSteps + 1]

View file

@ -567,7 +567,7 @@ SendSGBPackets:
push de
call InitGBCPalettes
pop hl
call EmptyFunc5
call EmptyFunc3
ret
.notGBC
push de
@ -597,7 +597,7 @@ InitGBCPalettes:
jr nz, .loop
ret
EmptyFunc5:
EmptyFunc3:
ret
CopySGBBorderTiles:

View file

@ -894,7 +894,7 @@ CableClub_Run:
jr z, .doBattleOrTrade
cp LINK_STATE_RESET ; this is never used
ret nz
predef EmptyFunc3
predef EmptyFunc
jp Init
.doBattleOrTrade
call CableClub_DoBattleOrTrade
@ -923,7 +923,7 @@ CableClub_Run:
ld [wNewSoundID], a
jp PlaySound
EmptyFunc3:
EmptyFunc:
ret
Diploma_TextBoxBorder:

View file

@ -307,6 +307,7 @@ LinkCanceledText:
StartNewGame:
ld hl, wd732
res 1, [hl]
StartNewGameDebug:
call OakSpeech
ld c, 20
call DelayFrames

View file

@ -361,7 +361,7 @@ IntroDrawBlackBars:
ld c, BG_MAP_WIDTH * 4
jp IntroPlaceBlackTiles
EmptyFunc4:
EmptyFunc2:
ret
IntroNidorinoAnimation0:

View file

@ -252,6 +252,11 @@ ENDC
and D_UP | SELECT | B_BUTTON
cp D_UP | SELECT | B_BUTTON
jp z, .doClearSaveDialogue
IF DEF(_DEBUG)
ld a, b
bit BIT_SELECT, a
jp nz, DebugMenu
ENDC
jp MainMenu
.doClearSaveDialogue

View file

@ -11,7 +11,7 @@ SpecialWarpIn::
.next
bit 1, [hl]
jr z, .next3
call EmptyFunc
call DebugStart
.next3
ld a, 0
.next2

Binary file not shown.

View file

@ -3,42 +3,66 @@
SECTION "rst0", ROM0[$0000]
rst $38
ds $08 - @, 0 ; unused
SECTION "rst8", ROM0[$0008]
rst $38
ds $10 - @, 0 ; unused
SECTION "rst10", ROM0[$0010]
rst $38
ds $18 - @, 0 ; unused
SECTION "rst18", ROM0[$0018]
rst $38
ds $20 - @, 0 ; unused
SECTION "rst20", ROM0[$0020]
rst $38
ds $28 - @, 0 ; unused
SECTION "rst28", ROM0[$0028]
rst $38
ds $30 - @, 0 ; unused
SECTION "rst30", ROM0[$0030]
rst $38
ds $38 - @, 0 ; unused
SECTION "rst38", ROM0[$0038]
rst $38
ds $40 - @, 0 ; unused
; Game Boy hardware interrupts
SECTION "vblank", ROM0[$0040]
jp VBlank
ds $48 - @, 0 ; unused
SECTION "lcd", ROM0[$0048]
rst $38
ds $50 - @, 0 ; unused
SECTION "timer", ROM0[$0050]
jp Timer
ds $58 - @, 0 ; unused
SECTION "serial", ROM0[$0058]
jp Serial
ds $60 - @, 0 ; unused
SECTION "joypad", ROM0[$0060]
reti
@ -54,4 +78,4 @@ Start::
; The Game Boy cartridge header data is patched over by rgbfix.
; This makes sure it doesn't get used for anything else.
ds $0150 - @, $00
ds $0150 - @

View file

@ -50,5 +50,15 @@ RunNPCMovementScript::
EndNPCMovementScript::
farjp _EndNPCMovementScript
EmptyFunc2::
DebugPressedOrHeldB::
IF DEF(_DEBUG)
ld a, [wd732]
bit 1, a
ret z
ldh a, [hJoyHeld]
bit BIT_B_BUTTON, a
ret nz
ldh a, [hJoyPressed]
bit BIT_B_BUTTON, a
ENDC
ret

View file

@ -2436,7 +2436,11 @@ CheckForUserInterruption::
jr z, .input
ldh a, [hJoy5]
IF DEF(_DEBUG)
and START | SELECT | A_BUTTON
ELSE
and START | A_BUTTON
ENDC
jr nz, .input
dec c

View file

@ -622,7 +622,11 @@ TextCommandJumpTable::
dw TextCommand_BOX ; TX_BOX
dw TextCommand_LOW ; TX_LOW
dw TextCommand_PROMPT_BUTTON ; TX_PROMPT_BUTTON
IF DEF(_DEBUG)
dw _ContTextNoPause ; TX_SCROLL
ELSE
dw TextCommand_SCROLL ; TX_SCROLL
ENDC
dw TextCommand_START_ASM ; TX_START_ASM
dw TextCommand_NUM ; TX_NUM
dw TextCommand_PAUSE ; TX_PAUSE

View file

@ -126,10 +126,15 @@ TalkToTrainer::
; checks if any trainers are seeing the player and wanting to fight
CheckFightingMapTrainers::
IF DEF(_DEBUG)
call DebugPressedOrHeldB
jr nz, .trainerNotEngaging
ENDC
call CheckForEngagingTrainers
ld a, [wSpriteIndex]
cp $ff
jr nz, .trainerEngaging
.trainerNotEngaging
xor a
ld [wSpriteIndex], a
ld [wTrainerHeaderFlagBit], a

View file

@ -16,7 +16,7 @@ INCLUDE "engine/gfx/sprite_oam.asm"
INCLUDE "engine/gfx/oam_dma.asm"
INCLUDE "engine/link/print_waiting_text.asm"
INCLUDE "engine/overworld/sprite_collisions.asm"
INCLUDE "engine/debug/test_battle.asm"
INCLUDE "engine/debug/debug_menu.asm"
INCLUDE "engine/events/pick_up_item.asm"
INCLUDE "engine/overworld/movement.asm"
INCLUDE "engine/link/cable_club.asm"

View file

@ -1,2 +1,3 @@
ea9bcae617fdf159b045185467ae58b2e4a48b9a *pokered.gbc
d7037c83e1ae5b39bde3c30787637ba1d4c48ce2 *pokeblue.gbc
5b1456177671b79b263c614ea0e7cc9ac542e9c4 *pokeblue_debug.gbc

View file

@ -35,6 +35,10 @@ CeruleanCityScript4:
ret
CeruleanCityScript0:
IF DEF(_DEBUG)
call DebugPressedOrHeldB
ret nz
ENDC
CheckEvent EVENT_BEAT_CERULEAN_ROCKET_THIEF
jr nz, .asm_194f7
ld hl, CeruleanCityCoords1

View file

@ -23,6 +23,10 @@ PewterCityScript0:
PewterCityScript_1925e:
CheckEvent EVENT_BEAT_BROCK
ret nz
IF DEF(_DEBUG)
call DebugPressedOrHeldB
ret nz
ENDC
ld hl, CoordsData_19277
call ArePlayerCoordsInArray
ret nc

View file

@ -17,6 +17,10 @@ PokemonTower2F_ScriptPointers:
dw PokemonTower2Script2
PokemonTower2Script0:
IF DEF(_DEBUG)
call DebugPressedOrHeldB
ret nz
ENDC
CheckEvent EVENT_BEAT_POKEMON_TOWER_RIVAL
ret nz
ld hl, CoordsData_6055e

View file

@ -2942,11 +2942,17 @@ wd730::
wd732::
; bit 0: play time being counted
; bit 1: remnant of debug mode? not set by the game code.
; if it is set
; bit 1: remnant of debug mode; only set by the debug build.
; if it is set:
; 1. skips most of Prof. Oak's speech, and uses NINTEN as the player's name and SONY as the rival's name
; 2. does not have the player start in floor two of the player's house (instead sending them to [wLastMap])
; 3. allows wild battles to be avoided by holding down B
; furthermore, in the debug build:
; 4. allows trainers to be avoided by holding down B
; 5. skips Safari Zone step counter by holding down B
; 6. skips the NPC who blocks Route 3 before beating Brock by holding down B
; 7. skips Cerulean City rival battle by holding down B
; 8. skips Pokémon Tower rival battle by holding down B
; bit 2: the target warp is a fly warp (bit 3 set or blacked out) or a dungeon warp (bit 4 set)
; bit 3: used warp pad, escape rope, dig, teleport, or fly, so the target warp is a "fly warp"
; bit 4: jumped into hole (Pokemon Mansion, Seafoam Islands, Victory Road) or went down waterfall (Seafoam Islands), so the target warp is a "dungeon warp"