Skip to content

Commit

Permalink
[iQue] Match some fs files (#72)
Browse files Browse the repository at this point in the history
* Header file from Tharo

Co-authored-by: Tharo <[email protected]>

* fsclose.c

* fsdelete.c

* fsdir.c

* fsread.o

* fsrename.c

* osBbFRepairBlock todo

* fswrite.c

* cleanups

* general cleanup

* yeet todo files

* Update src/bb/fs/fswrite.c

Co-authored-by: Tharo <[email protected]>

* review

* BBFS_NEXT_BLOCK

---------

Co-authored-by: Tharo <[email protected]>
  • Loading branch information
AngheloAlf and Thar0 authored Apr 28, 2024
1 parent b2d603f commit ade805e
Show file tree
Hide file tree
Showing 11 changed files with 513 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ tools/ido

# Tool artifacts
ctx.c
ctx.c.m2c

libultra_collection/
103 changes: 103 additions & 0 deletions include/PR/bbfs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#ifndef BBFS_H_
#define BBFS_H_

#include "ultratypes.h"

#define BB_FL_BLOCK_SIZE 16384
#define BB_INODE16_NAMELEN 11 /* maximum name length */
#define BB_INODE16_NUM 409

#define BBFS_ERR_NO_CARD (-1) /* card not present */
#define BBFS_ERR_FAIL (-2) /* operation failed */
#define BBFS_ERR_INVALID (-3) /* invalid parameters */
#define BBFS_ERR_CHANGED (-4) /* card changed */
#define BBFS_ERR_UNINIT (-5) /* fs uninitialized */
#define BBFS_ERR_EXISTS (-6) /* file exists */
#define BBFS_ERR_SPACE (-7) /* no space */
#define BBFS_ERR_ENTRY (-8) /* no entry */

/* Used for saving auxilliary game state data */
#define BBFS_ERR_STATE (-9) /* invalid state */
#define BBFS_ERR_STATE_LIMIT (-10) /* state limit reached */

typedef u16 BbFatEntry;

typedef struct {
/* 0x0000 */ u8 name[BB_INODE16_NAMELEN];
/* 0x000B */ u8 type;
/* 0x000C */ u16 block;
/* 0x000E */ u16 pad;
/* 0x0010 */ u32 size;
} BbInode; // size = 0x14

typedef struct {
/* 0x0000 */ BbFatEntry entry[4096];
/* 0x2000 */ BbInode inode[BB_INODE16_NUM];
/* 0x3FF4 */ u8 magic[4];
/* 0x3FF8 */ u32 seq;
/* 0x3FFC */ u16 link;
/* 0x3FFE */ u16 cksum;
} BbFat16; // size = 0x4000

// `fat` is a `BbFat16` pointer
#define BBFS_NEXT_BLOCK(fat, b) (fat[b >> 0xC].entry[b & 0xFFF])

extern BbFat16* __osBbFat;

typedef struct {
/* 0x0000 */ u8 root[32768];
} OSBbFs; // size = 0x8000

typedef struct {
/* 0x0000 */ u16 files;
/* 0x0002 */ u16 blocks;
/* 0x0004 */ u16 freeFiles;
/* 0x0006 */ u16 freeBlocks;
} OSBbStatFs; // size = 0x8

typedef struct {
/* 0x0000 */ char name[13];
/* 0x000D */ u8 type;
/* 0x0010 */ u32 size;
} OSBbDirEnt; // size = 0x14

typedef struct {
/* 0x0000 */ u8 type;
/* 0x0004 */ u32 size;
} OSBbStatBuf; // size = 0x8

s32 osBbFOpen(const char* name, const char* mode);
s32 osBbFWrite(s32 fd, u32 off, void* buf, u32 len);
s32 osBbFRead(s32 fd, u32 off, void* buf, u32 len);
s32 osBbFClose(s32 fd);
s32 osBbFStatFs(OSBbStatFs* statfs);
s32 osBbFInit(OSBbFs* fs);
s32 osBbFDelete(const char* name);
s32 osBbFCreate(const char* name, u8 type, u32 len);
s32 osBbFRename(const char* old, const char* new);
s32 osBbFStat(s32 fd, OSBbStatBuf* sb, u16* blockList, u32 listLen);
s32 osBbFReadDir(OSBbDirEnt* dir, u32 count);
s32 osBbFRepairBlock(s32 fd, u32 off, void* buf, u32 len);
s32 osBbFShuffle(s32 sfd, s32 dfd, s32 release, void* buf, u32 len);
s32 osBbFAutoSync(u32 on);
s32 osBbFSync(void);

// private

s32 __osBbFsGetAccess(void);
void __osBbFsRelAccess(void);

void __osBbFsFormatName(char*, const char*);

void __osBbFCheck(void);

s32 __osBbFsSync(int force);

u16 __osBbFReallocBlock(BbInode* in, u16 block, BbFatEntry newVal);

extern u16 __osBbFatBlock;
extern u16 __osBbFsBlocks;
extern BbFat16* __osBbFat;
extern u8 __osBbFsAutoSync;

#endif
14 changes: 14 additions & 0 deletions include/PR/os_bbcard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef _os_bb_card_h_
#define _os_bb_card_h_

#include <PR/ultratypes.h>

extern s32 osBbCardEraseBlock(u32 dev, u16 block);
extern s32 osBbCardEraseBlocks(u32 dev, const u16 block[], u32 n);
extern s32 osBbCardReadBlock(u32 dev, u16 block, void* addr, void* spare);
extern s32 osBbCardWriteBlock(u32 dev, u16 block, const void* addr,
const void* spare);
extern s32 osBbCardWriteBlocks(u32 dev, const u16 block[], u32 n,
const void* addr, const void* spare);

#endif
23 changes: 23 additions & 0 deletions src/bb/fs/fsclose.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "PR/os_internal.h"
#include "PR/bbfs.h"

s32 osBbFClose(s32 fd) {
BbFat16* fat;
s32 rv;

if (fd < 0 || fd >= BB_INODE16_NUM) {
return BBFS_ERR_INVALID;
}

rv = __osBbFsGetAccess();
if (rv != 0) {
return rv;
}

fat = __osBbFat;
if (fat->inode[fd].type == 0) {
rv = BBFS_ERR_INVALID;
}
__osBbFsRelAccess();
return rv;
}
47 changes: 47 additions & 0 deletions src/bb/fs/fsdelete.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "PR/os_internal.h"
#include "PR/bbfs.h"

s32 osBbFDelete(const char* name) {
unsigned char fname[BB_INODE16_NAMELEN];
s32 rv;
BbFat16* fat;
int i;

__osBbFsFormatName(fname, name);

if (fname[0] == '\0') {
return BBFS_ERR_INVALID;
}

rv = __osBbFsGetAccess();
if (rv < 0) {
return rv;
}

rv = BBFS_ERR_ENTRY;

fat = __osBbFat;
for (i = 0; i < BB_INODE16_NUM; i++) {
u16 b;

if (fat->inode[i].type != 0) {
if (bcmp(fname, fat->inode[i].name, BB_INODE16_NAMELEN * sizeof(unsigned char)) == 0) {
b = fat->inode[i].block;
while (b != 0xFFFF) {
u16 temp_v0; // not present on mdebug

temp_v0 = BBFS_NEXT_BLOCK(fat, b);
BBFS_NEXT_BLOCK(fat, b) = 0;
b = temp_v0;
}

bzero(&fat->inode[i], sizeof(fat->inode[i]));
rv = __osBbFsSync(FALSE);
break;
}
}
}

__osBbFsRelAccess();
return rv;
}
52 changes: 52 additions & 0 deletions src/bb/fs/fsdir.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "PR/os_internal.h"
#include "PR/bbfs.h"

s32 osBbFReadDir(OSBbDirEnt* dir, u32 count) {
s32 rv;
s32 i;
s32 j;
BbFat16* fat;
OSBbDirEnt* d;

d = dir;
rv = __osBbFsGetAccess();

if (rv < 0) {
return rv;
}

fat = __osBbFat;

for (i = 0, j = 0; i < BB_INODE16_NUM; i++) {
unsigned char* var_s2 = fat->inode[i].name;
s32 k;

if (fat->inode[i].type == 0) {
continue;
}

rv++;
if (d != NULL && j < count) {
d->type = fat->inode[i].type;
d->size = fat->inode[i].size;

for (k = 0; var_s2[k] != '\0' && k < 8; k++) {
d->name[k] = var_s2[k];
}

if (var_s2[8] != '\0') {
d->name[k] = '.';
bcopy(&var_s2[8], &d->name[k] + 1, 3);
d->name[k+4] = '\0';
} else {
d->name[k] = '\0';
}

d++;
j++;
}
}

__osBbFsRelAccess();
return rv;
}
66 changes: 66 additions & 0 deletions src/bb/fs/fsread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "PR/os_internal.h"
#include "PR/bbfs.h"

s32 osBbFRead(s32 fd, u32 off, void* buf, u32 len) {
s32 rv;
BbInode* in;
u32 count;
u32 b;
u32 i;
BbFat16* fat;

if (fd < 0 || fd >= BB_INODE16_NUM) {
return BBFS_ERR_INVALID;
}

rv = __osBbFsGetAccess();
if (rv < 0) {
return rv;
}

fat = __osBbFat;
in = &fat->inode[fd];
rv = BBFS_ERR_INVALID;

if (in->type != 0 && off % 0x4000 == 0) {
if (off < in->size && off + len >= off) {
if (in->size < off + len) {
len = in->size - off;
}

if (len == 0) {
rv = 0;
goto end;
}

b = in->block;

for (i = 0; i < off / 0x4000; i++) {
b = BBFS_NEXT_BLOCK(fat, b);
}

count = 0;

while (len != 0) {
if (b == 0 || b >= __osBbFsBlocks - 0x10) {
goto end;
}

rv = osBbCardReadBlock(0, b, buf, NULL);
if (rv < 0) {
goto end;
}

b = BBFS_NEXT_BLOCK(fat, b);
buf += 0x4000;
len = (len > 0x4000) ? (len - 0x4000) : 0;
count += 0x4000;
}
rv = count;
}
}

end:
__osBbFsRelAccess();
return rv;
}
62 changes: 62 additions & 0 deletions src/bb/fs/fsrename.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "PR/os_internal.h"
#include "PR/bbfs.h"

s32 osBbFRename(const char* old, const char* new) {
unsigned char fold[BB_INODE16_NAMELEN];
unsigned char fnew[BB_INODE16_NAMELEN];
s32 rv;
s32 inew;
s32 iold;
BbFat16* fat;
int i;

inew = -1;
iold = -1;

__osBbFsFormatName(fold, old);
__osBbFsFormatName(fnew, new);

if (fold[0] == '\0' || fnew[0] == '\0') {
return BBFS_ERR_INVALID;
}

rv = __osBbFsGetAccess();
if (rv < 0) {
return rv;
}

fat = __osBbFat;

for (i = 0; i < BB_INODE16_NUM; i++) {
if (fat->inode[i].type != 0) {
if (bcmp(fnew, fat->inode[i].name, BB_INODE16_NAMELEN * sizeof(unsigned char)) == 0) {
inew = i;
} else if (bcmp(fold, fat->inode[i].name, BB_INODE16_NAMELEN * sizeof(unsigned char)) == 0) {
iold = i;
}
}
}

rv = BBFS_ERR_ENTRY;
if (iold != -1) {
if (inew != -1) {
u16 b;

b = fat->inode[inew].block;
while (b != 0xFFFF) {
u16 temp;

temp = BBFS_NEXT_BLOCK(fat, b);
BBFS_NEXT_BLOCK(fat, b) = 0;
b = temp;
}
bzero(&fat->inode[inew], 0x14);
}

bcopy(fnew, fat->inode[iold].name, BB_INODE16_NAMELEN * sizeof(unsigned char));
rv = __osBbFsSync(FALSE);
}

__osBbFsRelAccess();
return rv;
}
Loading

0 comments on commit ade805e

Please sign in to comment.