From d0fbc7df560813d82f70b4167e255c4f451da6e5 Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Sun, 5 Feb 2023 19:57:06 -0600 Subject: [PATCH] Added enum for scancodes, More control in hex viewer, hex viewer can switch between 25/50 lines --- Makefile | 2 +- interrupt.c | 100 +-------------------------------------------------- interrupt.h | 8 ----- kbd.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ kbd.h | 45 +++++++++++++++++++++++ kernel.c | 99 ++++++++++++++++++++++++++++++++++++++++++++------ tests.h | 1 + 7 files changed, 237 insertions(+), 119 deletions(-) create mode 100644 kbd.c create mode 100644 kbd.h diff --git a/Makefile b/Makefile index f5faca4..dc1017e 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 tests.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 kbd.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/interrupt.c b/interrupt.c index fa82aec..54e2fc8 100644 --- a/interrupt.c +++ b/interrupt.c @@ -2,6 +2,7 @@ #include #include "interrupt.h" +#include "kbd.h" char int_nibbleToHex(uint8_t n) { return n > 9 ? (n - 10) + 'A' : n + '0'; @@ -236,106 +237,7 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { vga[0] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14; } -uint8_t scancodesToAscii[0x3B] = -"\0\0" // 0x00 - 0x01 -"1234567890" // 0x02 - 0x0B -"-=" // 0x0C - 0x0D -"\0\0" // 0x0E - 0x0F -"qwertyuiop[]" // 0x10 - 0x1B -"\0\0" // 0x1C - 0x1D -"asdfghjkl;'`" // 0x1E - 0x29 -"\0" // 0x2A -"\\zxcvbnm,./" // 0x2B - 0x35 -"\0" // 0x36 -"*" // 0x37 -"\0" // 0x38 -" " // 0x39 -"\0"; // 0x3A -uint8_t scancodesToAsciiShift[0x3B] = -"\0\0" // 0x00 - 0x01 -"!@#$%^&*()" // 0x02 - 0x0B -"_+" // 0x0C - 0x0D -"\0\0" // 0x0E - 0x0F -"QWERTYUIOP{}" // 0x10 - 0x1B -"\0\0" // 0x1C - 0x1D -"ASDFGHJKL:\"~" // 0x1E - 0x29 -"\0" // 0x2A -"|ZXCVBNM<>?" // 0x2B - 0x35 -"\0" // 0x36 -"*" // 0x37 -"\0" // 0x38 -" " // 0x39 -"\0"; // 0x3A -uint8_t _KBDWAIT; -uint8_t _KEYCAPS = 0, _KEYSHIFT = 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 - _KEYCAPS = !_KEYCAPS; - } else if (key == 0x2A || key == 0x36) { // left and right shift press - _KEYSHIFT = 1; - } else if (key == 0xAA || key == 0xB6) { // left and right shift release - _KEYSHIFT = 0; - } else if (key < 0x3B) { - uint8_t ascii = _KEYCAPS != _KEYSHIFT ? - scancodesToAsciiShift[key] : - scancodesToAscii[key]; - if (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__)) -void kbd_wait() { - _KBDWAIT = 0; - while(!_KBDWAIT) { - asm volatile("hlt"); - } -} - -__attribute((__no_caller_saved_registers__)) -uint8_t get_key() { - while(!_LSTKEY_ASCII) { - asm volatile("hlt"); - } - 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; -} - extern void timerHandler(); -//extern void keyboardHandler(); extern void gpfHandler(); extern void pageFaultHandler(); extern void unhandled_handler(); diff --git a/interrupt.h b/interrupt.h index e77ef32..cfdb107 100644 --- a/interrupt.h +++ b/interrupt.h @@ -29,14 +29,6 @@ typedef uint32_t FARPTR; FARPTR i386LinearToFp(void *ptr); -__attribute((__no_caller_saved_registers__)) -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/kbd.c b/kbd.c new file mode 100644 index 0000000..2b6cec2 --- /dev/null +++ b/kbd.c @@ -0,0 +1,101 @@ +#include "interrupt.h" +#include "kbd.h" + +uint8_t scancodesToAscii[0x3B] = +"\0\0" // 0x00 - 0x01 +"1234567890" // 0x02 - 0x0B +"-=" // 0x0C - 0x0D +"\0\0" // 0x0E - 0x0F +"qwertyuiop[]" // 0x10 - 0x1B +"\0\0" // 0x1C - 0x1D +"asdfghjkl;'`" // 0x1E - 0x29 +"\0" // 0x2A +"\\zxcvbnm,./" // 0x2B - 0x35 +"\0" // 0x36 +"*" // 0x37 +"\0" // 0x38 +" " // 0x39 +"\0"; // 0x3A +uint8_t scancodesToAsciiShift[0x3B] = +"\0\0" // 0x00 - 0x01 +"!@#$%^&*()" // 0x02 - 0x0B +"_+" // 0x0C - 0x0D +"\0\0" // 0x0E - 0x0F +"QWERTYUIOP{}" // 0x10 - 0x1B +"\0\0" // 0x1C - 0x1D +"ASDFGHJKL:\"~" // 0x1E - 0x29 +"\0" // 0x2A +"|ZXCVBNM<>?" // 0x2B - 0x35 +"\0" // 0x36 +"*" // 0x37 +"\0" // 0x38 +" " // 0x39 +"\0"; // 0x3A +uint8_t _KBDWAIT; +uint8_t _KEYCAPS = 0, _KEYSHIFT = 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 + _KEYCAPS = !_KEYCAPS; + } else if (key == 0x2A || key == 0x36) { // left and right shift press + _KEYSHIFT = 1; + } else if (key == 0xAA || key == 0xB6) { // left and right shift release + _KEYSHIFT = 0; + } else if (key < 0x3B) { + uint8_t ascii = _KEYCAPS != _KEYSHIFT ? + scancodesToAsciiShift[key] : + scancodesToAscii[key]; + if (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__)) +void kbd_wait() { + _KBDWAIT = 0; + while(!_KBDWAIT) { + asm volatile("hlt"); + } +} + +__attribute((__no_caller_saved_registers__)) +uint8_t get_key() { + while(!_LSTKEY_ASCII) { + asm volatile("hlt"); + } + 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/kbd.h b/kbd.h new file mode 100644 index 0000000..6835901 --- /dev/null +++ b/kbd.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include "interrupt.h" + +__attribute((__no_caller_saved_registers__)) +void kbd_wait(); + +__attribute((__no_caller_saved_registers__)) +uint8_t get_key(); + +__attribute((__no_caller_saved_registers__)) +uint16_t get_scancode(); + +__attribute__ ((interrupt)) +void keyboardHandler(struct interrupt_frame *frame); + +typedef enum { +KEY_ESCAPE=0x01, KEY_1=0x02, KEY_2=0x03, +KEY_3=0x04, KEY_4=0x05, KEY_5=0x06, KEY_6=0x07, +KEY_7=0x08, KEY_8=0x09, KEY_9=0x0A, KEY_0=0x0B, +KEY_HYPHEN=0x0C, KEY_EQUALS=0x0D, KEY_BACKSPACE=0x0E, KEY_TAB=0x0F, +KEY_Q=0x10, KEY_W=0x11, KEY_E=0x12, KEY_R=0x13, +KEY_T=0x14, KEY_Y=0x15, KEY_U=0x16, KEY_I=0x17, +KEY_O=0x18, KEY_P=0x19, KEY_SQBRKLEFT=0x1A, KEY_SQBRKRIGHT=0x1B, +KEY_ENTER=0x1C, KEY_CTRL=0x1D, KEY_A=0x1E, KEY_S=0x1F, +KEY_D=0x20, KEY_F=0x21, KEY_G=0x22, KEY_H=0x23, +KEY_J=0x24, KEY_K=0x25, KEY_L=0x26, KEY_SEMICOLON=0x27, +KEY_QUOTE=0x28, KEY_BACKTICK=0x29, KEY_SHIFTLEFT=0x2A, KEY_BACKSTROKE=0x2B, +KEY_Z=0x2C, KEY_X=0x2D, KEY_C=0x2E, KEY_V=0x2F, +KEY_B=0x30, KEY_N=0x31, KEY_M=0x32, KEY_COMMA=0x33, +KEY_PERIOD=0x34, KEY_SLASH=0x35, KEY_SHIFTRIGHT=0x36, KEY_KPDSTAR=0x37, +KEY_ALT=0x38, KEY_SPACE=0x39, KEY_CAPSLOCK=0x3A, KEY_F1=0x3B, +KEY_F2=0x3C, KEY_F3=0x3D, KEY_F4=0x3E, KEY_F5=0x3F, +KEY_F6=0x40, KEY_F7=0x41, KEY_F8=0x42, KEY_F9=0x43, +KEY_F10=0x44, KEY_NUMLOCK=0x45, KEY_SCROLLLOCK=0x46, KEY_KPD7=0x47, +KEY_KPD8=0x48, KEY_KPD9=0x49, KEY_KPDMINUS=0x4A, KEY_KPD4=0x4B, +KEY_KPD5=0x4C, KEY_KPD6=0x4D, KEY_KPDPLUS=0x4E, KEY_KPD1=0x4F, +KEY_KPD2=0x50, KEY_KPD3=0x51, KEY_KPD0=0x52, KEY_KPDPERIOD=0x53, +KEY_F11=0x57, KEY_F12=0x58, +KEY_DOWN=KEY_KPD2,KEY_UP=KEY_KPD8, +KEY_LEFT=KEY_KPD4,KEY_RIGHT=KEY_KPD6, +KEY_PGUP=KEY_KPD9,KEY_PGDOWN=KEY_KPD3, +KEY_HOME=KEY_KPD7,KEY_END=KEY_KPD1, +KEY_INSERT=KEY_KPD0, KEY_DELETE=KEY_KPDPERIOD +} SCANCODE; diff --git a/kernel.c b/kernel.c index 68a5d24..97b4963 100644 --- a/kernel.c +++ b/kernel.c @@ -3,6 +3,7 @@ #include "dosfs/dosfs.h" #include "print.h" #include "interrupt.h" +#include "kbd.h" #include "tss.h" #include "paging.h" #include "v86defs.h" @@ -115,8 +116,7 @@ void error_environment() { uint16_t *vga_text = ((uint16_t*)0xB8000); for (int i = 0; i < 80*50; i++) vga_text[i] = error_screen[i]; - uint8_t key; - while (key = get_key(), key != 'e' && key != 'E'); + while ((get_scancode() & 0xff) != KEY_E); v86_entry = i386LinearToFp(v86TransFlag); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s); } @@ -146,6 +146,29 @@ Protected Only (1MB+) 400000 - 700000 Usermode Code (3mB) 700000 - 800000 Usermode Stack (1mB) */ + +void SetVideo25Lines() { + union V86Regs_t regs; + regs.w.ax = 0x1114; // 80x25 mode + regs.w.bx = 0x0000; + FARPTR v86_entry = i386LinearToFp(v86VideoInt); + enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s); +} +void SetVideo50Lines() { + union V86Regs_t regs; + regs.w.ax = 0x1112; // 80x50 mode + regs.w.bx = 0x0000; + FARPTR v86_entry = i386LinearToFp(v86VideoInt); + enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s); +} +void SetCursorDisabled() { + union V86Regs_t regs; + regs.w.ax = 0x0100; // set cursor + regs.w.cx = 0x3F00; // disabled + FARPTR v86_entry = i386LinearToFp(v86VideoInt); + enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s); +} + void DrawScreen() { uint16_t *vga_text = (uint16_t *)0xB8000; // clear screen @@ -235,8 +258,6 @@ void PrintFileList() { vga_text = nextLine(vga_text) + 3; } } -const uint32_t byteCount = 16*24; -uint8_t diskReadBuf[16*24]; void FileReadTest(uint8_t *path, VOLINFO *vi) { uint32_t err; uint16_t *vga_text = (uint16_t *)0xb8000; @@ -251,13 +272,29 @@ void FileReadTest(uint8_t *path, VOLINFO *vi) { uint32_t successcount; uint32_t readOffset = 0, lastReadOffset = -1; char cont = 1; + uint32_t byteCount = 16*24, lastByteCount; + uint32_t screenSize = 80*25; + char reread; for (;cont;) { + uint8_t diskReadBuf[byteCount]; if (readOffset != lastReadOffset) { + lastReadOffset = readOffset; + reread = 1; + } + if (byteCount != lastByteCount) { + lastByteCount = byteCount; + reread = 1; + } + if (reread) { vga_text = (uint16_t *)0xb8000; - for (int i = 0; i < 80*25; i++) + for (int i = 0; i < screenSize; i++) vga_text[i] = 0x0f00; vga_text += printStr((char*)path, vga_text); - vga_text += printStr(" Up/Down to navigate - E to exit", vga_text); + { + const char prnt[] = "Scroll: Up/Down PgUp/PgDown Home/End Exit: E "; + vga_text = &((uint16_t*)0xb8000)[80-sizeof(prnt)]; + vga_text += printStr((char*)prnt, vga_text); + } vga_text = &((uint16_t*)0xb8000)[80]; DFS_Seek(&fi, readOffset, scratch); if (fi.pointer != readOffset) { @@ -295,22 +332,58 @@ void FileReadTest(uint8_t *path, VOLINFO *vi) { vga_text += printChar('|', vga_text); vga_text = nextLine(vga_text); } - lastReadOffset = readOffset; + reread = 0; } uint16_t key = get_scancode(); + union V86Regs_t regs; + FARPTR v86_entry; switch (key & 0xff) { - case 0x50: // down + case KEY_DOWN: // down if ((readOffset + byteCount) < fi.filelen) readOffset += byteCount; + else goto end; break; - case 0x48: // up - //asm volatile ("xchg %bx,%bx"); + case KEY_UP: // up if ((readOffset - byteCount) < fi.filelen) readOffset -= byteCount; + else goto home; break; - case 0x12: // e + case KEY_PGDOWN: + if ((readOffset + (byteCount*4)) < fi.filelen) + readOffset += (byteCount*4); + else goto end; + break; + case KEY_PGUP: + if ((readOffset - (byteCount*4)) < fi.filelen) + readOffset -= (byteCount*4); + else goto home; + break; + case KEY_HOME: home: + readOffset = 0; + break; + case KEY_END: end: + if ((fi.filelen / byteCount) * byteCount > readOffset) + readOffset = (fi.filelen / byteCount) * byteCount; + break; + case KEY_E: // e cont = 0; break; + case KEY_F2: + if (byteCount != 16*24) { + SetVideo25Lines(); + SetCursorDisabled(); + screenSize = 80*25; + byteCount = 16*24; + } + break; + case KEY_F5: + if (byteCount != 16*49) { + SetVideo50Lines(); + SetCursorDisabled(); + screenSize = 80*50; + byteCount = 16*49; + } + break; default: break; } @@ -363,6 +436,8 @@ void FileSelect() { } path[tmp] = 0; FileReadTest(path, &vi); + SetVideo25Lines(); + SetCursorDisabled(); DrawScreen(); break; default: @@ -423,6 +498,8 @@ void start() { if (key == 't' || key == 'T') RunTests(vga_text); DrawScreen(); + SetVideo25Lines(); + SetCursorDisabled(); FileSelect(); } diff --git a/tests.h b/tests.h index 5f1fb35..793209e 100644 --- a/tests.h +++ b/tests.h @@ -2,5 +2,6 @@ #include "print.h" #include "interrupt.h" #include "v86defs.h" +#include "kbd.h" void RunTests(uint16_t *vga_text);