News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Question about NES Pointers  (Read 3689 times)

joe73ffdq

  • Full Member
  • ***
  • Posts: 197
    • View Profile
Question about NES Pointers
« on: February 04, 2014, 10:13:03 pm »
There is something I mapped out, and most of it appears to be correct, but some of it doesnt.


These are pointers for effect routines in GFF

Effect 00: Ineffective....................94b8...338a4.....Eff-0
Effect 02: Undead damage...........fab8...3390a.....Eff-2
Effect 01: Damage.......................06b9...33916.....Eff-1

The pointers above match up and work fine.


Out of the 26 pointers for effect routines, there are 4 that dont appear to match what they are supposed to.

Effect 16: Damage..............................Quake......86da....35a96
Effect 0c: hit multiplier up....................................b5eb...36bc5
Effect 18: Set HP to 1.........................Tornado....77fe....37e87
Effect 17: 17-Death.......Earthquake...Chasm......8afe....37e9a

In the first set, pointer b8 goes with 33800. These following 4 dont appear to connect to the right routine


0-28000
1-29000
2-2A000
3-2B000
4-2C000
5-2D000
6-2E000
7-2F000
8-30000
9-31000
A-32000
B-33000......
C-34000
D-35000
E-36000
F-37000

Is my assessment correct that pointers have a range of 10000, or am I missing something here?

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7041
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Question about NES Pointers
« Reply #1 on: February 04, 2014, 11:55:18 pm »
I don't think you fully understand what a pointer is.

By default the NES could only handle 32KB of program ROM, mapped from CPU addresses $8000-FFFF.
Early on developers decided it wasn't enough so they made mappers by allowing the CPU to enable just certain sections (or "banks") of the ROM at once.
In the case of Final Fantasy, it allows the programmer to have two ROM banks (each 16KB or $4000 bytes) activate at once. The last ROM bank (ROM address $3C000-3FFFF, excluding the header) is always mapped from CPU address $C000-FFFF.
The contents of CPU address $8000-BFFF is any ONE other ROM bank.
A pointer is just a CPU address.

Let's take the first address on your list.
$338A4 is the ROM address. But that includes the $10 byte iNES header, which isn't part of the ROM on the actual cart. So we subtract it to get $33894. Since a ROM bank in Final Fantasy is $4000 bytes, that means $33894 is in the ROM bank that runs from $30000-33FFF (the ROM bank starts at the highest multiple of $4000 below $33894). (hint: because $4000 goes into $10000 4 times, you can tell the start of the bank by the last 4 digits of the pointer, a new bank starts at each ROM address ending in 0000, 4000, 8000 or C000, excluding the iNES header)
The pointer $B894 points to an address within that ROM bank.
$33894 modulus $4000 which is $3894. Because the ROM bank is mapped to CPU address $8000, we add $8000 to the relative address $3894 to get CPU address $B894: the pointer.
"My watch says 30 chickens" Google, 2018

joe73ffdq

  • Full Member
  • ***
  • Posts: 197
    • View Profile
Re: Question about NES Pointers
« Reply #2 on: February 05, 2014, 01:22:33 am »

The pointer $B894 points to an address within that ROM bank.
$33894 modulus $4000 which is $3894. Because the ROM bank is mapped to CPU address $8000, we add $8000 to the relative address $3894 to get CPU address $B894: the pointer.

The beginning of the pointer table for effect bytes starts at 33817/18, which is 94b8, Effect byte 00.

94b8 means that Effect 00 starts at 338a4.

Lets look at just the b in 94b8. Are the pointer possibilities limited to 8, 9, a, and b in bank 12, and then c, d, e, and f for bank 15?


So then with these, they all point to bank 15?

Effect 16: Damage..............................Quake......86da....3da96
Effect 0c: hit multiplier up....................................b5eb...3ebc5
Effect 18: Set HP to 1.........................Tornado....77fe....3fe87
Effect 17: 17-Death.......Earthquake...Chasm......8afe....3fe9a

Is that correct?



Thanks for the help. There are continual hurdles in learning this stuff.
« Last Edit: February 05, 2014, 01:50:33 am by joe73ffdq »

STARWIN

  • Sr. Member
  • ****
  • Posts: 452
    • View Profile
Re: Question about NES Pointers
« Reply #3 on: February 05, 2014, 02:58:56 pm »
pointers do not exist. the game has a routine or routines that deal with bank switching. how values that you find in some table relate to some code being called, entirely depends on the game code (and mapper hardware).

if my interpretation is correct (http://wiki.nesdev.com/w/index.php/INES_Mapper_001), you'll probably find STA XXXX commands in the bank switching routine, where XXXX is arbitrarily in range E000-FFFF, and accumulator holding the target bank number bit-by-bit in a somewhat ugly manner. ideally the routine they have implemented makes it slightly simpler to understand (put target bank value somewhere, call routine, and bank is switched).

you can follow the disassembly and execute the code in your head or store a trace of the execution of those particular effects to see what logic is used.

joe73ffdq

  • Full Member
  • ***
  • Posts: 197
    • View Profile
Re: Question about NES Pointers
« Reply #4 on: February 05, 2014, 05:57:12 pm »
I think I phrased my question wrong.

Here are specific pointers within the game. Copied directly from FF1 disassembly, Bank 12

b807: 94 b8       .DW $b894   ; Effect 00: "Ineffective"
b809: 99 b8       .DW $b899   ; Effect 01: Damage
b80b: 05 b9       .DW $b905   ; Effect 02: Undead damage
b80d:  2f b9       .DW $b92f    ; Effect 03: Apply status ailment
b80f:  5e b9       .DW $b95e   ; Effect 04: hit multiplier down

; Effect 00: Display "ineffective" message
b894: a9 04        LDA #$04
b896: 4c f2 b0     JMP $b0f2

(b807: 94 b8) points to (b894)

This in hex, points to 338a4


; Effect 01: damaging magic
b899: 20 85 b8    JSR $b885   ; $685c = #$01 ("spell was effective"?)
b89c:  20 73 b8    JSR $b873   ; w[0] = #$94
b89f:  20 f9 b8     JSR $b8f9    ; w[1] = spell effectivity

b809: 99 b8        .DW $b899   ; Effect 01: Damage

This in hex, points to 338a9
 
-------------------------------------


My question is for these, which are in GFF

Effect 15: Resist Earth..Float...............................21a3
Effect 16: Damage..............................Quake......86da
Effect 0c: hit multiplier up....................................b5eb
Effect 18: Set HP to 1.........................Tornado....77fe
Effect 17: 17-Death.......Earthquake...Chasm......8afe

In bank 12, the pointer with a "b" - 94 b8  - 94 (b)8 points to anything in 33000.....

With these specific 5 effect routines in GFF, they have pointers with "a, d, e, and f"

-------------------------------------


From what I now understand, 8=30000, 9=31000, a=32000, b=33000, c=3c000, d=3d000, e=3e000, and f=3f000

This would apply for bank 12 - 30010/3400f in hex

-------------------------------------


If the same routine was in bank 11 - 2c010/3000f, then those (routine specific pointers) would apply to...

8=2c000, 9=2d000, a=2e000, b=2f000, c=3c000, d=3d000, e=3e000, and f=3f000

-------------------------------------


The final question now is...

I know that 8, 9, a, and b work within each specific bank


Does c, d, e, and f refer to bank 15?

Can 0, 1, 2, 3, 4, 5, 6, and 7 be used. Example - can 94 b8 be changed to, lets say 9458
« Last Edit: February 05, 2014, 06:05:53 pm by joe73ffdq »

STARWIN

  • Sr. Member
  • ****
  • Posts: 452
    • View Profile
Re: Question about NES Pointers
« Reply #5 on: February 06, 2014, 11:24:02 am »
with a quick look at it..

the code that determines what to do with that table in anomie's disasm is in b7cd. my short notes of it:
Code: [Select]
LDA
effect (e)
ASL
e*2
LDA
left byte from table (ll)
STA 96

LDA
right byte from table (rr)
STA 97

...

JMP (0096)
jump to the address rrll
these addresses are between b894-bad7, which maps to the third bank slot according to what KingMike said

but we are already in that bank so nothing complicated happens, just an internal jump in bank 0c

how the GFF version does this? i don't know:

is the code in b7cd the same?

-if yes, then those effects you listed jump to
a321 same 3rd slot
da86 4th slot
ebb5 4th slot
fe77 4th slot
fe8a 4th slot

according to what KingMike said, the 4th slot is locked to the last bank (bank 0f i assume?)

put windows calculator to hex mode and figure the addresses out: bank*4000+10+offset-8000 = ROM address (bank number in hex..)

-if not, do a small disassembly of the section in GFF that uses the table in question, and try to read it
« Last Edit: February 06, 2014, 01:56:39 pm by STARWIN »

joe73ffdq

  • Full Member
  • ***
  • Posts: 197
    • View Profile
Re: Question about NES Pointers
« Reply #6 on: February 06, 2014, 02:47:28 pm »
Cast Spell---b7cd-b806

This is the same in GFF

-------------------------------

Effect routine Pointers

b807-b82b-----in an unpatched rom

b807-b840-----in GFF

--------------------------------

Effect routines start at

b894-----in an unpatched rom

b842-----inGFF

--------------------------------

Apply elemental weakness into w[0]

b851-b893--unpatched


Replaced by these in GFF

.....Effect 19: Resist Status and cures*..A-Spell......42b8...33852
.....Effect 14: Damage and Status Effect.......1........4db8...3385d

--------------------------------


Most of the Effect Routines have been moved around, but I have had no problem figuring out how to adjust the INT variables


I had wondered what the range of what the pointers were, because these threw me off

Effect 15: Resist Earth..Float...............................21a3
Effect 16: Damage..............................Quake......86da
Effect 0c: hit multiplier up....................................b5eb
Effect 18: Set HP to 1.........................Tornado....77fe
Effect 17: 17-Death.......Earthquake...Chasm......8afe

The first one 21a3-32331, made no sense because its in the middle of a different set of routines

The following 4 caused confusion initially. If b=33000, I didnt know if d=35000 or 3d000



Now I wonder if 0-7 can be used

b807: 94 b8       .DW $b894   ; Effect 00: "Ineffective"

Can I assign this pointer to 9458 if I wanted, and where would 9458 point to?


--------------------------------


Thanks for the help. I just started tinkering with pointers, and Im not quite sure of the range for their assignment.

STARWIN

  • Sr. Member
  • ****
  • Posts: 452
    • View Profile
Re: Question about NES Pointers
« Reply #7 on: February 06, 2014, 04:36:45 pm »
a321 same 3rd slot
da86 4th slot
ebb5 4th slot
fe77 4th slot
fe8a 4th slot

according to what KingMike said, the 4th slot is locked to the last bank (bank 0f i assume?)

Sorry, I wrote rubbish here: there are only two bank slots (or one) with MMC1. Hence if your code is in the switchable bank, all jumps are either to the bank itself or to the locked last (or first with some other configuration) bank.

--

I won't analyze GFF myself, but:

I had wondered what the range of what the pointers were, because these threw me off

Effect 15: Resist Earth..Float...............................21a3
Effect 16: Damage..............................Quake......86da
Effect 0c: hit multiplier up....................................b5eb
Effect 18: Set HP to 1.........................Tornado....77fe
Effect 17: 17-Death.......Earthquake...Chasm......8afe

The first one 21a3-32331, made no sense because its in the middle of a different set of routines
Well, with a quick deduction bank 12 (32331) should be correct. And for the others, in the last bank.

Can I assign this pointer to 9458 if I wanted, and where would 9458 point to?

If you feed the b7cd routine with 9458 via the table, it will throw you to 5894 - which is unlikely to be a good address. You want 8000-FFFF (roughly*). 8000-BFFF is this bank, and after C000 is the last bank.

*jumps to RAM areas should work; probably irrelevant

Thanks for the help. I just started tinkering with pointers, and Im not quite sure of the range for their assignment.
Pointers are not a data type, they are treated just as all other numbers. That means they won't have any special properties, such as range. This pointer data, when used by the b7cd routine, will be used to simply jump to the stored address (swapping right and left). From CPU point of view there is nothing special in the jump.

The only real problem in a case like this is knowing which bank is in which bank slot at the time when the code is executed - internal jumps to the same bank are easy, as are jumps to a static (locked) bank like the last bank here. And in your case we seem to only have these easy cases so far.
« Last Edit: February 06, 2014, 04:45:51 pm by STARWIN »

joe73ffdq

  • Full Member
  • ***
  • Posts: 197
    • View Profile
Re: Question about NES Pointers
« Reply #8 on: February 07, 2014, 12:45:28 am »
Now I fully understand it. I wasnt having any problems with any of the routines in testing, but I wanted to make sure on the matter and not be making a guess. I am putting together extensive documents for GFF, and I dont want to release information unless I am 100% on something. Now I know how to explain the use and parameters of routine pointers.

Now to the really fun stuff. The next section of these documents are the complete breakdown of INT variables. I have finally discovered how to break past the 1024 damage thresh hold, and can now have both physical and magical attacks reach up to 46800. I dont know why it gives funny symbols after that number, but with a 65535 HP cap anyway, its good enough.

Without any code explanation, here are some direct damage ranges I have found with adjusting INT variables

1-1024

20-1600

50-2500

200-6500

500-10000

I dont remember the exact numbers offhand, but this is awesome to try different variations. Its really funny how in one of the adjustments, the Intelligence stat contributes about 10 times to the damage outcome, then the power of the spell itself does.