War of the Lions

From Final Fantasy Hacktics Wiki
Jump to: navigation, search

Archaemic's Notes

Assorted notes taken by User:Archaemic when investigating slowdown and the graphics engine. See also the git repo


Add 0x8803fac for offsets in memory

  • 0x00000054: .text (mapped to 0x08804000 in RAM, entry at 0x08814b00)
  • 0x002479a8: .rodata.sceNid (mapped to 0x08a4b954 in RAM)
  • 0x0015fe14: .data (mapped to 0x08a4c11c in RAM)
  • 0x0026f930: Dimensions of battle screen
  • 0x002793cc: Dimensions of world map when returning from chronicle screen
  • 0x0027a1d4: Dimensions of world map when returning from tutorial screen

Set dimensions to 00 00 00 00 e0 01 10 01 46 00 10 00 e0 01 10 01 to disable stretch and center screen


  • ASM block at 0x00009a30 - 0x00021604
  • ASM block at 0x00039448 - 0x0003d458
  • ASM block at 0x0004f8a4 - 0x00054948
  • ASM block at 0x0005dbc0 - 0x00089438
  • ASM block at 0x000dca4c (?) - 0x000eb28c
  • ASM block at 0x001223f8 - 0x00141e1c
  • ASM block at 0x00167b3c - 0x00182ca0
  • ASM block at 0x0018761c - 0x001a8058
  • ASM block at 0x001b2800 - 0x001b6c5c
  • ASM block at 0x001c001c - 0x001cc278
  • ASM block at 0x001df000 - 0x001e05d4
  • ASM block at 0x001f1004 - 0x001f6ffc
  • ASM block at 0x00209004 - 0x00213f98
  • ASM block at 0x00228800 - 0x0022ea40
  • ASM block at 0x00238818 - 0x00249858
  • ASM block at 0x00263170 - 0x0026cfb8
  • ASM block at 0x0027e204 - 0x0028d880
  • SLPS-00770 system.cnf: 0x00008000 (not mapped)
  • SLPS-00770 PS-X EXE: 0x00008800 (not mapped)
  • psx_main thread entry: 0x002633d8 (mapped to 0x089efcc0)

In memory

Syscall table (.sce.stubText): 0x08a4af14 - 0x08a4b4e8

Mem addr. Syscall ID NID Function name
0x08a4af14 0x207e 0xca04a2b9 sceKernelRegisterSubIntrHandler
0x08a4af1c 0x2076 0xd61e6961 sceKernelReleaseSubIntrHandler
0x08a4af24 0x2078 0xfb8e22ec sceKernelEnableSubIntr
0x08a4af2c 0x2131 0x42ec03ac sceIoWrite
0x08a4af34 0x2133 0x55f4717d sceIoChdir
0x08a4af3c 0x2137 0x6a638d83 sceIoRead
0x08a4af44 0x213a 0x779103a0 sceIoRename
0x08a4af4c 0x213b 0x810c4bc3 sceIoClose
0x08a4af54 0x213d 0xa0b5a7c2 sceIoReadAsync
0x08a4af5c 0x2142 0xb29ddf9c sceIoDopen
0x08a4af64 0x214a 0xeb092469 sceIoDclose
0x08a4af6c 0x212b 0x109f50bc sceIoOpen
0x08a4af74 0x212e 0x27eb27b8 sceIoLseek
0x08a4af7c 0x2130 0x35dbd746 sceIoWaitAsyncCB
0x08a4af84 j 0x8800080 0x092968f4 sceKernelCpuSuspendIntr
0x08a4af8c j 0x88000ac 0x5f10d406 sceKernelCpuResumeIntr
0x08a4af94 0x21ff 0x05572a5f sceKernelExitGame
0x08a4af9c 0x2202 0x4ac57943 sceKernelRegisterExitCallback
0x08a4afa4 0x2159 0x2e0911aa sceKernelUnloadModule
0x08a4afac 0x214e 0xd8b73127 sceKernelGetModuleIdByAddress
0x08a4afb4 0x2150 0xf0a26395 sceKernelGetModuleId
0x08a4afbc 0x215e 0x8f2df740 ModuleMgrForUser_8F2DF740
0x08a4afc4 0x214b 0xd1ff982a sceKernelStopModule
0x08a4afcc 0x2118 0x172d316e sceKernelStdin
0x08a4afd4 0x2120 0xa6bab2e9 sceKernelStdout
0x08a4afdc 0x2121 0xf78ba90a sceKernelStderr
0x08a4afe4 0x21bb 0x13a5abef sceKernelPrintf
0x08a4afec 0x21bd 0x237dbd4f sceKernelAllocPartitionMemory
0x08a4aff4 0x21a9 0x7591c7db sceKernelSetCompiledSdkVersion
0x08a4affc 0x21ad 0x9d9a5ba1 sceKernelGetBlockHeadAddr
0x08a4b004 0x21b1 0xb6d61d02 sceKernelFreePartitionMemory
0x08a4b00c 0x21b5 0xf77d77cb sceKernelSetCompilerVersion
0x08a4b014 0x2094 0xceadeb47 sceKernelDelayThread
0x08a4b01c 0x20bf 0x1fb15a32 sceKernelSetEventFlag
0x08a4b024 0x2099 0xd6da4ba1 sceKernelCreateSema
0x08a4b02c 0x20a2 0xe81caf8f sceKernelCreateCallback
0x08a4b034 0x20a6 0xed1410e0 sceKernelDeleteFpl
0x08a4b03c 0x20a8 0xef9e4c70 sceKernelDeleteEventFlag
0x08a4b044 0x20a9 0xf0b7da1c sceKernelDeleteMsgPipe
0x08a4b04c 0x20ab 0xf475845d sceKernelStartThread
0x08a4b054 0x20ac 0xf6414a71 sceKernelFreeFpl
0x08a4b05c 0x20c1 0x278c0df5 sceKernelWaitThreadEnd
0x08a4b064 0x20c3 0x28b6489c sceKernelDeleteSema
0x08a4b06c 0x20c8 0x30fd48f0 sceKernelPollEventFlag
0x08a4b074 0x20ca 0x328c546a sceKernelWaitEventFlagCB
0x08a4b07c 0x20ce 0x349b864d sceKernelCancelMsgPipe
0x08a4b084 0x20d2 0x383f7bcc sceKernelTerminateDeleteThread
0x08a4b08c 0x20d6 0x3f53e640 sceKernelSignalSema
0x08a4b094 0x20d7 0x402fcf22 sceKernelWaitEventFlag
0x08a4b09c 0x20d8 0x446d8de6 sceKernelCreateThread
0x08a4b0a4 0x20db 0x4e3a1105 sceKernelWaitSema
0x08a4b0ac 0x20e0 0x55c20a00 sceKernelCreateEventFlag
0x08a4b0b4 0x20e8 0x623ae665 sceKernelTryAllocateFpl
0x08a4b0bc 0x20ec 0x6652b8ca sceKernelSetAlarm
0x08a4b0c4 0x20f6 0x74829b76 sceKernelReceiveMsgPipe
0x08a4b0cc 0x20f8 0x7c0dc2a0 sceKernelCreateMsgPipe
0x08a4b0d4 0x20fb 0x7e65b999 sceKernelCancelAlarm
0x08a4b0dc 0x20fc 0x809ce29b sceKernelExitDeleteThread
0x08a4b0e4 0x20fd 0x812346e4 sceKernelClearEventFlag
0x08a4b0ec 0x2101 0x82bc5777 sceKernelGetSystemTimeWide
0x08a4b0f4 0x2108 0x884c9f90 sceKernelTrySendMsgPipe
0x08a4b0fc 0x210f 0x9944f31f sceKernelSuspendThread
0x08a4b104 0x2111 0x9fa03cd3 sceKernelDeleteThread
0x08a4b10c 0x207f 0xaa73c935 sceKernelExitThread
0x08a4b114 0x208e 0xc07bb470 sceKernelCreateFpl
0x08a4b11c 0x21cf 0x71ec4271 sceKernelLibcGettimeofday
0x08a4b124 0x21d8 0x91e4f6a7 sceKernelLibcClock
0x08a4b12c 0x21ef 0x27cc57f0 sceKernelLibcTime
0x08a4b134 0x21f4 0x3ee30821 sceKernelDcacheWritebackRange
0x08a4b13c 0x22e2 0x136caf51 sceAudioOutputBlocking
0x08a4b144 0x22e3 0x13f592bc sceAudioOutputPannedBlocking
0x08a4b14c 0x22e9 0x5ec81c55 sceAudioChReserve
0x08a4b154 0x22ed 0x6fc46853 sceAudioChRelease
0x08a4b15c 0x22f1 0x95fd0c2d sceAudioChangeChannelConfig
0x08a4b164 0x22d5 0xb011922f sceAudioGetChannelRestLength
0x08a4b16c 0x22d6 0xb7e1d8e7 sceAudioChangeChannelVolume
0x08a4b174 0x22d7 0xcb2e439e sceAudioSetChannelDataLen
0x08a4b17c 0x22d9 0xe2d56b2d sceAudioOutputPanned
0x08a4b184 0x2285 0x1f4011e6 sceCtrlSetSamplingMode
0x08a4b18c 0x2289 0x3a622550 sceCtrlPeekBufferPositive
0x08a4b194 0x228e 0x6a2774f3 sceCtrlSetSamplingCycle
0x08a4b19c 0x2273 0x0e20f177 sceDisplaySetMode
0x08a4b1a4 0x2275 0x210eab3a sceDisplayGetAccumulatedHcount
0x08a4b1ac 0x2276 0x289d82fe sceDisplaySetFrameBuf
0x08a4b1b4 0x227a 0x46f186c3 sceDisplayWaitVblankStartCB
0x08a4b1bc 0x2267 0x984c27e7 sceDisplayWaitVblankStart
0x08a4b1c4 0x2268 0x9c6eaad7 sceDisplayGetVcount
0x08a4b1cc 0x2207 0x617f3fe6 sceDmacMemcpy
0x08a4b1d4 0x220c 0x03444eb4 sceGeListSync
0x08a4b1dc 0x220d 0x05db22ce sceGeUnsetCallback
0x08a4b1e4 0x220f 0x1c0d95a6 sceGeListEnQueueHead
0x08a4b1ec 0x2212 0x4c06e472 sceGeContinue
0x08a4b1f4 0x2215 0xa4fc06a4 sceGeSetCallback
0x08a4b1fc 0x2216 0xab49e76a sceGeListEnQueue
0x08a4b204 0x2217 0xb287bd61 sceGeDrawSync
0x08a4b20c 0x2218 0xb448ec0d sceGeBreak
0x08a4b214 0x221b 0xe0d68148 sceGeListUpdateStallAddr
0x08a4b21c 0x221c 0xe47e40e4 sceGeEdramGetAddr
0x08a4b224 j 0x9c08e38 0x0e3c2e9d sceMpegAvcDecode
0x08a4b22c j 0x9c09868 0x13407f13 sceMpegRingbufferDestruct
0x08a4b234 j 0x9c08aa0 0x167afd9e sceMpegInitAu
0x08a4b23c j 0x9c08508 0x21ff80e4 sceMpegQueryStreamOffset
0x08a4b244 j 0x9c097d0 0x37295ed8 sceMpegRingbufferConstruct
0x08a4b24c j 0x9c08878 0x42560f23 sceMpegRegistStream
0x08a4b254 j 0x9c09050 0x4571cc64 sceMpegAvcDecodeFlush
0x08a4b25c j 0x9c088dc 0x591a4aa2 sceMpegUnRegistStream
0x08a4b264 j 0x9c08830 0x606a4649 sceMpegDelete
0x08a4b26c j 0x9c08570 0x611e9e11 sceMpegQueryStreamSize
0x08a4b274 j 0x9c085c8 0x682a619b sceMpegInit
0x08a4b27c j 0x9c08df0 0x707b7629 sceMpegFlushAllStream
0x08a4b284 j 0x9c08fd8 0x740fccd1 sceMpegAvcDecodeStop
0x08a4b28c j 0x9c093f0 0x800c44df sceMpegAtracDecode
0x08a4b294 j 0x9c08604 0x874624d6 sceMpegFinish
0x08a4b29c j 0x9c08934 0xa780cf7e sceMpegMallocAvcEsBuf
0x08a4b2a4 j 0x9c098b0 0xb240a59e sceMpegRingbufferPut
0x08a4b2ac j 0x9c09918 0xb5f6dc87 sceMpegRingbufferAvailableSize
0x08a4b2b4 j 0x9c08640 0xc132e22f sceMpegQueryMemSize
0x08a4b2bc j 0x9c08978 0xceb870b1 sceMpegFreeAvcEsBuf
0x08a4b2c4 j 0x9c09740 0xd7a29f46 sceMpegRingbufferQueryMemSize
0x08a4b2cc j 0x9c086d8 0xd8c5f121 sceMpegCreate
0x08a4b2d4 j 0x9c08d20 0xe1ce83a7 sceMpegGetAtracAu
0x08a4b2dc j 0x9c089d0 0xf8dcb679 sceMpegQueryAtracEsSize
0x08a4b2e4 j 0x9c08c30 0xfe246728 sceMpegGetAvcAu
0x08a4b2ec 0x15 0x157e6225 sceNetAdhocPtpClose
0x08a4b2f4 0x15 0x4da4c788 sceNetAdhocPtpSend
0x08a4b2fc 0x15 0x877f6d66 sceNetAdhocPtpOpen
0x08a4b304 0x15 0x8bea2b3e sceNetAdhocPtpRecv
0x08a4b30c 0x15 0x9ac2eeac sceNetAdhocPtpFlush
0x08a4b314 0x15 0x9df81198 sceNetAdhocPtpAccept
0x08a4b31c 0x15 0xa62c6f57 sceNetAdhocTerm
0x08a4b324 0x15 0xe08bdac1 sceNetAdhocPtpListen
0x08a4b32c 0x15 0xe1d621d7 sceNetAdhocInit
0x08a4b334 0x15 0xfc6fc07b sceNetAdhocPtpConnect
0x08a4b33c 0x15 0x08fff7a0 sceNetAdhocctlScan
0x08a4b344 0x15 0x20b317a0 sceNetAdhocctlAddHandler
0x08a4b34c 0x15 0x34401d65 sceNetAdhocctlDisconnect
0x08a4b354 0x15 0x5e7f79c9 sceNetAdhocctlJoin
0x08a4b35c 0x15 0x6402490b sceNetAdhocctlDelHandler
0x08a4b364 0x15 0x81aee1be sceNetAdhocctlGetScanInfo
0x08a4b36c 0x15 0x9d689e13 sceNetAdhocctlTerm
0x08a4b374 0x15 0xe162cb14 sceNetAdhocctlGetPeerList
0x08a4b37c 0x15 0xe26f226e sceNetAdhocctlInit
0x08a4b384 0x15 0xec0635c1 sceNetAdhocctlCreate
0x08a4b38c 0x15 0x0bf0a3ae sceNetGetLocalEtherAddr
0x08a4b394 0x15 0x281928a9 sceNetTerm
0x08a4b39c 0x15 0x39af39a6 sceNetInit
0x08a4b3a4 0x15 0x89360950 sceNetEtherNtostr
0x08a4b3ac 0x244e 0x019b25eb __sceSasSetADSR
0x08a4b3b4 0x2450 0x267a6dd2 __sceSasRevParam
0x08a4b3bc 0x2451 0x2c8e6ab3 __sceSasGetPauseFlag
0x08a4b3c4 0x2452 0x33d4ab37 __sceSasRevType
0x08a4b3cc 0x2453 0x42778a9f __sceSasInit
0x08a4b3d4 0x2454 0x440ca7d8 __sceSasSetVolume
0x08a4b3dc 0x2456 0x50a14dfc __sceSasCoreWithMix
0x08a4b3e4 0x2457 0x5f9529f6 __sceSasSetSL
0x08a4b3ec 0x2458 0x68a46b95 __sceSasGetEndFlag
0x08a4b3f4 0x245a 0x74ae582a __sceSasGetEnvelopeHeight
0x08a4b3fc 0x245b 0x76f01aca __sceSasSetKeyOn
0x08a4b404 0x245c 0x787d04d5 __sceSasSetPause
0x08a4b40c 0x245d 0x99944089 __sceSasSetVoice
0x08a4b414 0x245e 0x9ec3676a __sceSasSetADSRmode
0x08a4b41c 0x245f 0xa0cf2fa4 __sceSasSetKeyOff
0x08a4b424 0x2461 0xa3589d81 __sceSasCore
0x08a4b42c 0x2462 0xad84d37f __sceSasSetPitch
0x08a4b434 0x2463 0xb7660a23 __sceSasSetNoise
0x08a4b43c 0x2442 0xbd11b7c2 __sceSasGetGrain
0x08a4b444 0x2443 0xcbcd4f79 __sceSasSetSimpleADSR
0x08a4b44c 0x2444 0xd1e0a01e __sceSasSetGrain
0x08a4b454 0x2445 0xd5a229c9 __sceSasRevEVOL
0x08a4b45c 0x2447 0xe175ef66 __sceSasGetOutputmode
0x08a4b464 0x2449 0xe855bf76 __sceSasSetOutputmode
0x08a4b46c 0x244b 0xf983b186 __sceSasRevVON
0x08a4b474 0x21c5 0x090ccb3f sceKernelPowerTick
0x08a4b47c 0x2260 0x4a9e5e29 sceUmdWaitDriveStatCB
0x08a4b484 0x2262 0x6af9b50a sceUmdCancelWaitDriveStat
0x08a4b48c 0x2263 0x6b4a146c sceUmdGetDriveStat
0x08a4b494 0x2253 0x8ef08fce sceUmdWaitDriveStat
0x08a4b49c 0x2257 0xc6183d47 sceUmdActivate
0x08a4b4a4 0x2259 0xe83742ba sceUmdDeactivate
0x08a4b4ac 0x2378 0x2a2b3de0 sceUtilityLoadModule
0x08a4b4b4 0x238d 0x50c4cd57 sceUtilitySavedataInitStart
0x08a4b4bc 0x239b 0x8874dbe0 sceUtilitySavedataGetStatus
0x08a4b4c4 0x23a2 0x9790b33c sceUtilitySavedataShutdownStart
0x08a4b4cc 0x23b9 0xd4b95ffb sceUtilitySavedataUpdate
0x08a4b4d4 0x23c0 0xe49bfe92 sceUtilityUnloadModule
0x08a4b4dc 0x2320 0x0c622081 sceWlanGetEtherAddr
0x08a4b4e4 0x241e 0x36aa6e91 sceImposeSetLanguageMode

Near $gp:

/* Final screen texture x */
unsigned short textureX; // 0x8bae180

/* Final screen texture y */
unsigned short textureY; // 0x8bae182

/* Final screen texture width */
unsigned short textureWidth; // 0x8bae184

/* Final screen texture height */
unsigned short textureHeight; // 0x8bae186

/* Final screen polygon x */
unsigned short polyX; // 0x8bae188

/* Final screen polygon y */
unsigned short polyY; // 0x8bae18a

/* Final screen polygon width */
unsigned short polyWidth; // 0x8bae18c

/* Final screen polygon height */
unsigned short polyHeight; // 0x8bae18e

Map of .bss:
// 0x8baf764 : numeric or logical
// 0x8baf76c : size is 0x72 + 0xFC * 5
struct WotlDrawContext {
	// 0x8baf76c : numeric or logical (can be -1)

	// 0x8baf770 : numeric or logical
	/* -1 to 4, index of active WotlGeContext */
	int activeIndex; // 0x8baf778

	// 0x8baf77c : tested against 1, but also used as a pointer; same type as 0x8baf7b8
	/* Queue ID from sceGeListEnQueue, set in func_88047bc */
	int qid0; // 0x8baf784

	/* Queue ID from sceGeListEnQueue, set in func_8804d30 */
	int qid1; // 0x8baf788

	/* Callback ID for sceGeListEnQueue */
	int cbid; // 0x8baf78c

	/* Framebuffer pixel store mode */
	int fbPsm; // 0x8baf790

	/* Framebuffer width */
	int fbWidth; // 0x8baf794

	/* Pointer to framebuffer */
	void* framebuffer; // 0x8baf798;
	/* Viewport width */
	int vpWidth; // 0x8baf7a8

	/* Viewport height */
	int vpHeight; // 0x8baf7ac

	// 0x8baf7b0 : int

	WotlGeContext* activeGeContext; // 0x8baf7b4

	// 0x8baf7b8 : size is 0xFC * 5
	struct WotlGeContext {
		// 0x8baf7b8 : numeric (?)

		/* Pointer to the GE list */
		void* list; // 0x8baf7bc

		/* Pointer to the GE stall list */
		void* stall; // 0x8baf7c0

		/* Size of the GE list */
		int size; 0x8baf7c4

		/* Index into the following array */
		int index; // 0x8baf7c8
		// 0x8baf7cc : array of pointer
		/* Framebuffer pixel store mode */
		int fbPsm; // 0x8baf850
		/* Viewport width */
		int vpWidth; // 0x8baf858

		/* Viewport height */
		int vpHeight; // 0x8baf85c
		// 0x8baf8b0 : -1 to 4?
	} geContext[5];
  • psx_main thread entry: 0x089efcc0
  • global pointer: 0x08bb3ea0
  • GE instruction lists:
  • 0x90f2c80 - 0x90f3c80: copy screen buffer
  • 0x90f3c80 - 0x9173c80: redraw scene


To disable stretch:

pokeh 0x08bae18a 16
pokeh 0x08bae188 70
pokeh 0x08bae186 0x110
pokeh 0x08bae184 0x1e0


There are two GE lists. One is at 0x90f2c80. This list stays mostly static and is used for copying the screen buffer onto the screen. The second is at 0x90f3c80, and contains all of the instructions used for redrawing the screen. Note that pointers into the information referenced within the instructions (like the vertex buffers) point to addresses within the lists. These are skipped using JUMPs.

The GE lists are rewritten in their entireties every frame. Note that nuances may change between frames, like vertex locations. I am still investigating where this gets rewritten.

There are 3 signals used for GE calls:

  • 1192: Redrawing the back buffer (scene)
  • 1919: Copying the back buffer to the main screen
  • 2005: Unknown

There are 5 GE contexts (WotlGeContext). Each of them corresponds to a different operation:

  • 0: Drawing the back buffer onto the current frame
  • 1: ???
  • 2: Drawing the current scene
  • 3: ???
  • 4: ???


The PSP (MIPS32R2 Allegrex) calling convention seems to dictate that args that don't fit into $a* go into $t*. Beware!

Evidence in the function at 0x88350c0 suggests that the game is still using the PS1's graphics protocol, emulated onto the PSP. Yikes.

I found some dead code that seems to access 0x1f80xxxx, which are related to the PS1's scratchpad, but none of these accesses are ever actually made. No references to PS1's GPU registers appear to be made.

Code that writes to the stall list seems to start at 0x880513c and continue until perhaps 0x8806cd8. These are probably the guts of the graphics routines. Look for lui *, 0x8bb followed by lw *, -2124(*).

The slowdown is directly affected by the return value of the function at 0x882b800. The number of frames to slow down appears to be related to the value stored at 0x9275224. The slowdown is set in the function at 0x8a0ef00, and is related to the value at 0x9275218, which itself is set in 0x887b400 and 0x8875a00.


GE: Presumably stands for "graphics engine". It's the graphics API on the PSP, and works by sending a list of assembled instructions in the GE's native format to the GPU all at once. There is no high-level abstraction of the instructions used in War of the Lions: they assemble the instructions by hand.

GE list: A list of instructions that are to be fed to the PSP's GPU. The instructions themselves are 4 bytes per instruction and documentation of the instructions can be found in the PSPSDK at src/gu/doc/commands.txt.

NID: An identifier that maps to a kernel system call on the PSP. Instead of using a straightforward constant syscall table like a sane operating system like Linux, they use NIDs to refer to syscalls, and then syscall table is loaded into the .sceStub.text section.

stall address: The address at which a GE list will stop executing until another list is enqueued or the stall address is updated to be further into the list.


These are miscellaneous notes for what I'm working on at the moment

There is a large struct (at least 108 bytes) that starts at 0x974ba80

Unstretch queue (calls to 0x8a08b80):

  • [x] 0x88d84a4 (new game prologue screen)
  • [-] 0x88d8308 (video cutscene, not stretched?)
  • [x] 0x887503c (battle map)
  • [?] 0x89aa3b4 (save screen)
  • [ ] 0x89aa938 (???)
  • [ ] 0x8a0b14c (pre-character info screen?, pre-world map?)
  • [x] 0x897f800 (character info screen)
  • [ ] 0x897ff80 (post-character info screen?)
  • [x] 0x8a0ab38 (data screen)
  • [ ] 0x88f806c (pre-world map?)
  • [x] 0x88f7ed8 (world map)
  • [ ] 0x8882ccc (after death before title screen?)
  • [ ] 0x88826e0 (title screen?)
  • [x] 0x88e3368 (return from chronicle screen)
  • [x] 0x890d61c (return from tutorial screen)
  • [ ] 0x88f7f60 (tavern)
  • [x] 0x8971c04 (outfitter)

RE queue:

  • 0x887b400, 0x8875a00 (sets slowdown, gigantic!)
-- Line of no real value --
  • 0x882bb40 (sets a function that's called by 0x882b800)
  • 0x882c1e0 (calls 0x882d600)
  • 0x882d600 (called every frame, write a decompiler!)
  • 0x8835798, 0x882eab0, 0x882e880, 0x883165c
  • 0x8805518, 0x8805690, 0x8849540 (inserts JUMPs)
  • 0x8804f78, 0x8807db0 (might have something to do with initializing the GE contexts)
  • 0x882c280 (might be what executes PS1 instructions)
  • 0x8835f00 (GE signal handler)
  • 0x8835f80 (install GE signal handler)
  • 0x8a08d80, 0x8a08cc0 (used for storing dimensions)
  • 0x8a0aac0, 0x88d8180
  • 0x88358c0, 0x88054c8
  • 0x89e8fc0, 0x89d7180
  • 0x8874f80 (battle map loading?)
  • 0x8874740, 0x88d6700, 0x88dbc40, 0x88e3140, 0x88f1040, 0x88f1980, 0x88f7e40, 0x88fa380, 0x890d440, 0x891f280, 0x893d340, 0x893e740, 0x893f640, 0x8946540

Use constants, especially for GE instructions!

Slowdown information/offsets

The slowdown is caused by three values in the executable that dictate how long the game should wait between frames. The reason this is incorrect in the game is unknown, but they can be fixed by patching these offsets into /PSP_GAME/SYSDIR/BOOT.BIN:

  • 0x20afd4 should be changed to 02
  • 0x20afe4 should be changed to 03
  • 0x20aff0 should be changed to 02

You must then replace /PSP_GAME/SYSDIR/EBOOT.BIN with the modified BOOT.BIN, or else the ISO loader will try to run the unmodified EBOOT.BIN.