Added enum for scancodes, More control in hex viewer, hex viewer can switch between 25/50 lines
This commit is contained in:
parent
7107c0ef8b
commit
d0fbc7df56
2
Makefile
2
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
|
||||
|
100
interrupt.c
100
interrupt.c
@ -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();
|
||||
|
@ -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
101
kbd.c
Normal 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
45
kbd.h
Normal 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;
|
99
kernel.c
99
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user