(Link to AcmlmWiki) Offline: thank ||bass
Register | Login
Views: 13,040,846
Main | Memberlist | Active users | Calendar | Chat | Online users
Ranks | FAQ | ACS | Stats | Color Chart | Search | Photo album
05-05-24 12:42 AM
0 users currently in ROM Hacking.
Acmlm's Board - I3 Archive - ROM Hacking - N64 Pointer Referencing New poll | |
Add to favorites | Next newer thread | Next older thread
User Post
Guy Perfect









Since: 11-18-05

Last post: 6287 days
Last view: 6285 days
Posted on 12-22-05 12:26 AM Link | Quote
Let's pretend I'm dealing with the North American version of F-Zero X and let's also pretend that I'm looking for a program pointer somewhere in the ROM that points to offset 2AD1E0.

Let's pretend also that the offset in question is the start of the track data and is not mentioned in the ROM as bytes. While there is one instance of 002AD1E0, nothing happens when it's changed.

802AD1E0 doesn't even show up, E0D12A doesn't find anything useful, etc.

So, um... Help? Any opcodes or what-not I could be searching for instead?
VL-Tone

Paratroopa








Since: 11-18-05

Last post: 6475 days
Last view: 6475 days
Posted on 12-22-05 06:06 AM Link | Quote
Did you also search for 2A00E0D1? (BADC format) there's two instances of it, close together and part of a list of similar pointers.


At 0x72030 in the ROM:

52 00 60 4D
52 00 F0 7A
52 00 30 87
F6 00 00 79
52 00 F0 7A
52 00 30 87
27 00 F0 87
27 00 00 F2
2B 00 A0 9E
52 00 20 49
2A 00 E0 D1 <---------
2B 00 A0 9E
27 00 F0 47
27 00 F0 87
17 00 E0 B1
17 00 60 B9
1B 00 50 85
1E 00 F0 23
1E 00 F0 23
22 00 A0 B0
17 00 60 B9
1B 00 50 85
14 00 70 5B
15 00 B0 35
15 00 B0 35
16 00 60 66
27 00 00 F2
2A 00 E0 D1 <---------
22 00 A0 B0
23 00 30 51
16 00 A0 C8
17 00 E0 B1
23 00 30 51
23 00 80 9A ...
Guy Perfect









Since: 11-18-05

Last post: 6287 days
Last view: 6285 days
Posted on 12-23-05 01:56 AM Link | Quote
A VERY peculiar bit of information.

In the North American ROM at offset 000DFC28, there is data displaying the value 80119550. That is the pointer to the first byte of course description text (i.e., the "FIGURE EIGHT" of Mute City 1). The only thing is, the actual ROM offset where that text is located is 000DFCB0.

When changed, it works exactly as if 80119550 truely WAS 000DFCB0. This works for all 24 courses, as this is a pointer table.

But how the heck is this possible? How can the value 80119550 actually represent 000DFCB0?
VL-Tone

Paratroopa








Since: 11-18-05

Last post: 6475 days
Last view: 6475 days
Posted on 12-23-05 04:08 AM Link | Quote
Take 3! I hope to be more helpful this time...

The game is probably copying some chunks of ROM data somewhere in RAM when it starts up, or when a level is loaded.

The pointer table you are talking about may be copied as part of a bigger RAM segment so its RAM offset is not directly/logically related to its ROM address. And that's also why you cannot find a pointer directly referring to the start of this text pointer table in ROM, since its not at the start of the copied data chunk.

You'd have to find out more about how the game manages ROM to RAM copying to find the exact answer, ideally using a tracer...

If you subtract 0x800398A0 from each offset in the text pointer table you can find the ROM position of the text. Subtracting the same number from other pointers that are just before the text table and text.

At 0xDF934 for example, you'll find the smallest pointer of this bunch: 0x801190F4, if you subtract 0x800398A0 you get 0x0D54F8, which is where you can find the beginning of a data pattern starting with 00110000. The pointers following after 0xDF934 also lead to coherent results when you do the same subtraction. Obviously it doesn't work for all the pointers in the game, but only those part of this "segment".

If you can find the start address in ROM and RAM of this particular segment it would help you very much.

By comparing this part in ROM and its "mirror" in RAM near 0x801190F4, (using a savestate for example) you may be able to find where it starts, just go back until the data doesn't match and bingo!
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6285 days
Last view: 6285 days
Posted on 12-23-05 12:20 PM Link | Quote
It helps to know a bit about N64 ASM. It does things 16 bits at a time, so you'd want to search for D1E0. If it is embedded within the code, the address you find it at will end with 2, 6, A or E, and the other half should be nearby also ending with one of those.

Also, like VL-Tone said, N64 games generally load all their code and most data into memory before processing it.
Guy Perfect









Since: 11-18-05

Last post: 6287 days
Last view: 6285 days
Posted on 12-23-05 02:42 PM Link | Quote
That in mind, I have an easy solution. I know where the data is in ROM, so I know what the relative offsets will be from one pointer to another. One string is 16 bytes, the next is 12 bytes, etc. Just write a program to find generic 80xxxxx0 pointer data followed by similar pointers with the designated values for difference and I shouldn't have any problems.

Tracer. Pfft. This idea is much easier. Though if worse comes to worse, I WILL look in nEmu's memory viewer for relative offsets.



EDIT:
Looks like the data I found was the value in RAM. I thought for sure 80xxxxxx was ROM, but it turns out that it's not. Text and horizon image pointer tables have been identified. Staff Ghost pointer table will probably have to use the method I proposed.


(edited by BGNG on 12-23-05 03:08 PM)
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6285 days
Last view: 6285 days
Posted on 12-25-05 06:08 AM Link | Quote
I think ROM is B0xxxxxx to B3xxxxxx. 800xxxxx to 803xxxxx is internal RAM, and 804xxxxx to 807xxxxx is the expansion pak.
Guy Perfect









Since: 11-18-05

Last post: 6287 days
Last view: 6285 days
Posted on 12-25-05 01:36 PM Link | Quote
Here's what the nEmu debugger shows as the memory map:

$0000 0000: RDRAM Memory
$03F0 0000: RDRAM Registers
$0400 0000: (Various registers; I'm not gonna post them all)
$0500 0000: Cartridge Domain 2 Address 1
$0600 0000: Cartridge Domain 1 Address 1
$0800 0000: Cartridge Domain 2 Address 2
$0100 0000: Cartridge Domain 1 Address 2 (This is where ROM usually starts)
$1FC0 0000: PIF Boot ROM
$1FC0 07C0: PIF RAM
$1FD0 0000: Cartridge Domain 1 Address 3



(edited by BGNG on 12-25-05 12:40 PM)
1182
Newcomer


 





Since: 03-30-06

Last post: 6596 days
Last view: 6596 days
Posted on 03-30-06 02:28 PM Link | Quote
Pardon ahead of time if I don't respond in a timely fashion. Internet access is a bit limitted...

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

There isn't a table of rom addresses in F-Zero X. The stages are calculated and loaded via ASM.
8007419C: [part of the stage load routine]
LUI T9,002B
ADDIU T9,T9,D1E0

8007406C is similar and may be an expansion-only routine.


If you follow this code you'll find this:
80074198:
LW T7,0030 (SP) //T7=800D9690=6 (stage number)
LUI T9,002B
ADDIU T9,T9,D1E0 //T9=2AD1E0
SLL T8,T7,0x6 //T8=T7*48=180
SUBU T8,T8,T7 //T8=17A
SLL T8,T8,0x5 //T8=T8*32=2F40
ADDU A0,T8,T9 //A0=JACK1 + offset=2B0120
OR A1,V0,R0 //A1=10B7B0
JAL 80073FA0
ADDIU A2,R0,07E0 //A2=7E0

-which advances between the various circuits. Track offsetting done later on.

Actual stage load is done here:
800C2CC4:
LUI T8,A460
SW V0,0000 (T8) //PI_DRAM_ADDR_REG=ram target address
LW T9,0030 (SP) //T9=800FB268=800FB450
LW T1,0038 (SP) //T1=800FB270= ROM address
LUI AT,1FFF
LW T0,000C (T9) //T0=800FB45C=B0000000
ORI AT,AT,FFFF //AT=1FFFFFFF
LUI T4,A460
OR T2,T0,T1 //T2=ROM as B0 register (ie: B02B0120)
AND T5,T2,AT //T5=ROM as direct (ie: 102B0120)
SW T5,0004 (T4) //PI_CART_ADDR_REG=direct ROM address
LW S0,0034 (SP) //S0=800FB26C=0
BEQ S0,R0,800C2D0C //
ADDIU AT,R0,0001 //AT=1

800C2D0C:
LW T7,0040 (SP) //T7=800FB278=length of data (400)
LUI T3,A460
ADDIU T6,T7,FFFF //T6=length-1
BEQ R0,R0,800C2D3C
SW T6,000C (T3) //PI_WR_LEN_REG=length
-at which point your data is instantly uploaded and it throws an exception (80000180)

interestingly enough, F-Zero X stages are loaded in two parts:
part one (0x400) is the track data proper (points, track type, etc)
part two (0x3E0) is made of the boosts, recharge, ramps, etc.

It is virtually unheard of for a N64 game to read ROM directly. Usually it accesses ROM via the PI registers as above. For more on this though you might as well rumage through the stuff at:
http://sourceforge.net/projects/n64dev
since they very nicely outline the various paths used for cart access.
---------------------------------
It shouldn't be impossible to get the in-game track editor working. By disabling or redirecting save/load at least the menus could be accessed and the data uploaded via PC utilities.

---------------------------------
I'm working on building a gameshark course uploader at the moment - or really rather close to it. I need a handle to replace after the overlays are loaded, but it does swap in a playable level. At the moment it is using the original stage's boost/ice/etc locations. The idea is simply loading the stage or circuit in ahead of time to an area of ram that is empty, then either redirecting pointers or copying over the buffer at 8010B7B0.

This won't allow upload at the moment, but this demo will replace the stage number of choice with Jack1:

81074430 8FA6
81074432 0028
81074450 80C9
81074452 0001
81074484 24C5
81074486 0020
81074488 24C3
8107448A 0000
810744D8 80CE
810744DA 0001
81074530 80C9
81074532 0001

810741C0 0C00
810741C2 91FC
810247F0 3402
810247F2 0005
810247F4 1444
810247F6 0003
810247F8 3C02
810247FA 8011
810247FC 2442
810247FE CF50
81024800 AFA2
81024802 0000
81024804 0801
81024806 D10A
81024808 0000
8102480A 1025

The value of 810247F2 00xx is the stage number you want to replace.
Final version will likely just be a simple copy routine, as this pointer redirection is just silly.

---------------------------------------
This may interest you a little as well:
Everyone knows all N64 games and disks have a 4 letter "name", and the name is used as an ID for things like memcart saves. However, despite that DD expansion disks are all labelled Dnnr, internally they use the header Ennr. The complete format list should be:

TNNR
[t]ype of game, either:
[N]64 cartridge only
[D]D64 disk only
[C]ombo N64 cartridge
[E]xpansion disk for cartridge
[N]ame of game, being two distinct ASCII subset values
[R]egion code, the three most common being:
[J]apan - NTSC
[E]nglish-speaking North America
[P]AL - generic european release

The nifty thing is that all Nintendo-produced combo drive code within the game roms is annotated with a rather nice header. Search for the string matching your game header name with the C- changed to an E-. Some 3rd party combo games also annotate their code but leave off the region code, such as Dezeamon 3D. You'll find the string EFZE at 6D0F0 (probable menu items) and 6E6B4 (DD64 error codes).
The only known exception to the rule are the non-japanese Zelda: OOT carts which have been stripped of their MQ stuff. However, many others include the code, such as F-Zero X and Mario Party.

In fact, I'd wager to guess that by gamesharking the header check routine and fiddling with the region code, you could get the F-Zero expansion to work on a US game. -that would be a real bite to do though.
Parasyte +

Red Paragoomba


 





Since: 01-05-06

Last post: 6606 days
Last view: 6606 days
Posted on 03-31-06 02:24 PM Link | Quote
Addresses above 0x20000000 can be mapped however the programmer wishes using the MIPS R4300i's Memory Management Unit. Typical MMU address space is as Hyper mentioned, with the addition of the 0xA0000000 area mapped to uncached RAM.

N64 does not read or execute directly from ROM; it transfers ROM contents in blocks to RAM via DMA. Thus all code is compiled to run from mapped RAM. Some games use the MMU further to map smaller portions of system RAM to other addresses such as the 0x70000000 area. A good example of this is GoldenEye 007.

In other words, the MMU can make N64 hacking a true pain in the ass.
Add to favorites | Next newer thread | Next older thread
Acmlm's Board - I3 Archive - ROM Hacking - N64 Pointer Referencing |


ABII

Acmlmboard 1.92.999, 9/17/2006
©2000-2006 Acmlm, Emuz, Blades, Xkeeper

Page rendered in 0.018 seconds; used 405.13 kB (max 499.53 kB)