1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-23 13:54:44 +00:00
oot/src/libultra_code/pfschecker.c
Lucas Shaw 7e195a3562
Matched most remaining libultra files (#221)
* osPfsIsPlug.c and osContSetCh.c OK

* update

* __osPfsGetStatus.c OK

* removed unused asm

* Updated all libultra controller files to use new structs instead of the temporary structs. Added os_pfs.h

* controller updates

* fixed header guard

* Made suggested changes

* guLookAt.c OK

* commit

* __osPfsSelectBank.c OK

* osPfsDeleteFile.c OK

* pfsreadwritefile.c OK

* osPfsFreeBlocks.c OK

* cleaned up ospfsfreeblocks

* started pfsinitpak.c

* pfsallocatefile.c OK

* contpfs.c decompiled with 1 non matching

* osPfsFindFile.c OK

* pfsinitpak.c decompiled. one non-matching

* Actually fixed merge conflict

* sins.c OK

* cosf.c sinf.c and sins.c OK

* moved osAfterPreNMI to its own file. Renamed code_801031F0 to contquery.c

* pfschecker.c OK

* final update and rename

* Removed makefile testing thing that i accidentally added

* Made suggested changes
2020-07-06 20:15:01 -04:00

204 lines
6.4 KiB
C

#include <ultra64.h>
#include <global.h>
#include <ultra64/pfs.h>
#define CHECK_IPAGE(p) \
(((p).ipage >= pfs->inodeStartPage) && ((p).inode_t.bank < pfs->banks) && ((p).inode_t.page >= 0x01) && \
((p).inode_t.page < 0x80))
s32 osPfsChecker(OSPfs* pfs) {
s32 j;
s32 ret;
__OSInodeUnit next;
__OSInode checkedInode;
__OSInode tempInode;
__OSDir tempDir;
__OSInodeUnit nextNodeInFile[16];
__OSInodeCache cache;
s32 fixed = 0;
u8 bank, prevBank = 254;
s32 cc, cl;
s32 offset;
ret = __osCheckId(pfs);
if (ret == PFS_ERR_NEW_PACK) {
ret = __osGetId(pfs);
}
if (ret) {
return ret;
}
if ((ret = func_80105788(pfs, &cache)) != 0) {
return ret;
}
for (j = 0; j < pfs->dir_size; j++) {
if ((ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + j, &tempDir)) != 0) {
return ret;
}
if ((tempDir.company_code != 0) || (tempDir.game_code != 0)) {
if ((tempDir.company_code == 0) || (tempDir.game_code == 0)) {
cc = -1;
} else {
next = tempDir.start_page;
cl = cc = 0;
bank = 255;
while (CHECK_IPAGE(next)) {
if (bank != next.inode_t.bank) {
bank = next.inode_t.bank;
if (prevBank != bank) {
ret = __osPfsRWInode(pfs, &tempInode, PFS_READ, bank);
prevBank = bank;
}
if ((ret != 0) && (ret != PFS_ERR_INCONSISTENT)) {
return ret;
}
}
if ((cc = func_80105A60(pfs, next, &cache) - cl) != 0) {
break;
}
cl = 1;
next = tempInode.inodePage[next.inode_t.page];
}
}
if ((cc != 0) || (next.ipage != PFS_EOF)) {
bzero(&tempDir, sizeof(__OSDir));
if (pfs->activebank != 0) {
if ((ret = __osPfsSelectBank(pfs, 0)) != 0) {
return ret;
}
}
if ((ret = __osContRamWrite(pfs->queue, pfs->channel, pfs->dir_table + j, &tempDir, 0)) != 0) {
return ret;
}
fixed++;
}
}
}
for (j = 0; j < pfs->dir_size; j++) {
if ((ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + j, &tempDir)) != 0) {
return ret;
}
if ((tempDir.company_code != 0) && (tempDir.game_code != 0) &&
(tempDir.start_page.ipage >= (u16)pfs->inodeStartPage)) { // cast required
nextNodeInFile[j].ipage = tempDir.start_page.ipage;
} else {
nextNodeInFile[j].ipage = 0;
}
}
for (bank = 0; bank < pfs->banks; bank++) {
ret = __osPfsRWInode(pfs, &tempInode, PFS_READ, bank);
if ((ret != 0) && (ret != PFS_ERR_INCONSISTENT)) {
return (ret);
}
offset = ((bank > PFS_ID_BANK_256K) ? 1 : pfs->inodeStartPage);
for (j = 0; j < offset; j++) {
checkedInode.inodePage[j].ipage = tempInode.inodePage[j].ipage;
}
for (; j < PFS_INODE_SIZE_PER_PAGE; j++) {
checkedInode.inodePage[j].ipage = PFS_PAGE_NOT_USED;
}
for (j = 0; j < pfs->dir_size; j++) {
while (nextNodeInFile[j].inode_t.bank == bank &&
nextNodeInFile[j].ipage >= (u16)pfs->inodeStartPage) { // cast required
u8 val;
val = nextNodeInFile[j].inode_t.page;
nextNodeInFile[j] = checkedInode.inodePage[val] = tempInode.inodePage[val];
}
}
if ((ret = __osPfsRWInode(pfs, &checkedInode, PFS_WRITE, bank)) != 0) {
return ret;
}
}
if (fixed != 0) {
pfs->status |= PFS_CORRUPTED;
} else {
pfs->status &= ~PFS_CORRUPTED;
}
return 0;
}
// Original name: corrupted_init (probably needs better name)
s32 func_80105788(OSPfs* pfs, __OSInodeCache* cache) {
s32 i;
s32 n;
s32 offset;
u8 bank;
__OSInodeUnit tpage;
__OSInode tempInode;
s32 ret;
for (i = 0; i < PFS_INODE_DIST_MAP; i++) {
cache->map[i] = 0;
}
cache->bank = 255;
for (bank = PFS_ID_BANK_256K; bank < pfs->banks; bank++) {
offset = ((bank > PFS_ID_BANK_256K) ? 1 : pfs->inodeStartPage);
ret = __osPfsRWInode(pfs, &tempInode, PFS_READ, bank);
if ((ret != 0) && (ret != PFS_ERR_INCONSISTENT)) {
return ret;
}
for (i = offset; i < PFS_INODE_SIZE_PER_PAGE; i++) {
tpage = tempInode.inodePage[i];
if ((tpage.ipage >= pfs->inodeStartPage) && (tpage.inode_t.bank != bank)) {
n = ((tpage.inode_t.page & 0x7F) / PFS_SECTOR_SIZE) +
PFS_SECTOR_PER_BANK * (tpage.inode_t.bank % PFS_BANK_LAPPED_BY);
cache->map[n] |= (1 << (bank % PFS_BANK_LAPPED_BY));
}
}
}
return 0;
}
// original name: corrupted (probably needs a better name)
s32 func_80105A60(OSPfs* pfs, __OSInodeUnit fpage, __OSInodeCache* cache) {
s32 j;
s32 n;
s32 hit = 0;
u8 bank;
s32 offset;
s32 ret = 0;
n = (fpage.inode_t.page / PFS_SECTOR_SIZE) + PFS_SECTOR_PER_BANK * (fpage.inode_t.bank % PFS_BANK_LAPPED_BY);
for (bank = PFS_ID_BANK_256K; bank < pfs->banks; bank++) {
offset = ((bank > PFS_ID_BANK_256K) ? 1 : pfs->inodeStartPage);
if ((bank == fpage.inode_t.bank) || (cache->map[n] & (1 << (bank % PFS_BANK_LAPPED_BY))) != 0) {
if (bank != cache->bank) {
ret = __osPfsRWInode(pfs, &(cache->inode), PFS_READ, bank);
if ((ret) && (ret != PFS_ERR_INCONSISTENT)) {
return ret;
}
cache->bank = bank;
}
for (j = offset; ((hit < 2) && (j < PFS_INODE_SIZE_PER_PAGE)); j++) {
if (cache->inode.inodePage[j].ipage == fpage.ipage) {
hit++;
}
}
if (hit >= 2) {
return 2;
}
}
}
return hit;
}