From ddadeed70c0786f0d9132d43d0230be6ce7a5522 Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Sat, 4 Feb 2023 18:51:09 -0600 Subject: [PATCH] Added a hex viewer, Fixed a bug in dosfs --- dosfs/dosfs.c | 16 +++- dosfs/tmpstring.c | 4 +- fault.nasm | 2 + kernel.c | 199 ++++++++++++++++++++++++++++++++++++++-------- print.c | 5 ++ print.h | 1 + tests.c | 12 ++- 7 files changed, 195 insertions(+), 44 deletions(-) diff --git a/dosfs/dosfs.c b/dosfs/dosfs.c index 8433d22..645290c 100755 --- a/dosfs/dosfs.c +++ b/dosfs/dosfs.c @@ -13,16 +13,23 @@ #include "../interrupt.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) { + // 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.blocks = count; v86disk_addr_packet.transfer_buffer = - (uintptr_t)buffer & 0x000F | - (((uintptr_t)buffer & 0xFFFF0) << 12); + (uintptr_t)v86buf & 0x000F | + (((uintptr_t)v86buf & 0xFFFF0) << 12); union V86Regs_t regs; FARPTR v86_entry = i386LinearToFp(v86DiskRead); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s); + if (v86buf != buffer) + memcpy(buffer, v86buf, count * SECTOR_SIZE); return 0; } 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 // 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 != - 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); // Abort if there was an error diff --git a/dosfs/tmpstring.c b/dosfs/tmpstring.c index 7fe3b94..4fc821a 100644 --- a/dosfs/tmpstring.c +++ b/dosfs/tmpstring.c @@ -86,8 +86,8 @@ int strcmp(const char *l, const char *r) /* STDLIB DIV FUNCTIONS */ -typedef struct { int quot, rem; } div_t; -typedef struct { long quot, rem; } ldiv_t; +typedef struct { int32_t quot, rem; } div_t; +typedef struct { int64_t quot, rem; } ldiv_t; div_t div(int num, int den) { return (div_t){ num/den, num%den }; diff --git a/fault.nasm b/fault.nasm index 682abbd..b729d83 100644 --- a/fault.nasm +++ b/fault.nasm @@ -14,6 +14,8 @@ call error_environment hlt jmp .hlt +global _gpf_eax_save +_gpf_eax_save: dd 0 extern gpf_handler_v86 global gpfHandler gpfHandler: diff --git a/kernel.c b/kernel.c index ccaa401..4ee902e 100644 --- a/kernel.c +++ b/kernel.c @@ -55,7 +55,16 @@ uint32_t get_cr4() { 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() { // Put V86 code in proper place based on linker char *s = &_edata; @@ -63,11 +72,7 @@ void setup_binary() { while (d < &_ev86code) *d++ = *s++; - // Put Usermode code in proper place based on linker - s = &_loadusercode; - d = &_usercode; - while (d < &_eusercode) - *d++ = *s++; + LoadUser(); // Clear BSS area for (d = &_bstart; d < &_bend; d++) @@ -174,41 +179,140 @@ void DrawScreen() { vga_text[80+42] = 0x1f00 | 'S'; vga_text[80+43] = 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; +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) { uintptr_t v = (uintptr_t)p; return (uint16_t *)(v + (160 - ((v - 0xb8000) % 160))); } void PrintFileList() { - uint16_t *vga_text = &((uint16_t *)0xb8000)[80*4+3]; - uint8_t *diskReadBuf = (uint8_t *)0x20000; - VOLINFO vi; - - 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 - *(uint8_t *)vga_text = de.name[i]; - vga_text++; + uint16_t *vga_text = &((uint16_t *)0xb8000)[80*6+3]; + for (int i = 0; i < fileCount; i++) { + DIRENT *de = &entries[i]; + 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 = nextLine(vga_text) + 3; + } +} +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; } - 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 = nextLine(vga_text) + 3; - fileCount++; + 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; uint16_t *vga_text = (uint16_t *)0xb8000; 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(); if (lastFileHovered != fileHovered) { - vga_text[80*(4+lastFileHovered)+2] = 0x1f00 | ' '; + *(uint8_t*)&vga_text[80*(6+lastFileHovered)+2] = ' '; lastFileHovered = fileHovered; } - vga_text[80*(4+fileHovered)+2] = 0x1f00 | '>'; + *(uint8_t*)&vga_text[80*(6+fileHovered)+2] = '>'; uint16_t key = get_scancode(); + uint8_t path[13], tmp, trailingSpace; switch (key & 0xff) { // scancode component case 0x50: // down fileHovered++; @@ -236,6 +348,23 @@ void FileSelect() { case 0x14: // t RunTests(vga_text); 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: break; } diff --git a/print.c b/print.c index 5d87c7b..7fbb935 100644 --- a/print.c +++ b/print.c @@ -26,6 +26,11 @@ uintptr_t printStr(char *v, uint16_t *buff) { 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) { char b[12]; char *s = &b[11]; diff --git a/print.h b/print.h index 43cdc37..27cd59b 100644 --- a/print.h +++ b/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 printStr(char *v, uint16_t *buff); uintptr_t printDec(uint32_t v, uint16_t *buff); +uintptr_t printChar(char v, uint16_t *buff); diff --git a/tests.c b/tests.c index e263e74..031ea08 100644 --- a/tests.c +++ b/tests.c @@ -14,7 +14,16 @@ void TestV86() { FARPTR v86_entry = i386LinearToFp(v86Test); 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() { + ReloadUser(); char *vga = jmp_usermode_test(); for (int i = 0; i < 320; i++) { vga[i] = i; @@ -126,9 +135,6 @@ void RunTests(uint16_t *vga_text) { TestDiskRead(); kbd_wait(); TestFAT(); - kbd_wait(); - TestFAT(); - kbd_wait(); vga_text = &((uint16_t*)0xB8000)[80*16]; vga_text += printStr("Press E for a flagrant system error. Press C to continue... ", vga_text);