diff --git a/include/functions.h b/include/functions.h index 18d006bbbe..61f1c6da94 100644 --- a/include/functions.h +++ b/include/functions.h @@ -305,8 +305,8 @@ void osViBlack(u8 active); s32 __osSiRawReadIo(u32 devAddr, u32* data); OSId osGetThreadId(OSThread* t); void osSpTaskYield(void); -s32 __osPfsGetNextPage(OSPfs* param_1, __OSInode* param_2, u8 param_3, u8 param_4); -s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, s32 offset, s32 size_in_bytes, u8* data_buffer); +s32 __osPfsGetNextPage(OSPfs* pfs, u8* bank, __OSInode* inode, __OSInodeUnit* page); +s32 osPfsReadWriteFile(OSPfs* pfs, s32 fileNo, u8 flag, s32 offset, s32 size, u8* data); s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel); // void __osPfsRequestOneChannel(void); // void __osPfsGetOneChannelData(void); diff --git a/include/io/controller.h b/include/io/controller.h index cbd4963ae8..9e36f9b628 100644 --- a/include/io/controller.h +++ b/include/io/controller.h @@ -99,8 +99,8 @@ typedef struct { /* 0x00 */ u32 ramarray[15]; - /* 0x3C */ u32 pifstatus; -} OSPifRam; + /* 0x3C */ u32 status; +} OSPifRam; // size = 0x40 typedef struct { diff --git a/spec b/spec index 152055696e..5e419dcb89 100644 --- a/spec +++ b/spec @@ -120,8 +120,6 @@ beginseg include "build/src/libultra/io/devmgr.o" include "build/src/libultra/io/pirawdma.o" include "build/src/libultra/io/contpfs.o" - include "build/data/boot/contpfs.data.o" - include "build/data/boot/contpfs.bss.o" include "build/asm/boot/getcount.text.o" pad_text include "build/asm/boot/guMtxL2F.text.o" diff --git a/src/boot_O2_g3/yaz0.c b/src/boot_O2_g3/yaz0.c index 094c0bb381..5fb32b8eaa 100644 --- a/src/boot_O2_g3/yaz0.c +++ b/src/boot_O2_g3/yaz0.c @@ -1,3 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" u8 sYaz0DataBuffer[0x400]; diff --git a/src/libultra/io/contchannelreset.c b/src/libultra/io/contchannelreset.c index 5a66274a96..d0f1fbd9bc 100644 --- a/src/libultra/io/contchannelreset.c +++ b/src/libultra/io/contchannelreset.c @@ -7,7 +7,7 @@ s32 __osContChannelReset(OSMesgQueue* mq, s32 channel) { __osSiGetAccess(); - __osPfsPifRam.pifstatus = 1; + __osPfsPifRam.status = 1; for (i = 0; i < channel; i++) { *bufptr++ = 0; diff --git a/src/libultra/io/contpfs.c b/src/libultra/io/contpfs.c index 3dd0c96ca8..fd4c4e459f 100644 --- a/src/libultra/io/contpfs.c +++ b/src/libultra/io/contpfs.c @@ -1,6 +1,42 @@ #include "ultra64.h" #include "global.h" +__OSInode __osPfsInodeCache; +OSViMode osViModeNtscHpn1 = { + 8, // type + { + // comRegs + 0x324E, // ctrl + 0x500, // width + 0x3E52239, // burst + 0x20C, // vSync + 0xC15, // hSync + 0xC150C15, // leap + 0x6C02EC, // hStart + 0x400, // xScale + 0, // vCurrent + }, + { // fldRegs + { + // [0] + 0x500, // origin + 0x400, // yScale + 0x2301FD, // vStart + 0xE0204, // vBurst + 2, // vIntr + }, + { + // [1] + 0xA00, // origin + 0x400, // yScale + 0x2501FF, // vStart + 0xE0204, // vBurst + 2, // vIntr + } }, +}; +s32 __osPfsInodeCacheChannel = -1; +u8 __osPfsInodeCacheBank = 250; + u16 __osSumcalc(u8* ptr, s32 length) { s32 i; u32 sum = 0; diff --git a/src/libultra/io/contreaddata.c b/src/libultra/io/contreaddata.c index 47b7968d38..b54d894f30 100644 --- a/src/libultra/io/contreaddata.c +++ b/src/libultra/io/contreaddata.c @@ -47,7 +47,7 @@ void __osPackReadData() { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.pifstatus = 1; + __osContPifRam.status = 1; readformat.dummy = 255; readformat.txsize = 1; readformat.rxsize = 4; diff --git a/src/libultra/io/controller.c b/src/libultra/io/controller.c index d84ba2d711..bd82709931 100644 --- a/src/libultra/io/controller.c +++ b/src/libultra/io/controller.c @@ -78,7 +78,7 @@ void __osPackRequestData(u8 poll) { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.pifstatus = 1; + __osContPifRam.status = 1; ptr = (u8*)__osContPifRam.ramarray; requestHeader.align = 255; requestHeader.txsize = 1; diff --git a/src/libultra/io/motor.c b/src/libultra/io/motor.c index b8216dfc78..649a8b368f 100644 --- a/src/libultra/io/motor.c +++ b/src/libultra/io/motor.c @@ -20,7 +20,7 @@ s32 __osMotorAccess(OSPfs* pfs, u32 vibrate) { } __osSiGetAccess(); - osPifBuffers[pfs->channel].pifstatus = 1; + osPifBuffers[pfs->channel].status = 1; buf += pfs->channel; for (i = 0; i < BLOCKSIZE; i++) { ((__OSContRamReadFormat*)buf)->data[i] = vibrate; diff --git a/src/libultra/io/pfsgetstatus.c b/src/libultra/io/pfsgetstatus.c index 8127dde217..1d8e6dcf5f 100644 --- a/src/libultra/io/pfsgetstatus.c +++ b/src/libultra/io/pfsgetstatus.c @@ -1,7 +1,75 @@ +#include "ultra64.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsGetStatus.s") +void __osPfsRequestOneChannel(s32 channel, u8 poll); +void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData); -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsRequestOneChannel.s") +s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel) { + s32 ret = 0; + OSMesg msg; + OSContStatus data; -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsGetOneChannelData.s") + __osPfsInodeCacheBank = 250; + + __osPfsRequestOneChannel(channel, CONT_CMD_REQUEST_STATUS); + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(queue, &msg, OS_MESG_BLOCK); + + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(queue, &msg, OS_MESG_BLOCK); + + __osPfsGetOneChannelData(channel, &data); + if (((data.status & CONT_CARD_ON) != 0) && ((data.status & CONT_CARD_PULL) != 0)) { + return PFS_ERR_NEW_PACK; + } else if (data.errno || ((data.status & CONT_CARD_ON) == 0)) { + return PFS_ERR_NOPACK; + } else if ((data.status & CONT_ADDR_CRC_ER) != 0) { + return PFS_ERR_CONTRFAIL; + } + return ret; +} + +void __osPfsRequestOneChannel(s32 channel, u8 poll) { + u8* bufptr; + __OSContRequestHeaderAligned req; + s32 idx; + + __osContLastPoll = CONT_CMD_END; + __osPfsPifRam.status = CONT_CMD_READ_BUTTON; + + bufptr = (u8*)&__osPfsPifRam; + + req.txsize = 1; + req.rxsize = 3; + req.poll = poll; + req.typeh = 0xFF; + req.typel = 0xFF; + req.status = 0xFF; + + for (idx = 0; idx < channel; idx++) { + *bufptr++ = 0; + } + + *((__OSContRequestHeaderAligned*)bufptr) = req; + bufptr += sizeof(req); + *((u8*)bufptr) = CONT_CMD_END; +} + +void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData) { + u8* bufptr = (u8*)&__osPfsPifRam; + __OSContRequestHeaderAligned req; + s32 idx; + + for (idx = 0; idx < channel; idx++) { + bufptr++; + } + + req = *((__OSContRequestHeaderAligned*)bufptr); + contData->errno = (req.rxsize & 0xC0) >> 4; + if (contData->errno) { + return; + } + + contData->type = (req.typel << 8) | req.typeh; + contData->status = req.status; +} diff --git a/src/libultra/io/pfsisplug.c b/src/libultra/io/pfsisplug.c index 358af0c985..474c7f914b 100644 --- a/src/libultra/io/pfsisplug.c +++ b/src/libultra/io/pfsisplug.c @@ -55,7 +55,7 @@ void __osPfsRequestData(u8 poll) { __osContLastPoll = poll; - __osPfsPifRam.pifstatus = 1; + __osPfsPifRam.status = 1; req.align = 0xFF; req.txsize = 1; diff --git a/src/libultra/io/pfsreadwritefile.c b/src/libultra/io/pfsreadwritefile.c index bc2b9741ce..b5ab6e4b4c 100644 --- a/src/libultra/io/pfsreadwritefile.c +++ b/src/libultra/io/pfsreadwritefile.c @@ -1,5 +1,124 @@ +#include "ultra64.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsreadwritefile/__osPfsGetNextPage.s") +#define CHECK_IPAGE(p, pfs) \ + (((p).ipage >= (pfs).inodeStartPage) && ((p).inode_t.bank < (pfs).banks) && ((p).inode_t.page >= 0x01) && \ + ((p).inode_t.page < 0x80)) -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsreadwritefile/osPfsReadWriteFile.s") +s32 __osPfsGetNextPage(OSPfs* pfs, u8* bank, __OSInode* inode, __OSInodeUnit* page) { + s32 ret; + + if (page->inode_t.bank != *bank) { + *bank = page->inode_t.bank; + if ((ret = __osPfsRWInode(pfs, inode, PFS_READ, *bank)) != 0) { + return ret; + } + } + *page = inode->inodePage[page->inode_t.page]; + + if (!CHECK_IPAGE(*page, *pfs)) { + if (page->ipage == PFS_EOF) { + return PFS_ERR_INVALID; + } + return PFS_ERR_INCONSISTENT; + } + return 0; +} + +s32 osPfsReadWriteFile(OSPfs* pfs, s32 fileNo, u8 flag, s32 offset, s32 size, u8* data) { + s32 ret; + __OSDir dir; + __OSInode inode; + __OSInodeUnit curPage; + s32 curBlock; + s32 blockSize; + u8* buffer; + u8 bank; + u16 blockno; + + if ((fileNo >= pfs->dir_size) || (fileNo < 0)) { + return PFS_ERR_INVALID; + } + if ((size <= 0) || ((size % BLOCKSIZE) != 0)) { + return PFS_ERR_INVALID; + } + if ((offset < 0) || ((offset % BLOCKSIZE) != 0)) { + return PFS_ERR_INVALID; + } + if (!(pfs->status & PFS_INITIALIZED)) { + return PFS_ERR_INVALID; + } + if (__osCheckId(pfs) == PFS_ERR_NEW_PACK) { + return PFS_ERR_NEW_PACK; + } + if (pfs->activebank != PFS_ID_BANK_256K && (ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K)) != 0) { + return ret; + } + if ((ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + fileNo, (u8*)&dir)) != 0) { + return ret; + } + if ((dir.company_code == 0) || (dir.game_code == 0)) { + return PFS_ERR_INVALID; + } + if (!CHECK_IPAGE(dir.start_page, *pfs)) { + if (dir.start_page.ipage == PFS_EOF) { + return PFS_ERR_INVALID; + } + return PFS_ERR_INCONSISTENT; + } + if ((flag == PFS_READ) && ((dir.status & PFS_WRITTEN) == 0)) { + return PFS_ERR_BAD_DATA; + } + + bank = 255; + curBlock = offset / BLOCKSIZE; + curPage = dir.start_page; + + while (curBlock >= 8) { + if ((ret = __osPfsGetNextPage(pfs, &bank, &inode, &curPage)) != 0) { + return ret; + } + curBlock -= 8; + } + + blockSize = size / BLOCKSIZE; + buffer = data; + + while (blockSize > 0) { + if (curBlock == 8) { + if ((ret = __osPfsGetNextPage(pfs, &bank, &inode, &curPage)) != 0) { + return ret; + } + curBlock = 0; + } + if (pfs->activebank != curPage.inode_t.bank && (ret = __osPfsSelectBank(pfs, curPage.inode_t.bank)) != 0) { + return ret; + } + + blockno = curPage.inode_t.page * PFS_ONE_PAGE + curBlock; + if (flag == PFS_READ) { + ret = __osContRamRead(pfs->queue, pfs->channel, blockno, buffer); + } else { + ret = __osContRamWrite(pfs->queue, pfs->channel, blockno, buffer, 0); + } + if (ret != 0) { + return ret; + } + + buffer += BLOCKSIZE; + curBlock++; + blockSize--; + } + + if (flag == PFS_WRITE && !(dir.status & PFS_WRITTEN)) { + dir.status |= PFS_WRITTEN; + if (pfs->activebank != PFS_ID_BANK_256K && (ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K)) != 0) { + return ret; + } + if ((ret = __osContRamWrite(pfs->queue, pfs->channel, pfs->dir_table + fileNo, (u8*)&dir, 0)) != 0) { + return ret; + } + } + + return __osPfsGetStatus(pfs->queue, pfs->channel); +} diff --git a/src/libultra/voice/voicegetstatus.c b/src/libultra/voice/voicegetstatus.c index 833f5ad272..d8e7edb671 100644 --- a/src/libultra/voice/voicegetstatus.c +++ b/src/libultra/voice/voicegetstatus.c @@ -12,7 +12,7 @@ s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 port, u8* status) { do { if (ret != CONT_ERR_CONTRFAIL) { - __osContPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osContPifRam.status = CONT_CMD_READ_BUTTON; for (i = 0; i < port; i++, *ptr++ = 0) { ;