Filesystem now uses an abstract representation
This commit is contained in:
parent
1b2184fe52
commit
5fe565b6f7
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();
|
||||
|
Loading…
Reference in New Issue
Block a user