Added a file selection screen (that does nothing), Moved tests to their own file, Fixed a race condition with the keyboard handler

This commit is contained in:
Lucia Ceionia 2023-02-02 21:40:39 -06:00
parent 2114741766
commit 964cbcd68d
9 changed files with 287 additions and 131 deletions

View File

@ -1,4 +1,4 @@
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o fault.o objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o fault.o tests.o
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
%.o: %.nasm %.o: %.nasm

View File

@ -1,6 +1,5 @@
[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
@ -72,5 +71,5 @@ string: db 'DISK ERROR'
addr_packet: addr_packet:
db 0x10, 0x00 ; size, reserved db 0x10, 0x00 ; size, reserved
dw 0x39 ; blocks dw 0x39 ; blocks
dd 0x8000 ; transfer buffer addr_packet_transfer_buff: dd 0x08000000 ; transfer buffer
dq 1 ; start block addr_packet_start_block: dq 1 ; start block

View File

@ -50,6 +50,7 @@ jmp gpf_handler_32
gpf_unhandled: gpf_unhandled:
mov dword [error_screen+0x00], 0x0f000f00 | 'G' | 'P' << 16 mov dword [error_screen+0x00], 0x0f000f00 | 'G' | 'P' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16 mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
xchg bx,bx
jmp _fault_coda jmp _fault_coda
_gpf_old_ds: dw 0 _gpf_old_ds: dw 0

View File

@ -82,6 +82,7 @@ void IRQ_clear_mask(char IRQline) {
} }
char v86_if = 0; char v86_if = 0;
extern uint16_t error_screen[80*50]; // defined in kernel.c
extern uint16_t *ivt; extern uint16_t *ivt;
extern void real_test(); extern void real_test();
extern void jmp_usermode_test(); extern void jmp_usermode_test();
@ -99,14 +100,14 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
stack = FP_TO_LINEAR(frame->ss, frame->esp); stack = FP_TO_LINEAR(frame->ss, frame->esp);
stack32 = (uint32_t*)stack; stack32 = (uint32_t*)stack;
char *vga = (char*)0xb8000 + (160 * 10); char *vga = (char*)error_screen + (160 * 10);
vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
vga = (char*)0xb8000 + (160 * 11); vga = (char*)error_screen + (160 * 11);
vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
vga = (char*)0xb8000 + (160 * 12); vga = (char*)error_screen + (160 * 12);
vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14;
@ -127,7 +128,8 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
// printByte(ip[i], vga); // printByte(ip[i], vga);
// vga += (sizeof(uint8_t)*2)*2; // vga += (sizeof(uint8_t)*2)*2;
//} //}
vga = (char*)0xb8000 + (160*3);
vga = (char*)error_screen + (160*3);
for(;;) { for(;;) {
switch (ip[0]) { switch (ip[0]) {
case 0x66: // O32 case 0x66: // O32
@ -220,14 +222,14 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
} }
} }
done:; done:;
vga = (char*)0xb8000 + (160 * 13); vga = (char*)error_screen + (160 * 13);
vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
vga = (char*)0xb8000 + (160 * 14); vga = (char*)error_screen + (160 * 14);
vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
vga = (char*)0xb8000 + (160 * 15); vga = (char*)error_screen + (160 * 15);
vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14;
vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14; vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14;
@ -266,9 +268,16 @@ uint8_t scancodesToAsciiShift[0x3B] =
"\0"; // 0x3A "\0"; // 0x3A
uint8_t _KBDWAIT; uint8_t _KBDWAIT;
uint8_t _KEYCAPS = 0, _KEYSHIFT = 0; uint8_t _KEYCAPS = 0, _KEYSHIFT = 0;
uint8_t _LSTKEY = 0; uint8_t _LSTKEY_ASCII = 0, _LSTKEY_SCAN = 0;
__attribute__ ((interrupt)) __attribute__ ((interrupt))
void keyboardHandler(struct interrupt_frame *frame) { void keyboardHandler(struct interrupt_frame *frame) {
uint16_t old_ds;
asm volatile(
"mov %%ds, %%bx\n"
"mov $0x10, %%ax\n"
"mov %%ax, %%ds\n"
:"=b"(old_ds)::"%ax"
);
uint8_t key; uint8_t key;
asm volatile("inb $0x60, %%al":"=a"(key)); asm volatile("inb $0x60, %%al":"=a"(key));
if (key == 0x3A) { // caps lock press if (key == 0x3A) { // caps lock press
@ -282,11 +291,19 @@ void keyboardHandler(struct interrupt_frame *frame) {
scancodesToAsciiShift[key] : scancodesToAsciiShift[key] :
scancodesToAscii[key]; scancodesToAscii[key];
if (ascii) { if (ascii) {
_LSTKEY = ascii; _LSTKEY_ASCII = ascii;
_LSTKEY_SCAN = key;
_KBDWAIT = 1; _KBDWAIT = 1;
} }
} else {
_LSTKEY_ASCII = 0;
_LSTKEY_SCAN = key;
} }
asm volatile("outb %%al, $0x20"::"a"(0x20)); asm volatile("outb %%al, $0x20"::"a"(0x20));
asm volatile(
"mov %%ax, %%ds\n"
::"a"(old_ds)
);
} }
__attribute((__no_caller_saved_registers__)) __attribute((__no_caller_saved_registers__))
@ -299,11 +316,21 @@ void kbd_wait() {
__attribute((__no_caller_saved_registers__)) __attribute((__no_caller_saved_registers__))
uint8_t get_key() { uint8_t get_key() {
while(!_LSTKEY) { while(!_LSTKEY_ASCII) {
asm volatile("hlt"); asm volatile("hlt");
} }
uint8_t k = _LSTKEY; uint8_t k = _LSTKEY_ASCII;
_LSTKEY = 0; _LSTKEY_ASCII = 0;
return k;
}
__attribute((__no_caller_saved_registers__))
uint16_t get_scancode() {
while(!_LSTKEY_SCAN) {
asm volatile("hlt");
}
uint16_t k = _LSTKEY_SCAN | (_LSTKEY_ASCII << 8);
_LSTKEY_SCAN = 0;
_LSTKEY_ASCII = 0;
return k; return k;
} }

View File

@ -1,3 +1,4 @@
#pragma once
#include <stdint.h> #include <stdint.h>
struct interrupt_frame { struct interrupt_frame {
@ -33,6 +34,8 @@ void kbd_wait();
__attribute((__no_caller_saved_registers__)) __attribute((__no_caller_saved_registers__))
uint8_t get_key(); uint8_t get_key();
__attribute((__no_caller_saved_registers__))
uint16_t get_scancode();
__attribute__ ((interrupt)) __attribute__ ((interrupt))
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code); void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code);

197
kernel.c
View File

@ -6,6 +6,7 @@
#include "tss.h" #include "tss.h"
#include "paging.h" #include "paging.h"
#include "v86defs.h" #include "v86defs.h"
#include "tests.h"
typedef unsigned short word; typedef unsigned short word;
@ -54,8 +55,6 @@ uint32_t get_cr4() {
return reg; return reg;
} }
extern char *jmp_usermode_test();
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode; extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
void setup_binary() { void setup_binary() {
// Put V86 code in proper place based on linker // Put V86 code in proper place based on linker
@ -142,95 +141,62 @@ Protected Only (1MB+)
400000 - 700000 Usermode Code (3mB) 400000 - 700000 Usermode Code (3mB)
700000 - 800000 Usermode Stack (1mB) 700000 - 800000 Usermode Stack (1mB)
*/ */
void DrawScreen() {
void TestV86() { uint16_t *vga_text = (uint16_t *)0xB8000;
union V86Regs_t regs; // clear screen
regs.d.edi = 0x11111111;
regs.d.esi = 0x22222222;
regs.d.ebx = 0x33333333;
regs.d.edx = 0x44444444;
regs.d.ecx = 0x55555555;
regs.d.eax = 0x66666666;
FARPTR v86_entry = i386LinearToFp(v86Test);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
}
void TestUser() {
char *vga = jmp_usermode_test();
for (int i = 0; i < 320; i++) {
vga[i] = i;
}
}
void TestDiskRead() {
union V86Regs_t regs;
word *vga_text = (word *)0xb8000 + (80*5);
vga_text += printStr("Setting Text Mode... ", vga_text);
regs.w.ax = 3; // text mode
FARPTR v86_entry = i386LinearToFp(v86VideoInt);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
vga_text += printStr("Done. Starting Disk Read... ", vga_text);
v86_entry = i386LinearToFp(v86DiskRead);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
vga_text = (word *)0xb8000;
char *diskReadBuf = (char *)0x23000;
for (int i = 0; i < (80*25)/2; i++) {
printByte(diskReadBuf[i], &vga_text[i*2]);
}
}
void TestFAT() {
word *vga_text = (word *)0xb8000;
uint8_t *diskReadBuf = (uint8_t *)0x22400;
for (int i = 0; i < 80*25; i++) for (int i = 0; i < 80*25; i++)
vga_text[i] = 0x0f00; vga_text[i] = 0x1f00;
// draw border
for (int c = 1; c < 79; c++) {
vga_text[c] = 0x1fc4; // top line
vga_text[(2*80)+c] = 0x1fc4; // 3rd line
vga_text[(24*80)+c] = 0x1fc4; // bottom line
}
for (int l = 1; l < 24; l++) {
vga_text[80*l] = 0x1fb3;
vga_text[(80*l)+79] = 0x1fb3;
}
vga_text[0] = 0x1fda;
vga_text[79] = 0x1fbf;
vga_text[2*80] = 0x1fc3;
vga_text[2*80+79] = 0x1fb4;
vga_text[24*80] = 0x1fc0;
vga_text[24*80+79] = 0x1fd9;
// name
vga_text[80+34] = 0x1f00 | '-';
vga_text[80+35] = 0x1f00 | ' ';
vga_text[80+36] = 0x1f00 | 'L';
vga_text[80+37] = 0x1f00 | 'u';
vga_text[80+38] = 0x1f00 | 'c';
vga_text[80+39] = 0x1f00 | 'i';
vga_text[80+40] = 0x1f00 | 'a';
vga_text[80+41] = 0x1f00 | 'O';
vga_text[80+42] = 0x1f00 | 'S';
vga_text[80+43] = 0x1f00 | ' ';
vga_text[80+44] = 0x1f00 | '-';
}
int32_t 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; VOLINFO vi;
uint8_t pactive, ptype; uint8_t pactive, ptype;
uint32_t pstart, psize; uint32_t pstart, psize;
pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize); pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
vga_text = (word *)0xb8000;
vga_text += printStr("PartStart: ", vga_text);
vga_text += printDword(pstart, vga_text);
vga_text += 2;
vga_text += printStr("PartSize: ", vga_text);
vga_text += printDword(psize, vga_text);
vga_text += 2;
vga_text += printStr("PartActive: ", vga_text);
vga_text += printByte(pactive, vga_text);
vga_text += 2;
vga_text += printStr("PartType: ", vga_text);
vga_text += printByte(ptype, vga_text);
vga_text = (word *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
//asm ("xchgw %bx, %bx");
DFS_GetVolInfo(0, diskReadBuf, pstart, &vi); DFS_GetVolInfo(0, diskReadBuf, pstart, &vi);
vga_text += printStr("Label: ", vga_text);
vga_text += printStr((char*)vi.label, vga_text);
vga_text += 2;
vga_text += printStr("Sec/Clus: ", vga_text);
vga_text += printByte(vi.secperclus, vga_text);
vga_text += 2;
vga_text += printStr("ResrvSec: ", vga_text);
vga_text += printWord(vi.reservedsecs, vga_text);
vga_text += 2;
vga_text += printStr("NumSec: ", vga_text);
vga_text += printDword(vi.numsecs, vga_text);
vga_text += 2;
vga_text += printStr("Sec/FAT: ", vga_text);
vga_text += printDword(vi.secperfat, vga_text);
vga_text += 2;
vga_text += printStr("FAT1@: ", vga_text);
vga_text += printDword(vi.fat1, vga_text);
vga_text += 2;
vga_text += printStr("ROOT@: ", vga_text);
vga_text += printDword(vi.rootdir, vga_text);
vga_text = (word *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
//asm ("xchgw %bx, %bx");
vga_text += printStr("Files in root:", vga_text);
DIRINFO di; DIRINFO di;
di.scratch = diskReadBuf; di.scratch = diskReadBuf;
DFS_OpenDir(&vi, (uint8_t*)"", &di); DFS_OpenDir(&vi, (uint8_t*)"", &di);
vga_text = (word *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
DIRENT de; DIRENT de;
fileCount = 0;
while (!DFS_GetNext(&vi, &di, &de)) { while (!DFS_GetNext(&vi, &di, &de)) {
if (de.name[0]) { if (de.name[0]) {
for (int i = 0; i < 11 && de.name[i]; i++) { for (int i = 0; i < 11 && de.name[i]; i++) {
@ -241,9 +207,38 @@ void TestFAT() {
vga_text += printStr(" ", 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); 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'; *(uint8_t*)vga_text++ = 'B';
vga_text = (word *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000); vga_text = nextLine(vga_text) + 3;
fileCount++;
}
}
}
void FileSelect() {
fileCount = 5;
uint16_t *vga_text = (uint16_t *)0xb8000;
int32_t fileHovered = 0, lastFileHovered = 0;
for (;;) {
PrintFileList();
if (lastFileHovered != fileHovered) {
vga_text[80*(4+lastFileHovered)+2] = 0x1f00 | ' ';
lastFileHovered = fileHovered;
}
vga_text[80*(4+fileHovered)+2] = 0x1f00 | '>';
uint16_t key = get_scancode();
switch (key & 0xff) { // scancode component
case 0x50: // down
fileHovered++;
if (fileHovered >= fileCount) fileHovered = 0;
break;
case 0x48: // up
fileHovered--;
if (fileHovered < 0) fileHovered = fileCount - 1;
break;
case 0x14: // t
RunTests(vga_text);
DrawScreen();
default:
break;
} }
//asm ("xchgw %bx, %bx");
} }
} }
@ -291,42 +286,14 @@ void start() {
vga_text++; vga_text++;
//print_cr3(); //print_cr3();
//print_cr4(); //print_cr4();
vga_text += printStr("V86 Test... ", vga_text);
//asm ("xchgw %bx, %bx");
TestV86(); // has int 3 wait in v86
vga_text = (word *)0xb8000 + (80*3);
backup_ivtbios(); backup_ivtbios();
vga_text += printStr("Done. Press 'N' for next test.", vga_text);
uint8_t key;
while ((key = get_key()) != 'N') {
*vga_text = (*vga_text & 0xFF00) | key;
vga_text++;
}
TestUser();
kbd_wait();
TestDiskRead();
kbd_wait();
TestFAT();
kbd_wait();
vga_text = &((uint16_t*)0xB8000)[80*16]; vga_text = &((word *)0xb8000)[80];
vga_text += printStr("Press E for a flagrant system error. Press C to continue... ", vga_text); vga_text += printStr("Press T for tests, or any key to continue... ", vga_text);
for (char l = 1;l;) { switch (key = get_key()) { uint8_t key = get_key();
case 'e': if (key == 't' || key == 'T')
case 'E': RunTests(vga_text);
// flagrant system error DrawScreen();
*((uint8_t*)0x1000000) = 0; FileSelect();
break;
case 'c':
case 'C':
// continue
l = 0;
break;
default:
*vga_text = (*vga_text & 0xFF00) | key;
vga_text++;
break;
}}
} }

152
tests.c Normal file
View File

@ -0,0 +1,152 @@
#include "tests.h"
#include "v86defs.h"
extern char *jmp_usermode_test();
void TestV86() {
union V86Regs_t regs;
regs.d.edi = 0x11111111;
regs.d.esi = 0x22222222;
regs.d.ebx = 0x33333333;
regs.d.edx = 0x44444444;
regs.d.ecx = 0x55555555;
regs.d.eax = 0x66666666;
FARPTR v86_entry = i386LinearToFp(v86Test);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
}
void TestUser() {
char *vga = jmp_usermode_test();
for (int i = 0; i < 320; i++) {
vga[i] = i;
}
}
void TestDiskRead() {
union V86Regs_t regs;
uint16_t *vga_text = (uint16_t *)0xb8000 + (80*5);
vga_text += printStr("Setting Text Mode... ", vga_text);
regs.w.ax = 3; // text mode
FARPTR v86_entry = i386LinearToFp(v86VideoInt);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
vga_text += printStr("Done. Starting Disk Read... ", vga_text);
char *diskReadBuf = (char *)0x23000;
v86disk_addr_packet.transfer_buffer =
(uintptr_t)diskReadBuf & 0x000F |
(((uintptr_t)diskReadBuf & 0xFFFF0) << 12);
v86_entry = i386LinearToFp(v86DiskRead);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
vga_text = (uint16_t *)0xb8000;
for (int i = 0; i < (80*25)/2; i++) {
printByte(diskReadBuf[i], &vga_text[i*2]);
}
}
void TestFAT() {
uint16_t *vga_text = (uint16_t *)0xb8000;
uint8_t *diskReadBuf = (uint8_t *)0x22400;
for (int i = 0; i < 80*25; i++)
vga_text[i] = 0x0f00;
VOLINFO vi;
uint8_t pactive, ptype;
uint32_t pstart, psize;
pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
vga_text = (uint16_t *)0xb8000;
vga_text += printStr("PartStart: ", vga_text);
vga_text += printDword(pstart, vga_text);
vga_text += 2;
vga_text += printStr("PartSize: ", vga_text);
vga_text += printDword(psize, vga_text);
vga_text += 2;
vga_text += printStr("PartActive: ", vga_text);
vga_text += printByte(pactive, vga_text);
vga_text += 2;
vga_text += printStr("PartType: ", vga_text);
vga_text += printByte(ptype, vga_text);
vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
//asm ("xchgw %bx, %bx");
DFS_GetVolInfo(0, diskReadBuf, pstart, &vi);
vga_text += printStr("Label: ", vga_text);
vga_text += printStr((char*)vi.label, vga_text);
vga_text += 2;
vga_text += printStr("Sec/Clus: ", vga_text);
vga_text += printByte(vi.secperclus, vga_text);
vga_text += 2;
vga_text += printStr("ResrvSec: ", vga_text);
vga_text += printWord(vi.reservedsecs, vga_text);
vga_text += 2;
vga_text += printStr("NumSec: ", vga_text);
vga_text += printDword(vi.numsecs, vga_text);
vga_text += 2;
vga_text += printStr("Sec/FAT: ", vga_text);
vga_text += printDword(vi.secperfat, vga_text);
vga_text += 2;
vga_text += printStr("FAT1@: ", vga_text);
vga_text += printDword(vi.fat1, vga_text);
vga_text += 2;
vga_text += printStr("ROOT@: ", vga_text);
vga_text += printDword(vi.rootdir, vga_text);
vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
//asm ("xchgw %bx, %bx");
vga_text += printStr("Files in root:", vga_text);
DIRINFO di;
di.scratch = diskReadBuf;
DFS_OpenDir(&vi, (uint8_t*)"", &di);
vga_text = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
DIRENT de;
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++;
}
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 = (uint16_t *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000);
}
//asm ("xchgw %bx, %bx");
}
}
void RunTests(uint16_t *vga_text) {
uint8_t key;
vga_text += printStr("V86 Test... ", vga_text);
//asm ("xchgw %bx, %bx");
TestV86(); // has int 3 wait in v86
vga_text = (uint16_t *)0xb8000 + (80*3);
vga_text += printStr("Done. Press 'N' for next test.", vga_text);
while ((key = get_key()) != 'N') {
*vga_text = (*vga_text & 0xFF00) | key;
vga_text++;
}
TestUser();
kbd_wait();
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);
for (char l = 1;l;) { switch (key = get_key()) {
case 'e':
case 'E':
// flagrant system error
*((uint8_t*)0x1000000) = 0;
break;
case 'c':
case 'C':
// continue
l = 0;
break;
default:
*vga_text = (*vga_text & 0xFF00) | key;
vga_text++;
break;
}}
}

6
tests.h Normal file
View File

@ -0,0 +1,6 @@
#include "dosfs/dosfs.h"
#include "print.h"
#include "interrupt.h"
#include "v86defs.h"
void RunTests(uint16_t *vga_text);

View File

@ -1,3 +1,4 @@
#pragma once
#include <stdint.h> #include <stdint.h>
extern void v86Test(); extern void v86Test();