data/claims/ffmq.yamlFinal Fantasy Mystic Quest's battle rules (TheAnsarya's ffmq-info, Final Fantasy - Mystic Quest (USA) (Rev 1))
Game: Final Fantasy Mystic Quest.
The game's random numbers come from one 16-bit state kept in save RAM at $70:1FFE: each call shifts it left twice, then adds the old state, $3711 and the frame counter at $0E96 in turn, each addition taking in the carry the step before left (the first takes bit 14 of the old state, which the second shift pushed out, so the step is 5 times the state plus that bit, not 5 times the state alone), keeps the 16-bit result, and returns its high byte, reduced modulo the range the caller puts in $A8 when that isn't 0. A range of $65 gives 0-100. ffmq/rng
About: Final Fantasy Mystic Quest Random number generator
Value: shifts 2 · increment 0x3711 · state $70:1FFE
Codeffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools ·src/asm/banks/bank_00.asm#L7802-L7832 — RNG_GenerateRandom (ffmq-info's label; elsewhere called ExecuteAudioCall, which it isn't)RNG_GenerateRandom:
php
phd
rep #$30
pha
lda.W #$005e
tcd
lda.L $701ffe
asl a
asl a
adc.L $701ffe
adc.W #$3711
…Checked by claude-agent, 2026-11-08 — read the routine at the pinned linesRevised after a check by a second AI model, 2026-11-08.The battle code calls it with $65 in $A8 for a draw of 0-100 (ffmq/formation-sets, ffmq/first-strike, ffmq/run). Because the frame counter feeds every step, the sequence depends on timing as well as the state.
The code at $00:A274 reads a word through the 24-bit pointer at $17 and moves the pointer past it, puts the word's low byte, the battle number, in $0513 and its high byte in $0A9C, and calls $00:D080 with the pointer saved. The battle setup at $02:8000 copies $0513 to $0514 unless it's $FF, and the number then picks the battle's formation set (ffmq-tables/formation-sets); battle numbers 0-19 are the battlefields. Not read here: the path from $00:D080 to the battle setup, and the dispatch that runs the code at $00:A274 as an event-script command. The manuals' account of battles on the map is ffmq/map-battles. ffmq/script-battle
src/asm/banks/bank_00.asm#L11161-L11177 — unlabelled code after Party_LoadCharacterData's rts: a word through [$17], its low byte to $0513 and its high byte to $0A9C, then the call to $00:D080lda.W #$0003
ldx.W #$8457
jsr.W Dialog_ExecuteSubroutine
rep #$30
lda.B [$17]
inc.B $17
inc.B $17
sep #$20
sta.W !sys_operation_type
xba
sta.W $0a9c
ldx.B $17
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L36-L46 — Battle_Initialize: $0513 to $0514 unless it's $FF, then the enemiesphk
plb
sep #$20
rep #$10
lda.W !sys_operation_type
cmp.B #$ff
beq Battle_SetupEnvironment
sta.W $0514
Battle_SetupEnvironment:
jsr.W Battle_InitializeEnemiesThe 207 battle numbers each have three formations at $02:CE12. When a battle starts, the game draws a number from 0 to 100 and takes the first formation for 0-33, the second for 34-67, and the third for 68-100. Computed: the third comes up 33 times in 101 and the others 34; battle number $FF skips the draw and uses the formation already in $0515. Battle numbers 0-19 are the 20 battlefields (ffmq/battlefields). CodeChecked by claude-agent, 2026-11-08 — read both ranges at the pinned linesRevised after a check by a second AI model, 2026-11-08.By the US and Japanese manuals and Squaresoft's newsletter, monsters stand on the map in dungeons and towns, and walking into one starts a battle; the Overworld has no monsters to run into, and its battlefields are optional: 20 of them, each of 10 battles, with a prize for clearing one (ffmq-tables/battlefields). The code that stores a battle's number is ffmq/script-battle. ffmq/map-battles
About: Final Fantasy Mystic Quest Visible encounter
ManualファイナルファンタジーUSA ミスティッククエスト 取扱説明書 (Final Fantasy USA: Mystic Quest instruction booklet) ·p. 24, 戦闘システム — in a dungeon, merely touching a monster in the passage starts a battle (our gloss)ダンジョンでは、通路にいるモンスターに当たるだけで戦闘(右の画面)になります。Final Fantasy Mystic Quest instruction booklet (USA) · p. 12, In the TownsRemember, walking up to monsters will provoke battles.Final Fantasy Mystic Quest instruction booklet (USA) · p. 22, Doing Battle — a battlefield is entered by choiceSimply walk onto a Battlefield Icon that has not been cleaned out, and press the A Button.The Ogopogo Examiner, Fall 1992 (vol. II) · sheet oe_2_2, Most User-Friendly FantasyIn the Overworld you will not run into monsters. You can choose to do battle by entering a Battlefield, but these are optional.ファイナルファンタジーUSA ミスティッククエスト 取扱説明書 (Final Fantasy USA: Mystic Quest instruction booklet) · p. 28, バトルポイントについて — a battle point holds 10 battles in all, with bonus experience, money or items for clearing them all (our gloss of the paragraph)バトルの数は全部で10回。The code at $00:A274 reads a word through the 24-bit pointer at $17 and moves the pointer past it, puts the word's low byte, the battle number, in $0513 and its high byte in $0A9C, and calls $00:D080 with the pointer saved. The battle setup at $02:8000 copies $0513 to $0514 unless it's $FF, and the number then picks the battle's formation set (ffmq-tables/formation-sets); battle numbers 0-19 are the battlefields. Not read here: the path from $00:D080 to the battle setup, and the dispatch that runs the code at $00:A274 as an event-script command. The manuals' account of battles on the map is ffmq/map-battles. CodeRevised after a check by a second AI model, 2026-11-08.The battlefields are the US manual's Battlefield Icons and the Japanese manual's バトルポイント (battle points). The sources say contact starts a fight; none says in so many words that a monster can be walked around.
Cited by: Random encounter, Visible encounter
Before the first round the game rolls for a first strike. Unless the formation's flags byte has bit 7 set, it takes the monsters' figure as the first slot's level plus twice the second slot's plus 3 (an empty slot's level is $FF, so each slot counts its level plus one, and the third slot is never read), divided by the number of monsters, and the party's as Benjamin's level, averaged with the companion's when one is present; it draws 0-100 and, when the draw is at least 100 minus 10 times the difference (the difference capped at 10), gives the first strike to the side with the higher figure. Computed: a difference of d gives a first strike 10d + 1 times in 101. The party's first strike is a round in which only the party acts; the monsters' is a round in which only they act, and only in battle numbers 0-19, the battlefields. With bit 7 set the roll is skipped and the monsters strike first in a battlefield. ffmq/first-strike
About: Final Fantasy Mystic Quest Turn order
Value: cap difference 10 · per level 10
Codeffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools ·src/asm/banks/bank_02.asm#L212-L247 — Battle_CheckEscape (ffmq-info's label; it runs once, before the first round): $1110 + $1190 + $1190 + 3 over the count $B3, against $1010 (and $1090), then the roll; $76 ← 2 for the party, 1 for the monsters if $0514 is below $14Battle_CheckEscape:
sep #$20
rep #$10
lda.B $af
and.B #$80
bne Battle_CheckBossFlag
lda.W !controller1_standard
clc
adc.W !controller2_standard
clc
adc.W !controller2_standard
inc a
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L248-L285 — Battle_CheckEscape (ffmq-info's label; it runs once, before the first round): $1110 + $1190 + $1190 + 3 over the count $B3, against $1010 (and $1090), then the roll; $76 ← 2 for the party, 1 for the monsters if $0514 is below $14 (continued)Battle_ProcessEscapeCalc:
pha
lda.B #$00
sbc.B #$00
sta.B $a0
pla
cmp.B #$0b
bcc Battle_ApplyEscapeBonus
lda.B #$0a
Battle_ApplyEscapeBonus:
sta.w !WRMPYA
lda.B #$0a
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L286-L294 — Battle_CheckEscape (ffmq-info's label; it runs once, before the first round): $1110 + $1190 + $1190 + 3 over the count $B3, against $1010 (and $1090), then the roll; $76 ← 2 for the party, 1 for the monsters if $0514 is below $14 (continued)Battle_CheckBossFlag:
lda.W $0514
cmp.B #$14
bcs Battle_EscapeFailed
ldx.W #$d28d
jsr.W Battle_DisplayMessage
lda.B #$01
sta.B $76
rtsffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L50-L66 — the call before the first round; $76 = 1 skips the command menulda.B #$ff
sta.W $0a84
jsl.L Battle_RefreshBattleDisplay
sep #$20
rep #$10
jsr.W Battle_CheckEscape
stz.B $b5
lda.B #$ff
sta.W !control_region_1
sta.W !control_region_2
sta.W !control_region_3
sta.W !menu_command_id
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L413-L446 — a round's actors: entities 2-4 when $76 is 1, 0-1 when it is 2, else all fiveBattle_InitializeSlots:
sep #$20
rep #$10
pea.w !JOY_DOWN
pld
stz.B $8a
stz.B $87
lda.B $76
dec a
beq Battle_SetupNormalBattle
dec a
beq Battle_SetupBossBattle
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L1872-L1880 — the formation loader: the flags byte to $AF, and $B3 counting the filled slotslda.W DB_UNREACH_02CA6A,x
sta.B $af
and.B #$30
sta.W $0a01
stz.B $b3
lda.B $ac
inc a
beq Battle_CalculateEnemyMagicDef
inc.B $b3Each of the 234 formations at $02:CA6A is 4 bytes: three monster slots and a flags byte. A slot of $FF is empty; otherwise its low seven bits are the monster number. Each slot's top bit is kept apart for that slot ($80 for an empty one), and the flags byte's bits 4 and 5 are kept apart too; what those do isn't read. Bit 7 of the flags byte skips the first-strike roll and bit 6 stops the party running (ffmq/first-strike, ffmq/run). Code — the flags byte and the slotsThe 9 character records at $0C:D0B0, 80 bytes each, are Benjamin's starting record and two for each companion, Kaeli, Tristam, Phoebe and Reuben, the second at a higher level. A new game copies record 0 to Benjamin's place at $1000; a script command copies the record it names, whole, to the companion's place at $1080 (ffmq/companion-records). By terriblesecret's field names, which the copies and the level-up fit, each holds the level ($10), current and maximum HP ($14, $16), the three kinds of magic points ($18-$1A, with maxima at $1B-$1D), the four stats as level gives them ($4C-$4F) and with equipment ($22-$25), and accuracy ($40), which Benjamin's level-up sets to 75 plus half the level. Code — offset $10 of a record is the level, so $1010 is Benjamin's and $1090 the companion's (ffmq-info labels $1090 char2_companion_id)Each of the 81 monsters, from the Brownie to the Dark King, has a 14-byte record at $02:C275 (HP as a word, then four stats, which terriblesecret names strength, defense, speed and magic, then eight more bytes), a 3-byte record at $02:C17C (its level, then its experience and gold, each stored as a third), and a 16-byte name at $0C:CBA0. When a battle loads a monster, the game copies its name, sets its level, sets current and maximum HP to the HP word, copies the four stats, copies bytes 6-7 to two places, bytes 8-11 to four, and bytes 12 and 13 to one place each, and and sets offset $2F to $80 for monster $42 (Behemoth) and every monster after it, $00 before it. HP runs from 50 (Brownie) to 40,000 (Dark King), levels from 1 to 40 (Dark King), and experience up to 762 (Stone Golem). Code — the loader puts a monster's level at offset $10 of its record, $1110, $1190 and $1210Checked by claude-agent, 2026-11-08 — read the three ranges at the pinned lines, including the 8-bit carry after the subtraction that sets $A0 to 0 or $FFRevised after a check by a second AI model, 2026-11-08.The monsters' slots are battle records $1100, $1180 and $1200, and a record's level is at offset $10, so $1110 and $1190 are the first two slots; the code adds the second twice where a sum over the three slots would read $1210. A party with no companion has $FF at $1090, which the code skips.
Cited by: Visible encounter
Each round the game gives every actor a key of its speed plus a random number below half its speed (0-255 when half its speed is 0), or 2 for an actor with status bit 6 or 7 set, and sorts the actors by key, highest first; an exchange needs a strictly higher key, so ties keep the order Benjamin, companion, first, second and third monster. A round after a first strike or a failed run includes only one side (ffmq/first-strike, ffmq/run). ffmq/turn-order
About: Final Fantasy Mystic Quest Turn order
Codeffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools ·src/asm/banks/bank_02.asm#L450-L491 — Battle_InitializeSlots (ffmq-info's label): the keys, then a bubble sort of $0481 and $047C; $76 is cleared after one roundBattle_ProcessSlotLoop:
lda.B $a0
sta.B $8b
phd
jsr.W Battle_SetEntityContextParty
lda.B $21
and.B #$c0
beq Battle_IncrementActiveCount
lda.B #$02
bra Battle_CalculateAGI
Battle_IncrementActiveCount:
inc.W $048a
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L492-L535 — Battle_InitializeSlots (ffmq-info's label): the keys, then a bubble sort of $0481 and $047C; $76 is cleared after one round (continued)Battle_SortLoop:
dex
beq Battle_SortComplete
lda.B $81,x
dex
cmp.B $81,x
beq Battle_SortContinue
bcs Battle_SwapSlots
Battle_SortContinue:
inx
bra Battle_SortLoop
Battle_SwapSlots:
…Checked by claude-agent, 2026-11-08 — read the loop and the sort at the pinned linesChecked by a second AI model, 2026-11-08.Speed is offset $24 of a battle record, where the loaders put the current speed (ffmq-tables/monsters, ffmq-tables/characters). The key is 8 bits.
The main loop runs the run check when bit 6 of $1020, in Benjamin's record, is set; what sets that bit isn't read. The run fails outright when the formation's flags byte has bit 6 set, and succeeds outright in round 0 after the party won the first strike. Otherwise the game takes the party's speed (Benjamin's, averaged with the companion's when both can act) and the monsters' average speed: the speeds of those that can act, summed from 1 instead of 0 when the first monster can't act, over their number. It draws a random byte modulo ⌊average ÷ 5⌋ × round + 1 (rounds counted from 0; the product and the + 1 kept to 8 bits), and the run succeeds when (average − draw) mod 256 is below the party's speed, so a draw larger than the average wraps to 256 + average − draw. A failed run gives the monsters a round to themselves. Computed: in round 0 the draw is 0, so the run succeeds only when the party is faster. ffmq/run
About: Final Fantasy Mystic Quest Fleeing
Codeffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools ·src/asm/banks/bank_02.asm#L297-L337 — Battle_CheckQuit (ffmq-info's label): the flags byte's bit 6; round $B5 0 with $76 = 2; Benjamin's $1024 and the companion's $10A4 when status bits 4-7 are clear; the monsters' $1124, $11A4 and $1224; the draw. Its !char and !controller names are ffmq-info's for the status bytes $1021, $10A1, $1121, $11A1 and $1221Battle_CheckQuit:
sep #$20
rep #$10
lda.B $af
and.B #$40
beq Battle_CheckGameOver
…
Battle_CheckGameOver:
lda.B $b5
bne Battle_CalculatePartyHP
lda.B $76
cmp.B #$02
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L338-L372 — Battle_CheckQuit (ffmq-info's label): the flags byte's bit 6; round $B5 0 with $76 = 2; Benjamin's $1024 and the companion's $10A4 when status bits 4-7 are clear; the monsters' $1124, $11A4 and $1224; the draw. Its !char and !controller names are ffmq-info's for the status bytes $1021, $10A1, $1121, $11A1 and $1221 (continued)Battle_CalculateEnemyHP:
rep #$30
lda.W #$0001
sta.B $a2
ldx.W #$0000
lda.W !controller1_extended
and.W #$00f0
bne Battle_AddEnemyHP
lda.W $1124
and.W #$00ff
inx
sta.B $a2
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L373-L407 — Battle_CheckQuit (ffmq-info's label): the flags byte's bit 6; round $B5 0 with $76 = 2; Benjamin's $1024 and the companion's $10A4 when status bits 4-7 are clear; the monsters' $1124, $11A4 and $1224; the draw. Its !char and !controller names are ffmq-info's for the status bytes $1021, $10A1, $1121, $11A1 and $1221 (continued)Battle_SumEnemy3HP:
lda.B $a2
sta.w !WRDIVL
sep #$20
rep #$10
txa
jsl.L ExecuteHardwareDivision
lda.w !RDDIVL
sta.B $a2
stz.B $a3
sta.w !WRDIVL
stz.w !WRDIVH
…Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x10223-0x10225 — $02:8223, untraced: jmp $82EE when bit 6 is set (our reading)Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x10230-0x10232 — $02:8230, untraced: jmp $82E5, the success path, in round 0 after the party's first strike (our reading)Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x102ee-0x102f8 — $02:82EE, after the routine's last instruction the disassembly traced: the failure message $D2AC and $76 ← 1 (our reading: ldx #$D2AC, jsr $8835, lda #$01, sta $76, rts)ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L68-L76 — the run command's call: A = $FF back from it is an escapeBattle_MainLoop:
jsl.L CallExternalMonitor
lda.W $1020
and.B #$40
beq Battle_ProcessTurn
jsr.W Battle_CheckQuit
inc a
bne Battle_ProcessTurn
jmp.W Battle_Escapeffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L155-L158 — the round number $B5 goes up after each roundcmp.B #$05
bcc Battle_ClearStatusFlags
inc.B $b5
jmp.W Battle_MainLoopChecked by claude-agent, 2026-11-08 — read the routine and the untraced bytes after it at the pinned lines and offsetsRevised after a check by a second AI model, 2026-11-08."Can act" is the status byte (offset $21) having bits 4-7 clear. With no monster able to act the division is by 0; with no party member able to act the party's speed is 0 and the run fails. When ⌊average ÷ 5⌋ × round is 255 the + 1 makes the range 0, which leaves the random byte whole (ffmq/rng).
After a won battle, each monster present adds 3 times its experience byte to the battle's experience and 3 times its gold byte to its gold (ffmq-tables/monsters). The code would use 6 for a gold byte of $42-$49 and 10 for $4A or more, but no monster's gold byte is above 10. ffmq/battle-rewards
Value: multiplier 3
Codeffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools ·src/asm/banks/bank_02.asm#L1376-L1410 — Battle_CalculateRewards (ffmq-info's label): for records $1100-$1200 with a level that isn't $FF, offset $53 times the multiplier to $A0 and offset $54 times it to $A2Battle_CalculateRewards:
php
sep #$20
rep #$10
ldx.W #$0000
stx.B $a0
stx.B $a2
ldx.W #$04ac
lda.B #$02
sta.B $8b
Battle_ProcessEnemyReward:
phd
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L1411-L1442 — Battle_CalculateRewards (ffmq-info's label): for records $1100-$1200 with a level that isn't $FF, offset $53 times the multiplier to $A0 and offset $54 times it to $A2 (continued)Battle_MultiplyRewardByLevel:
sta.w !WRMPYA
pla
sta.w !WRMPYB
pha
pla
rep #$30
lda.w !RDMPYL
clc
adc.W !sys_temp_work_2
sta.W !sys_temp_work_2
sep #$20
…Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x10965-0x1096e — $02:8965, the bytes the disassembly left untraced: cmp #$4A, bcs, lda #$06, bra, lda #$0A (our reading)Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x1417c-0x1426e — $02:C17C: the monsters' level, experience and gold bytesChecked by claude-agent, 2026-11-08 — read the loop and decoded the untraced bytes; read the largest gold byte off the tableChecked by a second AI model, 2026-11-08.The test compares the gold byte with $42, the first number of the bosses' range in the monster table, which suggests it was meant for the monster number; as shipped it never fires.
When Benjamin's experience reaches the figure at $0510, he goes up one level, to at most 41: his maximum HP rises by 40 and his current HP is scaled by the new maximum over the old; his maximum white magic rises by 1, black by 1 whenever half his level (rounded down) rises, and wizard whenever a quarter of it does; his level stats rise by 3 attack, 2 defense, 2 speed and 1 magic, and offset $40 becomes 75 plus half his level. The check runs once after a battle's rewards and once after a battlefield's experience reward. ffmq/benjamin-level-up
Value: cap 41 · hp 40 · attack 3 · defense 2 · speed 2 · magic 1 · offset 40 75 + level/2
Codeffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools ·src/asm/banks/bank_02.asm#L1104-L1148 — Battle_ProcessManualInput (ffmq-info's label): Benjamin's record (entity 0); a new level of $2A or more returnsBattle_ProcessManualInput:
sep #$20
rep #$10
phd
stz.B $8b
jsr.W Battle_SetEntityContextParty
lda.B $10
sta.W !sys_temp_work_1
inc a
cmp.B #$2a
bcc Battle_WaitForInput
…
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L1149-L1185 — Battle_ProcessManualInput (ffmq-info's label): Benjamin's record (entity 0); a new level of $2A or more returns (continued)clc
adc.B $10
sta.B $1b
lsr.W !sys_temp_work_1
lsr.W !sys_temp_work_2
lda.B $1c
sec
sbc.W !sys_temp_work_1
clc
adc.W !sys_temp_work_2
sta.B $1c
lsr.W !sys_temp_work_1
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L1186-L1217 — Battle_ProcessManualInput (ffmq-info's label): Benjamin's record (entity 0); a new level of $2A or more returns (continued)Battle_ProcessCommand:
sta.W $0000,x
inx
dey
bne Battle_InputReceived
lda.B $4c
sta.B $26
clc
adc.B $2a
sta.B $22
lda.B $4d
sta.B $27
…Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x10765-0x10766 — $02:8765, untraced: pld, rts, the return at level 42 (our reading)Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x107f9-0x107fa — $02:87F9, untraced: lda #$63, the clamp to 99 (our reading)ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L1533-L1558 — the check: $0510-$0512 against his experience at $1011-$1013Battle_DisplayNumberValue:
sep #$20
rep #$10
sec
lda.W $0512
cmp.W $1013
beq Battle_ConvertNumberLoop
bcc Battle_DisplayDigitLoop
rts
Battle_ConvertNumberLoop:
rep #$30
lda.W $0510
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L1440-L1451 — the call after the battle's rewardslda.B $8b
cmp.B #$05
bcc Battle_ProcessEnemyReward
ldx.B $a2
phx
ldx.W #$d2b8
jsr.W Battle_DisplayMessage
jsr.W Battle_DisplayNumberValue
plx
stx.B $a2
ldx.W #$d2c8
jsr.W Battle_DisplayMessageffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_02.asm#L1491-L1503 — the call after a battlefield's experience rewardlda.L DATA8_07efa1,x
bit.W #$8000
beq Battle_SetRewardBonus
and.W #$7fff
pha
asl a
clc
adc.B $01,s
sta.B $a0
pla
ldx.W #$d56c
jsr.W Battle_DisplayMessage
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L6238-L6273 — Math_Multiply16x16, at $00:96B3 (the ROM range below)Math_Multiply16x16:
php
rep #$30
phd
pha
phx
phy
lda.W #$0000
tcd
lda.B $9c
sta.B $a4
stz.B $9e
…Final Fantasy - Mystic Quest (USA) (Rev 1) · 0x16b3-0x16e3 — $00:96B3: the multiply the level-up callsffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L6606-L6649 — Math_Divide32by16 at $00:96E4Math_Divide32by16:
php
rep #$30
phd
pha
phx
lda.W #$0000
tcd
lda.B $98
sta.B $a4
lda.B $9a
sta.B $a6
…The level-up compares Benjamin's experience total at $1011-$1013 with the figure at $0510-$0512 (the experience for his next level). A Mesen probe replays the attract mode's level-25 Benjamin from one savestate, answers each read of his level with 1 to 41 in turn, and records what the game then writes to $0510-$0512: 13L³ + 100L² + 161L + 74 for levels 1 to 39 (348 at level 1, 929,600 at level 39), but 146,546 at level 40 and 218,780 at level 41, each 851,968 (13 × 65,536) below that cubic, so the level-40 figure is lower than the 929,600 that took him to level 40. The probe records the write coming from the script command at $00:AF5B with the event-script pointer at $03:AE36; the script isn't decoded. Verified — the figures at $0510The 9 character records at $0C:D0B0, 80 bytes each, are Benjamin's starting record and two for each companion, Kaeli, Tristam, Phoebe and Reuben, the second at a higher level. A new game copies record 0 to Benjamin's place at $1000; a script command copies the record it names, whole, to the companion's place at $1080 (ffmq/companion-records). By terriblesecret's field names, which the copies and the level-up fit, each holds the level ($10), current and maximum HP ($14, $16), the three kinds of magic points ($18-$1A, with maxima at $1B-$1D), the four stats as level gives them ($4C-$4F) and with equipment ($22-$25), and accuracy ($40), which Benjamin's level-up sets to 75 plus half the level. Code — the record's fields: $16 maximum HP, $1B-$1D the magic maxima, $4C-$4F the four statsChecked by claude-agent, 2026-11-08 — read the level-up and its callers at the pinned lines, and checked that the multiply's 49 bytes end where the divide at $96E4 startsRevised after a check by a second AI model, 2026-11-08.The four stats at $1026-$1029 are clamped to 99 before the level stats are copied over them, so the clamp doesn't limit the new values. Companions don't go through this routine: they arrive with a record's fixed level (ffmq/companion-records).
Cited by: Growth rate
A companion joins when an event-script command names one of the 9 character records (ffmq-tables/characters): the game copies all 80 bytes of that record over the companion's place at $1080, so the companion arrives at the record's level, HP, stats and equipment, and nothing of the previous companion's record is kept; bit 7 of offset $20 is cleared in the copy unless it was set in the record it replaced. ffmq/companion-records
src/asm/banks/bank_00.asm#L11130-L11159 — Party_LoadCharacterData (ffmq-info's label)Party_LoadCharacterData:
lda.W #$0080
and.w !char2_active_flag
php
lda.B [$17]
inc.B $17
and.W #$00ff
sep #$30
sta.W $0e92
sta.W !SNES_WRMPYA
lda.B #$50
jsl.L Math_SetMultiplier
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L8917-L8954 — Memory_CopyLarge (ffmq-info's label): A is the byte count; with $50 it copies one 64-byte block, then jumps into the 64-byte copy for the last 16Memory_CopyLarge:
clc
Memory_CopyLarge_Loop:
sbc.W #$003f
bcc Memory_CopyLarge_Final
pha
jsr.W Memory_Copy64Bytes
txa
adc.W #$003f
tax
tya
adc.W #$0040
…The 9 character records at $0C:D0B0, 80 bytes each, are Benjamin's starting record and two for each companion, Kaeli, Tristam, Phoebe and Reuben, the second at a higher level. A new game copies record 0 to Benjamin's place at $1000; a script command copies the record it names, whole, to the companion's place at $1080 (ffmq/companion-records). By terriblesecret's field names, which the copies and the level-up fit, each holds the level ($10), current and maximum HP ($14, $16), the three kinds of magic points ($18-$1A, with maxima at $1B-$1D), the four stats as level gives them ($4C-$4F) and with equipment ($22-$25), and accuracy ($40), which Benjamin's level-up sets to 75 plus half the level. Code — the 9 records and their levelsChecked by claude-agent, 2026-11-08 — read the command and Memory_CopyLarge at the pinned lines, and traced A = $50 through the block loop and the computed jumpRevised after a check by a second AI model, 2026-11-08.Each companion has two records, for its first and second time in the party, at levels 3 and 31 (Kaeli), 7 and 23 (Tristam), 15 and 34 (Phoebe), and 23 and 31 (Reuben).
A save holds three blocks: Benjamin's 80-byte record at $1000, the companion's at $1080, and the 380 bytes at $0E84-$0FFF. The routine at $00:C9D3 copies them, in that order, to the start of a buffer at $7F:3000 (540 bytes), and the routine it calls three times writes the buffer's first 902 bytes (what fills the last 362 isn't read) to save RAM in bank $70, after a 6-byte header that holds a checksum of them, at slot × 908 for slots n, n + 3 and n + 6, reading each copy back to check its checksum. Loading copies the three blocks back from the buffer and then runs the same save. A new game fills the blocks from the cartridge: Benjamin's record from the character table, $FF in the companion's level and status, and the 380 bytes from $0C:D380, which put each battlefield's count of 10 at $0FD4 (ffmq-tables/battlefields). So each battlefield's count, which a won battle there lowers and a cleared one leaves at 0, is in the save. ffmq/save-contents
src/asm/banks/bank_00.asm#L17590-L17623 — SaveFile_PrepareOperation (ffmq-info's label): $1000, $1080 and $0E84 to $7F:3000, then the write three times, slot + 3 each timeSaveFile_PrepareOperation:
php
rep #$30
phb
pha
phd
phx
phy
pha
stz.B $8e
phb
ldx.W #$1000
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L17553-L17587 — SaveFile_LoadWithValidation (ffmq-info's label, though it writes): the checksum of $7F:3000, 6 header bytes from $0E to $70 at the slot's offset, then $386 bytes of the buffer, and the checksum read backSaveFile_LoadWithValidation:
phb
phx
phy
pha
ldx.W #$3000
stx.B $5f
jsr.W SaveFile_SetBank7F
jsr.W SaveFile_CalculateChecksum
jsr.W SaveFile_CalculateOffset
ldy.B $0b
ldx.W #$000e
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L17475-L17485 — SaveFile_CalculateOffset: slot × $038CSaveFile_CalculateOffset:
and.W #$00ff
sta.B $98
lda.W #$038c
sta.B $9c
jsl.L Math_Multiply16x16
lda.B $9e
clc
adc.W #$0000
sta.B $0b
rtsffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L17512-L17532 — SaveFile_CalculateChecksum: $4646 and $2130 in the header, then the sum of $1C3 wordsSaveFile_CalculateChecksum:
pha
phx
lda.W #$4646
sta.B $0e
lda.W #$2130
sta.B $10
ldx.W #$01c3
lda.W #$0000
clc
SaveFile_ChecksumLoop:
adc.B [$5f]
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L17699-L17711 — SaveFile_CopyToRAM (ffmq-info's label): the load, from the buffer, then the save routineSaveFile_CopyToRAM:
ldx.W #$3000
ldy.W #$1000
lda.W #$004f
mvn $00,$7f
ldy.W #$1080
lda.W #$004f
mvn $00,$7f
ldy.W #$0e84
lda.W #$017b
mvn $00,$7f
pla
…ffmq-info: Final Fantasy Mystic Quest (SNES) disassembly and tools · src/asm/banks/bank_00.asm#L1055-L1065 — a new gameldx.W #$d380
ldy.W #$0e84
lda.W #$017b
mvn $00,$0c
ldx.W #$d0b0
ldy.W #$1000
lda.W #$004f
mvn $00,$0c
lda.W #$00ff
sta.w !char2_companion_id
sta.w !char2_statusEach of the 20 battlefields, battle numbers 0-19, has a count of battles at $0C:D4D0, which a new game copies to $0FD4, and a reward word at $07:EFA1. Every battlefield starts at 10. After a won battle with a number below 20, the game takes one off that battlefield's count and shows the number left; at zero it gives the reward: with the top bit set, the low 15 bits times 3 in experience; with bit 14, the item in the low byte; otherwise the low 14 bits times 3 in gold. The battlefield names are Archipelago's, not the game's: Archipelago's object ids 1-20 are taken as battle numbers 0-19 because their types (experience, item, gold) follow the reward words in the same order, and the official guide's numbered battlefields -2-, -5-, -19- and -20- have the rewards of battle numbers 1, 4, 18 and 19. Code — the countdown at $0FD4 + n after a won battleChecked by claude-agent, 2026-11-08 — read the save and load copies, the write to bank $70 and the checksum at the pinned linesRevised after a check by a second AI model, 2026-11-08.How Final Fantasy Mystic Quest computes physical and magic damage hasn't been read yet. ffmq/damage-formula
About: Final Fantasy Mystic Quest Damage formula
UnsourcedChecked by a second AI model, 2026-11-08.Cited by: Damage formula
How the game decides whether an attack hits hasn't been read yet. ffmq/hit-chance
About: Final Fantasy Mystic Quest Hit chance
UnsourcedChecked by a second AI model, 2026-11-08.Whether and how the game rolls critical hits hasn't been read yet. ffmq/critical-hit
About: Final Fantasy Mystic Quest Critical hit
UnsourcedRevised after a check by a second AI model, 2026-11-08.The shops' stock and prices and the chests' contents haven't been read yet. ffmq/shops-and-chests