255 lines
7.3 KiB
C
255 lines
7.3 KiB
C
#include"../sys.h"
|
|
|
|
asm("modentry:\n"
|
|
"mov $stack + 768, %esp\n"
|
|
"call startc");
|
|
|
|
#include"api.h"
|
|
#include"../std.h"
|
|
|
|
char stack[768];
|
|
|
|
struct LumaKbdEvent *KeyBuf = (void*) -1;
|
|
size_t KeyBufIndex = 0;
|
|
|
|
void __attribute__((naked)) irq() {
|
|
asm(
|
|
"call irqc\n"
|
|
"movl $15, %eax\n"
|
|
"movl $1, %edi\n"
|
|
"int $0xEC"
|
|
);
|
|
}
|
|
|
|
static void pushev(struct LumaKbdEvent ev) {
|
|
if(KeyBuf[KeyBufIndex].flag != KEYEV_FLAG_FREE) {
|
|
return;
|
|
} else {
|
|
KeyBuf[KeyBufIndex++] = ev;
|
|
if(KeyBufIndex == KEYBUF_MAX) KeyBufIndex = 0;
|
|
sys_signal_send(KeyBuf, KeyBufIndex);
|
|
}
|
|
}
|
|
|
|
void irqc() {
|
|
static const uint8_t ss21blchars1[] = {LK_Q, LK_1, 0, 0, 0, LK_Z, LK_S, LK_A, LK_W, LK_2, 0, 0, LK_C, LK_X, LK_D, LK_E, LK_4, LK_3, 0, 0, LK_SPACE, LK_V, LK_F, LK_T, LK_R, LK_5, 0, 0, LK_N, LK_B, LK_H, LK_G, LK_Y, LK_6, 0, 0, 0, LK_M, LK_J, LK_U, LK_7, LK_8, 0, 0, LK_COMMA, LK_K, LK_I, LK_O, LK_0, LK_9, 0, 0, LK_PERIOD, LK_SOLIDUS, LK_L, LK_SEMICOLON, LK_P, LK_DASH, 0, 0, 0, 0, LK_SQUOTE, 0, LK_S_BRACKET_L, LK_EQUALS};
|
|
|
|
static int stateLen = 0;
|
|
static uint8_t state[8]; // max 8 bytes per event
|
|
|
|
state[stateLen++] = inb(0x60);
|
|
|
|
if(stateLen == 8) { // Pause key, and state[0] should be 0xE1, but even if it isn't do this so as to reset state just in case
|
|
stateLen = 0;
|
|
pushev((struct LumaKbdEvent) {.scancode = LK_PAUSE, .flag = KEYEV_FLAG_PRESS});
|
|
pushev((struct LumaKbdEvent) {.scancode = LK_PAUSE, .flag = KEYEV_FLAG_RELEASE});
|
|
} else if(stateLen == 1 && state[0] != 0xE0 && state[0] != 0xE1 && state[0] != 0xF0) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS};
|
|
if(state[0] >= 0x15 && state[0] <= 0x55) {
|
|
if((ev.scancode = ss21blchars1[state[0] - 0x15])) {
|
|
pushev(ev);
|
|
}
|
|
} else {
|
|
if(state[0] == 0x12) {
|
|
ev.scancode = LK_LEFT_SHIFT;
|
|
} else if(state[0] == 0x59) {
|
|
ev.scancode = LK_RIGHT_SHIFT;
|
|
} else if(state[0] == 0x66) {
|
|
ev.scancode = LK_BACKSPACE;
|
|
} else if(state[0] == 0x5A) {
|
|
ev.scancode = LK_ENTER;
|
|
} else if(state[0] == 0x11) {
|
|
ev.scancode = LK_LEFT_ALT;
|
|
} else if(state[0] == 0x76) {
|
|
ev.scancode = LK_ESCAPE;
|
|
}
|
|
pushev(ev);
|
|
}
|
|
} else if(stateLen == 2 && state[0] == 0xE0 && state[1] == 0x1F) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS, .scancode = LK_LEFT_SYS};
|
|
pushev(ev);
|
|
} else if(stateLen == 2 && state[0] == 0xE0 && state[1] == 0x6B) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS, .scancode = LK_LEFT};
|
|
pushev(ev);
|
|
} else if(stateLen == 2 && state[0] == 0xE0 && state[1] == 0x74) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS, .scancode = LK_RIGHT};
|
|
pushev(ev);
|
|
} else if(stateLen == 2 && state[0] == 0xE0 && state[1] == 0x75) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS, .scancode = LK_UP};
|
|
pushev(ev);
|
|
} else if(stateLen == 2 && state[0] == 0xE0 && state[1] == 0x72) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS, .scancode = LK_DOWN};
|
|
pushev(ev);
|
|
} else if(stateLen == 2 && state[0] == 0xE0 && state[1] != 0xF0 && state[1] != 0x12) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS};
|
|
pushev(ev);
|
|
} else if(stateLen == 4 && state[0] == 0xE0 && state[1] == 0x12 && state[2] == 0xE0 && state[3] == 0x7C) { // Print screen pressed
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_PRESS};
|
|
pushev(ev);
|
|
} else if(stateLen == 6 && state[0] == 0xE0 && state[1] == 0xF0 && state[2] == 0x7C && state[3] == 0xE0 && state[4] == 0xF0 && state[5] == 0x12) { // Print screen released
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE};
|
|
pushev(ev);
|
|
} else if(stateLen == 2 && state[0] == 0xF0) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE};
|
|
if(state[1] >= 0x15 && state[1] <= 0x55) {
|
|
if((ev.scancode = ss21blchars1[state[1] - 0x15])) {
|
|
pushev(ev);
|
|
}
|
|
} else {
|
|
if(state[1] == 0x12) {
|
|
ev.scancode = LK_LEFT_SHIFT;
|
|
} else if(state[1] == 0x59) {
|
|
ev.scancode = LK_RIGHT_SHIFT;
|
|
} else if(state[1] == 0x66) {
|
|
ev.scancode = LK_BACKSPACE;
|
|
} else if(state[0] == 0x5A) {
|
|
ev.scancode = LK_ENTER;
|
|
} else if(state[1] == 0x11) {
|
|
ev.scancode = LK_LEFT_ALT;
|
|
} else if(state[1] == 0x76) {
|
|
ev.scancode = LK_ESCAPE;
|
|
}
|
|
pushev(ev);
|
|
}
|
|
} else if(stateLen == 3 && state[0] == 0xE0 && state[1] == 0xF0 && state[2] == 0x1F) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE, .scancode = LK_LEFT_SYS};
|
|
pushev(ev);
|
|
} else if(stateLen == 3 && state[0] == 0xE0 && state[1] == 0xF0 && state[2] == 0x6B) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE, .scancode = LK_LEFT};
|
|
pushev(ev);
|
|
} else if(stateLen == 3 && state[0] == 0xE0 && state[1] == 0xF0 && state[2] == 0x74) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE, .scancode = LK_RIGHT};
|
|
pushev(ev);
|
|
} else if(stateLen == 3 && state[0] == 0xE0 && state[1] == 0xF0 && state[2] == 0x75) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE, .scancode = LK_UP};
|
|
pushev(ev);
|
|
} else if(stateLen == 3 && state[0] == 0xE0 && state[1] == 0xF0 && state[2] == 0x72) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE, .scancode = LK_DOWN};
|
|
pushev(ev);
|
|
} else if(stateLen == 3 && state[0] == 0xE0 && state[1] == 0xF0 && state[2] != 0x7C) {
|
|
stateLen = 0;
|
|
struct LumaKbdEvent ev = {.flag = KEYEV_FLAG_RELEASE};
|
|
pushev(ev);
|
|
};
|
|
}
|
|
|
|
static volatile uint8_t *Framebuffer;
|
|
static void dbg(int j, uint8_t b) {
|
|
for(int i = 0; i < 8; i++) {
|
|
Framebuffer[j * 9 + 7 - i] = (b & (1 << i)) ? 80 : 0;
|
|
}
|
|
}
|
|
|
|
void startc() {
|
|
Framebuffer = sys_vpm_map(SYS_MAP_VIRT_ANY, (void*) 0xA0000, 32000);
|
|
for(int try = 0; try < 50; try++) {
|
|
Framebuffer[try] = 50;
|
|
sys_sleep(500);
|
|
if(sys_link_create('USB\0', 'UHCI', 4096) != (void*) -1) {
|
|
goto done;
|
|
}
|
|
}
|
|
while(1);
|
|
done:
|
|
while(inb(0x64) & 2);
|
|
outb(0x64, 0xAD);
|
|
while(inb(0x64) & 2);
|
|
outb(0x64, 0xA7);
|
|
inb(0x60);
|
|
while(inb(0x64) & 2);
|
|
outb(0x64, 0x20);
|
|
while((inb(0x64) & 1) == 0);
|
|
uint8_t c = inb(0x60);
|
|
while(inb(0x64) & 2);
|
|
outb(0x64, 0x60);
|
|
while(inb(0x64) & 2);
|
|
outb(0x60, c & ~67);
|
|
|
|
/* Enable */
|
|
while(inb(0x64) & 2);
|
|
outb(0x64, 0xAE);
|
|
|
|
while(inb(0x64) & 2);
|
|
outb(0x60, 0xFF);
|
|
while((inb(0x64) & 1) == 0);
|
|
if(inb(0x60) != 0xFA) while(1);
|
|
while((inb(0x64) & 1) == 0);
|
|
if(inb(0x60) != 0xAA) while(1);
|
|
|
|
do {
|
|
while(inb(0x64) & 2);
|
|
outb(0x60, 0xF5);
|
|
while((inb(0x64) & 1) == 0);
|
|
} while(inb(0x60) != 0xFA);
|
|
|
|
do {
|
|
while(inb(0x64) & 2);
|
|
outb(0x60, 0xF2);
|
|
while((inb(0x64) & 1) == 0);
|
|
} while(inb(0x60) != 0xFA);
|
|
|
|
while((inb(0x64) & 1) == 0);
|
|
|
|
uint8_t b1 = inb(0x60);
|
|
|
|
sys_sleep(50);
|
|
|
|
if(inb(0x64) & 1) {
|
|
uint8_t b2 = inb(0x60);
|
|
if(b1 != 0xAB) {
|
|
for(int i = 0; i < 15; i++) {
|
|
Framebuffer[i] = 90;
|
|
}
|
|
while(1);
|
|
}
|
|
} else while(1);
|
|
|
|
do {
|
|
KeyBuf = sys_link_create('LUMA', 'WM\0\0', 4096);
|
|
} while(KeyBuf == (void*) -1);
|
|
memory_barrier();
|
|
std_w8(KeyBuf, 0, 4096);
|
|
|
|
// Send type "input device"
|
|
sys_signal_send(KeyBuf, 0);
|
|
sys_signal_wait(KeyBuf, NULL);
|
|
|
|
sys_irq_claim(1, &irq);
|
|
|
|
while(inb(0x64) & 2);
|
|
outb(0x64, 0x20);
|
|
while((inb(0x64) & 1) == 0);
|
|
c = inb(0x60);
|
|
while(inb(0x64) & 2);
|
|
outb(0x64, 0x60);
|
|
while(inb(0x64) & 2);
|
|
outb(0x60, c | 1); // enable interrupt
|
|
|
|
inb(0x60);
|
|
|
|
do {
|
|
while(inb(0x64) & 2);
|
|
outb(0x60, 0xF4);
|
|
while((inb(0x64) & 1) == 0);
|
|
} while(inb(0x60) != 0xFA);
|
|
|
|
sys_wait_for_irq(1);
|
|
|
|
while(1) sys_signal_wait(SYS_SIGNAL_WAIT_ANY, NULL);
|
|
}
|