Support for multiple volumes, filesystem detection (currently FAT)
This commit is contained in:
parent
d0a5eb4c6f
commit
e688617286
77
file.c
77
file.c
@ -1,78 +1,113 @@
|
||||
#include "file.h"
|
||||
#include "fs.h"
|
||||
|
||||
#define MAXFS (0x20000/sizeof(filesystem))
|
||||
filesystem (*const FilesystemTable)[MAXFS] = (filesystem (* const)[MAXFS])0x240000;
|
||||
|
||||
// TODO Replace with something better
|
||||
extern uint8_t ActiveFsId;
|
||||
|
||||
// Sets adjusted_path to the path without filesystem info,
|
||||
// returns the filesystem calculated
|
||||
uint8_t GetFsFromPath(char *path, char **adjusted_path) {
|
||||
// On active filsystem
|
||||
if (*path == '/') {
|
||||
*adjusted_path = path;
|
||||
return GetActiveFilesystemId();
|
||||
}
|
||||
// Read the filesystem ID
|
||||
uint8_t id = 0;
|
||||
char *tmp_path = path;
|
||||
// Find first /
|
||||
for (;*tmp_path != '/';tmp_path++);
|
||||
*adjusted_path = tmp_path;
|
||||
// Read octal num
|
||||
tmp_path--;
|
||||
for (uint8_t bit_off = 0; tmp_path >= path; tmp_path--, bit_off+=3) {
|
||||
// Outside of octal range, error
|
||||
if (*tmp_path < '0' || *tmp_path > '8') return 0;
|
||||
id += (*tmp_path - '0') << bit_off;
|
||||
|
||||
}
|
||||
// Return filesystem
|
||||
return id;
|
||||
}
|
||||
|
||||
// Returns 0 on success, non-zero error code on error. Fills provided struct FILE
|
||||
int file_open(FILE *file, char *path, char mode) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
return fs->ops.file_open(fs->fs_data, file, path, mode);
|
||||
char *adj_path;
|
||||
uint8_t fsid = GetFsFromPath(path, &adj_path);
|
||||
filesystem *fs = GetFilesystem(fsid);
|
||||
int err = fs->ops.file_open(fs->fs_data, file, adj_path, mode);
|
||||
file->filesystem_id = fsid;
|
||||
return err;
|
||||
}
|
||||
|
||||
// Returns 0 on success, non-zero error code on error.
|
||||
int file_seek(FILE *file, uint32_t offset) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
filesystem *fs = GetFilesystem(file->filesystem_id);
|
||||
return fs->ops.file_seek(fs->fs_data, file, offset);
|
||||
}
|
||||
|
||||
// Returns 0 on error, bytes read on success.
|
||||
int file_read(FILE *file, uint8_t *dest, uint32_t len) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
filesystem *fs = GetFilesystem(file->filesystem_id);
|
||||
return fs->ops.file_read(fs->fs_data, file, dest, len);
|
||||
}
|
||||
|
||||
// Returns 0 on error, bytes written on success.
|
||||
int file_write(FILE *file, uint8_t *src, uint32_t len) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
filesystem *fs = GetFilesystem(file->filesystem_id);
|
||||
return fs->ops.file_write(fs->fs_data, file, src, len);
|
||||
}
|
||||
|
||||
void file_close(FILE *file) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
filesystem *fs = GetFilesystem(file->filesystem_id);
|
||||
return fs->ops.file_close(fs->fs_data, file);
|
||||
}
|
||||
|
||||
// Returns 0 on success, non-zero error code on error. Fills provided struct DIR
|
||||
int dir_open(DIR *dir, char *path) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
return fs->ops.dir_open(fs->fs_data, dir, path);
|
||||
char *adj_path;
|
||||
uint8_t fsid = GetFsFromPath(path, &adj_path);
|
||||
filesystem *fs = GetFilesystem(fsid);
|
||||
int err = fs->ops.dir_open(fs->fs_data, dir, adj_path);
|
||||
dir->filesystem_id = fsid;
|
||||
return err;
|
||||
}
|
||||
|
||||
// Return 0 on success, non-zero error code on error. Fills provided struct dirent.
|
||||
int dir_nextentry(DIR *dir, dirent *ent) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
filesystem *fs = GetFilesystem(dir->filesystem_id);
|
||||
return fs->ops.dir_nextentry(fs->fs_data, dir, ent);
|
||||
}
|
||||
|
||||
void dir_close(DIR *dir) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
filesystem *fs = GetFilesystem(dir->filesystem_id);
|
||||
return fs->ops.dir_close(fs->fs_data, dir);
|
||||
}
|
||||
|
||||
// Returns 0 on success, non-zero error code on error. Fills provided struct dirent.
|
||||
int path_getinfo(char *path, dirent *ent) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
return fs->ops.path_getinfo(fs->fs_data, path, ent);
|
||||
char *adj_path;
|
||||
filesystem *fs = GetFilesystem(GetFsFromPath(path, &adj_path));
|
||||
return fs->ops.path_getinfo(fs->fs_data, adj_path, ent);
|
||||
}
|
||||
|
||||
// Returns 0 on success, non-zero error code on error.
|
||||
int path_mkdir(char *path) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
return fs->ops.path_mkdir(fs->fs_data, path);
|
||||
char *adj_path;
|
||||
filesystem *fs = GetFilesystem(GetFsFromPath(path, &adj_path));
|
||||
return fs->ops.path_mkdir(fs->fs_data, adj_path);
|
||||
}
|
||||
|
||||
// Returns 0 on success, non-zero error code on error.
|
||||
int path_rmdir(char *path) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
return fs->ops.path_rmdir(fs->fs_data, path);
|
||||
char *adj_path;
|
||||
filesystem *fs = GetFilesystem(GetFsFromPath(path, &adj_path));
|
||||
return fs->ops.path_rmdir(fs->fs_data, adj_path);
|
||||
}
|
||||
|
||||
// Returns 0 on success, non-zero error code on error.
|
||||
int path_rmfile(char *path) {
|
||||
filesystem *fs = &(*FilesystemTable)[0];
|
||||
return fs->ops.path_rmfile(fs->fs_data, path);
|
||||
char *adj_path;
|
||||
filesystem *fs = GetFilesystem(GetFsFromPath(path, &adj_path));
|
||||
return fs->ops.path_rmfile(fs->fs_data, adj_path);
|
||||
}
|
||||
|
126
fs.c
126
fs.c
@ -1,15 +1,16 @@
|
||||
#include "fs.h"
|
||||
#include "disk.h"
|
||||
|
||||
struct FsType {
|
||||
uint32_t type_id;
|
||||
int (*init_func)(filesystem *, char);
|
||||
int (*init_func)(filesystem *, uint32_t);
|
||||
// Not yet decided
|
||||
char (*detect_func)();
|
||||
char (*detect_func)(uint32_t);
|
||||
};
|
||||
|
||||
// TODO Get these dynamically somehow
|
||||
int InitDosFs(filesystem *fs, char partition);
|
||||
char DetectDosPart();
|
||||
int InitDosFs(filesystem *fs, uint32_t start_sector);
|
||||
char DetectDosPart(uint32_t start_sector);
|
||||
|
||||
struct FsType SupportedFilesystems[] = {
|
||||
{
|
||||
@ -19,18 +20,111 @@ struct FsType SupportedFilesystems[] = {
|
||||
}
|
||||
};
|
||||
|
||||
#define MAXFS (0x20000/sizeof(filesystem))
|
||||
filesystem (*const ActiveFilesystems)[MAXFS] = (filesystem (* const)[MAXFS])0x240000;
|
||||
#define MAXFS 255
|
||||
filesystem *ActiveFilesystems = (filesystem *)0x240000;
|
||||
|
||||
// TODO Replace with something better
|
||||
uint8_t ActiveFsId;
|
||||
uint8_t ActiveFsIdx;
|
||||
|
||||
// TODO Make functions and just use those instead
|
||||
int MakeSystemVolume(uint8_t sysPartition) {
|
||||
filesystem *sys = &(*ActiveFilesystems)[0];
|
||||
SupportedFilesystems[0].init_func(sys, sysPartition);
|
||||
sys->type = SupportedFilesystems[0].type_id;
|
||||
sys->id = 0;
|
||||
ActiveFsId = 0;
|
||||
return 0;
|
||||
filesystem *GetFilesystem(uint8_t idx) {
|
||||
if (idx >= MAXFS) return 0;
|
||||
filesystem *fs = &ActiveFilesystems[idx];
|
||||
return fs->type != 0 ? fs : 0;
|
||||
}
|
||||
|
||||
filesystem *GetActiveFilesystem() {
|
||||
return &ActiveFilesystems[ActiveFsIdx];
|
||||
}
|
||||
uint8_t GetActiveFilesystemId() {
|
||||
return ActiveFsIdx;
|
||||
}
|
||||
|
||||
filesystem *SetActiveFilesystem(uint8_t idx) {
|
||||
if (idx >= MAXFS) return 0;
|
||||
filesystem *fs = &ActiveFilesystems[idx];
|
||||
if (fs->type == 0) return 0;
|
||||
ActiveFsIdx = idx;
|
||||
return fs;
|
||||
}
|
||||
|
||||
void ActiveFilesystemBitmap(char *bitmap) {
|
||||
for (int i = 0; i < 256; i++)
|
||||
bitmap[i] = ActiveFilesystems[i].type != 0;
|
||||
}
|
||||
|
||||
struct PartTableEntry_t {
|
||||
uint8_t attr;
|
||||
uint8_t start_chs0;
|
||||
uint8_t start_chs1;
|
||||
uint8_t start_chs2;
|
||||
uint8_t type;
|
||||
uint8_t end_chs0;
|
||||
uint8_t end_chs1;
|
||||
uint8_t end_chs2;
|
||||
uint32_t start_lba;
|
||||
uint32_t num_sectors;
|
||||
};
|
||||
typedef struct MBR_t {
|
||||
char boot_code[0x1B8];
|
||||
uint32_t signature;
|
||||
uint16_t reserved;
|
||||
struct PartTableEntry_t partTable[4];
|
||||
uint16_t boot_sig;
|
||||
} __attribute__((__packed__)) MBR_t;
|
||||
|
||||
// TODO Just check for this
|
||||
uint8_t BootPartition;
|
||||
uint8_t NextAvailableFilesystem;
|
||||
|
||||
MBR_t SysMbr;
|
||||
|
||||
void MakeMBRPartitions() {
|
||||
// Get MBR
|
||||
MBR_t *mbr = &SysMbr;
|
||||
Disk_ReadSector(0, (uint8_t*)mbr, 0, 1);
|
||||
|
||||
// Scan partitions
|
||||
for (int p = 0; p < 4; p++) {
|
||||
if (p == BootPartition) continue;
|
||||
if (mbr->partTable[p].type == 0) continue;
|
||||
uint32_t partStart = mbr->partTable[p].start_lba;
|
||||
if (partStart == 0) continue;
|
||||
// Scan supported filesystems
|
||||
filesystem *sys = &ActiveFilesystems[NextAvailableFilesystem];
|
||||
for (int i = 0; i < sizeof(SupportedFilesystems)/sizeof(struct FsType); i++) {
|
||||
if (!SupportedFilesystems[i].detect_func(partStart)) continue;
|
||||
SupportedFilesystems[i].init_func(sys, partStart);
|
||||
sys->type = SupportedFilesystems[i].type_id;
|
||||
ActiveFsIdx = NextAvailableFilesystem;
|
||||
NextAvailableFilesystem++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MakeSystemVolume(uint8_t bootPartition) {
|
||||
// Clear out filesystem area
|
||||
for (int i = 0; i < (sizeof(filesystem)*MAXFS)/sizeof(uint32_t);i++)
|
||||
((uint32_t*)ActiveFilesystems)[i] = 0;
|
||||
|
||||
BootPartition = bootPartition;
|
||||
NextAvailableFilesystem = 1;
|
||||
// Get MBR
|
||||
MBR_t *mbr = &SysMbr;
|
||||
Disk_ReadSector(0, (uint8_t*)mbr, 0, 1);
|
||||
// Get boot partition sector
|
||||
uint32_t sys_sector = mbr->partTable[bootPartition].start_lba;
|
||||
|
||||
// Scan supported filesystems
|
||||
filesystem *sys = &ActiveFilesystems[0];
|
||||
for (int i = 0; i < sizeof(SupportedFilesystems)/sizeof(struct FsType); i++) {
|
||||
asm volatile("xchg %bx,%bx");
|
||||
if (!SupportedFilesystems[i].detect_func(sys_sector)) continue;
|
||||
SupportedFilesystems[i].init_func(sys, sys_sector);
|
||||
sys->type = SupportedFilesystems[i].type_id;
|
||||
ActiveFsIdx = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Init Failed
|
||||
return -1;
|
||||
}
|
||||
|
12
fs.h
12
fs.h
@ -3,9 +3,7 @@
|
||||
#include "file_s.h"
|
||||
|
||||
typedef struct filesystem {
|
||||
uint8_t id;
|
||||
uint8_t resv0;
|
||||
uint16_t resv1;
|
||||
uint32_t resv0;
|
||||
uint32_t type;
|
||||
struct fs_operations {
|
||||
int (*file_open)(uint8_t *, FILE *, char *, char);
|
||||
@ -24,5 +22,11 @@ typedef struct filesystem {
|
||||
} ops;
|
||||
uint8_t labellen;
|
||||
char label[255];
|
||||
uint8_t fs_data[512-4-4-44-256];
|
||||
uint8_t fs_data[2048-4-4-44-256];
|
||||
} __attribute__((packed)) filesystem;
|
||||
|
||||
filesystem *GetFilesystem(uint8_t idx);
|
||||
filesystem *GetActiveFilesystem();
|
||||
uint8_t GetActiveFilesystemId();
|
||||
filesystem *SetActiveFilesystem(uint8_t idx);
|
||||
void ActiveFilesystemBitmap(char *bitmap);
|
||||
|
67
fs_dos.c
67
fs_dos.c
@ -2,6 +2,10 @@
|
||||
#include "fs.h"
|
||||
#include "dosfs/dosfs.h"
|
||||
|
||||
char *strncpy(char *restrict d, const char *restrict s, uintptr_t n);
|
||||
int strcmp(const char *l, const char *r);
|
||||
void *memcpy(void *restrict dest, const void *restrict src, uintptr_t n);
|
||||
|
||||
// Implementations for DOSFS
|
||||
|
||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
|
||||
@ -40,6 +44,18 @@ int file83ToPath(uint8_t *src, char *path) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uintptr_t stripToDir(char *path) {
|
||||
int i = 0;
|
||||
// find end of string
|
||||
for (;path[i];i++);
|
||||
// find last /
|
||||
for (;path[i] != '/' && i >= 0;i--);
|
||||
// path[i] == '/'
|
||||
// set next to end, return split location
|
||||
path[i+1] = 0;
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
int dos_file_open(uint8_t *dat, FILE *f, char *path, char mode) {
|
||||
fsdat *fs = (fsdat *)dat;
|
||||
uint8_t *scratch = (uint8_t *)0x20000;
|
||||
@ -92,7 +108,6 @@ int dos_dir_open(uint8_t *dat, DIR *d, char *path) {
|
||||
|
||||
int dos_dir_nextentry(uint8_t *dat, DIR *d, dirent *ent) {
|
||||
fsdat *fs = (fsdat *)dat;
|
||||
uint8_t *scratch = (uint8_t *)0x20000;
|
||||
DIRENT de;
|
||||
for (;;) {
|
||||
uint32_t code = DFS_GetNext(&fs->vi, (DIRINFO *)d->bytes, &de);
|
||||
@ -121,10 +136,35 @@ int dos_dir_nextentry(uint8_t *dat, DIR *d, dirent *ent) {
|
||||
// DOSFS doesn't have anything to clean up
|
||||
void dos_dir_close(uint8_t *dat, DIR *d) { return; }
|
||||
|
||||
// TODO Unimplemented
|
||||
// TODO Make this less expensive -> Use DOSFS directly?
|
||||
int dos_path_getinfo(uint8_t *dat, char *path, dirent *d) {
|
||||
fsdat *fs = (fsdat *)dat;
|
||||
uint8_t *scratch = (uint8_t *)0x20000;
|
||||
|
||||
// Get directory path is in
|
||||
uint8_t tmppath[MAX_PATH];
|
||||
strncpy((char*)tmppath,path,MAX_PATH);
|
||||
tmppath[MAX_PATH-1]=0;
|
||||
uintptr_t nameidx = stripToDir((char*)tmppath);
|
||||
char *name = &path[nameidx];
|
||||
|
||||
// Open directory
|
||||
DIR dir;
|
||||
dos_dir_open(dat, &dir, (char*)tmppath);
|
||||
|
||||
dirent de;
|
||||
// Enumerate info
|
||||
for (;dos_dir_nextentry(dat, &dir, &de) == 0;) {
|
||||
// Check if correct entry
|
||||
if (strcmp(de.name, name) == 0) {
|
||||
// Copy to caller dirent
|
||||
for (int i = 0; i < sizeof(dirent); i++)
|
||||
((uint8_t*)d)[i] = ((uint8_t*)&de)[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Did not find or error
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -152,20 +192,27 @@ int dos_path_rmfile(uint8_t *dat, char *path) {
|
||||
// DOSFS doesn't have anything to clean up
|
||||
void dos_endfs(uint8_t *dat) { return; }
|
||||
|
||||
// Not yet decided
|
||||
char DetectDosPart() {
|
||||
// Try to detect if partition is a valid DOS partition
|
||||
char DetectDosPart(uint32_t start_sector) {
|
||||
// Read sector
|
||||
//uint8_t *scratch = (uint8_t *)0x20000;
|
||||
//Disk_ReadSector(0, scratch, start_sector, 1);
|
||||
//// Check for start bytes EBXX90
|
||||
//if (((*(uint32_t*)&scratch[0]) & 0x00FF00FF) != 0x9000EB) return 0;
|
||||
//// Check for bytes per sector == 512 (We don't support other values anyway)
|
||||
//if (*(uint16_t*)&scratch[0xB] != 512) return 0;
|
||||
|
||||
// TODO Check more, so we *know* it's FAT
|
||||
|
||||
// We're probably FAT
|
||||
return 1;
|
||||
}
|
||||
|
||||
int InitDosFs(filesystem *fs, char partition) {
|
||||
int InitDosFs(filesystem *fs, uint32_t start_sector) {
|
||||
uint8_t *diskReadBuf = (uint8_t *)0x20000;
|
||||
uint8_t pactive, ptype;
|
||||
uint32_t pstart, psize;
|
||||
pstart = DFS_GetPtnStart(0, diskReadBuf, partition, &pactive, &ptype, &psize);
|
||||
if (pstart == -1) return -1;
|
||||
|
||||
VOLINFO *vi = (VOLINFO *)fs->fs_data;
|
||||
if (DFS_GetVolInfo(0, diskReadBuf, pstart, (VOLINFO *)fs->fs_data)) {
|
||||
if (DFS_GetVolInfo(0, diskReadBuf, start_sector, (VOLINFO *)fs->fs_data)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
20
hexedit.c
20
hexedit.c
@ -12,30 +12,28 @@ uint32_t blockLenMap[TOTALBLOCKS] __attribute__((section(".hexbss")));;
|
||||
// so that it can be expanded without telling C how much
|
||||
// it actually needs
|
||||
uint8_t writeStoreBase[BLOCKSIZE] __attribute__((section(".hexlatebss")));
|
||||
void HexEditor(char *path, dirent *de) {
|
||||
void HexEditor(char *path) {
|
||||
uint32_t err;
|
||||
uint16_t *vga_text = (uint16_t *)0xb8000;
|
||||
uint32_t screenSize = 80*25;
|
||||
uint8_t *scratch = (uint8_t *)0x20000;
|
||||
uint8_t (*writeStore)[BLOCKSIZE] = &writeStoreBase;
|
||||
uint32_t filelen = de->size;
|
||||
for (int i = 0; i < TOTALBLOCKS; i++)
|
||||
writtenMap[i] = 0;
|
||||
uint8_t *screenBuff = *writeStore;
|
||||
// First two blocks are screen buffer
|
||||
uint32_t nextFreeBlock = 2;
|
||||
|
||||
FILE file;
|
||||
vga_text = (uint16_t *)0xb8000;
|
||||
for (int i = 0; i < 80*50; i++)
|
||||
vga_text[i] = 0x0f00;
|
||||
err = file_open(&file, path, OPENREAD|OPENWRITE);
|
||||
dirent de;
|
||||
err = path_getinfo(path, &de);
|
||||
if (err) {
|
||||
vga_text += printStr("Open Error: ", vga_text);
|
||||
printDword(err, vga_text);
|
||||
vga_text += printStr("Error getting file info.", vga_text);
|
||||
kbd_wait();
|
||||
return;
|
||||
}
|
||||
uint32_t filelen = de.size;
|
||||
if (filelen == 0) {
|
||||
vga_text += printStr("File ", vga_text);
|
||||
vga_text += printStr((char*)path, vga_text);
|
||||
@ -50,6 +48,14 @@ void HexEditor(char *path, dirent *de) {
|
||||
kbd_wait();
|
||||
return;
|
||||
}
|
||||
FILE file;
|
||||
err = file_open(&file, path, OPENREAD|OPENWRITE);
|
||||
if (err) {
|
||||
vga_text += printStr("Open Error: ", vga_text);
|
||||
printDword(err, vga_text);
|
||||
kbd_wait();
|
||||
return;
|
||||
}
|
||||
uint32_t drawOffset = 0, lastDrawOffset = -1;
|
||||
char cont = 1;
|
||||
uint32_t byteCount = 16*24, lastByteCount = 0;
|
||||
|
39
kernel.c
39
kernel.c
@ -1,6 +1,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "fs.h"
|
||||
#include "print.h"
|
||||
#include "interrupt.h"
|
||||
#include "kbd.h"
|
||||
@ -281,13 +282,17 @@ void ScancodeTest() {
|
||||
}
|
||||
extern void create_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
|
||||
uint16_t FileSelectScreen[80*25];
|
||||
char ValidFilesystems[256];
|
||||
void FileSelect() {
|
||||
ActiveFilesystemBitmap(ValidFilesystems);
|
||||
uint8_t currentFsId = 0;
|
||||
char current_path[80];
|
||||
uintptr_t current_path_end;
|
||||
for (int i = 0; i < sizeof(current_path); i++)
|
||||
current_path[i] = 0;
|
||||
current_path[0] = '/';
|
||||
current_path_end = 1;
|
||||
current_path[0] = '0';
|
||||
current_path[1] = '/';
|
||||
current_path_end = 2;
|
||||
fileCount = 5;
|
||||
uint16_t *vga_text = (uint16_t *)FileSelectScreen;
|
||||
int32_t fileHovered = 0;
|
||||
@ -305,6 +310,8 @@ void FileSelect() {
|
||||
vga += 80;
|
||||
printStr("O to open directory", vga);
|
||||
vga += 80;
|
||||
printStr("S to switch volume", vga);
|
||||
vga += 80;
|
||||
printStr("F4 to run tests", vga);
|
||||
}
|
||||
printStr(current_path, &vga_text[80*4 + 2]);
|
||||
@ -360,7 +367,7 @@ void FileSelect() {
|
||||
for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
|
||||
current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
|
||||
current_path[current_path_end + DirEntries[fileHovered].namelen] = 0;
|
||||
create_child(GetFreeStack(), (uintptr_t)ProgramLoadTest, 2, current_path, &DirEntries[fileHovered]);
|
||||
create_child(GetFreeStack(), (uintptr_t)ProgramLoadTest, 1, current_path);
|
||||
current_path[current_path_end] = 0;
|
||||
RestoreVGA();
|
||||
reload = 1;
|
||||
@ -370,7 +377,7 @@ void FileSelect() {
|
||||
for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
|
||||
current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
|
||||
current_path[current_path_end + DirEntries[fileHovered].namelen] = 0;
|
||||
create_child(GetFreeStack(), (uintptr_t)HexEditor, 2, current_path, &DirEntries[fileHovered]);
|
||||
create_child(GetFreeStack(), (uintptr_t)HexEditor, 1, current_path);
|
||||
current_path[current_path_end] = 0;
|
||||
RestoreVGA();
|
||||
reload = 1;
|
||||
@ -381,7 +388,7 @@ void FileSelect() {
|
||||
for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
|
||||
current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
|
||||
current_path[current_path_end + DirEntries[fileHovered].namelen] = 0;
|
||||
create_child(GetFreeStack(), (uintptr_t)TextViewTest, 2, current_path, &DirEntries[fileHovered]);
|
||||
create_child(GetFreeStack(), (uintptr_t)TextViewTest, 1, current_path);
|
||||
current_path[current_path_end] = 0;
|
||||
RestoreVGA();
|
||||
reload = 1;
|
||||
@ -419,6 +426,25 @@ void FileSelect() {
|
||||
fileOffset = 0;
|
||||
}
|
||||
break;
|
||||
case KEY_S:
|
||||
// Next filesystem TODO Support over 077 I'm so lazy right now
|
||||
for (currentFsId = (currentFsId + 1) % 64; !ValidFilesystems[currentFsId]; currentFsId = (currentFsId + 1) % 64);
|
||||
if (currentFsId < 8) {
|
||||
current_path[0] = '0' + currentFsId;
|
||||
current_path[1] = '/';
|
||||
current_path[2] = 0;
|
||||
current_path_end = 2;
|
||||
} else {
|
||||
current_path[0] = '0' + (currentFsId >> 3);
|
||||
current_path[1] = '0' + (currentFsId & 7);
|
||||
current_path[2] = '/';
|
||||
current_path[3] = 0;
|
||||
current_path_end = 3;
|
||||
}
|
||||
reload = 1;
|
||||
fileHovered = 0;
|
||||
fileOffset = 0;
|
||||
break;
|
||||
case KEY_F6:
|
||||
ScancodeTest();
|
||||
reload = 1;
|
||||
@ -430,6 +456,7 @@ void FileSelect() {
|
||||
}
|
||||
|
||||
int MakeSystemVolume(uint8_t sysPartition);
|
||||
void MakeMBRPartitions();
|
||||
void SystemRun(uint8_t sysPartition) {
|
||||
uint16_t *vga_text = (word *)0xb8000;
|
||||
RestoreVGA();
|
||||
@ -439,7 +466,6 @@ void SystemRun(uint8_t sysPartition) {
|
||||
|
||||
// Check for FAT partition
|
||||
{
|
||||
// TODO Check partitions beyond 0
|
||||
while (1) {
|
||||
create_child(GetFreeStack(), (uintptr_t)MakeSystemVolume, 1, sysPartition);
|
||||
if (!check_error_code()) break;
|
||||
@ -449,6 +475,7 @@ void SystemRun(uint8_t sysPartition) {
|
||||
vga_text += printStr("Press R to retry.", vga_text);
|
||||
for (;(get_scancode() & 0xff) != KEY_R;);
|
||||
}
|
||||
create_child(GetFreeStack(), (uintptr_t)MakeMBRPartitions, 0);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
19
progs.c
19
progs.c
@ -3,7 +3,7 @@
|
||||
|
||||
extern char _USERMODE, _USERMODE_END;
|
||||
extern uint32_t create_user_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
|
||||
void ProgramLoadTest(char *path, dirent *de) {
|
||||
void ProgramLoadTest(char *path) {
|
||||
uint16_t *vga_text = (uint16_t *)0xb8000;
|
||||
for (int i = 0; i < 80*25; i++)
|
||||
vga_text[i] = 0x0f00;
|
||||
@ -11,7 +11,13 @@ void ProgramLoadTest(char *path, dirent *de) {
|
||||
uint8_t *diskReadBuf = (uint8_t *)&_USERMODE;
|
||||
{
|
||||
uint32_t err;
|
||||
uint8_t *scratch = (uint8_t *)0x20000;
|
||||
dirent de;
|
||||
err = path_getinfo(path, &de);
|
||||
if (de.size > 0x300000 || err) {
|
||||
vga_text += printStr("File too large or error.", vga_text);
|
||||
kbd_wait();
|
||||
return;
|
||||
}
|
||||
FILE file;
|
||||
err = file_open(&file, path, OPENREAD);
|
||||
if (err) {
|
||||
@ -19,18 +25,13 @@ void ProgramLoadTest(char *path, dirent *de) {
|
||||
printDword(err, vga_text);
|
||||
return;
|
||||
}
|
||||
if (de->size > 0x300000) {
|
||||
vga_text += printStr("File too large.", vga_text);
|
||||
kbd_wait();
|
||||
return;
|
||||
}
|
||||
err = file_seek(&file, 0);
|
||||
if (err) {
|
||||
vga_text += printStr("Seek Error", vga_text);
|
||||
return;
|
||||
}
|
||||
err = file_read(&file, diskReadBuf, de->size);
|
||||
if (!err && de->size > 0) {
|
||||
successcount = err = file_read(&file, diskReadBuf, de.size);
|
||||
if (!err && de.size > 0) {
|
||||
vga_text += printStr("Read Error", vga_text);
|
||||
printDword(err, vga_text);
|
||||
return;
|
||||
|
6
progs.h
6
progs.h
@ -7,6 +7,6 @@
|
||||
#include "helper.h"
|
||||
#include "file.h"
|
||||
|
||||
void HexEditor(char *path, dirent *de);
|
||||
void TextViewTest(char *path, dirent *de);
|
||||
void ProgramLoadTest(char *path, dirent *de);
|
||||
void HexEditor(char *path);
|
||||
void TextViewTest(char *path);
|
||||
void ProgramLoadTest(char *path);
|
||||
|
13
textedit.c
13
textedit.c
@ -12,12 +12,19 @@ uint8_t editedBlocks[TOTALBLOCKS] __attribute__((section(".textbss")));;
|
||||
uint8_t fileBuffer[MAXFILESIZE]
|
||||
__attribute__((aligned(0x1000)))
|
||||
__attribute__((section(".textlatebss")));
|
||||
void TextViewTest(char *path, dirent *de) {
|
||||
void TextViewTest(char *path) {
|
||||
uint16_t *vga_text = (uint16_t *)0xb8000;
|
||||
uint32_t fileLen = de->size;
|
||||
uint32_t fileLen;
|
||||
{
|
||||
uint32_t err;
|
||||
uint8_t *scratch = (uint8_t *)0x20000;
|
||||
dirent de;
|
||||
err = path_getinfo(path, &de);
|
||||
if (err) {
|
||||
vga_text += printStr("Error getting file info.", vga_text);
|
||||
kbd_wait();
|
||||
return;
|
||||
}
|
||||
fileLen = de.size;
|
||||
FILE file;
|
||||
err = file_open(&file, path, OPENREAD);
|
||||
if (err) {
|
||||
|
Loading…
Reference in New Issue
Block a user