Register | Login | Logout | Edit profile
Views: 1397612
Main | Memberlist | Calendar | Online users
Ranks | FAQ | Search | Photo album
11-13-07 11:42 PM
rustedmagick forums - The ROM Hacking Data Repository - Final Fantasy 1 (NES) |
Next newer thread | Next older thread
Bag of Stinky Weeds
Level: 9

Posts: 4/16
EXP: 2726
For next: 436

Since: 11-24-02

Since last post: 1815 days
Last activity: 1810 days
Posted on 11-24-02 05:37 PMQuote
All data if from the Game Hackers Database

Data submitted by Myan and Vagabond

The pointer table for the dialogue text. 28010-2820F

The dialogue text. 28210-2B60F

The pointer table for the monster attacks. 2B610-2B643

The monster attacks text. 2B644-2B70F

The pointer table for the items. 2B710-2B90F

The items text. 2B910-2BFD1

The battle text and pointers (mixed up a bit). 2CC50-2D00F

The pointer table for the monster names. 2D4F0-2D5EF

The monster name text. 2D5F0-2D95F

Weapon data. Each weapon entry consists of 8 bytes - hit percent, damage, an unknown parameter, spell cast, elemental, special effects, graphics block, and color index. 30010-3014F

Armor data. Each armor entry consists of 4 bytes - absorb, evade percent, elemental resistance, spell cast. 30150-301EF

Spell Data. Each spell entry consists of 8 bytes - Targeting, Effectiveness, Element, Effect byte 1, Effect byte 2, Graphics Block, Color index. 301F0-303EF

The pointer table for the epilogue text. 36810-36841

The epilogue text. 36842-36E0F
Price Data- starting with the first item of the item list, and going on through weapons, armor and spells. Each price uses 2 bytes. NOTE: Most "items" do not have a price because they cannot be bought or sold! 37C3C on indicates "store-bought" items, with the exception of the Bottle. 37C10?-37DEF

The intro text. 37F30-3800F

The pointer table for the shop text. 38010-3805B

The shop text. 3805C-3830F

Shop Data. Listed sequentially; one shop is separated from the next by 00. Shops go in order of weapon-armor-item-wmagic-bmagic-inn-clinic throughout most of the section; weapon, armor, item, and magic shops use a string of bits corresponding to the index of an item, inns and clinics use a single, 2-byte value for cost. 3839E-38480

The pointer table for the status menu text. 38510-3858F

The status menu text. 38590-38D12

Nesticle .STA file: The party's Gold. 1A-1E
(Nesticle .STA file)
Festering Blob of Unknown Origin
Resident Grumpy Old Bat All-Knowing Sage That Guy
Level: 51

Posts: 82/773
EXP: 976691
For next: 37247

Since: 03-19-02
From: Melniboné

Since last post: 24 days
Last activity: 9 hours
Posted on 02-04-03 02:59 PMQuote
Journal Entry #82, Day 321

Y Dienyddiwr Da's FFBytes documents cover all this and more, and then there's FFHackster... :P

However, yesterday, in #romhacking on, zero_soul was helping me with some stuff for FF1, and here's the discoveries that were made. Except for the first one, zero_soul found them all.

* Following Y Dienyddiwr Da's instructions, I got the actual offset for the list of starting characters. If you go to $39D4C, you'll find that it's set to $06. This is where you can add the other classes to the character creation list, or remove some.

* $39D4A - Characer Creation Selection Screen. Change $01 to $00 to force a default party. This will disable the left & right input from the contoller, allowing you to set the party you want the player to use.

* $3A0B0, $3A0C0, $3A0D0, $3A0E0 - Default party. I'm not sure what to do with this data yet. I'll have to ask zero_soul... :P

* $3031 - Starting Items. While it's not possible to give starting weapons, armors, or spells to the characters, you can give them starting items. You can give the party Key Items, or purchaseable items. Here's the list of what's what:

$3031 - Lute
$3032 - Crown
$3033 - Crystal
$3034 - Herb
$3035 - Key
$3036 - TNT
$3037 - Adamant
$3038 - Slab
$3039 - Ruby
$303A - Rod
$303B - Floater
$303C - Chime
$303D - Tail
$303E - Cube
$303F - Bottle
$3040 - Oxyale
$3046 = Tent
$3047 = Cabin
$3048 = House
$3049 = Heal
$304A = Pure
$304B = Soft

By default, each one is set to $00. Changing it will give the party that many of an item. This only applies to the purchaseable items. The key items will just be listed, regardless of what number you set them to.

* $3026 - changing this from $00 to $01 will trigger the Crossing the Bridge scene.

We're still looking for the place where we can change the default message speed, and it was also suggested to see if we can find a way to make the dialog window open instantaneously. They might both end up being ASM hacks...

Psst... wanna pet my
Day-Old Cod Sandwich?


Bag of Stinky Weeds
Level: 5

Posts: 2/4
EXP: 345
For next: 184

Since: 10-10-02

Since last post: 1430 days
Last activity: 1286 days
Posted on 04-20-03 12:00 AMQuote
Some more data, from FF1 Bonus Bytes:

Default Party:


Char. 1: $3A0BE
Char. 2: $3A0CE
Char. 3: $3A0DE
Char. 4: $3A0EE


Standard: Upgrade (*):
00 = Fighter 06 = Knight
01 = Thief 07 = Ninja
02 = Black Belt 08 = Master
03 = Red Mage 09 = Red Wizard
04 = White Mage 0A = White Wizard
05 = Black Mage 0B = Black Wizard

*: Use these at your own risk; they're glitched after class change.


Char. 1: $3A0C0
Char. 2: $3A0D0
Char. 3: $3A0E0
Char. 4: $3A0F0

There are four bytes to change there, all set by default at $FF, which is a space. You can change these to whatever... grab a table if need be. Remember, though, this will only give suggested names; you still have to
enter the names at selection. There is a way to make those names stick, though. It'll be in here in the next revision.

Background Colors:

This refers to menus, intro text, etc. The main tipoff for these is that the
palette is $0F-$00-$01-$30, which would be, in that order, black, white,
blue, gray. The blue, as you probably know, is the background, so change all
$01 values for the background.

Menu Colors: $3EB3A (thanks, Square! Just one value!)
"Equip/Trade/Drop" Menu Color: $3AD8E (highlight for selected option)
"Weapon/Armor" Menu Title Highlight: $3AD92
Intro BG Color: $3A12C (This will not change the text fade-in color.)


Walking: $3D088
Ship/Airship Multipliers: $3D08D, $3D096

Warning: Don't set higher than original airship speed, or you'll get palette glitches. If you use different speeds, the game may crash in battle. Their present values are $4A. Changing them to, say, $EA or $0A will speed up or
lower their speeds.


Intro Fade-In: $3A2C8

Currently set at $0F. Setting it lower makes the fade-in go faster. Raising it to, say, $FF builds in a nice bathroom break for your players, because it goes REALLY slow. I've noticed that the fadein is almost impossible to detect if set any lower than $0C.

Black Belt/Master Attributes

As you may have heard, the Black Belt and Master have their stats determined differently. Unarmed, their Damage will be double their current level. Without armor, their Absorb will be equal to their level. They also get double the hits of other classes. You can reassign them to other classes, as well.

At 2D97A, the code reads "C9 02 F0 05 C9 08 F0".
At 32DCF, the code reads "C9 02 F0 04 C9 08 D0".
At 3EED2, the code reads "C9 02 F0 04 C9 08 D0".
At 3EEF0, the code reads "C9 02 F0 04 C9 08 D0".

The $02 and $08 bytes select the Black Belt and Master classes, respectively. Change all of them using the values listed under "Default Party" and you can reassign them to those classes. If you select a value that isn't in the list (ie, anything higher than $0B), no one will get the bonuses. In other words, you can give none, 1, or 2 classes the bonuses. In addition, you can also
reassign them to a range of classes.

Change all the $F0 bytes to $90.
Change all the $D0 bytes to $B0.

Now, as long as the first class's value is less than the second class, all classes between the two numbers, including the first number, but not the second, get the bonuses. For instance, if you change the $F0 and $D0 bytes, but not the classes, all classes between Black Belt and Master get the bonuses (Black Belt, Red/White/Black Mages, Knight, Ninja, Master). The doubled hits may not carry over.

Hold Magic Switches

By default, the Fighter and Thief get no MP until class change. They can gain MP if they start off as Knights or Ninjas, though. Here's how to tweak that.

$2DC7D reads "F0 40 C9 01 F0 3C".

Change the $01 to whatever class you want to be without MP. So if you don't want the Red Mage to have magic, you'd change it to 03. Just like the Black Belt stats, you can tweak this, to include a range. Here's how. Change the second $F0 byte to read $30:

$2DC7D should now read "F0 40 C9 01 30 3C".

However, if you're using FFHackster, this WILL be overwritten. Until someone changes that... ^_^

Text Locations

Intro: $37F30
Bridge: $36843 "And so...our world."
Item Descriptions: $385BD
Spell Descriptions: $38A17
Ending: $368F3 "The Time-Loop...continue to shine..."
Character Name Menu: $3A021
Shop Text: $38095

There's more data from Goongyae's Final Facelift... I'll have to dig it up.
Bag of Stinky Weeds
Level: 3

Posts: 1/2
EXP: 119
For next: 9

Since: 12-16-02
From: Hell

Since last post: 1153 days
Last activity: 1153 days
Posted on 08-26-03 10:52 PMQuote

Gavin86 is Not a Robot

"Three things we lived by: truth in our hearts, strength in our hands, and fulfilment in our tongues"

Current Projects: FF: Revival of the Forest ::: Unlocked | Hacks

a little something i'm in the slow slow process of writing, it'll fit into a document i hope to complete on just stuff about Final Fantasy in general.

*::Final Fantasy 1 NES Basic Joystick Input Routine*
* ------------------------------------------------ *
* *
*By Gavin86 ( v1.2*

Well, not too much to this really. I'm in the middle of making a hack of
Final Fantasy 1 NES and i'm attempting to add a new joystick function with
one of the buttons. So I of course took it upon myself to learn about NES
joystick input and basic stuff like that. It's not the biggest code, not the
toughest, but I figured it may be able to help someone.

I've yet to look at other games joystick codes, so i'm not sure how Final
Fantasy would compare, but i would assume it could'nt be too far off.

And so without more rambling, here it is:

::A Quick Overview of the Routine

-Going through loop quickly: the LDA $4016 gets the first button status, the
returned value is then compared to one, which will either set or reset the
Carry register. The value in the Carry Regiser is then rotated (ROL) into
$20, then X with loaded value 8 is decremented until X euals zero, which will
cause a bypass branch (BNE) and RTS ending that current joypad read.

::Commented Dissassembled Joystick Input Routine

$D7C9 A9 LDA #$01 ===+ directly loads the Accumulator with 1
$D7CB 8D STA $4016 | stores the Accumulator value (1) into $4016
$D7CE A8 LDA #$00 | directly loads the Accumulator with 0
$D7D0 8D STA $4016 ===+ stores the Accumulator value (0) into $4016

$D7D3 A2 LDX #$08 =loads 8 so it can loop for each byte
$D7D5 AD LDA $4016 =loads the info from the joystick
$D7D8 29 AND #$03 ===+
$D7DA C9 CMP #$01 ===| =narrows down the data
$D7DC 26 ROL $20 =rotates info into memory...
$D7DE CA DEX =decrements X
$D7DF DO BNE $D7D5 =loops again if not 0
$D7E1 60 RTS =returns to main routine

-Basically the first 4 lines of code ($D7C9 - $D7D0) is a process called
"Joystick Strobing". Strobing involves writing ones and zeros into the
joystick input register ($4016) and a strobe has to be performed for every
read. This joystick register is used to define the type of input and is
used to read the status of all current joystick buttons. In this instance of
code joystick one is checked for A, SELECT, START, UP, DOWN, LEFT, and RIGHT
buttons with the AND bitwise operations later down the routine. All this is
detailed in Yoshi's doc, but i'll throw in the relevant info right here:

"On a full strobe, the joypad's button status will be returned in a
single-bit stream (D0). Multiple reads need to be made to read all the
information about the controller."

**So there isn't really much to do with strobing, just know that it's there
and that if you plan on writing any of your own code, that you'll have to
include it before every read.

-So then after it prepares the joystick for being read, the value 8 is loaded
into the X, then $4016 is read and loaded into the accumulator. The
accumulator value is operated on by the AND bitwise operand limiting the info
to the first two bits (D0 & D1). The value is compared to 1 with checking to
see if it is set or not. If it is set, the Carry is set and if not, the Carry
is reset.

**The X register is loaded with 8 preparing for the eventual loop that will
read and place the status of each joypad button into the single ram address.
The AND operand is used to only obtain the first two bits of the returned
value....which seems somewhat odd, considering the CMP will yeild the same
results without the AND, it will set the Carry exactly the same, and that
Carry will still be ROL'd the appears there really is no need to
bother coding the exclusion.

-The status of all 8 buttons is loaded into one zero-page RAM address: $20.
The ROL (Rotate Left) bitwise operand loads the value currently set into the
Carry into the first bit (D0) of $20 and shits every other bit left.

-After the ROL, there is a DEX (Decrement X) operand, lowering the value of
X by one. Then next line of code BNE (Branch on Z reset) basically checks the
status of the Z (Zero Processor Status Register) which will be set if the
result of the last operation performed was zero. So basically, if the last
operation (that being the Decrementing of X) resulted in X not being zero,
then branch to $D7D5 which will read the status of the other remaining
buttons and continue the loop until X does equal zero.

-And the last command ($D7E1) is of course the RTS (Return to Sub-Routine),
basic stack-manipulation command which will return to the address pushed
into the Stack either (and most usually) a JSR (Jump to Sub-Routine) command
or by some other tricky stack manipulation that really doesn't need to be
discussed right here for our purposes. This ends the joystick read info for
this particular portion of the Final Fantasy code.

-I should be making some additions to the document, and rather large ones at
that, detailing what exactly Final Fantasy will now do with this read info.

::Random Jumps to the Joystick Routine

I haven't really looked to far into where the joystick routine is jumped
to in the rom, but I did have these laying around. $D7C9 being the start of
the joystick routine.

]-$84CF Jumps to $D7C2
]-$D7C2 Jumps to $D7C9 <== Jumps to Joystick Input

]-$D7BE 60 RTS
]-$D7BF 4C JMP $C681
]-$D7C2 20 JSR $D7C9 <== Jumps to Joystick Input
]-$D7C5 20 JSR $D7E2
]-$D7C8 60 RTS


:: I just hope that this dissassembled code might help some people have a
:: better understanding of basic NES Joystick reads and in particular to get
:: a better feel for some of Final Fantasy's code in general.

version1.2 8/29/03 added a few more notes and side comments.
right-o, well i finally found some time to sit down and add a little bit to
the document....what happened to version 1.1 you ask? no idea. Oh well. I've
added a few coments for clarity. Although i feel i still have a lot of work
left to get this to a point where it just might be of some real use. I have
yet to add FF's button action code, something i hope to get around to soon

version1.0 6/26/03 first release of the document.
I guess this would be a version 1.0 :P I plan to add commented code of how
the game deals with what to do with the joystick status data.
All dissasembled data was commented by Gavin86 -003.

NOTE: just taken from a few posts at the CG-Games forum. might as well throw it in here.

3D630 = Changes the Dialouge Menu Speed on Open

3D634 = Changes the Dialouge Menu Length (but it displays wrong if it is longer. I didn't test it shorter)

3D6A9 = The Dialouge Menu Speed on Close

and again, setting the menu speeds to 60 will "technically" make them open instantly. But i still as of yet have not gotten rid of the annoying but brief pause before it opens, and the sounds that still plays normally. the value 60 actually makes a small "shadow" of sorts, it changed the pallete underneath the window for whichever reason. so 59 i think should work just fine.


Alright, well i've finally found that damned annoying sound that occurs when the dialogue window opens, and it just *might* be ralated to that troublesome "slight pause" that has been haunting my dreams lately

Basically, if you want to get rid of the sound entirly just NOP (write in the value "EA" or "4C" -- or any others you might know that produce an NOP in ASM -- into the hex editor) for 20 bytes starting at the address $3D6D7 in the Final Fantasy 1 rom. The last bye you edit should be at the address 3D6EA, if i'm not mistaken.


there is a JSR from this peice of code to the sound routine:
$D60C 20 JSR $D6C7
if you want to get a bigger picture of the code, i guess you cuold start here.

here is the sound code:
$D6C7 A2 LDX #$38
$D6C9 8E STX $4004
$D6CC 8D STA $4005
$D6D0 6A ROR A
$D6D1 49 EOR #$FF
$D6D3 8D STA $4006
$D6D6 A9 LDA #$00
$D6D8 8D STA $4007
$D6DB 60 RTS

the $4000's ($4000 through $4013 i believe) there are sound registers. I don't know exactly how to produce what i want, but with a little finagling, you'll get the idea of how it works. All i seem to be remebering off the top of my head is that $4005 was listed as some type of "sound ramp" or something...but i could very well be remembering that entirerly wrong

so if you want to change the sound, there it is. Just simply set a breakpoint in NESten or FCE for one of the addresses above and you should find it well enough. (i would reccomend going by addresses since it's exact, if you try setting breakpoints for writes to the sound registers your going to have to time it well enough, or NESten or FCE will snap on some of the background music not related to the dialouge window )

wake from your dreams
the drying of your tears
today we escape
we escape

(edited by Gavin86 on 08-29-03 02:19 AM)

(edited by Gavin86 on 08-29-03 02:20 AM)
Bag of Stinky Weeds
Level: 3

Posts: 1/2
EXP: 108
For next: 20

Since: 10-23-03

Since last post: 1481 days
Last activity: 1412 days
Posted on 10-23-03 06:14 PMQuote
Here's copy/pastage from a doc I wrote up to describe the map format:

FF1 Map Compression

Original info discovered by _Demo_ (I think)

Maps are seperated into 2 sections... one section contains the Overworld map, the other section contains the rest of the maps (I call them standard maps). The overworld map is 256x256 tiles large, and each standard map is 64x64 tiles large.

The overworld map is stored in the ROM starting at offset $4010 and ending at $7F50. The first 512 ($200) bytes are pointers... each pointer is 2 bytes and points to 1 row of tiles (so, $4010 points to the top row, $4012 points to the second row, etc, etc). The data pointed to is compressed map data (see below for how to decompress). To calculate the overworld pointers, you must subtract $4000 from the pointer's value to get the value pointed for.

For example: "00 82" would point to $4210 (after byte-swapping, adding $10 for the header, and subtracting $4000)

All the standard maps are stored between $10010 and $1C010. The first 122 ($7A) bytes are pointers... each pointer is 2 bytes and points to an entire map (not each individual row). Note that there are 61 standard maps total... I've thought about adding more... as there's room to do so in the map compression area... but there isn't enough room in other areas (like where all the palettes for the maps are listed). To calculate these pointers, just add $10000 to the value given by the pointer.

For example: "80 00" would point to $10090

Map decompression!

Maps are stored using a basic RLE (run-length encoded) compression method. Both types of maps use the same method of compression.. the only difference is that for overworld maps, each row is stored individually, whereas with standard maps, the entire map is stored in one lump.

Most of the time, tiles are just stored as normal, uncompressed data. Data is only compressed when there's a run of a bunch of the same tiles in a row. The run will be signalled with the high bit being on... then followed by a byte which tells the length of the run.

    65 21 15 18 92 06 07 0A
    ^           ^  ^
    |           |  |
    |           |  This is the length of the run
    |           |
    |           since the high bit is on, there's a run of this tile
    normal uncompressed data

The run in this case is a run of tile $12 (the low 7 bits of the byte), 6 tiles long. And thus, the above example would decompress like so:

65 21 15 18 12 12 12 12 12 12 07 0A
^           ^
|           |
|           we use the low 7 bits of $92, and run it 6 times
this data remains unchanged

A run length of $00 is actually a run length of 256... this is common to see in the overworld, where entired rows are nothing but water.. so they could be compressed down to 3 bytes:

97 00 FF
^  ^  ^
|  |  |
|  |  $FF is a reserved value... see below
|  |
|  put 256 waters in a row
the water tile is $17, so a run of water tiles would be $97 (high bit flipped on)

As I briefly said in the above example, $FF is a reserved value and cannot be used anywhere in the compression... so you CANNOT have a run 255 tiles long (instead you could have a run of 254, then follow it with a single uncompressed tile)... nor can you have a run of tile $7F.

$FF signals the end of a row (for the overworld) or the entire map (for standard maps) at must be placed accordingly.
Sliver X
Bag of Stinky Weeds
Level: 6

Posts: 4/7
EXP: 766
For next: 141

Since: 03-07-03

Since last post: 475 days
Last activity: 475 days
Posted on 04-09-04 10:16 PMQuote
°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~Final Fantasy°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\0.07
/§§§ /§§§ /§§§ /§§§ ¸§§§§§§¸ /§§§ ¸¿§§§§¿ °º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸0.07
/§§§¿/¿§§§ /§§§ /§§§ /§§§´//`§ /§§§ /§§§' ´¤§ ¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-0.07
/§§§§¿§§§§ /§§§ /§§§ /¤§§¿¸ /§§§ /§§§ ´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°0.07
/§§§'§'§§§ /§§§ /§§§ ` `¤§¿¸ /§§§ /§§§ \_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤0.07
/§§§ '/§§§ /§§§¸ ¸§§§ /¿¸ ¿§¿ /§§§ /§§§¸ ¸¿§ ¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´0.07
/§§§ /§§§ /`¤§§§§§¤´ /¤§§§§¤' /§§§ /`¤§§§§§' -~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\0.07
//// //// /////// ////// //// /////// °º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸0.07
º¤'´¯\_¸.-~ Document °º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-~°º¤'´¯\_¸.-0.07

Music Bytes 0.7 (Unofficial update by Sliver X)

I: Credits
Much thanks to Acmlm and Hal-Kun for their assistance

II: General
Address of Data ; 340D0
Adress of pointers ; 34010

III: Notes & Rests

As of so far, it seems every single value uses BWO (Bit Wise Operands), meaning
that changing the first digit changes the action and changing the second
bite works as a parameter for the first byte.

First Digit Values
0 = C
1 = C Sharp (C#)
2 = D
3 = D Sharp (D#)
4 = E
5 = F
6 = F Sharp (F#)
7 = G
8 = G Sharp (G#)
9 = A
A = A Sharp (A#)
B = B
C = Rest (Rs)

The second digit value denotes the length of the note, from 0 (longest) to 9 (shortest)
As to the probability of these values directly relating to Whole, Half, Quarter (etc) notes
seems fairly low.

D8(O1) to DB(O4) are Octave Shifts, D8 being lowest and DB being highest.

IV: Repeating and Looping:
D0(Lp ~Address~) = Loop Pointer, the next two values denote the address to go to.*
D1(Rp ~Address~) = Repeat Pointer, the next two values denote the address to play once.*
D2 to D7 are Play Address twice to Play Address 7 times
DC to DF are of currently Unknown Value

*See VII: Pointer Format & Usage for more information

V: Musical Control Strings
F denotes the begining of a Musical Control String (M.C.S.), and
the next 7 digits will make large differences in the song.
These M.C.S.s always appear at the begining of a song, but that doesnt mean that is the only
place it can be used. 6 digit (3 byte) M.C.S.s appear often in the middle of songs
(The Battle music is a good example of how these can be used numerous times in one song)

4 byte M.C.S. (F8 FB 05 E0)

Tempo A-E, F causes all music to Silence
| This digit seems valuable only as F so far
| |
| |Seems to be note scale (Speed and Tempo)
| ||
| || This byte does nothing of any known value
| || |
| || |Note Length
| || ||
| || || Musical Sound
| || || ,|
| || || ||
F*-**-**-** is a control Header so to speak,

A 3 byte M.C.S. appear often in mid song and are similar to 4 byte ones, except
there is no tempo value.

FF always Silences all music and im not sure there is way to start it up again.

"N.Instrm" means that the said values are Changing the sound of the music
(E.G F8-08-EE in the middle of song)

VI: The Master Music Table
[Offset: 34010 - 340CF]

This section of data tells the game where all the data for the songs begins.
If you look at the hex, you'll notice every set of six bytes are seperated by two zeroes.
Each set of six is the pointer locations for where each song starts, and each set of two within
a set is the location of the data for each of the three channels that can be used for music in
FF (Square 1, Square 2, and Triangle).
Data is always stored in the Master Music Table in the order just listed, so the first two
bytes are the start location for Square 1, the third and fourth Square 2, etc.

This shows the order of the songs in the MMT. Thusly, the first set of six is the Prelude, etc,

1 Prelude
2 Prologue
3 Ending
4 Overworld
5 Ship
6 Airship
7 Town
8 Coneria Castle
9 Dungeon 1
10 Dungeon 2
11 Dungeon 3
12 Dungeon 4
13 Dungeon 5
14 Dungeon 6
15 Shop
16 Battle
17 Menu
18 Dead
19 Fanfare
20 Item Received
21 Treasure Box
22 Item Received 2
23 Treasure Box 2

VII: Pointer Format & Usage

The MMT and the loop/repeat pointers in the music data itself use the SetOff 4000 system.

Here's an example of how to use it:

Figure 1: Prelude Pointers

This is the pointer data for the Prelude. Let's break them apart just for the hell of it:

C080 BD81 BC82

The way to calculate the actual address in the ROM these pointers are aiming at goes like this:

Example 1: Square 1

Now take the pointer and swap the bytes:


Now subtract $4000 from the thousands place:


Now add $10 to the tens place:


Since all the music data is within the 30000 area of the ROM, add a 3 to the beginning of the


This is the beginning offset of the first M.C.S. for the channel in question.

To generate a pointer from an address, so you can tell loop/repeat commands where to jump to,
just reverse the process:





C080 (Pointer)

VIII: Song Data Locations
[MMT Pointer/Offset/Name]

C0 80 / 340D0 / Prelude Square 1
BD 81 / 341CD / Prelude Square 2
BC 82 / 342CC / Prelude Triangle: Not used for this song (Points to Prologue's Triangle data.)
C1 82 / 342D1 / Prologue Square 1
0B 83 / 3431B / Prologue Square 2
57 83 / 34367 / Prologue Triangle
4E 9B / 34395 / Ending Square 1
1B 9C / 3442C / Ending Square 2
B7 9C / 35CB7 / Ending Triangle
3C 88
8C 88
03 89
FF 89
6B 8A
3D 8B
0F 8C
90 8C
3A 8F
6D 8F
B0 8F
54 8D
84 8D
E4 8D
F3 90
F4 91
7B 92
85 83
1C 84
E7 84
C0 85
28 86
6A 86
04 93
40 93
10 94
E4 8F
45 90
B8 90
C5 86
0D 87
D5 87
01 8E
5D 8E
A3 8E
8C 94
9F 95
BE 96
CC 97
01 98
36 98
8D 98
CB 98
F3 98
19 99
7E 99
DB 99
63 9A
7D 9A
95 9A
C0 80
BD 81
BC 82
C4 9A
D1 9A
E3 9A
12 9B
2B 9B
37 9B

Appendix 1: Song Data

Some Musical Terms Used in this doc
Prestissimo Incredibly Fast
Presto Very Fast
Allegro Fast
Allegretto Moderatly Fast
Andante Moderatly Slow
Adagio Slow
Larghetto Very Slow
Largo Incredibly Slow

Where you see Elipsis ("...") just continue the data on the next hex line.
Couldnt think of a better way of seperating everything.

Prelude 340D0 Main Track
Allegro, Moderately long note length
O1 A# O1 C D F A# O2 C D F A# O3 C D F A# O4 C D F A# F D C O3 A# F D C
O2 A# F D C O1 A# F D C O1 G A A# O1 D G A A# O2 D G A A# O3 D G A A# O4
D G D O3 A# A G D O2 A# A G D O1 A# A G D O1 A# A Rp 340D4 O1 G A# O1 D# F
G A# O2 D# F G A# O# D# F G A# O4 D# F G F D# O3 A# G F D# O2 A# G F D# O1 A#
G F D# O1 A# O1 A O1 C F G A O2 C F G A O3 C F G A O4 C F G A G F C
O3 A G F C O2 A G F C O1 A G F C O1 F# A# O1 C# F F# A# O2 C# F F# A# O3 C#
F F# A# O4 C# F F# F C# O3 A# F# F C# O2 A# F# F C# O1 A# F# F C# O1 A# O1 G# O1 C
D# G G# O2 C D# G G# O3 C D# G G# O4 C D# G G# G D# C O3 G# G D# C O2 G# G D#
C O1 G# G D# C Lp 340D4

Prelude 341CD Acompaniment
Allegro, Moderatly-Long Note length
Rs Rs O1 A# O1 C D F A# O2 C D F A# O3 C D F A# O4 C D F A# F D C O3 A# F
D C O2 A# F D C O1 A# F D C O1 G A A# O1 D G A A# O2 D G A A# O3 D G A
A# O4 D G D O3 A# A G D O2 A# A G D O1 A# A G D O1 A# A Rp 341D3 O1 G A# O1
D# F G A# O2 D# F G A# O# D# F G A# O4 D# F G F D# O3 A# G F D# O2 A# G F D#
O1 A# G F D# O1 A# O1 A O1 C F G A O2 C F G A O3 C F G A O4 C F G A G
F C O3 A G F C O2 A G F C O1 A G F C O1 F# A# O1 C# F F# A# O2 C# F F# A#
O3 C# F F# A# O4 C# F F# F C# O3 A# F# F C# O2 A# F# F C# O1 A# F# F C# O1 A# O1 G#
O1 C D# G G# O2 C D# G G# O3 C D# G G# O4 C D# G G# G D# C O3 G# G D# C O2 G#
G D# C O1 G# G D# C Lp 341D3


Prologue 342D1 Main Track
Allegretto, Moderate note length
O3 C F G C A# A G F E F G F F E D G A D O4 C O3 A# A G F3 A G D A
G Rp 342D2 O4 D D C O3 A A# A# A G F# G A A# O4 C D# D# D O3 A# O4 C C C# C
C C# C O3 A# A G Rp 342D2

Prologue 3431B Acompaniment
Allegretto Moderate note length
O2 C D E F D E G D E F G G A A# G G F# G A A# G F# O3 C O2 A# B O3 C
O2 A# Rp 3431C A# A G A A# Rs E A G F G A Rs F G D# D C D G A O3 C O2 G#
A# G F F G G# F G E Lp 3431C

Prologue 34367 Bass
Allegretto, Semi-Short-Moderate note length
O2 F E D C O1 A# B O2 C A# A G F# G F E C Rp 34268 A# A# F F D# D G F G#
D# D G G# O3 C# C O2 A# Lp 34368

Ending 34395 Main
Allegretto, Semi-Short-Moderate note length
O2 B O3 D F# O2 B O3 G F# E D E D N.Instrm C N.Instrm D F# A D B A G F# G
F# E F# G N.Instrm A C# E D Rs C# Rs D Rs O2 B O3 G A B D G F# Rs G Rs F# Rs
E A B O4 C# Rs O3 A B O4 C# E D C# D O3 C A G F# E Rs C D E D C# O2 A
N.Instrm O3 D Rs N.Instrm D C# O2 B O3 C# N.Instrm D Rs N.Instrm F# E D E N.Instrm
F# Rs N.Instrm A G F# G N.Instrm A N.Instrm F# E D C# E D C# O2 A# Lp 34396

Ending 3441C Acompaniment
Allegretto, Moderate note length
O1 B Rs O2 F# Rs O1 B Rs O2 F# Rs O1 B Rs O2 G Rs O1 B Rs O2 G Rs O1 B Rs O2 G Rs
O1 B Rs O2 G Rs C# Rs A Rs C# Rs A Rs D Rs A Rs D Rs A Rs D Rs B Rs D Rs B Rs
D Rs B Rs D Rs B Rs C# Rs A Rs C# Rs A Rs A Rs A Rs Rs A Rs A Rs Rs F# Rs F# Rs
Rs F# Rs F# Rs Rs B Rs B Rs Rs B Rs B Rs Rs O3 C# Rs C# Rs Rs C# Rs C# Rs Rs O2 A Rs
A Rs Rs A Rs A Rs Rs F# Rs F# Rs Rs F# Rs F# Rs Rs E Rs G Rs E Rs G Rs E Rs G Rs
E Rs G Rs E Rs G Rs E Rs G Rs A G F# E F# E D C# N.Instrm F# D G D A A D
A G E 2Rp344DA F# D G D A A D A F# E Lp 3442D

Ending Bass
Allegretto Moderate note length
O1 B O2 E G A G D G B A E Rs C# Rs O1 A Rs Rs F O2 O1 Rs F Rs rS O1 F Rs O2
F C# Rs Rs O1 B O2 F Rs B Rs Rs O1 B Rs O2 B F Rs Rs O1 G O2 D Rs G Rs Rs O1 G
Rs O2 G D Rs Rs O1 A O2 E Rs A Rs Rs O1 A Rs O2 A E O2 Rs O1 F O2 C# Rs F O2 Rs
O1 F Rs O2 F C# Rs Rs O1 B O2 F Rs B Rs Rs O1 Rs Rs O2 B F Rs C O3 A Rs O2 C O3
C Rs O2 C O3 C Rs O2 C O3 C Rs O1 A O2 A Rs O1 A O2 A Rs O1 A O2 A Rs O1 A O2
A Rs D A Rs Rs A Rs D B Rs Rs B Rs D O3 C# Rs Rs C# Rs O2 D B Rs Rs B Rs
2Rp34593 D A Rs Rs A Rs D B Rs Rs B Rs D O3 C# Rs Rs C# Rs O2 F O3 C# Rs O2 F O3
C3 Rs Lp 344F8

Allegretto Moderate note length
O2 F# G G# G F# G G# A# G# G D# C F# G G# G F# G G# A# G# G D# C D# E G A# B
O3 C C# C O2 B O3 C C# D# C# C O2 G# F B O3 C C# C O2 B O3 C C# D# C# C O2 G#
F O3 C O2 A# G# F Rp 345D4 N.Instrm O3 G G# G Rs Rs A# A G# Rp 3461A O4 C C# C Rs
Rs D# D C# Rp 34629 Lp 345D1

Allegretto Semi-Moderate note Length
O1 G Rs G Rs Rs G Rs G Rs G Rs O2 C Rs C Rs C Rs C Rs C Rs Rp 3463C N.Instrm D
C F D G F F E E D# D# Rp 34656 G F A# G O3 C O2 A# A# A A G# G# Rp 34667
Lp 34639

Allegretto Moderate note length
O2 C Rs C Rs Rs C Rs C Rs C Rs F Rs F Rs F Rs F Rs F Rs Rp 3467E G F# F E F
F# G F# F E F F# G F# F E A# O3 C O2 A B G# A# Rp 34697 O3 C O2 B A# A A# B
O3 C O2 B A# A A# B O3 C O2 B A# A O3 D# F D E C# D# Rp 346B2 Lp 3467B

Allegretto Moderate note Length
O2 B G# B A# G# F# A G# Rs B O3 C# O2 B A# G# F# O3 E D# N.Instrm Rs O2 D# F F# G
G# A N.Instrm A# B O3 C# O2 B A# G# O3 D# C# D# E D# O2 B Rs O3 D# C# O2 B A# G# G
N.Instrm A# Rs Lp 346D6

Allegretto Moderate note Length
O1 B O2 D# C# D# O1 B O2 D# C# D# O1 A# O2 D# C# D# O1 A# O2 D# C# D# O1 G# O2 D# C# D#
O1 G# O2 D# C# D# O1 A# O2 D# C# D# O1 A# O2 D# C# D# O1 B O2 D# C# D# O1 B O2 D# C# D#
O1 A# O2 D# C# D# O1 A# O2 D# C# D# O1 G# O2 D# C# D# O1 G# O2 D# C# D# O1 G# O2 C# O1 B
O2 C# O1 G# O2 C# O1 B O2 C# N.Instrm D# D# Rs O1 A# O2 D# D# Rs O1 A# O2 D# D# Rs O1 B
O2 D# D# Rs O1 B O2 E E Rs C# E E Rs C# F F Rs D# F F Rs D# N.Instrm G# Rs
N.Instrm O1 B O2 E G# N.Instrm E Rs N.Instrm O1 G# O2 C# E N.Instrm G Rs N.Instrm O1
A# O2 D# G O1 G A# O2 C# E G E C# O1 A# Lp 3471E






Rough Location of all music:
Festering Blob of Unknown Origin
Resident Grumpy Old Bat All-Knowing Sage That Guy
Level: 51

Posts: 139/773
EXP: 976691
For next: 37247

Since: 03-19-02
From: Melniboné

Since last post: 24 days
Last activity: 9 hours
Posted on 05-24-04 09:41 PMQuote
Journal Entry #139, Day 797

Originally posted by Disch on Acmlm's Board
Yeah... so... I've decided to release this. It's just sitting on my HD and I'm not doing anything with it. So yeah... (edit: do the right-click save-as thing)

Everything you need to re-assemble is included. Just be sure to read the readme or I'll slap you.

Badges Earned

The Holy Empire of Menzobarranzen - Death is coming...

AdventureQuest Stats

Bag of Stinky Weeds
Level: 3

Posts: 2/2
EXP: 119
For next: 9

Since: 12-16-02
From: Hell

Since last post: 1153 days
Last activity: 1153 days
Posted on 09-16-04 10:22 PMQuote

Gavin86 is Not a Robot

"Three things we lived by: truth in our hearts, strength in our hands, and fulfilment in our tongues"

Current Projects: FF: Revival of the Forest ::: Unlocked | Hacks

Main Menu Hand Pointer Data

3B636 - X position of Character4 Sprite
3B64A - Y position of Character4 Sprite

3B8AC - X position of ORB 1

3B7E9 - X position of Character1 Hand Cursor
3B7EA - Y position of Character1 Hand Cursor

3B7EB - X position of Character2 Hand Cursor
3B7EC - Y position of Character2 Hand Cursor

3B7ED - X position of Character3 Hand Cursor
3B7EE - Y position of Character3 Hand Cursor

3B7EF - X position of Character4 Hand Cursor
3B7F0 - Y position of Character4 Hand Cursor

3B7F1 - Y position of ITEM Hand Cursor
3B7F2 - Y position of MAGIC Hand Cursor
3B7F3 - Y position of WEAPON Hand Cursor
3B7F4 - Y position of STATUS Hand Cursor

$9C02 - routine that clears the screen (blanks the Name Table)

$B635 - character sprite display on main menu

$B8EF - character main menu window loading routine

3A2E3 - Text 'default' color after flicker, returns to this color
3A2B8 - Text color that the above flicker math routine is applied to
3EB40 - Text color after flicker effect has been applied on text line
3EB48 - Text 'color number 02' after flicker effect

3E0AA - horizontal spacing between text and left boundary of window
3E0B1 - vertical spacing between text and top boundary of window

3E082 - horizontal window border subtraction
3E089 - vertical window border subtraction

- Where on the pattern table to load each tile for the window from:
3E0C8 - ($FA) left
3E0CD - ($FF) background
3E0D5 - ($FB) right
3E11F - ($F7) upper-left
3E124 - ($F8) top
3E12C - ($F9) upper-right
- ($FD) bottom

3F2F5 - main battle border X & Y position
3F2FA - main battle border Width (should not be below 3)
3F2FC - main battle border Height (should not be below 3)

3F301 - character battle border X position
3F306 - character battle border Y position
3F308 - character battle border Width
3F30A - character battle border Height

$F3C6 - draws the battle stat windows

3F3E0 - stat battle width for all 4 stat windows
3F30F - stat battle x position for all 4 stat windows
3F311 - stat battle window 4 y position
3F316 - stat battle window 3 y position
3F31B - stat battle window 2 y position
3F320 - stat battle window 1 y position

$C006 - routine to transfer window X,Y coordinates to text location
X,Y coordinates. Then calls $DCAB to set up text draw
locations. i beleive draw routine is $DCBF

$E0FC - draws top border of window
$E0A5 - draws sides border of window
$E0D7 - draws bottom border of window

$F3BF - stores current A and X values into the VRAM write address

$F314 - loads the attribute table for the battle screen

$F33D - loads which palette set to use for BG

$F347 - loads which palette set to use for Enemies

$F3F1 - turn off the PPU

3F39D - how many tiles the first section of the BG should draw
3F3AA - how many tiles the second section of the BG should draw

$F385 - draws the BG environment tiles

3F35D - row 1 BG environment tile set (00,04,08,0C)
3F364 - row 2 BG environment tile set (00,04,08,0C)
3F36B - row 3 BG environment tile set (00,04,08,0C)
3F372 - row 4 BG environment tile set (00,04,08,0C)

3F9F5 - Enemy window X coordinate
3F9F6 - Enemy window Y coordinate
3F9F7 - Enemy window Width
3F9F8 - Enemy window Height

3F9FA - current Attacker window X coordinate
3F9FB - current Attacker window Y coordinate
3F9FC - current Attacker window Width
3F9FD - current Attacker window Height
3F9FF - current Attacker text X coordinate
3FA00 - current Attacker text Y coordinate

3FA02 - hit number window X coordinate
3FA03 - hit number window Y coordinate
3FA04 - hit number window Width
3FA05 - hit number window Height
3FA07 - hit number text X coordinate
3FA08 - hit number text Y coordinate

3FA0A - current Attackee window X coordinate
3FA0B - current Attackee window Y coordinate
3FA0C - current Attackee window Width
3FA0D - current Attackee window Height
3FA0F - current Attackee text X coordinate
3FA10 - current Attackee text Y coordinate

3FA12 - Attack Status window X coordinate
3FA13 - Attack Status window Y coordinate
3FA14 - Attack Status window Width
3FA15 - Attack Status window Height
3FA17 - Attack Status text X coordinate
3FA18 - Attack Status text Y coordinate

3FA1A - Battle Info window X coordinate
3FA1B - Battle Info window Y coordinate
3FA1C - Battle Info window Width
3FA1D - Battle Info window Height
3FA1F - Battle Info text X coordinate
3FA20 - Battle Info text Y coordinate

3FA22 - Magic window X coordinate
3FA23 - Magic window Y coordinate
3FA24 - Magic window Width
3FA25 - Magic window Height

3FA27 - Drink window X coordinate
3FA28 - Drink window Y coordinate
3FA29 - Drink window Width
3FA2A - Drink window Height

3FA2C - Battle options window X coordinate
3FA2D - Battle options window Y coordinate
3FA2E - Battle options window Width
3FA2F - Battle options window Height

3FA31 - "FIGHT" battle X coordinate
3FA32 - "FIGHT" battle Y coordinate
3FA33 - Text pointer byte (Low)
3FA34 - Text pointer byte (High)

3FA36 - "MAGIC" battle X coordinate
3FA37 - "MAGIC" battle Y coordinate
3FA38 - Text pointer byte (Low)
3FA39 - Text pointer byte (High)

3FA3B - "DRINK" battle X coordinate
3FA3C - "DRINK" battle Y coordinate
3FA3D - Text pointer byte (Low)
3FA3E - Text pointer byte (High)

3FA40 - "ITEM" battle X coordinate
3FA41 - "ITEM" battle Y coordinate
3FA42 - Text pointer byte (Low)
3FA43 - Text pointer byte (High)

3FA45 - "RUN" battle X coordinate
3FA46 - "RUN" battle Y coordinate
3FA47 - Text pointer byte (Low)
3FA48 - Text pointer byte (High)

3FA49 - Pattern table location for "FIGHT" tiles (through 3FA4C)
3FA4E - Pattern table location for "MAGIC" tiles (through 3FA51)
3FA53 - Pattern table location for "DRINK" tiles (through 3FA56)
3FA58 - Pattern table location for "ITEM" tiles (through 3FA5B)
3FA5D - Pattern table location for "RUN" tiles (through 3FA5F)

3FA61 - value for which string to display in Enemy name slot 1
3FA63 - value for which string to display in Enemy name slot 2
3FA65 - value for which string to display in Enemy name slot 3
3FA67 - value for which string to display in Enemy name slot 4

$F59B - Main battle window SRAM setup routine

$6AA1 - (RAM) holds the value of the battle menu width

$9B2D - routine that aquires the X,Y values for the cursor
on the Select Button Screen

$A219 - sets up the PPU for displaying stuff, global

$C06C - jumps to flashy text screen stuff

$A0EE - flashy screen routine

wake from your dreams
the drying of your tears
today we escape
we escape
Next newer thread | Next older thread
rustedmagick forums - The ROM Hacking Data Repository - Final Fantasy 1 (NES) |

AcmlmBoard v1.8a BMF Hax0r Special™
© 2000-2002 Acmlm
Board additions/modifications by:

Page rendered in 0.014 seconds.