From 964cbcd68dfdede67f46e27c1cae9237ae015604 Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Thu, 2 Feb 2023 21:40:39 -0600 Subject: [PATCH] Added a file selection screen (that does nothing), Moved tests to their own file, Fixed a race condition with the keyboard handler --- Makefile | 2 +- boot.nasm | 5 +- fault.nasm | 1 + interrupt.c | 51 ++++++++++---- interrupt.h | 3 + kernel.c | 197 ++++++++++++++++++++++------------------------------ tests.c | 152 ++++++++++++++++++++++++++++++++++++++++ tests.h | 6 ++ v86defs.h | 1 + 9 files changed, 287 insertions(+), 131 deletions(-) create mode 100644 tests.c create mode 100644 tests.h diff --git a/Makefile b/Makefile index 413c5ca..f5faca4 100644 --- a/Makefile +++ b/Makefile @@ -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 %.o: %.nasm diff --git a/boot.nasm b/boot.nasm index cedfe4a..23e7669 100644 --- a/boot.nasm +++ b/boot.nasm @@ -1,6 +1,5 @@ [ORG 0x7c00] [BITS 16] - xor ax, ax mov ds, ax mov es, ax @@ -72,5 +71,5 @@ string: db 'DISK ERROR' addr_packet: db 0x10, 0x00 ; size, reserved dw 0x39 ; blocks -dd 0x8000 ; transfer buffer -dq 1 ; start block +addr_packet_transfer_buff: dd 0x08000000 ; transfer buffer +addr_packet_start_block: dq 1 ; start block diff --git a/fault.nasm b/fault.nasm index ee8fd84..682abbd 100644 --- a/fault.nasm +++ b/fault.nasm @@ -50,6 +50,7 @@ jmp gpf_handler_32 gpf_unhandled: mov dword [error_screen+0x00], 0x0f000f00 | 'G' | 'P' << 16 mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16 +xchg bx,bx jmp _fault_coda _gpf_old_ds: dw 0 diff --git a/interrupt.c b/interrupt.c index d06380d..fa82aec 100644 --- a/interrupt.c +++ b/interrupt.c @@ -82,6 +82,7 @@ void IRQ_clear_mask(char IRQline) { } char v86_if = 0; +extern uint16_t error_screen[80*50]; // defined in kernel.c extern uint16_t *ivt; extern void real_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); 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] = '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 = (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] = '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] = '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; @@ -127,7 +128,8 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { // printByte(ip[i], vga); // vga += (sizeof(uint8_t)*2)*2; //} - vga = (char*)0xb8000 + (160*3); + + vga = (char*)error_screen + (160*3); for(;;) { switch (ip[0]) { case 0x66: // O32 @@ -220,14 +222,14 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { } } 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] = '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 = (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] = '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] = '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; @@ -266,9 +268,16 @@ uint8_t scancodesToAsciiShift[0x3B] = "\0"; // 0x3A uint8_t _KBDWAIT; uint8_t _KEYCAPS = 0, _KEYSHIFT = 0; -uint8_t _LSTKEY = 0; +uint8_t _LSTKEY_ASCII = 0, _LSTKEY_SCAN = 0; __attribute__ ((interrupt)) 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; asm volatile("inb $0x60, %%al":"=a"(key)); if (key == 0x3A) { // caps lock press @@ -282,11 +291,19 @@ void keyboardHandler(struct interrupt_frame *frame) { scancodesToAsciiShift[key] : scancodesToAscii[key]; if (ascii) { - _LSTKEY = ascii; + _LSTKEY_ASCII = ascii; + _LSTKEY_SCAN = key; _KBDWAIT = 1; } + } else { + _LSTKEY_ASCII = 0; + _LSTKEY_SCAN = key; } asm volatile("outb %%al, $0x20"::"a"(0x20)); + asm volatile( + "mov %%ax, %%ds\n" + ::"a"(old_ds) + ); } __attribute((__no_caller_saved_registers__)) @@ -299,11 +316,21 @@ void kbd_wait() { __attribute((__no_caller_saved_registers__)) uint8_t get_key() { - while(!_LSTKEY) { + while(!_LSTKEY_ASCII) { asm volatile("hlt"); } - uint8_t k = _LSTKEY; - _LSTKEY = 0; + uint8_t k = _LSTKEY_ASCII; + _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; } diff --git a/interrupt.h b/interrupt.h index 5aeefcf..e77ef32 100644 --- a/interrupt.h +++ b/interrupt.h @@ -1,3 +1,4 @@ +#pragma once #include struct interrupt_frame { @@ -33,6 +34,8 @@ void kbd_wait(); __attribute((__no_caller_saved_registers__)) uint8_t get_key(); +__attribute((__no_caller_saved_registers__)) +uint16_t get_scancode(); __attribute__ ((interrupt)) void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code); diff --git a/kernel.c b/kernel.c index 5e3f6d1..ccaa401 100644 --- a/kernel.c +++ b/kernel.c @@ -6,6 +6,7 @@ #include "tss.h" #include "paging.h" #include "v86defs.h" +#include "tests.h" typedef unsigned short word; @@ -54,8 +55,6 @@ uint32_t get_cr4() { return reg; } -extern char *jmp_usermode_test(); - extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode; void setup_binary() { // Put V86 code in proper place based on linker @@ -142,95 +141,62 @@ Protected Only (1MB+) 400000 - 700000 Usermode Code (3mB) 700000 - 800000 Usermode Stack (1mB) */ - -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), ®s); -} -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), ®s); - 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), ®s); - 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; +void DrawScreen() { + uint16_t *vga_text = (uint16_t *)0xB8000; + // clear screen 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; uint8_t pactive, ptype; uint32_t pstart, 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); - 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; di.scratch = diskReadBuf; DFS_OpenDir(&vi, (uint8_t*)"", &di); - vga_text = (word *)((((((uintptr_t)vga_text)-0xb8000) - ((((uintptr_t)vga_text)-0xb8000) % 160)) + 160)+0xb8000); DIRENT de; + fileCount = 0; while (!DFS_GetNext(&vi, &di, &de)) { if (de.name[0]) { for (int i = 0; i < 11 && de.name[i]; i++) { @@ -241,9 +207,38 @@ void TestFAT() { 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 = (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++; //print_cr3(); //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(); - 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 += 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; - }} + vga_text = &((word *)0xb8000)[80]; + vga_text += printStr("Press T for tests, or any key to continue... ", vga_text); + uint8_t key = get_key(); + if (key == 't' || key == 'T') + RunTests(vga_text); + DrawScreen(); + FileSelect(); } diff --git a/tests.c b/tests.c new file mode 100644 index 0000000..e263e74 --- /dev/null +++ b/tests.c @@ -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), ®s); +} +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), ®s); + 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), ®s); + 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; + }} +} + diff --git a/tests.h b/tests.h new file mode 100644 index 0000000..5f1fb35 --- /dev/null +++ b/tests.h @@ -0,0 +1,6 @@ +#include "dosfs/dosfs.h" +#include "print.h" +#include "interrupt.h" +#include "v86defs.h" + +void RunTests(uint16_t *vga_text); diff --git a/v86defs.h b/v86defs.h index cebd680..acf20b6 100644 --- a/v86defs.h +++ b/v86defs.h @@ -1,3 +1,4 @@ +#pragma once #include extern void v86Test();