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 "../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
|
||||
|
@ -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 };
|
||||
|
@ -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:
|
||||
|
199
kernel.c
199
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;
|
||||
}
|
||||
|
5
print.c
5
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];
|
||||
|
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 printStr(char *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);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user