From d63430bb4d646a3729017aa56995ddf1ca56e521 Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Mon, 6 Feb 2023 00:01:48 -0600 Subject: [PATCH] Bootloader can load more from disk, Text file viewer added --- boot.nasm | 37 ++++++--- kernel.c | 226 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 232 insertions(+), 31 deletions(-) diff --git a/boot.nasm b/boot.nasm index 23e7669..1186a9d 100644 --- a/boot.nasm +++ b/boot.nasm @@ -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] [BITS 16] xor ax, ax mov ds, 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 si, addr_packet 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 pop es xor di, di @@ -20,15 +41,6 @@ loop err_print hlt_loop: hlt 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] Pmode: mov eax, 0x10 @@ -70,6 +82,7 @@ string: db 'DISK ERROR' addr_packet: db 0x10, 0x00 ; size, reserved -dw 0x39 ; blocks -addr_packet_transfer_buff: dd 0x08000000 ; transfer buffer +dw secreadcnt ; blocks +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 diff --git a/kernel.c b/kernel.c index 97b4963..4d79d5c 100644 --- a/kernel.c +++ b/kernel.c @@ -202,10 +202,6 @@ 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) { @@ -258,7 +254,7 @@ void PrintFileList() { vga_text = nextLine(vga_text) + 3; } } -void FileReadTest(uint8_t *path, VOLINFO *vi) { +void HexViewTest(uint8_t *path, VOLINFO *vi) { uint32_t err; uint16_t *vga_text = (uint16_t *)0xb8000; 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() { fileCount = 5; uint16_t *vga_text = (uint16_t *)0xb8000; int32_t fileHovered = 0, lastFileHovered = 0; 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; if (reload) { OpenVol(&vi); @@ -408,7 +598,7 @@ void FileSelect() { } *(uint8_t*)&vga_text[80*(6+fileHovered)+2] = '>'; uint16_t key = get_scancode(); - uint8_t path[13], tmp, trailingSpace; + uint8_t path[13]; switch (key & 0xff) { // scancode component case 0x50: // down fileHovered++; @@ -423,23 +613,21 @@ void FileSelect() { 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); + case KEY_X: + File83ToPath((char*)entries[fileHovered].name, (char*)path); + HexViewTest(path, &vi); SetVideo25Lines(); SetCursorDisabled(); DrawScreen(); break; + case KEY_V: + File83ToPath((char*)entries[fileHovered].name, (char*)path); + TextViewTest(path, &vi); + SetVideo25Lines(); + SetCursorDisabled(); + DrawScreen(); + reload = 1; + break; default: break; }