Added enum for scancodes, More control in hex viewer, hex viewer can switch between 25/50 lines

This commit is contained in:
Lucia Ceionia 2023-02-05 19:57:06 -06:00
parent 7107c0ef8b
commit d0fbc7df56
7 changed files with 237 additions and 119 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 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

View File

@ -2,6 +2,7 @@
#include <stddef.h>
#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();

View File

@ -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);

101
kbd.c Normal file
View File

@ -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;
}

45
kbd.h Normal file
View File

@ -0,0 +1,45 @@
#pragma once
#include <stdint.h>
#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;

View File

@ -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), &regs);
}
@ -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), &regs);
}
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), &regs);
}
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), &regs);
}
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();
}

View File

@ -2,5 +2,6 @@
#include "print.h"
#include "interrupt.h"
#include "v86defs.h"
#include "kbd.h"
void RunTests(uint16_t *vga_text);