Added a hex viewer, Fixed a bug in dosfs

This commit is contained in:
Lucia Ceionia 2023-02-04 18:51:09 -06:00
parent 964cbcd68d
commit ddadeed70c
7 changed files with 195 additions and 44 deletions

View File

@ -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), &regs); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
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

View File

@ -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 };

View File

@ -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:

189
kernel.c
View File

@ -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;
uint32_t pstart, psize;
pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
DFS_GetVolInfo(0, diskReadBuf, pstart, &vi);
DIRINFO di;
di.scratch = diskReadBuf;
DFS_OpenDir(&vi, (uint8_t*)"", &di);
DIRENT de;
fileCount = 0;
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 if (i == 8) { *(uint8_t*)vga_text = ' '; vga_text++; } // space for 8.3
*(uint8_t *)vga_text = de.name[i]; *(uint8_t *)vga_text = de->name[i];
vga_text++; vga_text++;
} }
vga_text += printStr(" ", 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((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'; *(uint8_t*)vga_text++ = 'B';
vga_text = nextLine(vga_text) + 3; vga_text = nextLine(vga_text) + 3;
fileCount++; }
}
const uint32_t byteCount = 16*24;
uint8_t diskReadBuf[16*24];
void FileReadTest(uint8_t *path, VOLINFO *vi) {
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;
}
err = DFS_ReadFile(&fi, scratch, diskReadBuf, &successcount, byteCount);
if (err && err != DFS_EOF) {
vga_text += printStr("Read Error: ", vga_text);
printDword(err, vga_text);
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;
} }

View File

@ -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];

View File

@ -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
View File

@ -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), &regs); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
} }
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);