Cite as
nmikstas/dragon-warrior-disassembly
Original
https://github.com/nmikstas/dragon-warrior-disassembly
Pinned
nmikstas/dragon-warrior-disassembly @ ebe6a13da77a3593c67300f54d95ed49c23effc2
Accessed
2026-10-20
Licence
none stated (no LICENSE file for the disassembly; the bundled Ophis assembler carries its own BSD-style license)
Credit
nmikstas, who reverse-engineered and commented the whole game (README: "over 33,00 lines of code"), July 2020, with fixes to 2023. Every label and comment quoted in dw1 claims is theirs.
Notes
Ophis-format source for the four 16 KB PRG banks (source_files/Bank00-03.asm). Reassembled with Ophis on 2026-10-20, the banks match the md5s in the repo's build_script. That build is not Rev 1: Rev 1 differs in three bytes of text in banks 0 and 2 (dw1/rev1-text), and banks 1 and 3, which hold the battle code, are identical to it.

Cited on

Claims (37)

Dragon Warrior saves the hero as a 32-byte record in battery-backed cartridge RAM; bytes 0-1 hold experience, 2-3 gold, 4-7 the inventory, 8 the magic keys (capped at 6), 9 the herbs, 10 the equipment, 11-13 spell, player, and story flags, 14-21 the name, 22 the message speed, 23 HP, 24 MP, 25 whether HP and MP are refilled at the start, 26-29 the filler byte $C8, and 30-31 a check value.source_files/Bank03.asm L9836–9936source_files/Bank03.asm L10196–10198source_files/Dragon_Warrior_Defines.asm L658–660Code
Dragon Warrior's check value is a 16-bit CRC of the record's first 30 bytes, read from byte 29 down to byte 0, one bit at a time from the top, with the polynomial $1021 and both bytes seeded with $1D.source_files/Bank03.asm L10209–10220source_files/Bank03.asm L10261–10284Code
Dragon Warrior writes each save 10 times, one record after another, into its slot's 320 bytes; loading checks the copies in order, counts each one whose CRC fails, loads the first that passes, and rewrites all 10 from it, and if none passes the game marks the slot invalid (clearing its valid flag and mask bit, not its data) and says no deeds were recorded.source_files/Dragon_Warrior_Defines.asm L662–668source_files/Bank03.asm L9798–9832source_files/Bank03.asm L9966–10035source_files/Bank03.asm L9315–9338source_files/Bank03.asm L9455–9460Code
Dragon Warrior marks its battery RAM as initialized with the 10 ASCII bytes KEN MASUTA, written both before and after the three save slots; before showing the saved games it checks the copy after the slots and then the one before, and only if neither matches does it erase all three slots, then rewrites both copies.source_files/Bank03.asm L9242–9300source_files/Bank03.asm L10321–10323source_files/Dragon_Warrior_Defines.asm L657–665source_files/Bank03.asm L9470–9480Code
Dragon Warrior's title screen reads "©1989 ENIX" and "LICENSED TO NINTENDO", by the disassembly's comments on the strings' tiles.source_files/Bank00.asm L7375–7389Code notes
Rev 1 differs from the build of nmikstas's disassembly in three bytes of text and none of code; on its title screen "TRADEMARK TO NINTENDO" becomes "TRADEMARK OF NINTENDO".source_files/Bank00.asm L7399–7400source_files/Bank02.asm L2840–2841Code
UpdateRandNum steps a 16-bit state as s←771s+129(mod65536), and battle code reads its high byte, RandNumUB.source_files/Bank03.asm L668–692Code
GetJoypadStatus steps the generator each time it reads the controller.source_files/Bank03.asm L805–811Code
Computed from the generator's update, its 65,536 states form two cycles of 32,768, and over each cycle the high byte takes every value exactly 128 times.source_files/Bank03.asm L668–692Code
The hero's attack power is Strength plus the weapon's bonus; defense power is half of Agility, rounded down, plus the armor's and shield's bonuses, plus 2 with the Dragon's Scale.source_files/Bank03.asm L8655–8704Code
PlyrCalcHitDmg takes X=A−⌊D/2⌋, the hero's attack power less half the monster's defense byte; if X≥2, damage is ⌊(X+⌊r(X+1)/256⌋)/4⌋ for a random byte r, so from ⌊X/4⌋ to ⌊X/2⌋.source_files/Bank03.asm L6719–6722source_files/Bank03.asm L8491–8500source_files/Bank03.asm L8541–8560Code
When X<2, the hero deals 0 or 1 damage, each half the time.source_files/Bank03.asm L8533–8539Code
Zero damage from the hero ends the turn as a failed attack, before any dodge check.source_files/Bank03.asm L6761–6773Code
Before the normal formula, a 1-in-32 roll gives the hero an "excellent move", except against either form of the Dragonlord; it deals A−⌊r⌊A/2⌋/256⌋ for a random byte r, from ⌈A/2⌉+1 to A (more than half to all of the attack power), and ignores defense.source_files/Bank03.asm L6724–6759Code
After the damage is set, an awake monster dodges when a roll of 0–63 falls below d, the low nibble of its resistance byte, a chance of d/64; a sleeping monster never dodges, and spells skip the check.source_files/Bank03.asm L6775–6796source_files/Bank03.asm L6809–6814Code
EnCalcHitDmg takes X=A−⌊D/2⌋, the monster's attack less half the hero's defense power; if X≥⌊A/2⌋+1, it uses the hero's normal formula, and otherwise the monster deals ⌊(⌊r(⌊A/2⌋+1)/256⌋+2)/3⌋, from 0 to about A/6.source_files/Bank03.asm L7761–7765source_files/Bank03.asm L8502–8531Code
A monster's physical attack has no critical branch and no dodge roll for the hero; EnPhysAttack goes straight to EnCalcHitDmg, and only 0 damage misses.source_files/Bank03.asm L7751–7774Code
A monster's HP is its base value less up to a quarter, H−⌊⌊rH/256⌋/4⌋; the Dragonlord's final form always has its base HP.source_files/Bank03.asm L6614–6652Code
The hero's Hurt deals 5–12 damage and Hurtmore 58–65, whatever the stats on either side; a roll of 0–15 below the high nibble of the monster's resistance byte blocks the spell instead.source_files/Bank03.asm L6924–6960source_files/Bank03.asm L7306–7316Code
A monster's Hurt deals 3–10 damage and Hurtmore 30–45; Magic Armor or Erdrick's Armor cuts either to 2⌊d/3⌋.source_files/Bank03.asm L7821–7867Code
At the start of a battle, CalcWhoIsNext gives the hero the first turn when Agility × a random byte is at least the monster's defense byte × a roll of 0–63; otherwise the monster attacks first.source_files/Bank03.asm L6654–6663source_files/Bank03.asm L8290–8325Code
TryRun lets the hero escape when Agility × a random byte is at least the monster's defense byte × a roll whose range grows with the monster: 0–63 from Slime to Druinlord, 0–94 from Drollmagi to Werewolf, 0–127 from Green Dragon to Blue Dragon, and 0–255 from Stoneman on. Running from a sleeping monster always works.source_files/Bank03.asm L7191–7195source_files/Bank03.asm L8256–8293source_files/Dragon_Warrior_Defines.asm L970–986Code
Measured in the ROM over all 65,536 generator states, with Agility 40 against a defense byte of 40, the hero escapes 87.70% of the time from the first group, 81.64% from the second, 75.20% from the third, and 50.20% from the fourth; the hero takes the first turn 87.70% of the time.source_files/Bank03.asm L8256–8325Verified
Measured in the ROM over all 65,536 generator states, attack power 60 against a defense byte of 40 deals 10–20 damage, each of 10 to 19 in 25 of 256 rolls and 20 in 6; attack power 20 deals 0 or 1, half each.source_files/Bank03.asm L8491–8560Verified
Measured the same way, a monster's attack of 90 against defense power 60 deals 15–30 damage, and an attack of 20 against defense power 40 deals 0–4, mostly 1–3.source_files/Bank03.asm L8502–8560Verified
At the start of a battle and before each monster turn, CheckEnRun gives the monster a 1-in-4 chance to flee when half the hero's Strength is at least the monster's attack.source_files/Bank03.asm L8455–8467source_files/Bank03.asm L6654source_files/Bank03.asm L7682–7683Code
Each step on the map draws a byte and starts a fight when its masked bits are all 0: 1 in 8 on sand and hills, 1 in 16 in swamp, forest, brick, and barrier squares, and on other terrain 1 in 32 where the X and Y coordinates are both even or both odd, 1 in 16 elsewhere.source_files/Bank03.asm L1887–1888source_files/Bank03.asm L1948–1981source_files/Bank03.asm L2020–2045Code
On the overworld's zone 0, the slime-only region around Tantegel Castle, a second byte lets only half of those fights through, and a quarter on hills.source_files/Bank03.asm L2093–2114Code
After the first turn, the hero and the monster alternate; each of the hero's actions ends by jumping to StartEnemyTurn, and each of the monster's to StartPlayerTurn.source_files/Bank03.asm L6803–6807source_files/Bank03.asm L7772–7777Code
A failed run prints "But was blocked in front" and passes the turn to the monster.source_files/Bank03.asm L7194–7200Code
The dodge nibble d of the 40 monsters (each dodges d/64 of the hero's attacks, dodge) is 1 or 2 for 27 of them; the Demon Knight's is 15, the Werewolf's 7, the Poltergeist's and Drakeema's 6, six monsters' 4, and the Golem's and both Dragonlord forms' 0.source_files/Bank01.asm L4425–4442source_files/Bank01.asm L4504–4506source_files/Bank01.asm L4552–4554source_files/Bank01.asm L3873–3874source_files/Dragon_Warrior_Defines.asm L550–573Code
The high nibble h of the same byte blocks Hurt and Hurtmore h/16 of the time (hero-spells); it is 0 for 26 of the 40 monsters and 15 for seven, the Metal Slime, Golem, Demon Knight, Wizard, Red Dragon, and both Dragonlord forms.source_files/Bank03.asm L6927–6941source_files/Bank01.asm L4504–4506Code
Each fight picks one of its zone's five monster slots with equal chance; zone 0, around Tantegel Castle, holds three Slime slots and two Red Slime slots, and zone 1 adds a Drakee, all with dodge 1.source_files/Bank03.asm L2165–2175source_files/Bank03.asm L9064–9072source_files/Bank03.asm L9090–9092Code
The Demon Knight, the hardest monster to hit at 15/64, fills one of the five slots in overworld zones 10, 11, and 12; the Werewolf, at 7/64, fills one in zone 12 and in zone 13, which Hauksness also uses, and one on the Dragonlord's castle ground floor.source_files/Bank03.asm L9101–9104source_files/Bank03.asm L9109source_files/Bank03.asm L2119–2128Code
The Dragonlord's castle's six sublevels draw from three rows, Werewolf, Green Dragon, Starwyvern, Wizard, and Axe Knight on the first; Wizard, Axe Knight, two Blue Dragons, and Stoneman on the next three; and Wizard, Stoneman, two Armored Knights, and Red Dragon on the last two and the bottom floor. Apart from the Werewolf's 7, their dodge nibbles are 1 or 2.source_files/Bank03.asm L9078–9082source_files/Bank03.asm L9083source_files/Dragon_Warrior_Defines.asm L1007–1012source_files/Bank03.asm L9109–9111source_files/Bank03.asm L2131–2134Code
In Dragon Warrior II (NA NES), as in Dragon Warrior, each monster starts a fight with its base HP less up to a quarter; the order changes, as Dragon Warrior II quarters the base HP before multiplying by a random byte, H−⌊⌊H/4⌋r/256⌋, where Dragon Warrior quarters the product.source_files/Bank03.asm L6614–6652Code
Dragon Warrior II (NA NES) changes Dragon Warrior's battle rules: the hero's 1-in-32 "excellent move" becomes a 1-in-64 "tremendous blow", the fixed alternation of hero and monster becomes a round order sorted by half the agility plus a roll, and running no longer weighs the hero's Agility against the monster.source_files/Bank03.asm L6724–6759source_files/Bank03.asm L6803–6807source_files/Bank03.asm L7772–7777source_files/Bank03.asm L8290–8325Code