Bootloader can load more from disk, Text file viewer added

This commit is contained in:
Lucia Ceionia 2023-02-06 00:01:48 -06:00
parent d0fbc7df56
commit d63430bb4d
2 changed files with 232 additions and 31 deletions

View File

@ -1,12 +1,33 @@
secreadcnt equ 0x38
kernelreads equ 0x10000/(512*secreadcnt) ; 64K / Sector Size FIXME This underestimates when kernel size is not divisible by bytes per read
[ORG 0x7c00] [ORG 0x7c00]
[BITS 16] [BITS 16]
xor ax, ax xor ax, ax
mov ds, ax mov ds, ax
mov es, ax mov es, ax
mov ax, 0x8000
mov ss, ax
mov sp, 0xFF00
mov cx, kernelreads
read_loop:
xor ax, ax
mov ah, 0x42 mov ah, 0x42
mov si, addr_packet mov si, addr_packet
int 0x13 int 0x13
jnc entry jc err
add word [addr_packet_transfer_buff_seg], (secreadcnt*512)/16
add word [addr_packet_start_block], secreadcnt
loop read_loop
entry:
cli ; no interrupts
xor ax,ax
mov ds, ax
lgdt [gdt_desc] ; load gdt register
mov eax, cr0 ; set pmode bit
or al, 1
mov cr0, eax
jmp 08h:Pmode
err:
push 0xb800 push 0xb800
pop es pop es
xor di, di xor di, di
@ -20,15 +41,6 @@ loop err_print
hlt_loop: hlt_loop:
hlt hlt
jmp hlt_loop jmp hlt_loop
entry:
cli ; no interrupts
xor ax,ax
mov ds, ax
lgdt [gdt_desc] ; load gdt register
mov eax, cr0 ; set pmode bit
or al, 1
mov cr0, eax
jmp 08h:Pmode
[BITS 32] [BITS 32]
Pmode: Pmode:
mov eax, 0x10 mov eax, 0x10
@ -70,6 +82,7 @@ string: db 'DISK ERROR'
addr_packet: addr_packet:
db 0x10, 0x00 ; size, reserved db 0x10, 0x00 ; size, reserved
dw 0x39 ; blocks dw secreadcnt ; blocks
addr_packet_transfer_buff: dd 0x08000000 ; transfer buffer addr_packet_transfer_buff_off: dw 0x0000 ; transfer buffer offset
addr_packet_transfer_buff_seg: dw 0x0800 ; transfer buffer segment
addr_packet_start_block: dq 1 ; start block addr_packet_start_block: dq 1 ; start block

226
kernel.c
View File

@ -202,10 +202,6 @@ 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) { uint32_t OpenVol(VOLINFO *vi) {
@ -258,7 +254,7 @@ void PrintFileList() {
vga_text = nextLine(vga_text) + 3; vga_text = nextLine(vga_text) + 3;
} }
} }
void FileReadTest(uint8_t *path, VOLINFO *vi) { void HexViewTest(uint8_t *path, VOLINFO *vi) {
uint32_t err; uint32_t err;
uint16_t *vga_text = (uint16_t *)0xb8000; uint16_t *vga_text = (uint16_t *)0xb8000;
uint8_t *scratch = (uint8_t *)0x20000; uint8_t *scratch = (uint8_t *)0x20000;
@ -389,11 +385,205 @@ void FileReadTest(uint8_t *path, VOLINFO *vi) {
} }
} }
} }
void TextViewTest(uint8_t *path, VOLINFO *vi) {
uint16_t *vga_text = (uint16_t *)0xb8000;
uint32_t fileLen;
uint8_t *diskReadBuf = (uint8_t *)0x500000;
{
uint32_t err;
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;
}
// file too large
if (fi.filelen > 0x300000) {
vga_text += printStr("File too large.", vga_text);
kbd_wait();
return;
}
DFS_Seek(&fi, 0, scratch);
if (fi.pointer != 0) {
vga_text += printStr("Seek Error", vga_text);
return;
}
err = DFS_ReadFile(&fi, scratch, diskReadBuf, &fileLen, fi.filelen);
if (err && err != DFS_EOF) {
vga_text += printStr("Read Error: ", vga_text);
printDword(err, vga_text);
return;
}
}
uint32_t *lineOffsets = (uint32_t *)0x400000;
uint32_t lastLine;
{
char nl;
uint8_t c = 0x0A; // start with a pretend newline
uint32_t line = -1; // start a pretend line behind
for (int32_t o = -1; o < (int32_t)fileLen; c = diskReadBuf[++o]) {
// newline
if (c == 0x0A) {
lineOffsets[++line] = o;
}
// file too large
if ((uintptr_t)&lineOffsets[line] >= 0x4FFFFC) {
vga_text += printStr("File too large.", vga_text);
kbd_wait();
return;
}
}
lastLine = line;
}
uint32_t currLine = 0;
char cont = 1;
uint32_t screenSize = 80*25;
char redraw = 1;
uint32_t linesOnScreen = 0;
for (;cont;) {
if (redraw) {
vga_text = (uint16_t *)0xb8000;
for (int i = 0; i < screenSize; i++)
vga_text[i] = 0x0f00;
vga_text += printStr((char*)path, vga_text);
vga_text += 2;
vga_text += printStr("Line: ", vga_text);
vga_text += printDec(currLine, vga_text);
vga_text += printChar('/', vga_text);
vga_text += printDec(lastLine, vga_text);
vga_text += printStr(" Scroll: Up/Down PgUp/PgDown Home/End", vga_text);
{
const char prnt[] = "Exit: E ";
vga_text = &((uint16_t*)0xb8000)[80-sizeof(prnt)];
vga_text += printStr((char*)prnt, vga_text);
}
for (vga_text = &((uint16_t*)0xb8000)[84]; vga_text < &((uint16_t*)0xb8000)[screenSize]; vga_text += 80)
*(uint8_t*)vga_text = '|';
vga_text = &((uint16_t*)0xb8000)[0];
uint32_t lineOff = 6;
uint8_t c = 0x0A; // start with a pretend newline
uint32_t line = currLine - 1; // start a pretend line behind
int32_t o = lineOffsets[currLine]; // the real or fake newline on previous line
linesOnScreen = screenSize/80;
for (; o < (int32_t)fileLen && vga_text < &((uint16_t*)0xb8000)[screenSize]; c = diskReadBuf[++o]) {
// newline
if (c == 0x0A) {
vga_text = nextLine(vga_text);
line++;
{
uint16_t *vga_tmp = vga_text;
uint16_t decTmp[11];
char cnt = printDec(line, decTmp);
char off = cnt <= 4 ? 0 : cnt - 4;
vga_tmp += 4 - (cnt - off);
for (int i = off; i < cnt; i++, vga_tmp++)
*(uint8_t*)vga_tmp = (uint8_t)decTmp[i];
}
vga_text += 6;
lineOff = 6;
continue;
}
*(uint8_t*)vga_text = c;
vga_text++;
lineOff++;
if (lineOff == 80) { // last char
vga_text += 6;
lineOff = 6;
linesOnScreen--;
}
}
redraw = 0;
}
uint16_t key = get_scancode();
union V86Regs_t regs;
FARPTR v86_entry;
switch (key & 0xff) {
case KEY_DOWN: // down
if (currLine < lastLine && lineOffsets[currLine+1] < fileLen) {
currLine++;
redraw = 1;
}
break;
case KEY_UP: // up
if ((currLine > 0 && lineOffsets[currLine-1] < fileLen) || currLine == 1) {
currLine--;
redraw = 1;
}
break;
case KEY_PGDOWN:
if (currLine+(linesOnScreen/2) <= lastLine && lineOffsets[currLine+(linesOnScreen/2)] < fileLen) {
currLine += (linesOnScreen/2);
redraw = 1;
} else goto end;
break;
case KEY_PGUP:
if (currLine > (linesOnScreen/2) && lineOffsets[currLine-(linesOnScreen/2)] < fileLen) {
currLine -= (linesOnScreen/2);
redraw = 1;
} else if (currLine <= (linesOnScreen/2)) {
currLine = 0;
redraw = 1;
}
break;
case KEY_HOME: home:
if (currLine != 0) {
currLine = 0;
redraw = 1;
}
break;
case KEY_END: end:
if (currLine != lastLine) {
currLine = lastLine;
redraw = 1;
}
break;
case KEY_E: // e
cont = 0;
break;
case KEY_F2:
if (screenSize != 80*25) {
SetVideo25Lines();
SetCursorDisabled();
screenSize = 80*25;
redraw = 1;
}
break;
case KEY_F5:
if (screenSize != 80*50) {
SetVideo50Lines();
SetCursorDisabled();
screenSize = 80*50;
redraw = 1;
}
break;
default:
break;
}
}
}
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++] = '.';
for (int i = 8; i < 11 && src[i]; i++, tmp++) {
path[tmp] = src[i];
}
path[tmp] = 0;
}
void FileSelect() { 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 (char reload = 1;;) { for (char reload = 1;;) {
// Info line (4)
printStr("T to run tests - X to view in hex - V to view as text", &vga_text[80*4+2]);
VOLINFO vi; DIRINFO di; VOLINFO vi; DIRINFO di;
if (reload) { if (reload) {
OpenVol(&vi); OpenVol(&vi);
@ -408,7 +598,7 @@ void FileSelect() {
} }
*(uint8_t*)&vga_text[80*(6+fileHovered)+2] = '>'; *(uint8_t*)&vga_text[80*(6+fileHovered)+2] = '>';
uint16_t key = get_scancode(); uint16_t key = get_scancode();
uint8_t path[13], tmp, trailingSpace; uint8_t path[13];
switch (key & 0xff) { // scancode component switch (key & 0xff) { // scancode component
case 0x50: // down case 0x50: // down
fileHovered++; fileHovered++;
@ -423,23 +613,21 @@ void FileSelect() {
DrawScreen(); DrawScreen();
reload = 1; reload = 1;
break; break;
case 0x18: // o case KEY_X:
for (trailingSpace=0, tmp = 0; tmp < 8 && entries[fileHovered].name[tmp]; tmp++) { File83ToPath((char*)entries[fileHovered].name, (char*)path);
path[tmp] = entries[fileHovered].name[tmp]; HexViewTest(path, &vi);
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);
SetVideo25Lines(); SetVideo25Lines();
SetCursorDisabled(); SetCursorDisabled();
DrawScreen(); DrawScreen();
break; break;
case KEY_V:
File83ToPath((char*)entries[fileHovered].name, (char*)path);
TextViewTest(path, &vi);
SetVideo25Lines();
SetCursorDisabled();
DrawScreen();
reload = 1;
break;
default: default:
break; break;
} }