Support for multiple volumes, filesystem detection (currently FAT)
This commit is contained in:
		
							
								
								
									
										77
									
								
								file.c
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								file.c
									
									
									
									
									
								
							@@ -1,78 +1,113 @@
 | 
				
			|||||||
#include "file.h"
 | 
					#include "file.h"
 | 
				
			||||||
#include "fs.h"
 | 
					#include "fs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAXFS (0x20000/sizeof(filesystem))
 | 
					 | 
				
			||||||
filesystem (*const FilesystemTable)[MAXFS] = (filesystem (* const)[MAXFS])0x240000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO Replace with something better
 | 
					// TODO Replace with something better
 | 
				
			||||||
extern uint8_t ActiveFsId;
 | 
					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
 | 
					// Returns 0 on success, non-zero error code on error. Fills provided struct FILE
 | 
				
			||||||
int file_open(FILE *file, char *path, char mode) {
 | 
					int file_open(FILE *file, char *path, char mode) {
 | 
				
			||||||
	filesystem *fs = &(*FilesystemTable)[0];
 | 
					    char *adj_path;
 | 
				
			||||||
	return fs->ops.file_open(fs->fs_data, file, path, mode);
 | 
						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.
 | 
					// Returns 0 on success, non-zero error code on error.
 | 
				
			||||||
int file_seek(FILE *file, uint32_t offset) {
 | 
					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);
 | 
					    return fs->ops.file_seek(fs->fs_data, file, offset);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns 0 on error, bytes read on success.
 | 
					// Returns 0 on error, bytes read on success.
 | 
				
			||||||
int file_read(FILE *file, uint8_t *dest, uint32_t len) {
 | 
					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);
 | 
					    return fs->ops.file_read(fs->fs_data, file, dest, len);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns 0 on error, bytes written on success.
 | 
					// Returns 0 on error, bytes written on success.
 | 
				
			||||||
int file_write(FILE *file, uint8_t *src, uint32_t len) {
 | 
					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);
 | 
					    return fs->ops.file_write(fs->fs_data, file, src, len);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void file_close(FILE *file) {
 | 
					void file_close(FILE *file) {
 | 
				
			||||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
					    filesystem *fs = GetFilesystem(file->filesystem_id);
 | 
				
			||||||
    return fs->ops.file_close(fs->fs_data, file);
 | 
					    return fs->ops.file_close(fs->fs_data, file);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns 0 on success, non-zero error code on error. Fills provided struct DIR
 | 
					// Returns 0 on success, non-zero error code on error. Fills provided struct DIR
 | 
				
			||||||
int dir_open(DIR *dir, char *path) {
 | 
					int dir_open(DIR *dir, char *path) {
 | 
				
			||||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
					    char *adj_path;
 | 
				
			||||||
    return fs->ops.dir_open(fs->fs_data, dir, 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.
 | 
					// Return 0 on success, non-zero error code on error. Fills provided struct dirent.
 | 
				
			||||||
int dir_nextentry(DIR *dir, dirent *ent) {
 | 
					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);
 | 
					    return fs->ops.dir_nextentry(fs->fs_data, dir, ent);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dir_close(DIR *dir) {
 | 
					void dir_close(DIR *dir) {
 | 
				
			||||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
					    filesystem *fs = GetFilesystem(dir->filesystem_id);
 | 
				
			||||||
    return fs->ops.dir_close(fs->fs_data, dir);
 | 
					    return fs->ops.dir_close(fs->fs_data, dir);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns 0 on success, non-zero error code on error. Fills provided struct dirent.
 | 
					// Returns 0 on success, non-zero error code on error. Fills provided struct dirent.
 | 
				
			||||||
int path_getinfo(char *path, dirent *ent) {
 | 
					int path_getinfo(char *path, dirent *ent) {
 | 
				
			||||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
					    char *adj_path;
 | 
				
			||||||
    return fs->ops.path_getinfo(fs->fs_data, path, ent);
 | 
						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. 
 | 
					// Returns 0 on success, non-zero error code on error. 
 | 
				
			||||||
int path_mkdir(char *path) {
 | 
					int path_mkdir(char *path) {
 | 
				
			||||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
					    char *adj_path;
 | 
				
			||||||
    return fs->ops.path_mkdir(fs->fs_data, 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. 
 | 
					// Returns 0 on success, non-zero error code on error. 
 | 
				
			||||||
int path_rmdir(char *path) {
 | 
					int path_rmdir(char *path) {
 | 
				
			||||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
					    char *adj_path;
 | 
				
			||||||
    return fs->ops.path_rmdir(fs->fs_data, 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. 
 | 
					// Returns 0 on success, non-zero error code on error. 
 | 
				
			||||||
int path_rmfile(char *path) {
 | 
					int path_rmfile(char *path) {
 | 
				
			||||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
					    char *adj_path;
 | 
				
			||||||
    return fs->ops.path_rmfile(fs->fs_data, 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 "fs.h"
 | 
				
			||||||
 | 
					#include "disk.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FsType {
 | 
					struct FsType {
 | 
				
			||||||
	uint32_t type_id;
 | 
						uint32_t type_id;
 | 
				
			||||||
	int (*init_func)(filesystem *, char);
 | 
						int (*init_func)(filesystem *, uint32_t);
 | 
				
			||||||
	// Not yet decided
 | 
						// Not yet decided
 | 
				
			||||||
	char (*detect_func)();
 | 
						char (*detect_func)(uint32_t);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO Get these dynamically somehow
 | 
					// TODO Get these dynamically somehow
 | 
				
			||||||
int InitDosFs(filesystem *fs, char partition);
 | 
					int InitDosFs(filesystem *fs, uint32_t start_sector);
 | 
				
			||||||
char DetectDosPart();
 | 
					char DetectDosPart(uint32_t start_sector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FsType SupportedFilesystems[] = {
 | 
					struct FsType SupportedFilesystems[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -19,18 +20,111 @@ struct FsType SupportedFilesystems[] = {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAXFS (0x20000/sizeof(filesystem))
 | 
					#define MAXFS 255
 | 
				
			||||||
filesystem (*const ActiveFilesystems)[MAXFS] = (filesystem (* const)[MAXFS])0x240000;
 | 
					filesystem *ActiveFilesystems = (filesystem *)0x240000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO Replace with something better
 | 
					uint8_t ActiveFsIdx;
 | 
				
			||||||
uint8_t ActiveFsId;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO Make functions and just use those instead
 | 
					filesystem *GetFilesystem(uint8_t idx) {
 | 
				
			||||||
int MakeSystemVolume(uint8_t sysPartition) {
 | 
						if (idx >= MAXFS) return 0;
 | 
				
			||||||
	filesystem *sys = &(*ActiveFilesystems)[0];
 | 
						filesystem *fs = &ActiveFilesystems[idx];
 | 
				
			||||||
	SupportedFilesystems[0].init_func(sys, sysPartition);
 | 
						return fs->type != 0 ? fs : 0;
 | 
				
			||||||
	sys->type = SupportedFilesystems[0].type_id;
 | 
					}
 | 
				
			||||||
	sys->id = 0;
 | 
					
 | 
				
			||||||
	ActiveFsId = 0;
 | 
					filesystem *GetActiveFilesystem() {
 | 
				
			||||||
	return 0;
 | 
						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"
 | 
					#include "file_s.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct filesystem {
 | 
					typedef struct filesystem {
 | 
				
			||||||
    uint8_t id;
 | 
					    uint32_t resv0;
 | 
				
			||||||
    uint8_t resv0;
 | 
					 | 
				
			||||||
    uint16_t resv1;
 | 
					 | 
				
			||||||
    uint32_t type;
 | 
					    uint32_t type;
 | 
				
			||||||
    struct fs_operations {
 | 
					    struct fs_operations {
 | 
				
			||||||
        int (*file_open)(uint8_t *, FILE *, char *, char);
 | 
					        int (*file_open)(uint8_t *, FILE *, char *, char);
 | 
				
			||||||
@@ -24,5 +22,11 @@ typedef struct filesystem {
 | 
				
			|||||||
    } ops;
 | 
					    } ops;
 | 
				
			||||||
    uint8_t labellen;
 | 
					    uint8_t labellen;
 | 
				
			||||||
    char label[255];
 | 
					    char label[255];
 | 
				
			||||||
    uint8_t fs_data[512-4-4-44-256];
 | 
					    uint8_t fs_data[2048-4-4-44-256];
 | 
				
			||||||
} __attribute__((packed)) filesystem;
 | 
					} __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 "fs.h"
 | 
				
			||||||
#include "dosfs/dosfs.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
 | 
					// Implementations for DOSFS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
					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;
 | 
					    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) {
 | 
					int dos_file_open(uint8_t *dat, FILE *f, char *path, char mode) {
 | 
				
			||||||
    fsdat *fs = (fsdat *)dat;
 | 
					    fsdat *fs = (fsdat *)dat;
 | 
				
			||||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
					    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) {
 | 
					int dos_dir_nextentry(uint8_t *dat, DIR *d, dirent *ent) {
 | 
				
			||||||
    fsdat *fs = (fsdat *)dat;
 | 
					    fsdat *fs = (fsdat *)dat;
 | 
				
			||||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
					 | 
				
			||||||
    DIRENT de;
 | 
					    DIRENT de;
 | 
				
			||||||
    for (;;) {
 | 
					    for (;;) {
 | 
				
			||||||
        uint32_t code = DFS_GetNext(&fs->vi, (DIRINFO *)d->bytes, &de);
 | 
					        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
 | 
					// DOSFS doesn't have anything to clean up
 | 
				
			||||||
void dos_dir_close(uint8_t *dat, DIR *d) { return; }
 | 
					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) {
 | 
					int dos_path_getinfo(uint8_t *dat, char *path, dirent *d) {
 | 
				
			||||||
    fsdat *fs = (fsdat *)dat;
 | 
					    fsdat *fs = (fsdat *)dat;
 | 
				
			||||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
					    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;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,20 +192,27 @@ int dos_path_rmfile(uint8_t *dat, char *path) {
 | 
				
			|||||||
// DOSFS doesn't have anything to clean up
 | 
					// DOSFS doesn't have anything to clean up
 | 
				
			||||||
void dos_endfs(uint8_t *dat) { return; }
 | 
					void dos_endfs(uint8_t *dat) { return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Not yet decided
 | 
					// Try to detect if partition is a valid DOS partition
 | 
				
			||||||
char DetectDosPart() {
 | 
					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;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int InitDosFs(filesystem *fs, char partition) {
 | 
					int InitDosFs(filesystem *fs, uint32_t start_sector) {
 | 
				
			||||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
					    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;
 | 
					    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;
 | 
					        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
 | 
					// so that it can be expanded without telling C how much
 | 
				
			||||||
// it actually needs
 | 
					// it actually needs
 | 
				
			||||||
uint8_t writeStoreBase[BLOCKSIZE] __attribute__((section(".hexlatebss")));
 | 
					uint8_t writeStoreBase[BLOCKSIZE] __attribute__((section(".hexlatebss")));
 | 
				
			||||||
void HexEditor(char *path, dirent *de) {
 | 
					void HexEditor(char *path) {
 | 
				
			||||||
    uint32_t err;
 | 
					    uint32_t err;
 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    uint32_t screenSize = 80*25;
 | 
					    uint32_t screenSize = 80*25;
 | 
				
			||||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
					 | 
				
			||||||
    uint8_t (*writeStore)[BLOCKSIZE] = &writeStoreBase;
 | 
					    uint8_t (*writeStore)[BLOCKSIZE] = &writeStoreBase;
 | 
				
			||||||
    uint32_t filelen = de->size;
 | 
					 | 
				
			||||||
    for (int i = 0; i < TOTALBLOCKS; i++)
 | 
					    for (int i = 0; i < TOTALBLOCKS; i++)
 | 
				
			||||||
        writtenMap[i] = 0;
 | 
					        writtenMap[i] = 0;
 | 
				
			||||||
    uint8_t *screenBuff = *writeStore;
 | 
					    uint8_t *screenBuff = *writeStore;
 | 
				
			||||||
    // First two blocks are screen buffer
 | 
					    // First two blocks are screen buffer
 | 
				
			||||||
    uint32_t nextFreeBlock = 2;
 | 
					    uint32_t nextFreeBlock = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FILE file;
 | 
					 | 
				
			||||||
    vga_text = (uint16_t *)0xb8000;
 | 
					    vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    for (int i = 0; i < 80*50; i++)
 | 
					    for (int i = 0; i < 80*50; i++)
 | 
				
			||||||
        vga_text[i] = 0x0f00;
 | 
					        vga_text[i] = 0x0f00;
 | 
				
			||||||
    err = file_open(&file, path, OPENREAD|OPENWRITE);
 | 
					    dirent de;
 | 
				
			||||||
 | 
					    err = path_getinfo(path, &de);
 | 
				
			||||||
    if (err) {
 | 
					    if (err) {
 | 
				
			||||||
        vga_text += printStr("Open Error: ", vga_text);
 | 
					        vga_text += printStr("Error getting file info.", vga_text);
 | 
				
			||||||
        printDword(err, vga_text);
 | 
					 | 
				
			||||||
        kbd_wait();
 | 
					        kbd_wait();
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    uint32_t filelen = de.size;
 | 
				
			||||||
    if (filelen == 0) {
 | 
					    if (filelen == 0) {
 | 
				
			||||||
        vga_text += printStr("File ", vga_text);
 | 
					        vga_text += printStr("File ", vga_text);
 | 
				
			||||||
        vga_text += printStr((char*)path, vga_text);
 | 
					        vga_text += printStr((char*)path, vga_text);
 | 
				
			||||||
@@ -50,6 +48,14 @@ void HexEditor(char *path, dirent *de) {
 | 
				
			|||||||
        kbd_wait();
 | 
					        kbd_wait();
 | 
				
			||||||
        return;
 | 
					        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;
 | 
					    uint32_t drawOffset = 0, lastDrawOffset = -1;
 | 
				
			||||||
    char cont = 1;
 | 
					    char cont = 1;
 | 
				
			||||||
    uint32_t byteCount = 16*24, lastByteCount = 0;
 | 
					    uint32_t byteCount = 16*24, lastByteCount = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										39
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								kernel.c
									
									
									
									
									
								
							@@ -1,6 +1,7 @@
 | 
				
			|||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "file.h"
 | 
					#include "file.h"
 | 
				
			||||||
 | 
					#include "fs.h"
 | 
				
			||||||
#include "print.h"
 | 
					#include "print.h"
 | 
				
			||||||
#include "interrupt.h"
 | 
					#include "interrupt.h"
 | 
				
			||||||
#include "kbd.h"
 | 
					#include "kbd.h"
 | 
				
			||||||
@@ -281,13 +282,17 @@ void ScancodeTest() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
extern void create_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
 | 
					extern void create_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
 | 
				
			||||||
uint16_t FileSelectScreen[80*25];
 | 
					uint16_t FileSelectScreen[80*25];
 | 
				
			||||||
 | 
					char ValidFilesystems[256];
 | 
				
			||||||
void FileSelect() {
 | 
					void FileSelect() {
 | 
				
			||||||
 | 
					    ActiveFilesystemBitmap(ValidFilesystems);
 | 
				
			||||||
 | 
					    uint8_t currentFsId = 0;
 | 
				
			||||||
    char current_path[80];
 | 
					    char current_path[80];
 | 
				
			||||||
    uintptr_t current_path_end;
 | 
					    uintptr_t current_path_end;
 | 
				
			||||||
    for (int i = 0; i < sizeof(current_path); i++)
 | 
					    for (int i = 0; i < sizeof(current_path); i++)
 | 
				
			||||||
        current_path[i] = 0;
 | 
					        current_path[i] = 0;
 | 
				
			||||||
    current_path[0] = '/';
 | 
					    current_path[0] = '0';
 | 
				
			||||||
    current_path_end = 1;
 | 
					    current_path[1] = '/';
 | 
				
			||||||
 | 
					    current_path_end = 2;
 | 
				
			||||||
    fileCount = 5;
 | 
					    fileCount = 5;
 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)FileSelectScreen;
 | 
					    uint16_t *vga_text = (uint16_t *)FileSelectScreen;
 | 
				
			||||||
    int32_t fileHovered = 0;
 | 
					    int32_t fileHovered = 0;
 | 
				
			||||||
@@ -305,6 +310,8 @@ void FileSelect() {
 | 
				
			|||||||
            vga += 80;
 | 
					            vga += 80;
 | 
				
			||||||
            printStr("O to open directory", vga);
 | 
					            printStr("O to open directory", vga);
 | 
				
			||||||
            vga += 80;
 | 
					            vga += 80;
 | 
				
			||||||
 | 
					            printStr("S to switch volume", vga);
 | 
				
			||||||
 | 
					            vga += 80;
 | 
				
			||||||
            printStr("F4 to run tests", vga);
 | 
					            printStr("F4 to run tests", vga);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        printStr(current_path, &vga_text[80*4 + 2]);
 | 
					        printStr(current_path, &vga_text[80*4 + 2]);
 | 
				
			||||||
@@ -360,7 +367,7 @@ void FileSelect() {
 | 
				
			|||||||
                for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
 | 
					                for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
 | 
				
			||||||
                    current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
 | 
					                    current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
 | 
				
			||||||
                current_path[current_path_end + DirEntries[fileHovered].namelen] = 0;
 | 
					                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;
 | 
					                current_path[current_path_end] = 0;
 | 
				
			||||||
                RestoreVGA();
 | 
					                RestoreVGA();
 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
@@ -370,7 +377,7 @@ void FileSelect() {
 | 
				
			|||||||
                for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
 | 
					                for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
 | 
				
			||||||
                    current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
 | 
					                    current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
 | 
				
			||||||
                current_path[current_path_end + DirEntries[fileHovered].namelen] = 0;
 | 
					                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;
 | 
					                current_path[current_path_end] = 0;
 | 
				
			||||||
                RestoreVGA();
 | 
					                RestoreVGA();
 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
@@ -381,7 +388,7 @@ void FileSelect() {
 | 
				
			|||||||
                for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
 | 
					                for (int i = 0; i < DirEntries[fileHovered].namelen; i++)
 | 
				
			||||||
                    current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
 | 
					                    current_path[current_path_end + i] = DirEntries[fileHovered].name[i];
 | 
				
			||||||
                current_path[current_path_end + DirEntries[fileHovered].namelen] = 0;
 | 
					                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;
 | 
					                current_path[current_path_end] = 0;
 | 
				
			||||||
                RestoreVGA();
 | 
					                RestoreVGA();
 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
@@ -419,6 +426,25 @@ void FileSelect() {
 | 
				
			|||||||
                    fileOffset = 0;
 | 
					                    fileOffset = 0;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                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:
 | 
					            case KEY_F6:
 | 
				
			||||||
                ScancodeTest();
 | 
					                ScancodeTest();
 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
@@ -430,6 +456,7 @@ void FileSelect() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int MakeSystemVolume(uint8_t sysPartition);
 | 
					int MakeSystemVolume(uint8_t sysPartition);
 | 
				
			||||||
 | 
					void MakeMBRPartitions();
 | 
				
			||||||
void SystemRun(uint8_t sysPartition) {
 | 
					void SystemRun(uint8_t sysPartition) {
 | 
				
			||||||
    uint16_t *vga_text = (word *)0xb8000;
 | 
					    uint16_t *vga_text = (word *)0xb8000;
 | 
				
			||||||
    RestoreVGA();
 | 
					    RestoreVGA();
 | 
				
			||||||
@@ -439,7 +466,6 @@ void SystemRun(uint8_t sysPartition) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Check for FAT partition
 | 
					    // Check for FAT partition
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // TODO Check partitions beyond 0
 | 
					 | 
				
			||||||
        while (1) {
 | 
					        while (1) {
 | 
				
			||||||
            create_child(GetFreeStack(), (uintptr_t)MakeSystemVolume, 1, sysPartition);
 | 
					            create_child(GetFreeStack(), (uintptr_t)MakeSystemVolume, 1, sysPartition);
 | 
				
			||||||
            if (!check_error_code()) break;
 | 
					            if (!check_error_code()) break;
 | 
				
			||||||
@@ -449,6 +475,7 @@ void SystemRun(uint8_t sysPartition) {
 | 
				
			|||||||
            vga_text += printStr("Press R to retry.", vga_text);
 | 
					            vga_text += printStr("Press R to retry.", vga_text);
 | 
				
			||||||
            for (;(get_scancode() & 0xff) != KEY_R;);
 | 
					            for (;(get_scancode() & 0xff) != KEY_R;);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        create_child(GetFreeStack(), (uintptr_t)MakeMBRPartitions, 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (;;) {
 | 
					    for (;;) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								progs.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								progs.c
									
									
									
									
									
								
							@@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern char _USERMODE, _USERMODE_END;
 | 
					extern char _USERMODE, _USERMODE_END;
 | 
				
			||||||
extern uint32_t create_user_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
 | 
					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;
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    for (int i = 0; i < 80*25; i++)
 | 
					    for (int i = 0; i < 80*25; i++)
 | 
				
			||||||
        vga_text[i] = 0x0f00;
 | 
					        vga_text[i] = 0x0f00;
 | 
				
			||||||
@@ -11,7 +11,13 @@ void ProgramLoadTest(char *path, dirent *de) {
 | 
				
			|||||||
    uint8_t *diskReadBuf = (uint8_t *)&_USERMODE;
 | 
					    uint8_t *diskReadBuf = (uint8_t *)&_USERMODE;
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint32_t err;
 | 
					        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;
 | 
					        FILE file;
 | 
				
			||||||
        err = file_open(&file, path, OPENREAD);
 | 
					        err = file_open(&file, path, OPENREAD);
 | 
				
			||||||
        if (err) {
 | 
					        if (err) {
 | 
				
			||||||
@@ -19,18 +25,13 @@ void ProgramLoadTest(char *path, dirent *de) {
 | 
				
			|||||||
            printDword(err, vga_text);
 | 
					            printDword(err, vga_text);
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (de->size > 0x300000) {
 | 
					 | 
				
			||||||
            vga_text += printStr("File too large.", vga_text);
 | 
					 | 
				
			||||||
            kbd_wait();
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        err = file_seek(&file, 0);
 | 
					        err = file_seek(&file, 0);
 | 
				
			||||||
        if (err) {
 | 
					        if (err) {
 | 
				
			||||||
            vga_text += printStr("Seek Error", vga_text);
 | 
					            vga_text += printStr("Seek Error", vga_text);
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        err = file_read(&file, diskReadBuf, de->size);
 | 
					        successcount = err = file_read(&file, diskReadBuf, de.size);
 | 
				
			||||||
        if (!err && de->size > 0) {
 | 
					        if (!err && de.size > 0) {
 | 
				
			||||||
            vga_text += printStr("Read Error", vga_text);
 | 
					            vga_text += printStr("Read Error", vga_text);
 | 
				
			||||||
            printDword(err, vga_text);
 | 
					            printDword(err, vga_text);
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								progs.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								progs.h
									
									
									
									
									
								
							@@ -7,6 +7,6 @@
 | 
				
			|||||||
#include "helper.h"
 | 
					#include "helper.h"
 | 
				
			||||||
#include "file.h"
 | 
					#include "file.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HexEditor(char *path, dirent *de);
 | 
					void HexEditor(char *path);
 | 
				
			||||||
void TextViewTest(char *path, dirent *de);
 | 
					void TextViewTest(char *path);
 | 
				
			||||||
void ProgramLoadTest(char *path, dirent *de);
 | 
					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]
 | 
					uint8_t fileBuffer[MAXFILESIZE]
 | 
				
			||||||
    __attribute__((aligned(0x1000)))
 | 
					    __attribute__((aligned(0x1000)))
 | 
				
			||||||
    __attribute__((section(".textlatebss")));
 | 
					    __attribute__((section(".textlatebss")));
 | 
				
			||||||
void TextViewTest(char *path, dirent *de) {
 | 
					void TextViewTest(char *path) {
 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    uint32_t fileLen = de->size;
 | 
					    uint32_t fileLen;
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint32_t err;
 | 
					        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;
 | 
					        FILE file;
 | 
				
			||||||
        err = file_open(&file, path, OPENREAD);
 | 
					        err = file_open(&file, path, OPENREAD);
 | 
				
			||||||
        if (err) {
 | 
					        if (err) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user