USF specification v1.0 9/19/04 - v1.0 - First official version --- Structure of a USF file A USF file may contain an N64 save state and/or ROM image. The structure is that of a PSF file with version code 0x21. The save state and ROM are stored in the reserved area of the PSF file. The compressed program section is not used, thus the program size and CRC should both be zero. The organization of the reserved area is: SR64 ROM image (stored as little endian 4 byte words) or 4 zero bytes (signifying no ROM) then SR64 Project 64 v1.4 save state (format below) or 4 zero bytes (signifying no save state) --- Definition of SR64 Format SR64 is a sparse storage scheme. Instead of storing an entire file SR64 makes it possible to store only those parts which are important. USF uses this format to store the ROM and save state. SR64 format is: 4 byte identifier: "SR64" each chunk: 4 byte little endian chunk length n (if 0 this ends the sparse segment) 4 byte little endian chunk offset n bytes data --- Loading a USF or USFlib/miniUSF 1. initialize the ROM and save state to zero. 2. if the USF contains a _lib tag (_libn not supported as of this version) recursively load the specified file starting from step 2 3. load the ROM and save state, replacing any data with the same addresses that may have already been loaded By convention a file that includes a _lib tag is named with a .miniusf extension and a file that is included via a _lib tag is name with a .usflib extension. --- Definition of Project 64 v1.4 save state (DWORD is 4-byte little endian, _int64 is 8-byte little endian) 0x000: DWORD: 0x23D8A6C8, identifier 0x004: DWORD: RDRAM size in bytes 0x008: ROM header, first 0x40 bytes of ROM stored as DWORDs 0x048: DWORD: VI timer (PJ64 internal) 0x04c: DWORD: PC 0x050: 32 _int64: CPU General Purposes Registers 0x150: 32 _int64: Floating Point Registers 0x250: 32 DWORD: COP0 Registers 0x2d0: 32 DWORD: Floating Point Control Registers 0x350: _int64: HI 0x358: _int64: LO 0x360: 10 DWORD: RDRAM Registers 0x388: 10 DWORD: SP Registers 0x3b0: 10 DWORD: DP Registers 0x3d8: 4 DWORD: MI Registers 0x3e8: 14 DWORD: VI Registers 0x420: 6 DWORD: AI Registers 0x438: 13 DWORD: PI Registers 0x46c: 8 DWORD: RI Registers 0x48c: 4 DWORD: SI Registers 0x49c: 32 TLB entries (20 bytes each), see PJ64 source for format 0x71c: PIF RAM, 0x40 bytes stored as DWORDs 0x75c: RDRAM, stored as DWORDs, whatever size specified by 0x004. 0x75c+RDRAM size: 0x1000 bytes RSP DMEM, stored as DWORDs 0x175c+RDRAM size: 0x1000 bytes RSP IMEM, stored as DWORDs Most of these values are relatively straightforward and would be a component of any N64 emulator. --- Bug tags This is specific to the 64th Note implementation of a USF player. The presence of the tags _64thbug1 or _64thbug2 (regardless of the associated value) will force the player to run in interpreter CPU mode. This is assumed to be a bug in 64th Note and any players which are able to play the affected sets without problems are welcome to ignore these tags.