Road Rash N64 PAL Prototype

Check it out- it's a PAL prototype for Road Rash 64! The binary of this rom dump shows quite a bit of difference from the final PAL release, and we are in extra luck this time, because with some next level help, we have been able to learn EXACTLY what those in-game differences are!

The rom was sent to the incredibly skilled Project64 contributor and all around N64 developer/hacker shygoo, and he did a byte by byte breakdown of nearly every difference found in the prototype.

HUGE shoutout and thank you to shygoo for analyzing the rom!

Differences Discovered



Minor performance fix for splitscreen mode

In the retail ROM, the following functions are called from function 8006B53C only when the game is NOT in split-screen mode. In the prototype ROM, these functions are called unconditionally:

8005B420 -- processes character animations
8005BB7C -- processes weapon animations
8005BE88 -- processes tire marks
8005C42C -- ? not sure what this does

If the above function calls are replaced with NOPs while playing the prototype in split-screen mode (so that it behaves similarly to the retail ROM), CPU usage is slightly reduced and there is otherwise no noticeable impact on gameplay. So I suspect these functions are already called elsewhere while in split-screen mode, and this change was probably a performance fix which removes some redundant processing.

Pointer updates

There are two tables of pointers at 000A2D14 and 000A6130, in which all instances of 8006BC6C in the prototype ROM were changed to 8006BC78 in the retail ROM (to account for the changes to function 8006B53C mentioned earlier).

Both 8006BC6C and 8006BC78 point to an empty function so this change shouldn't affect gameplay.


Minor performance tweaks to 4MB mode

The following changes affect the game while there is no expansion pak present (i.e. when only 4MB of RAM is available).

Prototype Retail Description
1. 8001D080: li v0, 20 li v0, 16 maximum number of tire marks
2. 8001D124: li a1, (14000*8)+320 li a1, (14200*8)+320 size of display list buffer A (in bytes, + reserved section)
3. 8001D140: li v1, 14000 li v1, 14200 size of display list buffer B
4. 8001D174: li a1, (410*64) li a1, (420*64) size of matrix table A (in bytes)
5. 8001D17C: li v1, 410 li v1, 420 size of matrix table B

1. The maximum number of tire marks to render was reduced from 20 to 16.

2-3. The display list buffer size was increased slightly from 14000 to 14200 commands. This number divided by 2 is roughly the maximum number of display list commands the game is allowed to process per frame, so this change effectively increases the number of usable commands by 100.

(If the maximum number of commands is exceeded, the graphics thread is frozen until the number of commands returns to an acceptable level).

4-5. The maximum number of transformation matrices was increased from 410 to 420. This is essentially number of 3D objects the game is allowed to deal with at a time.


Differing padding bytes

Sometimes old compilers and assemblers wouldn't properly clear out memory, so garbage data would be left behind in the padding bytes between functions and data structures. These sections probably differ between the two ROMs just by virtue of being compiled in different environments. The changes shouldn't affect gameplay.

Padding bytes containing code fragments in the prototype ROM:

	0000103C:0000103E (0x02 bytes): "BS"
	0000103F:00001040 (0x01 bytes): "S"
	00001068:0000106B (0x03 bytes): "D, "
	0000106C:00001070 (0x04 bytes): "   B"
	00001168:00001170 (0x08 bytes): "E;    ty"
	0000117F:00001180 (0x01 bytes): "r"
	000017E8:000017F0 (0x08 bytes): "    exte"
	0000182C:00001830 (0x04 bytes): "    "
	00001864:00001870 (0x0C bytes): "            "
	00001934:0000193E (0x0A bytes): "ATA;      "
	0000193F:00001940 (0x01 bytes): " "
	0000196C:00001970 (0x04 bytes): "s32 "
	000019A8:000019B0 (0x08 bytes): ";  } SPH"
	000019D4:000019E0 (0x0C bytes): "t s_physics_"
	00001A1C:00001A20 (0x04 bytes): "32  "
	00001A6C:00001A70 (0x04 bytes): "URFA"
	00001A7C:00001A80 (0x04 bytes): " sur"
	00001AB4:00001AC0 (0x0C bytes): "TA cscd;  } "
	00001AC4:00001AD0 (0x0C bytes): "ICS_INIT_DAT"
	00001B08:00001B10 (0x08 bytes): "ICS_INIT"
	00001B1C:00001B1F (0x03 bytes): "   "
	00001B2C:00001B30 (0x04 bytes): "ate;"
	00001D99:00001DA0 (0x07 bytes): "que;   "
	00004A4C:00004A50 (0x04 bytes): "ER *"
	00004E88:00004E90 (0x08 bytes): ";   Vect"
	00004EE8:00004EF0 (0x08 bytes): "r;     f"
	000050A4:000050B0 (0x0C bytes): "h" 1        "
	00005628:00005630 (0x08 bytes): "        "
	0000579C:000057A0 (0x04 bytes): "def "
	000057A4:000057B0 (0x0C bytes): "ct s_particl"
	000057BC:000057C0 (0x04 bytes): "CLE_"
	000057CC:000057D0 (0x04 bytes): "  Ve"
	00005A0C:00005A10 (0x04 bytes): "DATA"
	00005A8C:00005A90 (0x04 bytes): "_sys"
	00005B14:00005B20 (0x0C bytes): "eate_metal_s"
	00005BE8:00005BF0 (0x08 bytes): "_sparks("
	00005CE8:00005CF0 (0x08 bytes): "  void c"
	0000657D:00006580 (0x03 bytes): "dex"
	0000683C:00006840 (0x04 bytes): "void"
	00006854:00006860 (0x0C bytes): "um_Race_Bike"
	00006914:00006920 (0x0C bytes): "ntities[14  "
	00006954:00006960 (0x0C bytes): "];  extern N"
	0000697C:00006980 (0x04 bytes): "s[6 "
	00006994:000069A0 (0x0C bytes): "ENTITY *Weap"
	00006C14:00006C20 (0x0C bytes): "ure  {   N64"
	00006D99:00006DA0 (0x07 bytes): "n bool "
	00007424:00007430 (0x0C bytes): "         ext"
	00007674:00007680 (0x0C bytes): "enum e_dir_s"
	00007CEC:00007CF0 (0x04 bytes): "disp"
	00007D1C:00007D20 (0x04 bytes): "_cop"
	00007F0C:00007F10 (0x04 bytes): "   f"
	00007FC8:00007FD0 (0x08 bytes): "hed;   b"
	00008044:00008050 (0x0C bytes): ";    typedef"
	00008254:00008260 (0x0C bytes): " ];  extern "
	000084E8:000084F0 (0x08 bytes): "w[4];   "
	0000851C:00008520 (0x04 bytes): "_Lev"
	00008584:00008590 (0x0C bytes): "player * pla"
	00008634:00008640 (0x0C bytes): "ayer * playe"
	00008954:00008960 (0x0C bytes): "NT * jpp);  "
	00008964:00008968 (0x04 bytes): "rn s"
	00008969:00008970 (0x07 bytes): "2 choos"
	0000899C:000089A0 (0x04 bytes): "_pat"
	000089AC:000089B0 (0x04 bytes): "T * "
	000089BC:000089C0 (0x04 bytes): " fin"
	000091D8:000091E0 (0x08 bytes): " f32  Or"
	0000A308:0000A310 (0x08 bytes): "rt_colli"
	0000AB94:0000ABA0 (0x0C bytes): " RTI_BG_2_A,"
	0000AC98:0000ACA0 (0x08 bytes): "RTI_BG_4"
	0000DCF8:0000DD00 (0x08 bytes): "P_9,   C"
	0000E368:0000E370 (0x08 bytes): "2, Vecto"
	0000F27C:0000F280 (0x04 bytes): ";  v"
	00011274:00011280 (0x0C bytes): "list (FX *li"
	00012D48:00012D50 (0x08 bytes): "0);     "
	000150BC:000150C0 (0x04 bytes): "    "

	00018C58:00018C60 (0x08 bytes): "; .endef"
	0001A76C:0001A770 (0x04 bytes): "e_da"
	0001AE0C:0001AE10 (0x04 bytes): "8; ."
	0001B244:0001B250 (0x0C bytes): "; .type 0x2;"
	0001BEB8:0001BEC0 (0x08 bytes): "ndef   ."
	0001C238:0001C240 (0x08 bytes): "fake; .s"
	0001D794:0001D7A0 (0x0C bytes): "8; .type 0xe"

	0001DDC8:0001DDD0 (0x08 bytes): "l 18; .t"
	00020644:00020650 (0x0C bytes): "ype 0xe; .si"
	00021FC4:00021FD0 (0x0C bytes): ".endef   .de"
	000224E4:000224F0 (0x0C bytes): " .def .88fak"
	000312A8:000312B0 (0x08 bytes): " COL_LIN"
	000353BC:000353C0 (0x04 bytes): " .si"
	0003600C:00036010 (0x04 bytes): "ef C"
	00038B64:00038B70 (0x0C bytes): " .endef   .d"
	00042684:00042690 (0x0C bytes): "e 0xb; .ende"
	000470DC:000470E0 (0x04 bytes): "ndef"
	000477D4:000477E0 (0x0C bytes): "0x8; .endef "
	000494A4:000494B0 (0x0C bytes): "13; .tag s_c"
	00049AE8:00049AF0 (0x08 bytes): ".type 0x"
	0004F95C:0004F960 (0x04 bytes): "l 13"
	0004FBFC:0004FC00 (0x04 bytes): "size"
	00050774:00050780 (0x0C bytes): "g e_gang_typ"
	0005227C:00052280 (0x04 bytes): "1 "p"
	0005380C:00053810 (0x04 bytes): "40; "
	00055114:00055120 (0x0C bytes): " .type 0x35;"
	00056788:00056790 (0x08 bytes): "        "
	00067178:00067180 (0x08 bytes): "urrXres♫"
	0006B734:0006B740 (0x0C bytes): "ilesizeT    "

	0006C873:0006C880 (0x0D bytes): " 84fake♦.eosT"

	000738DC:000738E0 (0x04 bytes): ".eos"

	00074BAC:00074BB0 (0x04 bytes): "ect_"
	000751D8:000751E0 (0x08 bytes): "taObject"
	0007533C:00075340 (0x04 bytes): "faci"
	000754F4:00075500 (0x0C bytes): "  ►s_n64_lig"

	000788B9:000788C0 (0x07 bytes): "rial♦.e"
	0007A538:0007A540 (0x08 bytes): "iding_fr"
	0007AA88:0007AA90 (0x08 bytes): "   WT_P"
	0007AE48:0007AE50 (0x08 bytes): "lie_bar_"

	0007EA04:0007EA10 (0x0C bytes): "placeR  H   "
	0007EDC8:0007EDD0 (0x08 bytes): b_buste"
				

More suspected padding byte diffs:

These have not been looked at as closely, but are suspected to be useless padding bytes because most of them look like random numbers that end on 0x10-aligned boundaries.

	00015C74:00015C80 (0x0C bytes)

	00059728:00059730 (0x08 bytes)
	00059B98:00059BA0 (0x08 bytes)
	0005AAEC:0005AAF0 (0x04 bytes)
	0005B498:0005B4A0 (0x08 bytes)
	0005BD34:0005BD40 (0x0C bytes)
	0005C014:0005C020 (0x0C bytes)
	0005D14C:0005D150 (0x04 bytes)
	00060554:00060560 (0x0C bytes)
	000655AC:000655B0 (0x04 bytes)

	00074A64:00074A70 (0x0C bytes)

	00075508:00075510 (0x08 bytes)
	00075534:00075540 (0x0C bytes)

	0007B518:0007B520 (0x08 bytes)

	0008AF18:0008AF20 (0x08 bytes)
	0008B8E4:0008B8F0 (0x0C bytes)
	0009B734:0009B740 (0x0C bytes)
	0009BEEC:0009BEF0 (0x04 bytes)
	0009D96C:0009D970 (0x04 bytes)
	0009D994:0009D9A0 (0x0C bytes)
	0009DB28:0009DB30 (0x08 bytes)
	0009DBD4:0009DBE0 (0x0C bytes)
	0009DCC8:0009DCD0 (0x08 bytes)
	0009DCD4:0009DCE0 (0x0C bytes)
	0009DEC6:0009DED0 (0x0A bytes)
	0009DFC4:0009DFD0 (0x0C bytes)
	0009DFD6:0009DFE0 (0x0A bytes)
	0009E2F8:0009E300 (0x08 bytes)
	0009EC54:0009EC60 (0x0C bytes)
	0009EC84:0009EC90 (0x0C bytes)
	0009EC96:0009ECA0 (0x0A bytes)
	0009ECAC:0009ECB0 (0x04 bytes)
	0009ECB8:0009ECC0 (0x08 bytes)
	0009ED76:0009ED80 (0x0A bytes)
	0009ED8D:0009ED90 (0x03 bytes)
	0009EDC8:0009EDD0 (0x08 bytes)
	0009EDD8:0009EDE0 (0x08 bytes)
	0009EDE8:0009EDF0 (0x08 bytes)
	0009EE08:0009EE10 (0x08 bytes)
	0009EE24:0009EE30 (0x0C bytes)

	000A0398:000A0399 (0x01 bytes)
	000A039A:000A03A0 (0x06 bytes)
	000A053E:000A0540 (0x02 bytes)
	000A0638:000A0640 (0x08 bytes)
	000A2554:000A2560 (0x0C bytes)
	000A258C:000A2590 (0x04 bytes)
	000A2948:000A2950 (0x08 bytes)

	000A3296:000A32A0 (0x0A bytes)
	000A32CC:000A32D0 (0x04 bytes)
	000A32E8:000A32F0 (0x08 bytes)
	000A32F8:000A3300 (0x08 bytes)
	000A3318:000A3320 (0x08 bytes)
	000A3614:000A3620 (0x0C bytes)
	000A3624:000A362F (0x0B bytes)
	000A459C:000A45A0 (0x04 bytes)
	000A5408:000A5410 (0x08 bytes)
	000A5968:000A5970 (0x08 bytes)
	000A5978:000A5980 (0x08 bytes)
	000A5AB8:000A5AC0 (0x08 bytes)
	000A5FEA:000A5FF0 (0x06 bytes)
	000A6054:000A6060 (0x0C bytes)
	000A606A:000A6070 (0x06 bytes)

	000A6414:000A6420 (0x0C bytes)
	000A6492:000A6495 (0x03 bytes)
	000A6496:000A64A0 (0x0A bytes)
	000A65CC:000A65D0 (0x04 bytes)
	000A660C:000A6610 (0x04 bytes)
	000A7688:000A7690 (0x08 bytes)
	000A772C:000A7730 (0x04 bytes)
	000A77BB:000A77C0 (0x05 bytes)
	000A79D3:000A79E0 (0x0D bytes)
	000A85C4:000A85D0 (0x0C bytes)
	000A85D2:000A85E0 (0x0E bytes)
	000A85E8:000A85F0 (0x08 bytes)
	000A85FC:000A8600 (0x04 bytes)
	000A8678:000A8680 (0x08 bytes)
	000A86A8:000A86B0 (0x08 bytes)
	000A87CC:000A87D0 (0x04 bytes)
	000A87D4:000A87E0 (0x0C bytes)
	000A87E8:000A87F0 (0x08 bytes)
	000A886E:000A8870 (0x02 bytes)
	000A888C:000A8890 (0x04 bytes)
	
	000A8934:000A893D (0x09 bytes)

	000A893E:000A8940 (0x02 bytes)

	000AA9D1:000AAA00 (0x2F bytes)		
				

Have any N64 prototypes that you want to sell, trade, or share, or know somebody who does?
Need help dumping your prototypes? Let us know!

This prototype dumped and brought to you by Baker64