You've already forked hackerlibultra
mirror of
https://github.com/HackerN64/hackerlibultra.git
synced 2026-01-21 10:37:53 -08:00
Some Docs (#79)
* osAiGetLength Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * osAiSetFrequency Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * contquery.c * osContSetCh * bzero Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * osInvalDCache Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * osInvalICache Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * __osProbeTLB Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * osSetIntMask Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * osWritebackDCache Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * crc Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * __osVoiceContDataCrc Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * voice file headers Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * exceptasm Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * CHECK_IPAGE in pfsreadwritefile * prs read write macros in __osPfsRWInode * PIF_RAM_SIZE in sirawdma * Additional use of VI_SUBPIXEL_SH in __osViSwapContext * Remove PR/os.h includes from some libc files * Add void as arg to empty arg functions * interrupt threadasm macros * Use NTLBENTRIES in osMapTLBRdb * Some usage of NULL in thread.c * Use K0BASE/RDB_BASE_VIRTUAL_ADDR instead of KUSIZE in some places * Force semicolon usage on _osVirtualToPhysical * replace tabs with spaces * __osContinitialized boolean * PR review cleanup Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Update src/os/invaldcache.s Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> --------- Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
This commit is contained in:
@@ -67,5 +67,5 @@ extern __OSViContext *__osViNext;
|
||||
extern u32 __additional_scanline;
|
||||
__OSViContext *__osViGetCurrentContext(void);
|
||||
void __osViInit(void);
|
||||
extern OSDevMgr __osViDevMgr;
|
||||
extern OSDevMgr __osViDevMgr;
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
/**
|
||||
* Returns the number of bytes remaining in a currently ongoing audio DMA.
|
||||
*
|
||||
* Note that audio DMA is double-buffered, a DMA can be queued while another is in-progress. This only returns
|
||||
* information about the currently in-progress DMA.
|
||||
*/
|
||||
u32 osAiGetLength(void) {
|
||||
return IO_READ(AI_LEN_REG);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
u32 osAiGetStatus() {
|
||||
u32 osAiGetStatus(void) {
|
||||
return IO_READ(AI_STATUS_REG);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,12 @@ extern s32 osViClock;
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
/**
|
||||
* Programs the operating frequency of the Audio DAC.
|
||||
*
|
||||
* @param frequency Target Playback frequency.
|
||||
* @return The actual playback frequency, or -1 if the supplied frequency cannot be used.
|
||||
*/
|
||||
s32 osAiSetFrequency(u32 frequency) {
|
||||
register unsigned int dacRate;
|
||||
register unsigned char bitRate;
|
||||
@@ -31,15 +37,20 @@ s32 osAiSetFrequency(u32 frequency) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Calculate the DAC sample period ("dperiod") (dperiod + 1 = vid_clock / frequency)
|
||||
f = osViClock / (float)frequency + .5f;
|
||||
dacRate = f;
|
||||
|
||||
// Upcoming division by 66. If dacRate is smaller than 2 * 66 = 132, bitrate will be 1 and AI_BITRATE_REG will be
|
||||
// programmed with 0, which results in no audio output. Return -1 to indicate an unusable frequency.
|
||||
if (dacRate < AI_MIN_DAC_RATE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Calculate the largest "bitrate" (ABUS clock half period, "aclockhp") supported for this dacrate. These two
|
||||
// quantities must satisfy (dperiod + 1) >= 66 * (aclockhp + 1), here this is taken as equality.
|
||||
bitRate = dacRate / 66;
|
||||
|
||||
// Clamp to max value
|
||||
if (bitRate > AI_MAX_BIT_RATE) {
|
||||
bitRate = AI_MAX_BIT_RATE;
|
||||
}
|
||||
@@ -49,5 +60,7 @@ s32 osAiSetFrequency(u32 frequency) {
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON);
|
||||
#endif
|
||||
// Return the true playback frequency (frequency = vid_clock / (dperiod + 1)), which may differ from the target
|
||||
// frequency.
|
||||
return osViClock / (s32)dacRate;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#include "PRinternal/controller.h"
|
||||
#include "PRinternal/siint.h"
|
||||
|
||||
/**
|
||||
* Starts to read the values for SI device status and type which are connected to the controller port and joyport
|
||||
* connector.
|
||||
*/
|
||||
s32 osContStartQuery(OSMesgQueue* mq) {
|
||||
s32 ret = 0;
|
||||
|
||||
@@ -19,6 +23,9 @@ s32 osContStartQuery(OSMesgQueue* mq) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from osContStartQuery to status. Both functions must be paired for use.
|
||||
*/
|
||||
void osContGetQuery(OSContStatus* data) {
|
||||
u8 pattern;
|
||||
__osContGetInitData(&pattern, data);
|
||||
|
||||
@@ -11,7 +11,7 @@ OSTimer __osEepromTimer;
|
||||
OSMesgQueue __osEepromTimerQ ALIGNED(8);
|
||||
OSMesg __osEepromTimerMsg;
|
||||
|
||||
s32 __osContinitialized = 0;
|
||||
s32 __osContinitialized = FALSE;
|
||||
|
||||
s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) {
|
||||
OSMesg dummy;
|
||||
@@ -20,11 +20,11 @@ s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) {
|
||||
OSTimer mytimer;
|
||||
OSMesgQueue timerMesgQueue;
|
||||
|
||||
if (__osContinitialized != 0) {
|
||||
if (__osContinitialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__osContinitialized = 1;
|
||||
__osContinitialized = TRUE;
|
||||
|
||||
t = osGetTime();
|
||||
if (t < OS_USEC_TO_CYCLES(500000)) {
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#include "PRinternal/controller.h"
|
||||
#include "PRinternal/siint.h"
|
||||
|
||||
/*
|
||||
* This function specifies the number of devices for the functions to access when those functions access to multiple
|
||||
* direct SI devices.
|
||||
*/
|
||||
s32 osContSetCh(u8 ch) {
|
||||
s32 ret = 0;
|
||||
|
||||
|
||||
136
src/io/crc.c
136
src/io/crc.c
@@ -1,56 +1,154 @@
|
||||
/**
|
||||
* File: crc.c
|
||||
* Description: Functions to compute Cyclic Redundancy Check for specific addresses and data.
|
||||
*
|
||||
* CRC notes:
|
||||
*
|
||||
* General
|
||||
* ===
|
||||
* - CRC (Cyclic Redundancy Check) is a way of verifying that no errors were introduced in transmitted data.
|
||||
* - It reads the entire message and generates a check number that is appended to it.
|
||||
* - A CRC is specified by the length `n` of the check number and a number (called the generator) smaller than `1 << n`.
|
||||
* - Different generators have different error-checking capabilities. The choice of a generator is a sophisticated
|
||||
* mathematical problem.
|
||||
*
|
||||
* Mathematical basis
|
||||
* ===
|
||||
* - The algorithm is based on division of polynomials. The polynomials have coefficients in the field with two
|
||||
* elements, 0 and 1, with addition given by XOR and multiplication by AND (it turns out this really is a field).
|
||||
* Subtraction is the same as addition.
|
||||
* - There is a one-to-one correspondence between binary polynomials and binary numbers: just evaluate the polynomial at
|
||||
* 2, or write down an \f$ X^k \f$ corresponding to each `1 << k` the number is composed of.
|
||||
* - The message bits `m{L}m{L-1}...m{1}m{0}` correspond to a polynomial \f$ m(X) = m_L X^L + m_{L-1} X^{L-1} + \dotsb +
|
||||
* m_1 X^1 + m_0 X^0 \f$. We multiply this by \f$ X^n \f$ to make a space to insert the remainder at the end; this new
|
||||
* polynomial will be the dividend.
|
||||
* - The generator `p{n-1}p{n-2}...p{1}p{0}` corresponds to a polynomial \f$ p(X) = X^n + p_{n-1} X^{n-1} + \dotsb + p_1
|
||||
* X^1 + p_0 X^0 \f$: the leading term is omitted in the binary description because it is always \f$ X^n \f$. The
|
||||
* generator polynomial is the divisor.
|
||||
* - The usual division algorithm is followed: we look along the dividend until we see a nonzero coefficient, then
|
||||
* subtract an appropriate multiple of the divisor to cancel it out. We repeat this until we reach the end of the
|
||||
* number.
|
||||
* - Arithmetic in the field with two elements is particularly simple: subtraction is identical to addition, so also
|
||||
* given by XOR, and the only multipliers required for subtracting the divisor are \f$ X^k \f$.
|
||||
* - After applying the algorithm, the output is a polynomial \f$ R(X) \f$ so that we have
|
||||
* \f[ m(X) X^n = Q(X) p(X) + R(X) \f]
|
||||
* (\f$ R(X) \f$ is the *remainder after dividing by \f$ p(X) \f$*).
|
||||
* - Therefore, \f$ m(X) X^n - R(X) \f$ is divisible by the generator polynomial. This means that if we append the
|
||||
* binary number corresponding to \f$ R(X) \f$ to the message and rerun the algorithm, we will get 0 if no errors have
|
||||
* been introduced.
|
||||
*
|
||||
*
|
||||
* Implementation
|
||||
* ===
|
||||
* - We translate the binary polynomials to binary numbers by evaluating them at 2. The leading term in the generator
|
||||
* polynomial is always \f$ X^n \f$, so we discard it to save space. In the binary field, subtraction is the same as
|
||||
* addition, and given by XOR. Multiplication by \f$ X \f$ is given by shifting left.
|
||||
* - Instead of fixing the message and moving the divisor polynomial right, we scan the message from the most
|
||||
* significant digit, adding it to the end of the return value, (that is, for 1s, we shift and add 1, for 0s we just
|
||||
* shift, effectively using the return value as a shift register).
|
||||
* - When the return value has a 1 in the nth position (corresponding to the leading term in the generator polynomial),
|
||||
* we binary-subtract (i.e. XOR) the return value with the generator polynomial's number.
|
||||
* - This is repeated until we reach the end of the message.
|
||||
* - Finally, to take into account the final multiplication by \f$ X^n \f$, we run another loop, which acts like we
|
||||
* passed \f$ n \f$ more digits in the message that are all zero. Remember this gives us the extra space at the end for
|
||||
* the check digits to be added.
|
||||
*
|
||||
*
|
||||
* - To specify a CRC, at minimum we need the length of the check (i.e. the degree of the generator polynomial), \f$ n
|
||||
* \f$, and the rest of the generator polynomial. This is usually expressed in the binary form, written as hex for
|
||||
* compactness. Algorithms may also reverse or invert certain parts of the data or check to improve particular aspects
|
||||
* of the algorithm, but the libultra functions use the simplest version.
|
||||
*
|
||||
*
|
||||
* Resources
|
||||
* ===
|
||||
* - Wikipedia: [Cyclic redundancy check](https://en.wikipedia.org/wiki/Cyclic_redundancy_check), and more specifically
|
||||
* [Computation of cyclic redundancy checks](https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks)
|
||||
* - Ben Eater has two videos on CRCs, the last two linked on [Error Detection | Ben Eater](https://eater.net/crc)
|
||||
* - A page that specifically describes the same shift-register-style algorithms as libultra uses: [Understanding and
|
||||
* implementing CRC (Cyclic Redundancy Check) calculation
|
||||
* ](http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html)
|
||||
*/
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
|
||||
#define ADDRESS_CRC_MESSAGE_LENGTH 10
|
||||
#define ADDRESS_CRC_LENGTH 5
|
||||
#define ADDRESS_CRC_GENERATOR 0x15
|
||||
#define ADDRESS_CRC_MASK ((1 << ADDRESS_CRC_LENGTH) - 1)
|
||||
|
||||
/**
|
||||
* CRC-5 with the generating polynomial \f$ x^5 + x^4 + x^2 + 1 \f$, AKA 0x15 = 0b(1)1 0101.
|
||||
* It only works on the bits from 0x7FF = 11 11111111, i.e. 10 bits.
|
||||
*
|
||||
* Usually used as __osContAddressCrc(addr) | (addr << 5) to add the CRC to the end. The overall length of 10 + 5 bits
|
||||
* allows the address + CRC to fit into one s16.
|
||||
*
|
||||
* `addr` is the address of a block in the mempak, only valid up to 0x7FF.
|
||||
*/
|
||||
u8 __osContAddressCrc(u16 addr) {
|
||||
u32 temp = 0;
|
||||
u32 i = 0x400;
|
||||
u32 i = (1 << ADDRESS_CRC_MESSAGE_LENGTH);
|
||||
|
||||
do {
|
||||
// temp is used as a shift register for the CRC
|
||||
temp <<= 1;
|
||||
|
||||
if ((u32)addr & i) {
|
||||
if (temp & 0x20) {
|
||||
temp ^= 0x14;
|
||||
if (temp & (1 << ADDRESS_CRC_LENGTH)) {
|
||||
// Same as temp++; temp ^= 0x15 since last bit always 0 after the shift
|
||||
temp ^= ADDRESS_CRC_GENERATOR - 1;
|
||||
} else {
|
||||
++temp;
|
||||
}
|
||||
} else if (temp & 0x20) {
|
||||
temp ^= 0x15;
|
||||
} else if (temp & (1 << ADDRESS_CRC_LENGTH)) {
|
||||
temp ^= ADDRESS_CRC_GENERATOR;
|
||||
}
|
||||
|
||||
i >>= 1;
|
||||
} while (i != 0);
|
||||
|
||||
i = 5;
|
||||
|
||||
// Acts like 5 bits of 0s are appended to addr
|
||||
i = ADDRESS_CRC_LENGTH;
|
||||
do {
|
||||
temp <<= 1;
|
||||
if (temp & 0x20) {
|
||||
temp ^= 0x15;
|
||||
if (temp & (1 << ADDRESS_CRC_LENGTH)) {
|
||||
temp ^= ADDRESS_CRC_GENERATOR;
|
||||
}
|
||||
} while (--i != 0);
|
||||
|
||||
return temp & 0x1F;
|
||||
// Discard the irrelevant bits above the actual remainder
|
||||
return temp & ADDRESS_CRC_MASK;
|
||||
}
|
||||
|
||||
#define DATA_CRC_MESSAGE_BYTES 32
|
||||
#define DATA_CRC_LENGTH 8
|
||||
#define DATA_CRC_GENERATOR 0x85
|
||||
|
||||
/**
|
||||
* CRC-8 with generating polynomial \f$ x^8 + x^7 + x^2 + 1 \f$, AKA 0x85 = 0b(1) 1000 0101.
|
||||
* Expects exactly 0x20 = 32 bytes of data.
|
||||
*/
|
||||
u8 __osContDataCrc(u8* data) {
|
||||
u32 temp = 0;
|
||||
u32 i;
|
||||
u32 j;
|
||||
|
||||
for (i = 0x20; i; --i) {
|
||||
for (j = 0x80; j; j >>= 1) {
|
||||
for (i = DATA_CRC_MESSAGE_BYTES; i; --i) {
|
||||
// Loop over each bit in the byte starting with most significant
|
||||
for (j = (1 << (DATA_CRC_LENGTH - 1)); j; j >>= 1) {
|
||||
temp <<= 1;
|
||||
|
||||
if ((*data & j) != 0) {
|
||||
if ((temp & 0x100) != 0) {
|
||||
temp ^= 0x84;
|
||||
if ((temp & (1 << DATA_CRC_LENGTH)) != 0) {
|
||||
// Same as ret++; ret ^= 0x85 since last bit always 0 after the shift
|
||||
temp ^= DATA_CRC_GENERATOR - 1;
|
||||
} else {
|
||||
++temp;
|
||||
}
|
||||
} else if (temp & 0x100) {
|
||||
temp ^= 0x85;
|
||||
} else if (temp & (1 << DATA_CRC_LENGTH)) {
|
||||
temp ^= DATA_CRC_GENERATOR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,10 +157,10 @@ u8 __osContDataCrc(u8* data) {
|
||||
do {
|
||||
temp <<= 1;
|
||||
|
||||
if (temp & 0x100) {
|
||||
temp ^= 0x85;
|
||||
if (temp & (1 << DATA_CRC_LENGTH)) {
|
||||
temp ^= DATA_CRC_GENERATOR;
|
||||
}
|
||||
} while (++i < 8U);
|
||||
} while (++i < DATA_CRC_LENGTH);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
u32 osDpGetStatus() {
|
||||
u32 osDpGetStatus(void) {
|
||||
return IO_READ(DPC_STATUS_REG);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
OSPiHandle DriveRomHandle ALIGNED(8);
|
||||
|
||||
OSPiHandle *osDriveRomInit() {
|
||||
OSPiHandle *osDriveRomInit(void) {
|
||||
u32 saveMask;
|
||||
|
||||
if (DriveRomHandle.baseAddress == PHYS_TO_K1(PI_DOM1_ADDR1)) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
OSPiHandle LeoDiskHandle ALIGNED(8);
|
||||
OSPiHandle *__osDiskHandle;
|
||||
|
||||
OSPiHandle *osLeoDiskInit() {
|
||||
OSPiHandle *osLeoDiskInit(void) {
|
||||
u32 saveMask;
|
||||
|
||||
LeoDiskHandle.type = DEVICE_TYPE_64DD;
|
||||
|
||||
@@ -11,7 +11,7 @@ u8 leoDiskStack[OS_PIM_STACKSIZE] ALIGNED(16);
|
||||
static void __osLeoAbnormalResume(void);
|
||||
static void __osLeoResume(void);
|
||||
|
||||
s32 __osLeoInterrupt() {
|
||||
s32 __osLeoInterrupt(void) {
|
||||
u32 stat = 0;
|
||||
volatile u32 pi_stat;
|
||||
u32 bm_stat;
|
||||
|
||||
@@ -241,7 +241,7 @@ s32 osPfsAllocateFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name
|
||||
|
||||
backup_inode.inode_page[old_last_page].inode_t.bank = bank;
|
||||
backup_inode.inode_page[old_last_page].inode_t.page = start_page;
|
||||
ERRCK(__osPfsRWInode(pfs, &backup_inode, OS_WRITE, old_bank));
|
||||
ERRCK(__osPfsRWInode(pfs, &backup_inode, PFS_WRITE, old_bank));
|
||||
|
||||
dir.start_page = fpage;
|
||||
dir.company_code = company_code;
|
||||
|
||||
@@ -56,7 +56,7 @@ s32 osPfsChecker(OSPfs* pfs) {
|
||||
bank = next_page.inode_t.bank;
|
||||
|
||||
if (oldbank != bank) {
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, OS_READ, bank);
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, PFS_READ, bank);
|
||||
oldbank = bank;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ s32 osPfsChecker(OSPfs* pfs) {
|
||||
while (CHECK_IPAGE(next_page)) {
|
||||
if (bank != next_page.inode_t.bank) {
|
||||
bank = next_page.inode_t.bank;
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, OS_READ, bank);
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, PFS_READ, bank);
|
||||
if (ret != 0 && ret != PFS_ERR_INCONSISTENT) {
|
||||
return ret;
|
||||
}
|
||||
@@ -143,7 +143,7 @@ s32 osPfsChecker(OSPfs* pfs) {
|
||||
}
|
||||
|
||||
for (bank = 0; bank < pfs->banks; bank++) {
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, 0, bank);
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, PFS_READ, bank);
|
||||
|
||||
if (ret != 0 && ret != PFS_ERR_INCONSISTENT) {
|
||||
return ret;
|
||||
@@ -165,7 +165,7 @@ s32 osPfsChecker(OSPfs* pfs) {
|
||||
file_next_node[j] = checked_inode.inode_page[pp] = tmp_inode.inode_page[pp];
|
||||
}
|
||||
}
|
||||
ERRCK(__osPfsRWInode(pfs, &checked_inode, OS_WRITE, bank));
|
||||
ERRCK(__osPfsRWInode(pfs, &checked_inode, PFS_WRITE, bank));
|
||||
}
|
||||
|
||||
if (fixed) {
|
||||
@@ -194,7 +194,7 @@ s32 corrupted_init(OSPfs* pfs, __OSInodeCache* cache) {
|
||||
for (bank = 0; bank < pfs->banks; bank++) {
|
||||
offset = bank > 0 ? 1 : pfs->inode_start_page;
|
||||
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, OS_READ, bank);
|
||||
ret = __osPfsRWInode(pfs, &tmp_inode, PFS_READ, bank);
|
||||
|
||||
if (ret != 0 && ret != PFS_ERR_INCONSISTENT) {
|
||||
return ret;
|
||||
@@ -235,7 +235,7 @@ s32 corrupted(OSPfs* pfs, __OSInodeUnit fpage, __OSInodeCache* cache) {
|
||||
|
||||
if (bank == fpage.inode_t.bank || cache->map[n] & (1 << (bank % PFS_BANK_LAPPED_BY))) {
|
||||
if (bank != cache->bank) {
|
||||
ret = __osPfsRWInode(pfs, &cache->inode, 0, bank);
|
||||
ret = __osPfsRWInode(pfs, &cache->inode, PFS_READ, bank);
|
||||
|
||||
if (ret != 0 && ret != PFS_ERR_INCONSISTENT) {
|
||||
return ret;
|
||||
|
||||
@@ -39,13 +39,13 @@ s32 osPfsDeleteFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name,
|
||||
startpage = dir.start_page.inode_t.page;
|
||||
|
||||
for (bank = dir.start_page.inode_t.bank; bank < pfs->banks;) {
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, OS_READ, bank));
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, PFS_READ, bank));
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
ERRCK(__osPfsReleasePages(pfs, &inode, startpage, bank, &last_page));
|
||||
#else
|
||||
ERRCK(__osPfsReleasePages(pfs, &inode, startpage, &sum, bank, &last_page, TRUE));
|
||||
#endif
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, OS_WRITE, bank));
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, PFS_WRITE, bank));
|
||||
|
||||
if (last_page.ipage == PFS_EOF) {
|
||||
break;
|
||||
|
||||
@@ -73,7 +73,7 @@ s32 osPfsFileState(OSPfs* pfs, s32 file_no, OSPfsState* state) {
|
||||
bank = dir.start_page.inode_t.bank;
|
||||
|
||||
while (bank < pfs->banks) {
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, OS_READ, bank));
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, PFS_READ, bank));
|
||||
next_page = inode.inode_page[start_page];
|
||||
pages++;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ s32 osPfsFreeBlocks(OSPfs* pfs, s32* bytes_not_used) {
|
||||
PFS_CHECK_ID();
|
||||
#endif
|
||||
for (bank = 0; bank < pfs->banks; bank++) {
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, OS_READ, bank));
|
||||
ERRCK(__osPfsRWInode(pfs, &inode, PFS_READ, bank));
|
||||
offset = ((bank > 0) ? 1 : pfs->inode_start_page);
|
||||
|
||||
for (j = offset; j < ARRLEN(inode.inode_page); j++) {
|
||||
|
||||
@@ -2,20 +2,22 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "PRinternal/controller.h"
|
||||
|
||||
#define CHECK_IPAGE(p) \
|
||||
(((p).ipage >= pfs->inode_start_page) && ((p).inode_t.bank < pfs->banks) && ((p).inode_t.page >= 0x01) && \
|
||||
((p).inode_t.page < 0x80))
|
||||
|
||||
static s32 __osPfsGetNextPage(OSPfs* pfs, u8* bank, __OSInode* inode, __OSInodeUnit* page) {
|
||||
s32 ret;
|
||||
|
||||
if (page->inode_t.bank != *bank) {
|
||||
*bank = page->inode_t.bank;
|
||||
ERRCK(__osPfsRWInode(pfs, inode, 0, *bank));
|
||||
ERRCK(__osPfsRWInode(pfs, inode, PFS_READ, *bank));
|
||||
}
|
||||
|
||||
*page = inode->inode_page[page->inode_t.page];
|
||||
|
||||
if (page->ipage < pfs->inode_start_page || page->inode_t.bank >= pfs->banks || page->inode_t.page <= 0 ||
|
||||
page->inode_t.page >= ARRLEN(inode->inode_page)) {
|
||||
|
||||
if (page->ipage == 1) {
|
||||
if (!CHECK_IPAGE(*page)) {
|
||||
if (page->ipage == PFS_EOF) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
@@ -55,9 +57,8 @@ s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, int offset, int size_in
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (dir.start_page.ipage < pfs->inode_start_page || dir.start_page.inode_t.bank >= pfs->banks ||
|
||||
dir.start_page.inode_t.page <= 0 || dir.start_page.inode_t.page >= ARRLEN(inode.inode_page)) {
|
||||
if ((dir.start_page.ipage == 1)) {
|
||||
if (!CHECK_IPAGE(dir.start_page)) {
|
||||
if ((dir.start_page.ipage == PFS_EOF)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
int __osPiDeviceBusy() {
|
||||
int __osPiDeviceBusy(void) {
|
||||
register u32 stat = IO_READ(PI_STATUS_REG);
|
||||
if (stat & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
|
||||
return TRUE;
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
u32 osPiGetStatus() {
|
||||
u32 osPiGetStatus(void) {
|
||||
return IO_READ(PI_STATUS_REG);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user