War of the Lions
Contents
Archaemic's Notes
Assorted notes taken by User:Archaemic when investigating slowdown and the graphics engine. See also the git repo
SYSDIR/BOOT.BIN
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
See also: War of the Lions/BOOT.BIN
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
USRDIR/fftpack.bin
- 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
ACTIONS
To disable stretch:
pokeh 0x08bae18a 16 pokeh 0x08bae188 70 pokeh 0x08bae186 0x110 pokeh 0x08bae184 0x1e0
ARCHITECTURE
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: ???
MISCELLANEOUS
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.
GLOSSARY
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.
SCRATCH
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.