Bootloader can load more from disk, Text file viewer added
This commit is contained in:
parent
d0fbc7df56
commit
d63430bb4d
37
boot.nasm
37
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]
|
[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
226
kernel.c
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user