Added a hex viewer, Fixed a bug in dosfs
This commit is contained in:
parent
964cbcd68d
commit
ddadeed70c
@ -13,16 +13,23 @@
|
|||||||
#include "../interrupt.h"
|
#include "../interrupt.h"
|
||||||
#include "../v86defs.h"
|
#include "../v86defs.h"
|
||||||
|
|
||||||
// all reading at 0x23000 - be careful!
|
|
||||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
|
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
|
||||||
|
// NOTE If the buffer provided is outside the 0x20000-0x2FE00 range,
|
||||||
|
// the function will use that buffer for the Virtual 8086 process
|
||||||
|
// and copy to the other buffer after
|
||||||
|
uint8_t *v86buf = buffer;
|
||||||
|
if ((uintptr_t)v86buf < 0x20000 || (uintptr_t)v86buf > 0x2FE00)
|
||||||
|
v86buf = (uint8_t *)0x20000;
|
||||||
v86disk_addr_packet.start_block = sector;
|
v86disk_addr_packet.start_block = sector;
|
||||||
v86disk_addr_packet.blocks = count;
|
v86disk_addr_packet.blocks = count;
|
||||||
v86disk_addr_packet.transfer_buffer =
|
v86disk_addr_packet.transfer_buffer =
|
||||||
(uintptr_t)buffer & 0x000F |
|
(uintptr_t)v86buf & 0x000F |
|
||||||
(((uintptr_t)buffer & 0xFFFF0) << 12);
|
(((uintptr_t)v86buf & 0xFFFF0) << 12);
|
||||||
union V86Regs_t regs;
|
union V86Regs_t regs;
|
||||||
FARPTR v86_entry = i386LinearToFp(v86DiskRead);
|
FARPTR v86_entry = i386LinearToFp(v86DiskRead);
|
||||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
||||||
|
if (v86buf != buffer)
|
||||||
|
memcpy(buffer, v86buf, count * SECTOR_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
|
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
|
||||||
@ -1038,8 +1045,9 @@ void DFS_Seek(PFILEINFO fileinfo, uint32_t offset, uint8_t *scratch)
|
|||||||
|
|
||||||
// seek by clusters
|
// seek by clusters
|
||||||
// larwe 9/30/06 bugfix changed .rem to .quot in both div calls
|
// larwe 9/30/06 bugfix changed .rem to .quot in both div calls
|
||||||
|
// Lucia 2/4/2023 'fileinfo->pointer + offset' into just 'offset' for bugfix
|
||||||
while (div(fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot !=
|
while (div(fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot !=
|
||||||
div(fileinfo->pointer + offset, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot) {
|
div(offset, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot) {
|
||||||
|
|
||||||
fileinfo->cluster = DFS_GetFAT(fileinfo->volinfo, scratch, &tempint, fileinfo->cluster);
|
fileinfo->cluster = DFS_GetFAT(fileinfo->volinfo, scratch, &tempint, fileinfo->cluster);
|
||||||
// Abort if there was an error
|
// Abort if there was an error
|
||||||
|
@ -86,8 +86,8 @@ int strcmp(const char *l, const char *r)
|
|||||||
|
|
||||||
|
|
||||||
/* STDLIB DIV FUNCTIONS */
|
/* STDLIB DIV FUNCTIONS */
|
||||||
typedef struct { int quot, rem; } div_t;
|
typedef struct { int32_t quot, rem; } div_t;
|
||||||
typedef struct { long quot, rem; } ldiv_t;
|
typedef struct { int64_t quot, rem; } ldiv_t;
|
||||||
div_t div(int num, int den)
|
div_t div(int num, int den)
|
||||||
{
|
{
|
||||||
return (div_t){ num/den, num%den };
|
return (div_t){ num/den, num%den };
|
||||||
|
@ -14,6 +14,8 @@ call error_environment
|
|||||||
hlt
|
hlt
|
||||||
jmp .hlt
|
jmp .hlt
|
||||||
|
|
||||||
|
global _gpf_eax_save
|
||||||
|
_gpf_eax_save: dd 0
|
||||||
extern gpf_handler_v86
|
extern gpf_handler_v86
|
||||||
global gpfHandler
|
global gpfHandler
|
||||||
gpfHandler:
|
gpfHandler:
|
||||||
|
199
kernel.c
199
kernel.c
@ -55,7 +55,16 @@ uint32_t get_cr4() {
|
|||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
|
extern char _loadusercode, _usercode, _eusercode;
|
||||||
|
void LoadUser() {
|
||||||
|
// Put Usermode code in proper place based on linker
|
||||||
|
char *s = &_loadusercode;
|
||||||
|
char *d = &_usercode;
|
||||||
|
while (d < &_eusercode)
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char _edata, _v86code, _ev86code, _bstart, _bend;
|
||||||
void setup_binary() {
|
void setup_binary() {
|
||||||
// Put V86 code in proper place based on linker
|
// Put V86 code in proper place based on linker
|
||||||
char *s = &_edata;
|
char *s = &_edata;
|
||||||
@ -63,11 +72,7 @@ void setup_binary() {
|
|||||||
while (d < &_ev86code)
|
while (d < &_ev86code)
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
|
|
||||||
// Put Usermode code in proper place based on linker
|
LoadUser();
|
||||||
s = &_loadusercode;
|
|
||||||
d = &_usercode;
|
|
||||||
while (d < &_eusercode)
|
|
||||||
*d++ = *s++;
|
|
||||||
|
|
||||||
// Clear BSS area
|
// Clear BSS area
|
||||||
for (d = &_bstart; d < &_bend; d++)
|
for (d = &_bstart; d < &_bend; d++)
|
||||||
@ -174,41 +179,140 @@ void DrawScreen() {
|
|||||||
vga_text[80+42] = 0x1f00 | 'S';
|
vga_text[80+42] = 0x1f00 | 'S';
|
||||||
vga_text[80+43] = 0x1f00 | ' ';
|
vga_text[80+43] = 0x1f00 | ' ';
|
||||||
vga_text[80+44] = 0x1f00 | '-';
|
vga_text[80+44] = 0x1f00 | '-';
|
||||||
|
|
||||||
|
// Info line (4)
|
||||||
|
vga_text = &vga_text[80*4+2];
|
||||||
|
printStr("T to run tests - O to view file in hex", vga_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t OpenVol(VOLINFO *vi) {
|
||||||
|
uint8_t *diskReadBuf = (uint8_t *)0x20000;
|
||||||
|
uint8_t pactive, ptype;
|
||||||
|
uint32_t pstart, psize;
|
||||||
|
pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
|
||||||
|
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);
|
||||||
|
}
|
||||||
int32_t fileCount;
|
int32_t fileCount;
|
||||||
|
DIRENT *entries = (DIRENT*)0x400000;
|
||||||
|
void GetFileList(VOLINFO *vi, DIRINFO *di) {
|
||||||
|
uint8_t *diskReadBuf = (uint8_t *)0x20000;
|
||||||
|
DIRENT de;
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
uint16_t *nextLine(uint16_t *p) {
|
uint16_t *nextLine(uint16_t *p) {
|
||||||
uintptr_t v = (uintptr_t)p;
|
uintptr_t v = (uintptr_t)p;
|
||||||
return (uint16_t *)(v + (160 - ((v - 0xb8000) % 160)));
|
return (uint16_t *)(v + (160 - ((v - 0xb8000) % 160)));
|
||||||
}
|
}
|
||||||
void PrintFileList() {
|
void PrintFileList() {
|
||||||
uint16_t *vga_text = &((uint16_t *)0xb8000)[80*4+3];
|
uint16_t *vga_text = &((uint16_t *)0xb8000)[80*6+3];
|
||||||
uint8_t *diskReadBuf = (uint8_t *)0x20000;
|
for (int i = 0; i < fileCount; i++) {
|
||||||
VOLINFO vi;
|
DIRENT *de = &entries[i];
|
||||||
|
for (int i = 0; i < 11 && de->name[i]; i++) {
|
||||||
uint8_t pactive, ptype;
|
if (i == 8) { *(uint8_t*)vga_text = ' '; vga_text++; } // space for 8.3
|
||||||
uint32_t pstart, psize;
|
*(uint8_t *)vga_text = de->name[i];
|
||||||
pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
|
vga_text++;
|
||||||
|
}
|
||||||
DFS_GetVolInfo(0, diskReadBuf, pstart, &vi);
|
vga_text += printStr(" ", vga_text);
|
||||||
|
vga_text += printDec((uint32_t)de->filesize_0 +
|
||||||
DIRINFO di;
|
((uint32_t)de->filesize_1 << 8) +
|
||||||
di.scratch = diskReadBuf;
|
((uint32_t)de->filesize_2 << 16) +
|
||||||
DFS_OpenDir(&vi, (uint8_t*)"", &di);
|
((uint32_t)de->filesize_3 << 24), vga_text);
|
||||||
DIRENT de;
|
*(uint8_t*)vga_text++ = 'B';
|
||||||
fileCount = 0;
|
vga_text = nextLine(vga_text) + 3;
|
||||||
while (!DFS_GetNext(&vi, &di, &de)) {
|
}
|
||||||
if (de.name[0]) {
|
}
|
||||||
for (int i = 0; i < 11 && de.name[i]; i++) {
|
const uint32_t byteCount = 16*24;
|
||||||
if (i == 8) { *(uint8_t*)vga_text = ' '; vga_text++; } // space for 8.3
|
uint8_t diskReadBuf[16*24];
|
||||||
*(uint8_t *)vga_text = de.name[i];
|
void FileReadTest(uint8_t *path, VOLINFO *vi) {
|
||||||
vga_text++;
|
uint32_t err;
|
||||||
|
uint16_t *vga_text = (uint16_t *)0xb8000;
|
||||||
|
uint8_t *scratch = (uint8_t *)0x20000;
|
||||||
|
FILEINFO fi;
|
||||||
|
err = DFS_OpenFile(vi, path, DFS_READ, scratch, &fi);
|
||||||
|
if (err) {
|
||||||
|
vga_text += printStr("Open Error: ", vga_text);
|
||||||
|
printDword(err, vga_text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t successcount;
|
||||||
|
uint32_t readOffset = 0, lastReadOffset = -1;
|
||||||
|
char cont = 1;
|
||||||
|
for (;cont;) {
|
||||||
|
if (readOffset != lastReadOffset) {
|
||||||
|
vga_text = (uint16_t *)0xb8000;
|
||||||
|
for (int i = 0; i < 80*25; i++)
|
||||||
|
vga_text[i] = 0x0f00;
|
||||||
|
vga_text += printStr((char*)path, vga_text);
|
||||||
|
vga_text += printStr(" Up/Down to navigate - E to exit", vga_text);
|
||||||
|
vga_text = &((uint16_t*)0xb8000)[80];
|
||||||
|
DFS_Seek(&fi, readOffset, scratch);
|
||||||
|
if (fi.pointer != readOffset) {
|
||||||
|
vga_text += printStr("Seek Error", vga_text);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
vga_text += printStr(" ", vga_text);
|
err = DFS_ReadFile(&fi, scratch, diskReadBuf, &successcount, byteCount);
|
||||||
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);
|
if (err && err != DFS_EOF) {
|
||||||
*(uint8_t*)vga_text++ = 'B';
|
vga_text += printStr("Read Error: ", vga_text);
|
||||||
vga_text = nextLine(vga_text) + 3;
|
printDword(err, vga_text);
|
||||||
fileCount++;
|
return;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < successcount && i < byteCount; i += 16) {
|
||||||
|
vga_text += printDword(i + readOffset, vga_text);
|
||||||
|
vga_text += printChar(' ', vga_text);
|
||||||
|
vga_text += printChar(' ', vga_text);
|
||||||
|
for (uint32_t j = 0; j < 16; j++) {
|
||||||
|
if (i + j < successcount)
|
||||||
|
vga_text += printByte(diskReadBuf[i + j], vga_text);
|
||||||
|
else {
|
||||||
|
vga_text += printChar(' ', vga_text);
|
||||||
|
vga_text += printChar(' ', vga_text);
|
||||||
|
}
|
||||||
|
vga_text += printChar(' ', vga_text);
|
||||||
|
if (j == 8)
|
||||||
|
vga_text += printChar(' ', vga_text);
|
||||||
|
}
|
||||||
|
vga_text += printChar(' ', vga_text);
|
||||||
|
vga_text += printChar('|', vga_text);
|
||||||
|
for (uint32_t j = 0; j < 16; j++) {
|
||||||
|
if (i + j < successcount)
|
||||||
|
vga_text += printChar(diskReadBuf[i + j], vga_text);
|
||||||
|
else vga_text += printChar(' ', vga_text);
|
||||||
|
}
|
||||||
|
vga_text += printChar('|', vga_text);
|
||||||
|
vga_text = nextLine(vga_text);
|
||||||
|
}
|
||||||
|
lastReadOffset = readOffset;
|
||||||
|
}
|
||||||
|
uint16_t key = get_scancode();
|
||||||
|
switch (key & 0xff) {
|
||||||
|
case 0x50: // down
|
||||||
|
if ((readOffset + byteCount) < fi.filelen)
|
||||||
|
readOffset += byteCount;
|
||||||
|
break;
|
||||||
|
case 0x48: // up
|
||||||
|
//asm volatile ("xchg %bx,%bx");
|
||||||
|
if ((readOffset - byteCount) < fi.filelen)
|
||||||
|
readOffset -= byteCount;
|
||||||
|
break;
|
||||||
|
case 0x12: // e
|
||||||
|
cont = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,14 +320,22 @@ void FileSelect() {
|
|||||||
fileCount = 5;
|
fileCount = 5;
|
||||||
uint16_t *vga_text = (uint16_t *)0xb8000;
|
uint16_t *vga_text = (uint16_t *)0xb8000;
|
||||||
int32_t fileHovered = 0, lastFileHovered = 0;
|
int32_t fileHovered = 0, lastFileHovered = 0;
|
||||||
for (;;) {
|
for (char reload = 1;;) {
|
||||||
|
VOLINFO vi; DIRINFO di;
|
||||||
|
if (reload) {
|
||||||
|
OpenVol(&vi);
|
||||||
|
OpenDir((uint8_t*)"", &vi, &di);
|
||||||
|
GetFileList(&vi, &di);
|
||||||
|
reload = 0;
|
||||||
|
}
|
||||||
PrintFileList();
|
PrintFileList();
|
||||||
if (lastFileHovered != fileHovered) {
|
if (lastFileHovered != fileHovered) {
|
||||||
vga_text[80*(4+lastFileHovered)+2] = 0x1f00 | ' ';
|
*(uint8_t*)&vga_text[80*(6+lastFileHovered)+2] = ' ';
|
||||||
lastFileHovered = fileHovered;
|
lastFileHovered = fileHovered;
|
||||||
}
|
}
|
||||||
vga_text[80*(4+fileHovered)+2] = 0x1f00 | '>';
|
*(uint8_t*)&vga_text[80*(6+fileHovered)+2] = '>';
|
||||||
uint16_t key = get_scancode();
|
uint16_t key = get_scancode();
|
||||||
|
uint8_t path[13], tmp, trailingSpace;
|
||||||
switch (key & 0xff) { // scancode component
|
switch (key & 0xff) { // scancode component
|
||||||
case 0x50: // down
|
case 0x50: // down
|
||||||
fileHovered++;
|
fileHovered++;
|
||||||
@ -236,6 +348,23 @@ void FileSelect() {
|
|||||||
case 0x14: // t
|
case 0x14: // t
|
||||||
RunTests(vga_text);
|
RunTests(vga_text);
|
||||||
DrawScreen();
|
DrawScreen();
|
||||||
|
reload = 1;
|
||||||
|
break;
|
||||||
|
case 0x18: // o
|
||||||
|
for (trailingSpace=0, tmp = 0; tmp < 8 && entries[fileHovered].name[tmp]; tmp++) {
|
||||||
|
path[tmp] = entries[fileHovered].name[tmp];
|
||||||
|
if (entries[fileHovered].name[tmp] == ' ') trailingSpace++;
|
||||||
|
else trailingSpace = 0;
|
||||||
|
}
|
||||||
|
tmp -= trailingSpace;
|
||||||
|
path[tmp++] = '.';
|
||||||
|
for (int i = 8; i < 11 && entries[fileHovered].name[i]; i++, tmp++) {
|
||||||
|
path[tmp] = entries[fileHovered].name[i];
|
||||||
|
}
|
||||||
|
path[tmp] = 0;
|
||||||
|
FileReadTest(path, &vi);
|
||||||
|
DrawScreen();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
5
print.c
5
print.c
@ -26,6 +26,11 @@ uintptr_t printStr(char *v, uint16_t *buff) {
|
|||||||
return s - v;
|
return s - v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uintptr_t printChar(char v, uint16_t *buff) {
|
||||||
|
*(char*)buff = v;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t printDec(uint32_t v, uint16_t *buff) {
|
uintptr_t printDec(uint32_t v, uint16_t *buff) {
|
||||||
char b[12];
|
char b[12];
|
||||||
char *s = &b[11];
|
char *s = &b[11];
|
||||||
|
1
print.h
1
print.h
@ -5,3 +5,4 @@ uintptr_t printWord(uint16_t v, uint16_t *buff);
|
|||||||
uintptr_t printDword(uint32_t v, uint16_t *buff);
|
uintptr_t printDword(uint32_t v, uint16_t *buff);
|
||||||
uintptr_t printStr(char *v, uint16_t *buff);
|
uintptr_t printStr(char *v, uint16_t *buff);
|
||||||
uintptr_t printDec(uint32_t v, uint16_t *buff);
|
uintptr_t printDec(uint32_t v, uint16_t *buff);
|
||||||
|
uintptr_t printChar(char v, uint16_t *buff);
|
||||||
|
12
tests.c
12
tests.c
@ -14,7 +14,16 @@ void TestV86() {
|
|||||||
FARPTR v86_entry = i386LinearToFp(v86Test);
|
FARPTR v86_entry = i386LinearToFp(v86Test);
|
||||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
||||||
}
|
}
|
||||||
|
extern char _loadusercode, _usercode, _eusercode;
|
||||||
|
void ReloadUser() {
|
||||||
|
// Put Usermode code in proper place based on linker
|
||||||
|
char *s = &_loadusercode;
|
||||||
|
char *d = &_usercode;
|
||||||
|
while (d < &_eusercode)
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
void TestUser() {
|
void TestUser() {
|
||||||
|
ReloadUser();
|
||||||
char *vga = jmp_usermode_test();
|
char *vga = jmp_usermode_test();
|
||||||
for (int i = 0; i < 320; i++) {
|
for (int i = 0; i < 320; i++) {
|
||||||
vga[i] = i;
|
vga[i] = i;
|
||||||
@ -126,9 +135,6 @@ void RunTests(uint16_t *vga_text) {
|
|||||||
TestDiskRead();
|
TestDiskRead();
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
TestFAT();
|
TestFAT();
|
||||||
kbd_wait();
|
|
||||||
TestFAT();
|
|
||||||
kbd_wait();
|
|
||||||
|
|
||||||
vga_text = &((uint16_t*)0xB8000)[80*16];
|
vga_text = &((uint16_t*)0xB8000)[80*16];
|
||||||
vga_text += printStr("Press E for a flagrant system error. Press C to continue... ", vga_text);
|
vga_text += printStr("Press E for a flagrant system error. Press C to continue... ", vga_text);
|
||||||
|
Loading…
Reference in New Issue
Block a user