Filesystem now uses an abstract representation
This commit is contained in:
		
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,5 +1,6 @@
 | 
			
		||||
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o\
 | 
			
		||||
		  paging.o fault.o tests.o kbd.o helper.o progs.o disk.o hexedit.o textedit.o
 | 
			
		||||
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o gdt.o\
 | 
			
		||||
		  paging.o fault.o tests.o kbd.o helper.o disk.o file.o fs.o dosfs/dosfs.o fs_dos.o\
 | 
			
		||||
		  progs.o hexedit.o textedit.o
 | 
			
		||||
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding\
 | 
			
		||||
		 -march=i686 -fno-stack-protector -Wno-int-conversion -nostdlib -c
 | 
			
		||||
LFLAGS = -Wl,--gc-sections -Wl,--print-gc-sections -m32 -nostartfiles -nostdlib
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								disk.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								disk.c
									
									
									
									
									
								
							@@ -1,11 +1,11 @@
 | 
			
		||||
#include "disk.h"
 | 
			
		||||
#include "v86defs.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "dosfs/dosfs.h"
 | 
			
		||||
#include "stdint.h"
 | 
			
		||||
 | 
			
		||||
extern void *memcpy(void *restrict dest, const void *restrict src, uintptr_t n);
 | 
			
		||||
 | 
			
		||||
#define SECTOR_SIZE 512
 | 
			
		||||
#define DISKCACHEBLOCKSIZE 0x1000 // 512 * 4
 | 
			
		||||
#define DISKCACHESECTORMASK 7
 | 
			
		||||
#define DISKCACHESECTORSIZE 8
 | 
			
		||||
@@ -104,7 +104,7 @@ void InitDisk() {
 | 
			
		||||
	Disk_SetupCHS();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
uint32_t Disk_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
	uint8_t *cache = FindInCache(sector);
 | 
			
		||||
	if (cache) {
 | 
			
		||||
		memcpy(buffer, cache, count * SECTOR_SIZE);
 | 
			
		||||
@@ -158,7 +158,7 @@ uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t
 | 
			
		||||
		memcpy(buffer, v86buf, count * SECTOR_SIZE);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
uint32_t Disk_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
	// NOTE If the buffer provided is outside the 0x20000-0x2FE00 range,
 | 
			
		||||
	// the function will use copy that buffer into the Virtual 8086 disk range
 | 
			
		||||
	uint8_t *v86buf = buffer;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								disk.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								disk.h
									
									
									
									
									
								
							@@ -1 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
void InitDisk();
 | 
			
		||||
 | 
			
		||||
uint32_t Disk_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count);
 | 
			
		||||
uint32_t Disk_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								file.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								file.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
// 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error.
 | 
			
		||||
int file_seek(FILE *file, uint32_t offset) {
 | 
			
		||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
			
		||||
    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];
 | 
			
		||||
    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];
 | 
			
		||||
    return fs->ops.file_write(fs->fs_data, file, src, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void file_close(FILE *file) {
 | 
			
		||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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];
 | 
			
		||||
    return fs->ops.dir_nextentry(fs->fs_data, dir, ent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dir_close(DIR *dir) {
 | 
			
		||||
    filesystem *fs = &(*FilesystemTable)[0];
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								file.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								file.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "file_s.h"
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error. Fills provided struct FILE
 | 
			
		||||
int file_open(FILE *file, char *path, char mode);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error.
 | 
			
		||||
int file_seek(FILE *file, uint32_t offset);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on error, bytes read on success.
 | 
			
		||||
int file_read(FILE *file, uint8_t *dest, uint32_t len);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on error, bytes written on success.
 | 
			
		||||
int file_write(FILE *file, uint8_t *src, uint32_t len);
 | 
			
		||||
 | 
			
		||||
void file_close(FILE *file);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error. Fills provided struct DIR
 | 
			
		||||
int dir_open(DIR *dir, char *path);
 | 
			
		||||
 | 
			
		||||
// Return 0 on success, non-zero error code on error. Fills provided struct dirent.
 | 
			
		||||
int dir_nextentry(DIR *dir, dirent *ent);
 | 
			
		||||
 | 
			
		||||
void dir_close(DIR *dir);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error. Fills provided struct dirent.
 | 
			
		||||
int path_getinfo(char *path, dirent *ent);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error. 
 | 
			
		||||
int path_mkdir(char *path);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error. 
 | 
			
		||||
int path_rmdir(char *path);
 | 
			
		||||
 | 
			
		||||
// Returns 0 on success, non-zero error code on error. 
 | 
			
		||||
int path_rmfile(char *path);
 | 
			
		||||
							
								
								
									
										31
									
								
								file_s.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								file_s.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
typedef struct FILE {
 | 
			
		||||
    uint8_t filesystem_id;
 | 
			
		||||
    uint8_t bytes[0x3F];
 | 
			
		||||
} __attribute__((__packed__)) FILE;
 | 
			
		||||
 | 
			
		||||
typedef struct DIR {
 | 
			
		||||
    uint8_t filesystem_id;
 | 
			
		||||
    uint8_t bytes[0x3F];
 | 
			
		||||
} __attribute__((__packed__)) DIR;
 | 
			
		||||
 | 
			
		||||
typedef enum filetype {
 | 
			
		||||
    FT_UNKNOWN,
 | 
			
		||||
    FT_REG,
 | 
			
		||||
    FT_DIR
 | 
			
		||||
} filetype;
 | 
			
		||||
 | 
			
		||||
typedef struct dirent {
 | 
			
		||||
    filetype type;
 | 
			
		||||
    uint32_t size;
 | 
			
		||||
    uint32_t last_modified;
 | 
			
		||||
    uint32_t last_accessed;
 | 
			
		||||
    uint32_t created;
 | 
			
		||||
    uint8_t namelen;
 | 
			
		||||
    char name[255];
 | 
			
		||||
} dirent;
 | 
			
		||||
 | 
			
		||||
#define OPENREAD 1
 | 
			
		||||
#define OPENWRITE 2
 | 
			
		||||
							
								
								
									
										36
									
								
								fs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								fs.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
 | 
			
		||||
struct FsType {
 | 
			
		||||
	uint32_t type_id;
 | 
			
		||||
	int (*init_func)(filesystem *, char);
 | 
			
		||||
	// Not yet decided
 | 
			
		||||
	char (*detect_func)();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// TODO Get these dynamically somehow
 | 
			
		||||
int InitDosFs(filesystem *fs, char partition);
 | 
			
		||||
char DetectDosPart();
 | 
			
		||||
 | 
			
		||||
struct FsType SupportedFilesystems[] = {
 | 
			
		||||
	{
 | 
			
		||||
		.type_id =  0xD05,
 | 
			
		||||
		.init_func = InitDosFs,
 | 
			
		||||
		.detect_func = DetectDosPart
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define MAXFS (0x20000/sizeof(filesystem))
 | 
			
		||||
filesystem (*const ActiveFilesystems)[MAXFS] = (filesystem (* const)[MAXFS])0x240000;
 | 
			
		||||
 | 
			
		||||
// TODO Replace with something better
 | 
			
		||||
uint8_t ActiveFsId;
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								fs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								fs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include "file_s.h"
 | 
			
		||||
 | 
			
		||||
typedef struct filesystem {
 | 
			
		||||
    uint8_t id;
 | 
			
		||||
    uint8_t resv0;
 | 
			
		||||
    uint16_t resv1;
 | 
			
		||||
    uint32_t type;
 | 
			
		||||
    struct fs_operations {
 | 
			
		||||
        int (*file_open)(uint8_t *, FILE *, char *, char);
 | 
			
		||||
        int (*file_seek)(uint8_t *, FILE *, uint32_t);
 | 
			
		||||
        int (*file_read)(uint8_t *, FILE *, uint8_t *, uint32_t);
 | 
			
		||||
        int (*file_write)(uint8_t *, FILE *, uint8_t *, uint32_t);
 | 
			
		||||
        void (*file_close)(uint8_t *, FILE *);
 | 
			
		||||
        int (*dir_open)(uint8_t *, DIR *, char *);
 | 
			
		||||
        int (*dir_nextentry)(uint8_t *, DIR *, dirent *);
 | 
			
		||||
        void (*dir_close)(uint8_t *, DIR *);
 | 
			
		||||
        int (*path_getinfo)(uint8_t *, char *, dirent *);
 | 
			
		||||
        int (*path_mkdir)(uint8_t *, char *);
 | 
			
		||||
        int (*path_rmdir)(uint8_t *, char *);
 | 
			
		||||
        int (*path_rmfile)(uint8_t *, char *);
 | 
			
		||||
        void (*endfs)(uint8_t *);
 | 
			
		||||
    } ops;
 | 
			
		||||
    uint8_t labellen;
 | 
			
		||||
    char label[255];
 | 
			
		||||
    uint8_t fs_data[512-4-4-44-256];
 | 
			
		||||
} __attribute__((packed)) filesystem;
 | 
			
		||||
							
								
								
									
										192
									
								
								fs_dos.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								fs_dos.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
#include "disk.h"
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
#include "dosfs/dosfs.h"
 | 
			
		||||
 | 
			
		||||
// Implementations for DOSFS
 | 
			
		||||
 | 
			
		||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
    return Disk_ReadSector(unit, buffer, sector, count);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
    return Disk_WriteSector(unit, buffer, sector, count);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// System Implementations
 | 
			
		||||
 | 
			
		||||
typedef struct fsdat {
 | 
			
		||||
	VOLINFO vi;
 | 
			
		||||
} fsdat;
 | 
			
		||||
 | 
			
		||||
int file83ToPath(uint8_t *src, char *path) {
 | 
			
		||||
    uint8_t tmp, trailingSpace;
 | 
			
		||||
    for (trailingSpace=0, tmp = 0; tmp < 8 && src[tmp]; tmp++) {
 | 
			
		||||
        path[tmp] = src[tmp];
 | 
			
		||||
        if (src[tmp] == ' ') trailingSpace++;
 | 
			
		||||
        else trailingSpace = 0;
 | 
			
		||||
    }
 | 
			
		||||
    tmp -= trailingSpace;
 | 
			
		||||
    path[tmp++] = '.';
 | 
			
		||||
    trailingSpace = 0;
 | 
			
		||||
    for (int i = 8; i < 11 && src[i]; i++, tmp++) {
 | 
			
		||||
        path[tmp] = src[i];
 | 
			
		||||
        if (src[i] == ' ') trailingSpace++;
 | 
			
		||||
        else trailingSpace = 0;
 | 
			
		||||
    }
 | 
			
		||||
    tmp -= trailingSpace;
 | 
			
		||||
    if (trailingSpace == 3) tmp--;
 | 
			
		||||
    path[tmp] = 0;
 | 
			
		||||
    return tmp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dos_file_open(uint8_t *dat, FILE *f, char *path, char mode) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    uint8_t dfs_mode =
 | 
			
		||||
        (mode & OPENREAD ? DFS_READ : 0) |
 | 
			
		||||
        (mode & OPENWRITE ? DFS_WRITE : 0);
 | 
			
		||||
    return DFS_OpenFile(&fs->vi, (uint8_t *)path, dfs_mode, scratch, (FILEINFO *)f->bytes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dos_file_seek(uint8_t *dat, FILE *f, uint32_t offset) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    DFS_Seek((FILEINFO *)f->bytes, offset, scratch);
 | 
			
		||||
    if (((FILEINFO *)f->bytes)->pointer != offset) return -1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dos_file_read(uint8_t *dat, FILE *f, uint8_t *dest, uint32_t len) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    uint32_t successcount;
 | 
			
		||||
    uint32_t err = DFS_ReadFile((FILEINFO *)f->bytes, scratch, dest, &successcount, len);
 | 
			
		||||
    // Error
 | 
			
		||||
    if (err != 0 && err != DFS_EOF)
 | 
			
		||||
        return 0;
 | 
			
		||||
    // Success or EOF
 | 
			
		||||
    return successcount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dos_file_write(uint8_t *dat, FILE *f, uint8_t *src, uint32_t len) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    uint32_t successcount;
 | 
			
		||||
    uint32_t err = DFS_WriteFile((FILEINFO *)f->bytes, scratch, src, &successcount, len);
 | 
			
		||||
    // Error
 | 
			
		||||
    if (err != 0) return 0;
 | 
			
		||||
    // Success
 | 
			
		||||
    return successcount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DOSFS doesn't have anything to clean up
 | 
			
		||||
void dos_file_close(uint8_t *dat, FILE *f) { return; }
 | 
			
		||||
 | 
			
		||||
int dos_dir_open(uint8_t *dat, DIR *d, char *path) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    ((DIRINFO *)d->bytes)->scratch = scratch;
 | 
			
		||||
    return DFS_OpenDir(&fs->vi, (uint8_t *)path, (DIRINFO *)d->bytes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
        if (code == DFS_EOF) return 1;
 | 
			
		||||
        if (code != DFS_OK) return -1;
 | 
			
		||||
        // Deleted file, continue to next entry
 | 
			
		||||
        if (de.name[0] == 0) continue;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    // Copy info
 | 
			
		||||
    ent->type = de.attr & ATTR_DIRECTORY ? FT_DIR : FT_REG;
 | 
			
		||||
    ent->size = (uint32_t)de.filesize_0 +
 | 
			
		||||
                ((uint32_t)de.filesize_1 << 8) +
 | 
			
		||||
                ((uint32_t)de.filesize_2 << 16) +
 | 
			
		||||
                ((uint32_t)de.filesize_3 << 24);
 | 
			
		||||
    // Haven't decided format on these yet
 | 
			
		||||
    ent->last_modified = 0;
 | 
			
		||||
    ent->last_accessed = 0;
 | 
			
		||||
    ent->created = 0;
 | 
			
		||||
    
 | 
			
		||||
    ent->namelen = file83ToPath(de.name, ent->name);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DOSFS doesn't have anything to clean up
 | 
			
		||||
void dos_dir_close(uint8_t *dat, DIR *d) { return; }
 | 
			
		||||
 | 
			
		||||
// TODO Unimplemented
 | 
			
		||||
int dos_path_getinfo(uint8_t *dat, char *path, dirent *d) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO Unimplemented
 | 
			
		||||
int dos_path_mkdir(uint8_t *dat, char *path) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO Unimplemented
 | 
			
		||||
int dos_path_rmdir(uint8_t *dat, char *path) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO Unimplemented
 | 
			
		||||
int dos_path_rmfile(uint8_t *dat, char *path) {
 | 
			
		||||
    fsdat *fs = (fsdat *)dat;
 | 
			
		||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DOSFS doesn't have anything to clean up
 | 
			
		||||
void dos_endfs(uint8_t *dat) { return; }
 | 
			
		||||
 | 
			
		||||
// Not yet decided
 | 
			
		||||
char DetectDosPart() {
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int InitDosFs(filesystem *fs, char partition) {
 | 
			
		||||
    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)) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; vi->label[i] && i < sizeof(vi->label); i++)
 | 
			
		||||
        fs->label[i] = vi->label[i];
 | 
			
		||||
    fs->labellen = i;
 | 
			
		||||
 | 
			
		||||
	fs->ops.file_open = dos_file_open;
 | 
			
		||||
    fs->ops.file_seek = dos_file_seek;
 | 
			
		||||
    fs->ops.file_read = dos_file_read;
 | 
			
		||||
    fs->ops.file_write = dos_file_write;
 | 
			
		||||
    fs->ops.file_close = dos_file_close;
 | 
			
		||||
    fs->ops.dir_open = dos_dir_open;
 | 
			
		||||
    fs->ops.dir_nextentry = dos_dir_nextentry;
 | 
			
		||||
    fs->ops.dir_close = dos_dir_close;
 | 
			
		||||
    fs->ops.path_getinfo = dos_path_getinfo;
 | 
			
		||||
    fs->ops.path_mkdir = dos_path_mkdir;
 | 
			
		||||
    fs->ops.path_rmdir = dos_path_rmdir;
 | 
			
		||||
    fs->ops.path_rmfile = dos_path_rmfile;
 | 
			
		||||
    fs->ops.endfs = dos_endfs;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								helper.c
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								helper.c
									
									
									
									
									
								
							@@ -48,55 +48,6 @@ void SetCursorDisabled() {
 | 
			
		||||
    V8086Int(0x10, ®s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This should DEFINITELY be an argument
 | 
			
		||||
uint8_t SystemPartition = 0;
 | 
			
		||||
uint32_t OpenVol(VOLINFO *vi) {
 | 
			
		||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
			
		||||
    uint8_t pactive, ptype;
 | 
			
		||||
    uint32_t pstart, psize;
 | 
			
		||||
    pstart = DFS_GetPtnStart(0, diskReadBuf, SystemPartition, &pactive, &ptype, &psize);
 | 
			
		||||
    if (pstart == -1) return -1;
 | 
			
		||||
    return DFS_GetVolInfo(0, diskReadBuf, pstart, vi);
 | 
			
		||||
}
 | 
			
		||||
uint32_t OpenDir(uint8_t *path, VOLINFO *vi, DIRINFO *di) {
 | 
			
		||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
			
		||||
    di->scratch = diskReadBuf;
 | 
			
		||||
    return DFS_OpenDir(vi, path, di);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void File83ToPath(char *src, char *path) {
 | 
			
		||||
    uint8_t tmp, trailingSpace;
 | 
			
		||||
    for (trailingSpace=0, tmp = 0; tmp < 8 && src[tmp]; tmp++) {
 | 
			
		||||
        path[tmp] = src[tmp];
 | 
			
		||||
        if (src[tmp] == ' ') trailingSpace++;
 | 
			
		||||
        else trailingSpace = 0;
 | 
			
		||||
    }
 | 
			
		||||
    tmp -= trailingSpace;
 | 
			
		||||
    path[tmp++] = '.';
 | 
			
		||||
    trailingSpace = 0;
 | 
			
		||||
    for (int i = 8; i < 11 && src[i]; i++, tmp++) {
 | 
			
		||||
        path[tmp] = src[i];
 | 
			
		||||
        if (src[i] == ' ') trailingSpace++;
 | 
			
		||||
        else trailingSpace = 0;
 | 
			
		||||
    }
 | 
			
		||||
    tmp -= trailingSpace;
 | 
			
		||||
    if (trailingSpace == 3) tmp--;
 | 
			
		||||
    path[tmp] = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GetFileList(DIRENT *entries, int32_t *entCount, int32_t maxEntries, VOLINFO *vi, DIRINFO *di) {
 | 
			
		||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
			
		||||
    DIRENT de;
 | 
			
		||||
    int32_t fileCount = 0;
 | 
			
		||||
    while (!DFS_GetNext(vi, di, &de)) {
 | 
			
		||||
        if (de.name[0]) {
 | 
			
		||||
            uint8_t *d = (uint8_t*)&entries[fileCount];
 | 
			
		||||
            uint8_t *s = (uint8_t*)&de;
 | 
			
		||||
            for (int i = 0; i < sizeof(DIRENT); i++)
 | 
			
		||||
                d[i] = s[i];
 | 
			
		||||
            fileCount++;
 | 
			
		||||
        }
 | 
			
		||||
        if (fileCount >= maxEntries) break;
 | 
			
		||||
    }
 | 
			
		||||
    *entCount = fileCount;
 | 
			
		||||
void GetFileList(DIR *dir, dirent *entries, int32_t *entCount, int32_t maxEntries) {
 | 
			
		||||
    for ((*entCount) = 0; *entCount < maxEntries && !dir_nextentry(dir, &entries[*entCount]); (*entCount)++);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								helper.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								helper.h
									
									
									
									
									
								
							@@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#include "interrupt.h"
 | 
			
		||||
#include "v86defs.h"
 | 
			
		||||
#include "dosfs/dosfs.h"
 | 
			
		||||
#include "file.h"
 | 
			
		||||
 | 
			
		||||
void V8086Int(uint8_t interrupt, union V86Regs_t *regs);
 | 
			
		||||
 | 
			
		||||
@@ -14,7 +14,4 @@ void SetCursorDisabled();
 | 
			
		||||
uint16_t *nextLine(uint16_t *p, uint16_t *b);
 | 
			
		||||
void trimPath(char *path, char *buff, uint32_t maxLen);
 | 
			
		||||
 | 
			
		||||
uint32_t OpenVol(VOLINFO *vi);
 | 
			
		||||
uint32_t OpenDir(uint8_t *path, VOLINFO *vi, DIRINFO *di);
 | 
			
		||||
void File83ToPath(char *src, char *path);
 | 
			
		||||
void GetFileList(DIRENT *entries, int32_t *entCount, int32_t maxEntries, VOLINFO *vi, DIRINFO *di);
 | 
			
		||||
void GetFileList(DIR *dir, dirent *entries, int32_t *entCount, int32_t maxEntries);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								hexedit.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								hexedit.c
									
									
									
									
									
								
							@@ -1,3 +1,4 @@
 | 
			
		||||
#include "file.h"
 | 
			
		||||
#include "progs.h"
 | 
			
		||||
 | 
			
		||||
#define BLOCKSIZE 0x10000 // 64K
 | 
			
		||||
@@ -11,37 +12,38 @@ 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(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
void HexEditor(char *path, dirent *de) {
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    FILEINFO fi;
 | 
			
		||||
    FILE file;
 | 
			
		||||
    vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    for (int i = 0; i < 80*50; i++)
 | 
			
		||||
        vga_text[i] = 0x0f00;
 | 
			
		||||
    err = DFS_OpenFile(vi, path, DFS_READ | DFS_WRITE, scratch, &fi);
 | 
			
		||||
    err = file_open(&file, path, OPENREAD|OPENWRITE);
 | 
			
		||||
    if (err) {
 | 
			
		||||
        vga_text += printStr("Open Error: ", vga_text);
 | 
			
		||||
        printDword(err, vga_text);
 | 
			
		||||
        kbd_wait();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (fi.filelen == 0) {
 | 
			
		||||
    if (filelen == 0) {
 | 
			
		||||
        vga_text += printStr("File ", vga_text);
 | 
			
		||||
        vga_text += printStr((char*)path, vga_text);
 | 
			
		||||
        vga_text += printStr(" has no data.", vga_text);
 | 
			
		||||
        kbd_wait();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (fi.filelen > MAXFILESIZE) {
 | 
			
		||||
    if (filelen > MAXFILESIZE) {
 | 
			
		||||
        vga_text += printStr("File ", vga_text);
 | 
			
		||||
        vga_text += printStr((char*)path, vga_text);
 | 
			
		||||
        vga_text += printStr(" is too large (> 2GB).", vga_text);
 | 
			
		||||
@@ -70,13 +72,13 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
        // things will be caught by sanity checks.
 | 
			
		||||
        // Scroll Back
 | 
			
		||||
        if (cursorScreenOff < 0) {
 | 
			
		||||
            if (drawOffset - 16 < fi.filelen)
 | 
			
		||||
            if (drawOffset - 16 < filelen)
 | 
			
		||||
                drawOffset -= 16;
 | 
			
		||||
            cursorScreenOff += 16;
 | 
			
		||||
        }
 | 
			
		||||
        // Scroll Forward
 | 
			
		||||
        if (cursorScreenOff >= byteCount) {
 | 
			
		||||
            if (drawOffset + 16 < fi.filelen)
 | 
			
		||||
            if (drawOffset + 16 < filelen)
 | 
			
		||||
                drawOffset += 16;
 | 
			
		||||
            cursorScreenOff -= 16;
 | 
			
		||||
        }
 | 
			
		||||
@@ -84,8 +86,8 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
        // Sanity checks
 | 
			
		||||
        if (cursorScreenOff >= byteCount)
 | 
			
		||||
            cursorScreenOff = byteCount - 1;
 | 
			
		||||
        if (cursorScreenOff + drawOffset >= fi.filelen)
 | 
			
		||||
            cursorScreenOff = fi.filelen - drawOffset - 1;
 | 
			
		||||
        if (cursorScreenOff + drawOffset >= filelen)
 | 
			
		||||
            cursorScreenOff = filelen - drawOffset - 1;
 | 
			
		||||
        if (cursorScreenOff < 0) cursorScreenOff = 0;
 | 
			
		||||
 | 
			
		||||
        if (cursorNibble != lastCursorNibble)
 | 
			
		||||
@@ -185,16 +187,14 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
            } else {
 | 
			
		||||
                uint32_t blockOffset = drawOffset & BLOCKMASK;
 | 
			
		||||
                vga_text = &((uint16_t*)0xb8000)[80];
 | 
			
		||||
                DFS_Seek(&fi, blockOffset, scratch);
 | 
			
		||||
                if (fi.pointer != blockOffset) {
 | 
			
		||||
                if (file_seek(&file, blockOffset)) {
 | 
			
		||||
                    vga_text += printStr("Seek Error", vga_text);
 | 
			
		||||
                    kbd_wait();
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                err = DFS_ReadFile(&fi, scratch, screenBuff, &currBuffLength, BLOCKSIZE);
 | 
			
		||||
                if (err && err != DFS_EOF) {
 | 
			
		||||
                    vga_text += printStr("Read Error: ", vga_text);
 | 
			
		||||
                    printDword(err, vga_text);
 | 
			
		||||
                currBuffLength = file_read(&file, screenBuff, BLOCKSIZE);
 | 
			
		||||
                if (!currBuffLength && blockOffset != filelen) {
 | 
			
		||||
                    vga_text += printStr("Read Error", vga_text);
 | 
			
		||||
                    kbd_wait();
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
@@ -222,16 +222,14 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
                } else {
 | 
			
		||||
                    uint32_t blockOffset = (drawOffset & BLOCKMASK) + BLOCKSIZE;
 | 
			
		||||
                    vga_text = &((uint16_t*)0xb8000)[80];
 | 
			
		||||
                    DFS_Seek(&fi, blockOffset, scratch);
 | 
			
		||||
                    if (fi.pointer != blockOffset) {
 | 
			
		||||
                    if (file_seek(&file, blockOffset)) {
 | 
			
		||||
                        vga_text += printStr("Seek Error", vga_text);
 | 
			
		||||
                        kbd_wait();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    err = DFS_ReadFile(&fi, scratch, &screenBuff[BLOCKSIZE], &nextBuffLength, BLOCKSIZE);
 | 
			
		||||
                    if (err && err != DFS_EOF) {
 | 
			
		||||
                        vga_text += printStr("Read Error: ", vga_text);
 | 
			
		||||
                        printDword(err, vga_text);
 | 
			
		||||
                    nextBuffLength = file_read(&file, &screenBuff[BLOCKSIZE], BLOCKSIZE);
 | 
			
		||||
                    if (!nextBuffLength && blockOffset != filelen) {
 | 
			
		||||
                        vga_text += printStr("Read Error", vga_text);
 | 
			
		||||
                        kbd_wait();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -301,12 +299,12 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
        switch (key & 0xff) {
 | 
			
		||||
            case KEY_DOWN:
 | 
			
		||||
                // Stay in file
 | 
			
		||||
                if ((cursorScreenOff + 16 + drawOffset) < fi.filelen)
 | 
			
		||||
                if ((cursorScreenOff + 16 + drawOffset) < filelen)
 | 
			
		||||
                    cursorScreenOff += 16;
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_UP:
 | 
			
		||||
                // Stay in file
 | 
			
		||||
                if ((uint32_t)(cursorScreenOff - 16 + drawOffset) < fi.filelen)
 | 
			
		||||
                if ((uint32_t)(cursorScreenOff - 16 + drawOffset) < filelen)
 | 
			
		||||
                    cursorScreenOff -= 16;
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_LEFT:
 | 
			
		||||
@@ -316,7 +314,7 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
                    cursorNibble = 0;
 | 
			
		||||
                    cursorScreenOff |= 0xF;
 | 
			
		||||
                // Stay in file
 | 
			
		||||
                } else if ((cursorScreenOff - 1 + drawOffset) < fi.filelen) {
 | 
			
		||||
                } else if ((cursorScreenOff - 1 + drawOffset) < filelen) {
 | 
			
		||||
                    cursorScreenOff--;
 | 
			
		||||
                    if (cursorNibble == 1) cursorNibble = 0;
 | 
			
		||||
                }
 | 
			
		||||
@@ -328,19 +326,19 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
                    cursorNibble = 2;
 | 
			
		||||
                    cursorScreenOff &= ~0xF;
 | 
			
		||||
                // Stay in file
 | 
			
		||||
                } else if ((cursorScreenOff + 1 + drawOffset) < fi.filelen) {
 | 
			
		||||
                } else if ((cursorScreenOff + 1 + drawOffset) < filelen) {
 | 
			
		||||
                    cursorScreenOff++;
 | 
			
		||||
                    if (cursorNibble == 0) cursorNibble = 1;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_PGDOWN:
 | 
			
		||||
                if (drawOffset + byteCount < fi.filelen)
 | 
			
		||||
                if (drawOffset + byteCount < filelen)
 | 
			
		||||
                    drawOffset += byteCount;
 | 
			
		||||
                else if ((fi.filelen / byteCount) * byteCount > drawOffset)
 | 
			
		||||
                    drawOffset = (fi.filelen / byteCount) * byteCount;
 | 
			
		||||
                else if ((filelen / byteCount) * byteCount > drawOffset)
 | 
			
		||||
                    drawOffset = (filelen / byteCount) * byteCount;
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_PGUP:
 | 
			
		||||
                if (drawOffset - byteCount < fi.filelen)
 | 
			
		||||
                if (drawOffset - byteCount < filelen)
 | 
			
		||||
                    drawOffset -= byteCount;
 | 
			
		||||
                else drawOffset = 0;
 | 
			
		||||
                break;
 | 
			
		||||
@@ -359,8 +357,8 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
                drawOffset = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_F4: // end of file
 | 
			
		||||
                if ((fi.filelen / byteCount) * byteCount > drawOffset)
 | 
			
		||||
                    drawOffset = (fi.filelen / byteCount) * byteCount;
 | 
			
		||||
                if ((filelen / byteCount) * byteCount > drawOffset)
 | 
			
		||||
                    drawOffset = (filelen / byteCount) * byteCount;
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_F6: // TODO write file
 | 
			
		||||
                break;
 | 
			
		||||
@@ -425,23 +423,21 @@ void HexEditor(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
    for(;(key & 0xff) != KEY_N && (key & 0xff) != KEY_Y;key = get_scancode());
 | 
			
		||||
    if ((key & 0xff) != KEY_Y) return;
 | 
			
		||||
    // Write changes
 | 
			
		||||
    for (int i = 0; i < TOTALBLOCKS && (i << BLOCKSHIFT) < fi.filelen; i++) {
 | 
			
		||||
    for (int i = 0; i < TOTALBLOCKS && (i << BLOCKSHIFT) < filelen; i++) {
 | 
			
		||||
        // No change in current block
 | 
			
		||||
        uint16_t blockIdx = writtenMap[i];
 | 
			
		||||
        uint32_t blockLen = blockLenMap[i];
 | 
			
		||||
        if (!blockIdx) continue;
 | 
			
		||||
        // Write block to file
 | 
			
		||||
        uint32_t successcount;
 | 
			
		||||
        uint32_t blockOff = i << BLOCKSHIFT;
 | 
			
		||||
        DFS_Seek(&fi, blockOff, scratch);
 | 
			
		||||
        if (fi.pointer != blockOff) {
 | 
			
		||||
        if (file_seek(&file, blockOff)) {
 | 
			
		||||
            vga_text = (uint16_t*)0xb8000;
 | 
			
		||||
            vga_text += printStr("Seek Error ", vga_text);
 | 
			
		||||
            kbd_wait();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        uint32_t err = DFS_WriteFile(&fi, scratch, writeStore[blockIdx], &successcount, blockLen);
 | 
			
		||||
        if (successcount < blockLen || err) {
 | 
			
		||||
        uint32_t successcount = file_write(&file, writeStore[blockIdx], blockLen);
 | 
			
		||||
        if (successcount < blockLen) {
 | 
			
		||||
            vga_text = (uint16_t*)0xb8000;
 | 
			
		||||
            vga_text += printStr("Write Error ", vga_text);
 | 
			
		||||
            kbd_wait();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								kernel.c
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include "dosfs/dosfs.h"
 | 
			
		||||
#include "file.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "interrupt.h"
 | 
			
		||||
#include "kbd.h"
 | 
			
		||||
@@ -182,7 +182,9 @@ Protected Only (1MB+)
 | 
			
		||||
100000 - 200000 Kernel Code (1mB)
 | 
			
		||||
200000 - 200080 TSS (128B)
 | 
			
		||||
200080 - 202080 TSS IOMAP (8kB)
 | 
			
		||||
202080 - 300000 Free (~1/2mB)
 | 
			
		||||
202080 - 208000 Free (~24kB)
 | 
			
		||||
208000 - 240000 Kernel File Stack (224kB)
 | 
			
		||||
240000 - 280000 Active Filesystems (128kB)
 | 
			
		||||
280000 - 300000 Disk Cache (512kB)
 | 
			
		||||
300000 - 310000 Task Stack (64kB)
 | 
			
		||||
310000 - 320000 Interrupt Stack (64kB)
 | 
			
		||||
@@ -191,9 +193,6 @@ Protected Only (1MB+)
 | 
			
		||||
700000 - 800000 Usermode Stack (1mB)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// FIXME Truly awful
 | 
			
		||||
extern uint8_t SystemPartition;
 | 
			
		||||
 | 
			
		||||
void DrawScreen(uint16_t *vga) {
 | 
			
		||||
    uint16_t *vga_text = vga;
 | 
			
		||||
    // clear screen
 | 
			
		||||
@@ -227,7 +226,6 @@ void DrawScreen(uint16_t *vga) {
 | 
			
		||||
    vga_text[80+42] = 0x1f00 | 'S';
 | 
			
		||||
    vga_text[80+43] = 0x1f00 | ' ';
 | 
			
		||||
    vga_text[80+44] = 0x1f00 | '-';
 | 
			
		||||
    printByte(SystemPartition, &vga_text[80+50]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetPalette() {
 | 
			
		||||
@@ -253,28 +251,22 @@ int32_t fileCount, fileOffset;
 | 
			
		||||
// after every task called. This might be fine,
 | 
			
		||||
// since the task might have modified the directory.
 | 
			
		||||
extern char _USERMODE;
 | 
			
		||||
DIRENT *const DirEntries = (DIRENT*)&_USERMODE;
 | 
			
		||||
dirent *const DirEntries = (dirent*)&_USERMODE;
 | 
			
		||||
#define MAXDISPFILES 16
 | 
			
		||||
void PrintFileList(uint16_t *vga) {
 | 
			
		||||
    uint16_t *vga_text = &((uint16_t *)vga)[80*6+3];
 | 
			
		||||
    for (int i = 0; (i + fileOffset) < fileCount && i < MAXDISPFILES; i++) {
 | 
			
		||||
        DIRENT *de = &DirEntries[i + fileOffset];
 | 
			
		||||
        for (int i = 0; i < 11 && de->name[i]; i++) {
 | 
			
		||||
            if (i == 8) { *(uint8_t*)vga_text = ' '; vga_text++; } // space for 8.3
 | 
			
		||||
            *(uint8_t *)vga_text = de->name[i];
 | 
			
		||||
            vga_text++;
 | 
			
		||||
        }
 | 
			
		||||
        dirent *de = &DirEntries[i + fileOffset];
 | 
			
		||||
        de->name[de->namelen < 20 ? de->namelen : 20] = 0;
 | 
			
		||||
        vga_text += printStr(de->name, vga_text);
 | 
			
		||||
        vga_text += printStr("  ", vga_text);
 | 
			
		||||
        vga_text += printDec((uint32_t)de->filesize_0 +
 | 
			
		||||
                ((uint32_t)de->filesize_1 << 8) +
 | 
			
		||||
                ((uint32_t)de->filesize_2 << 16) +
 | 
			
		||||
                ((uint32_t)de->filesize_3 << 24), vga_text);
 | 
			
		||||
        vga_text += printDec(de->size, vga_text);
 | 
			
		||||
        *(uint8_t*)vga_text++ = 'B';
 | 
			
		||||
        vga_text = nextLine(vga_text, vga) + 3;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
char IsDir(DIRENT *de) {
 | 
			
		||||
    return de->attr & ATTR_DIRECTORY;
 | 
			
		||||
char IsDir(dirent *de) {
 | 
			
		||||
    return de->type == FT_DIR;
 | 
			
		||||
}
 | 
			
		||||
void ScancodeTest() {
 | 
			
		||||
    uint16_t *vga = (uint16_t*)0xb8000;
 | 
			
		||||
@@ -289,7 +281,7 @@ void ScancodeTest() {
 | 
			
		||||
extern void create_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
 | 
			
		||||
uint16_t FileSelectScreen[80*25];
 | 
			
		||||
void FileSelect() {
 | 
			
		||||
    uint8_t current_path[80];
 | 
			
		||||
    char current_path[80];
 | 
			
		||||
    uintptr_t current_path_end;
 | 
			
		||||
    for (int i = 0; i < sizeof(current_path); i++)
 | 
			
		||||
        current_path[i] = 0;
 | 
			
		||||
@@ -314,15 +306,14 @@ void FileSelect() {
 | 
			
		||||
            vga += 80;
 | 
			
		||||
            printStr("F4 to run tests", vga);
 | 
			
		||||
        }
 | 
			
		||||
        printStr((char*)current_path, &vga_text[80*4 + 2]);
 | 
			
		||||
        printStr(current_path, &vga_text[80*4 + 2]);
 | 
			
		||||
        for (int i = 2; i < 15; i++)
 | 
			
		||||
            *(uint8_t*)&vga_text[80*5 + i] = '-';
 | 
			
		||||
        VOLINFO vi; DIRINFO di;
 | 
			
		||||
        DIR dir;
 | 
			
		||||
        if (reload) {
 | 
			
		||||
            OpenVol(&vi);
 | 
			
		||||
            current_path[current_path_end] = 0;
 | 
			
		||||
            OpenDir(current_path, &vi, &di);
 | 
			
		||||
            GetFileList(DirEntries, &fileCount, INT32_MAX, &vi, &di);
 | 
			
		||||
            dir_open(&dir, current_path);
 | 
			
		||||
            GetFileList(&dir, DirEntries, &fileCount, INT32_MAX);
 | 
			
		||||
            reload = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (fileHovered >= fileCount) {
 | 
			
		||||
@@ -365,23 +356,32 @@ void FileSelect() {
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_P:
 | 
			
		||||
                if (IsDir(&DirEntries[fileHovered])) break;
 | 
			
		||||
                File83ToPath((char*)DirEntries[fileHovered].name, (char*)¤t_path[current_path_end]);
 | 
			
		||||
                create_child(GetFreeStack(), (uintptr_t)ProgramLoadTest, 2, current_path, &vi);
 | 
			
		||||
                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]);
 | 
			
		||||
                current_path[current_path_end] = 0;
 | 
			
		||||
                RestoreVGA();
 | 
			
		||||
                reload = 1;
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_X:
 | 
			
		||||
                if (IsDir(&DirEntries[fileHovered])) break;
 | 
			
		||||
                File83ToPath((char*)DirEntries[fileHovered].name, (char*)¤t_path[current_path_end]);
 | 
			
		||||
                create_child(GetFreeStack(), (uintptr_t)HexEditor, 2, current_path, &vi);
 | 
			
		||||
                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]);
 | 
			
		||||
                current_path[current_path_end] = 0;
 | 
			
		||||
                RestoreVGA();
 | 
			
		||||
                reload = 1;
 | 
			
		||||
                break;
 | 
			
		||||
            case KEY_T:
 | 
			
		||||
                if (IsDir(&DirEntries[fileHovered])) break;
 | 
			
		||||
                File83ToPath((char*)DirEntries[fileHovered].name, (char*)¤t_path[current_path_end]);
 | 
			
		||||
                //TextViewTest(path, &vi);
 | 
			
		||||
                create_child(GetFreeStack(), (uintptr_t)TextViewTest, 2, current_path, &vi);
 | 
			
		||||
                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]);
 | 
			
		||||
                current_path[current_path_end] = 0;
 | 
			
		||||
                RestoreVGA();
 | 
			
		||||
                reload = 1;
 | 
			
		||||
                break;
 | 
			
		||||
@@ -389,7 +389,12 @@ void FileSelect() {
 | 
			
		||||
            case 0x9C: // enter release
 | 
			
		||||
                if (IsDir(&DirEntries[fileHovered])) {
 | 
			
		||||
                    uint8_t tmp_path[80];
 | 
			
		||||
                    File83ToPath((char*)DirEntries[fileHovered].name, (char*)tmp_path);
 | 
			
		||||
                    {
 | 
			
		||||
                        int i;
 | 
			
		||||
                        for (i = 0; i < DirEntries[fileHovered].namelen && i < sizeof(tmp_path)-1; i++)
 | 
			
		||||
                            tmp_path[i] = DirEntries[fileHovered].name[i];
 | 
			
		||||
                        tmp_path[i] = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((*(uint32_t*)tmp_path & 0xffff) == ('.' | 0x0000)) {
 | 
			
		||||
                        // Current dir, do nothing
 | 
			
		||||
                        break;
 | 
			
		||||
@@ -423,17 +428,17 @@ void FileSelect() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SystemRun() {
 | 
			
		||||
int MakeSystemVolume(uint8_t sysPartition);
 | 
			
		||||
void SystemRun(uint8_t sysPartition) {
 | 
			
		||||
    uint16_t *vga_text = (word *)0xb8000;
 | 
			
		||||
    RestoreVGA();
 | 
			
		||||
    DrawScreen((uint16_t*)0xb8000);
 | 
			
		||||
 | 
			
		||||
    // Check for FAT partition
 | 
			
		||||
    {
 | 
			
		||||
        VOLINFO vi;
 | 
			
		||||
        // TODO Check partitions beyond 0
 | 
			
		||||
        while (1) {
 | 
			
		||||
            create_child(GetFreeStack(), (uintptr_t)OpenVol, 1, &vi);
 | 
			
		||||
            create_child(GetFreeStack(), (uintptr_t)MakeSystemVolume, 1, sysPartition);
 | 
			
		||||
            if (!check_error_code()) break;
 | 
			
		||||
            vga_text = &((word*)0xb8000)[80*4 + 2];
 | 
			
		||||
            vga_text += printStr("Error loading file select. Ensure the disk has a valid MBR and FAT partition.", vga_text);
 | 
			
		||||
@@ -526,9 +531,9 @@ void start() {
 | 
			
		||||
    InitDisk();
 | 
			
		||||
 | 
			
		||||
    // DL contained disk number, DH contained active partition
 | 
			
		||||
    SystemPartition = boot_dx >> 8;
 | 
			
		||||
    uint8_t SystemPartition = boot_dx >> 8;
 | 
			
		||||
 | 
			
		||||
    create_child(GetFreeStack(), (uintptr_t)SystemRun, 0);
 | 
			
		||||
    create_child(GetFreeStack(), (uintptr_t)SystemRun, 1, SystemPartition);
 | 
			
		||||
    // If this returns, something is *very* wrong, reboot the system
 | 
			
		||||
    // TODO Maybe try to recover?
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								progs.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								progs.c
									
									
									
									
									
								
							@@ -1,10 +1,11 @@
 | 
			
		||||
#include "progs.h"
 | 
			
		||||
#include "file.h"
 | 
			
		||||
 | 
			
		||||
// 400000 - 700000 Usermode Code (3mB)
 | 
			
		||||
// 700000 - 800000 Usermode Stack (1mB)
 | 
			
		||||
extern char _USERMODE;
 | 
			
		||||
extern uint32_t create_user_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
 | 
			
		||||
void ProgramLoadTest(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
void ProgramLoadTest(char *path, dirent *de) {
 | 
			
		||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    for (int i = 0; i < 80*25; i++)
 | 
			
		||||
        vga_text[i] = 0x0f00;
 | 
			
		||||
@@ -13,33 +14,29 @@ void ProgramLoadTest(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t err;
 | 
			
		||||
        uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
        FILEINFO fi;
 | 
			
		||||
        err = DFS_OpenFile(vi, path, DFS_READ, scratch, &fi);
 | 
			
		||||
        FILE file;
 | 
			
		||||
        err = file_open(&file, path, OPENREAD);
 | 
			
		||||
        if (err) {
 | 
			
		||||
            vga_text += printStr("Open Error: ", vga_text);
 | 
			
		||||
            printDword(err, vga_text);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (fi.filelen > 0x300000) {
 | 
			
		||||
        if (de->size > 0x300000) {
 | 
			
		||||
            vga_text += printStr("File too large.", vga_text);
 | 
			
		||||
            kbd_wait();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        DFS_Seek(&fi, 0, scratch);
 | 
			
		||||
        if (fi.pointer != 0) {
 | 
			
		||||
        err = file_seek(&file, 0);
 | 
			
		||||
        if (err) {
 | 
			
		||||
            vga_text += printStr("Seek Error", vga_text);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        err = DFS_ReadFile(&fi, scratch, diskReadBuf, &successcount, fi.filelen);
 | 
			
		||||
        if (err && err != DFS_EOF) {
 | 
			
		||||
            vga_text += printStr("Read Error: ", vga_text);
 | 
			
		||||
        err = file_read(&file, diskReadBuf, de->size);
 | 
			
		||||
        if (!err && de->size > 0) {
 | 
			
		||||
            vga_text += printStr("Read Error", vga_text);
 | 
			
		||||
            printDword(err, vga_text);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (successcount < fi.filelen) {
 | 
			
		||||
            vga_text += printStr("Could not read all file bytes.", vga_text);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    vga_text += printStr("Successfully loaded program \"", vga_text);
 | 
			
		||||
    vga_text += printStr((char*)path, vga_text);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								progs.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								progs.h
									
									
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include "dosfs/dosfs.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "kbd.h"
 | 
			
		||||
#include "v86defs.h"
 | 
			
		||||
#include "helper.h"
 | 
			
		||||
#include "file.h"
 | 
			
		||||
 | 
			
		||||
void HexEditor(uint8_t *path, VOLINFO *vi);
 | 
			
		||||
void TextViewTest(uint8_t *path, VOLINFO *vi);
 | 
			
		||||
void ProgramLoadTest(uint8_t *path, VOLINFO *vi);
 | 
			
		||||
void HexEditor(char *path, dirent *de);
 | 
			
		||||
void TextViewTest(char *path, dirent *de);
 | 
			
		||||
void ProgramLoadTest(char *path, dirent *de);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										145
									
								
								tests.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								tests.c
									
									
									
									
									
								
							@@ -123,79 +123,76 @@ void TestCHS() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FIXME Just horrible
 | 
			
		||||
extern uint8_t SystemPartition;
 | 
			
		||||
 | 
			
		||||
void TestFAT() {
 | 
			
		||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    uint8_t *diskReadBuf = (uint8_t *)0x22400;
 | 
			
		||||
    for (int i = 0; i < 80*25; i++)
 | 
			
		||||
        vga_text[i] = 0x0f00;
 | 
			
		||||
    VOLINFO vi;
 | 
			
		||||
 | 
			
		||||
    uint8_t pactive, ptype;
 | 
			
		||||
    uint32_t pstart, psize;
 | 
			
		||||
    pstart = DFS_GetPtnStart(0, diskReadBuf, SystemPartition, &pactive, &ptype, &psize);
 | 
			
		||||
    vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    vga_text += printStr("PartStart: ", vga_text);
 | 
			
		||||
    vga_text += printDword(pstart, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("PartSize: ", vga_text);
 | 
			
		||||
    vga_text += printDword(psize, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("PartActive: ", vga_text);
 | 
			
		||||
    vga_text += printByte(pactive, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("PartType: ", vga_text);
 | 
			
		||||
    vga_text += printByte(ptype, vga_text);
 | 
			
		||||
    vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
    //asm ("xchgw %bx, %bx");
 | 
			
		||||
 | 
			
		||||
    DFS_GetVolInfo(0, diskReadBuf, pstart, &vi);
 | 
			
		||||
    vga_text += printStr("Label: ", vga_text);
 | 
			
		||||
    vga_text += printStr((char*)vi.label, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("Sec/Clus: ", vga_text);
 | 
			
		||||
    vga_text += printByte(vi.secperclus, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("ResrvSec: ", vga_text);
 | 
			
		||||
    vga_text += printWord(vi.reservedsecs, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("NumSec: ", vga_text);
 | 
			
		||||
    vga_text += printDword(vi.numsecs, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("Sec/FAT: ", vga_text);
 | 
			
		||||
    vga_text += printDword(vi.secperfat, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("FAT1@: ", vga_text);
 | 
			
		||||
    vga_text += printDword(vi.fat1, vga_text);
 | 
			
		||||
    vga_text += 2;
 | 
			
		||||
    vga_text += printStr("ROOT@: ", vga_text);
 | 
			
		||||
    vga_text += printDword(vi.rootdir, vga_text);
 | 
			
		||||
    vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
    //asm ("xchgw %bx, %bx");
 | 
			
		||||
 | 
			
		||||
    vga_text += printStr("Files in root:", vga_text);
 | 
			
		||||
    DIRINFO di;
 | 
			
		||||
    di.scratch = diskReadBuf;
 | 
			
		||||
    DFS_OpenDir(&vi, (uint8_t*)"", &di);
 | 
			
		||||
    vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
    DIRENT de;
 | 
			
		||||
    while (!DFS_GetNext(&vi, &di, &de)) {
 | 
			
		||||
        if (de.name[0]) {
 | 
			
		||||
            for (int i = 0; i < 11 && de.name[i]; i++) {
 | 
			
		||||
                if (i == 8) { *(uint8_t*)vga_text = ' '; vga_text++; } // space for 8.3
 | 
			
		||||
                *(uint8_t *)vga_text = de.name[i];
 | 
			
		||||
                vga_text++;
 | 
			
		||||
            }
 | 
			
		||||
            vga_text += printStr("  ", vga_text);
 | 
			
		||||
            vga_text += printDec((uint32_t)de.filesize_0 + ((uint32_t)de.filesize_1 << 8) + ((uint32_t)de.filesize_2 << 16) + ((uint32_t)de.filesize_3 << 24), vga_text);
 | 
			
		||||
            *(uint8_t*)vga_text++ = 'B';
 | 
			
		||||
            vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
        }
 | 
			
		||||
        //asm ("xchgw %bx, %bx");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
//void TestFAT() {
 | 
			
		||||
//    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
//    uint8_t *diskReadBuf = (uint8_t *)0x22400;
 | 
			
		||||
//    for (int i = 0; i < 80*25; i++)
 | 
			
		||||
//        vga_text[i] = 0x0f00;
 | 
			
		||||
//    VOLINFO vi;
 | 
			
		||||
//
 | 
			
		||||
//    uint8_t pactive, ptype;
 | 
			
		||||
//    uint32_t pstart, psize;
 | 
			
		||||
//    pstart = DFS_GetPtnStart(0, diskReadBuf, SystemPartition, &pactive, &ptype, &psize);
 | 
			
		||||
//    vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
//    vga_text += printStr("PartStart: ", vga_text);
 | 
			
		||||
//    vga_text += printDword(pstart, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("PartSize: ", vga_text);
 | 
			
		||||
//    vga_text += printDword(psize, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("PartActive: ", vga_text);
 | 
			
		||||
//    vga_text += printByte(pactive, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("PartType: ", vga_text);
 | 
			
		||||
//    vga_text += printByte(ptype, vga_text);
 | 
			
		||||
//    vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
//    //asm ("xchgw %bx, %bx");
 | 
			
		||||
//
 | 
			
		||||
//    DFS_GetVolInfo(0, diskReadBuf, pstart, &vi);
 | 
			
		||||
//    vga_text += printStr("Label: ", vga_text);
 | 
			
		||||
//    vga_text += printStr((char*)vi.label, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("Sec/Clus: ", vga_text);
 | 
			
		||||
//    vga_text += printByte(vi.secperclus, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("ResrvSec: ", vga_text);
 | 
			
		||||
//    vga_text += printWord(vi.reservedsecs, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("NumSec: ", vga_text);
 | 
			
		||||
//    vga_text += printDword(vi.numsecs, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("Sec/FAT: ", vga_text);
 | 
			
		||||
//    vga_text += printDword(vi.secperfat, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("FAT1@: ", vga_text);
 | 
			
		||||
//    vga_text += printDword(vi.fat1, vga_text);
 | 
			
		||||
//    vga_text += 2;
 | 
			
		||||
//    vga_text += printStr("ROOT@: ", vga_text);
 | 
			
		||||
//    vga_text += printDword(vi.rootdir, vga_text);
 | 
			
		||||
//    vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
//    //asm ("xchgw %bx, %bx");
 | 
			
		||||
//
 | 
			
		||||
//    vga_text += printStr("Files in root:", vga_text);
 | 
			
		||||
//    DIRINFO di;
 | 
			
		||||
//    di.scratch = diskReadBuf;
 | 
			
		||||
//    DFS_OpenDir(&vi, (uint8_t*)"", &di);
 | 
			
		||||
//    vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
//    DIRENT de;
 | 
			
		||||
//    while (!DFS_GetNext(&vi, &di, &de)) {
 | 
			
		||||
//        if (de.name[0]) {
 | 
			
		||||
//            for (int i = 0; i < 11 && de.name[i]; i++) {
 | 
			
		||||
//                if (i == 8) { *(uint8_t*)vga_text = ' '; vga_text++; } // space for 8.3
 | 
			
		||||
//                *(uint8_t *)vga_text = de.name[i];
 | 
			
		||||
//                vga_text++;
 | 
			
		||||
//            }
 | 
			
		||||
//            vga_text += printStr("  ", vga_text);
 | 
			
		||||
//            vga_text += printDec((uint32_t)de.filesize_0 + ((uint32_t)de.filesize_1 << 8) + ((uint32_t)de.filesize_2 << 16) + ((uint32_t)de.filesize_3 << 24), vga_text);
 | 
			
		||||
//            *(uint8_t*)vga_text++ = 'B';
 | 
			
		||||
//            vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
 | 
			
		||||
//        }
 | 
			
		||||
//        //asm ("xchgw %bx, %bx");
 | 
			
		||||
//    }
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
void RunTests() {
 | 
			
		||||
    char doTests = 1;
 | 
			
		||||
@@ -258,7 +255,7 @@ void RunTests() {
 | 
			
		||||
                TestCHS();
 | 
			
		||||
                kbd_wait();
 | 
			
		||||
                TestDiskRead();
 | 
			
		||||
                TestFAT();
 | 
			
		||||
                //TestFAT();
 | 
			
		||||
                break;
 | 
			
		||||
            case 'r':
 | 
			
		||||
            case 'R':
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								tests.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tests.h
									
									
									
									
									
								
							@@ -1,5 +1,4 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dosfs/dosfs.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "interrupt.h"
 | 
			
		||||
#include "v86defs.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								textedit.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								textedit.c
									
									
									
									
									
								
							@@ -12,14 +12,14 @@ uint8_t editedBlocks[TOTALBLOCKS] __attribute__((section(".textbss")));;
 | 
			
		||||
uint8_t fileBuffer[MAXFILESIZE]
 | 
			
		||||
    __attribute__((aligned(0x1000)))
 | 
			
		||||
    __attribute__((section(".textlatebss")));
 | 
			
		||||
void TextViewTest(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
void TextViewTest(char *path, dirent *de) {
 | 
			
		||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    uint32_t fileLen;
 | 
			
		||||
    uint32_t fileLen = de->size;
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t err;
 | 
			
		||||
        uint8_t *scratch = (uint8_t *)0x20000;
 | 
			
		||||
        FILEINFO fi;
 | 
			
		||||
        err = DFS_OpenFile(vi, path, DFS_READ, scratch, &fi);
 | 
			
		||||
        FILE file;
 | 
			
		||||
        err = file_open(&file, path, OPENREAD);
 | 
			
		||||
        if (err) {
 | 
			
		||||
            vga_text += printStr("Open Error: ", vga_text);
 | 
			
		||||
            printDword(err, vga_text);
 | 
			
		||||
@@ -27,19 +27,18 @@ void TextViewTest(uint8_t *path, VOLINFO *vi) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // file too large
 | 
			
		||||
        if (fi.filelen > MAXFILESIZE) {
 | 
			
		||||
        if (fileLen > MAXFILESIZE) {
 | 
			
		||||
            vga_text += printStr("File too large.", vga_text);
 | 
			
		||||
            kbd_wait();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        DFS_Seek(&fi, 0, scratch);
 | 
			
		||||
        if (fi.pointer != 0) {
 | 
			
		||||
        if (file_seek(&file, 0)) {
 | 
			
		||||
            vga_text += printStr("Seek Error", vga_text);
 | 
			
		||||
            kbd_wait();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        err = DFS_ReadFile(&fi, scratch, fileBuffer, &fileLen, fi.filelen);
 | 
			
		||||
        if (err && err != DFS_EOF) {
 | 
			
		||||
        uint32_t bytesRead = file_read(&file, fileBuffer, fileLen);
 | 
			
		||||
        if (bytesRead < fileLen) {
 | 
			
		||||
            vga_text += printStr("Read Error: ", vga_text);
 | 
			
		||||
            printDword(err, vga_text);
 | 
			
		||||
            kbd_wait();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user