Move to git
This commit is contained in:
13
luma/ps2/Makefile
Normal file
13
luma/ps2/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
|
||||
|
||||
HEADERS := $(call rwildcard,.,*.h)
|
||||
SOURCEC := $(call rwildcard,.,*.c)
|
||||
OBJECTS := $(patsubst %.c, ../../build/ps2/%.o, $(SOURCEC))
|
||||
|
||||
mod: $(OBJECTS)
|
||||
i386-elf-gcc -pie -T ../../mod.ld -Wl,-no-dynamic-linker -nostdlib -o main.elf $(OBJECTS) -lgcc
|
||||
../../elftomod.py main.elf ../../bootfs/luma_ps2.mod modentry:0
|
||||
|
||||
../../build/ps2/%.o: %.c
|
||||
mkdir -p $(@D)
|
||||
i386-elf-gcc -march=i386 -Isrc -Os -pie -nodefaultlibs -nostdlib -nostartfiles -fomit-frame-pointer -c -o $@ -ffreestanding -mgeneral-regs-only -std=gnu99 -Wall $<
|
||||
97
luma/ps2/api.h
Normal file
97
luma/ps2/api.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef _LUMA_KBD_H
|
||||
#define _LUMA_KBD_H
|
||||
|
||||
enum LumaKbdScancode {
|
||||
LK_INVALID,
|
||||
LK_0,
|
||||
LK_1,
|
||||
LK_2,
|
||||
LK_3,
|
||||
LK_4,
|
||||
LK_5,
|
||||
LK_6,
|
||||
LK_7,
|
||||
LK_8,
|
||||
LK_9,
|
||||
LK_F1,
|
||||
LK_F2,
|
||||
LK_F3,
|
||||
LK_F4,
|
||||
LK_F5,
|
||||
LK_F6,
|
||||
LK_F7,
|
||||
LK_F8,
|
||||
LK_F9,
|
||||
LK_F10,
|
||||
LK_F11,
|
||||
LK_F12,
|
||||
LK_PAUSE,
|
||||
LK_LEFT_ALT,
|
||||
LK_RIGHT_ALT,
|
||||
LK_LEFT_SHIFT,
|
||||
LK_RIGHT_SHIFT,
|
||||
LK_LEFT_CTRL,
|
||||
LK_RIGHT_CTRL,
|
||||
LK_LEFT_SYS,
|
||||
LK_RIGHT_SYS,
|
||||
LK_BACKSPACE,
|
||||
LK_A,
|
||||
LK_B,
|
||||
LK_C,
|
||||
LK_D,
|
||||
LK_E,
|
||||
LK_F,
|
||||
LK_G,
|
||||
LK_H,
|
||||
LK_I,
|
||||
LK_J,
|
||||
LK_K,
|
||||
LK_L,
|
||||
LK_M,
|
||||
LK_N,
|
||||
LK_O,
|
||||
LK_P,
|
||||
LK_Q,
|
||||
LK_R,
|
||||
LK_S,
|
||||
LK_T,
|
||||
LK_U,
|
||||
LK_V,
|
||||
LK_W,
|
||||
LK_X,
|
||||
LK_Y,
|
||||
LK_Z,
|
||||
LK_SPACE,
|
||||
LK_SLASH,
|
||||
LK_COMMA,
|
||||
LK_PERIOD,
|
||||
LK_SOLIDUS,
|
||||
LK_SEMICOLON,
|
||||
LK_SQUOTE,
|
||||
LK_DQUOTE,
|
||||
LK_S_BRACKET_L,
|
||||
LK_S_BRACKET_R,
|
||||
LK_R_BRACKET_L,
|
||||
LK_R_BRACKET_R,
|
||||
LK_DASH,
|
||||
LK_EQUALS,
|
||||
LK_ENTER,
|
||||
LK_ESCAPE,
|
||||
LK_UP,
|
||||
LK_DOWN,
|
||||
LK_LEFT,
|
||||
LK_RIGHT,
|
||||
};
|
||||
|
||||
#define KEYEV_FLAG_FREE 0
|
||||
#define KEYEV_FLAG_PRESS 1
|
||||
#define KEYEV_FLAG_RELEASE 2
|
||||
struct LumaKbdEvent {
|
||||
uint8_t scancode;
|
||||
uint8_t flag;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define KEYBUF_SIZE 4096
|
||||
#define KEYBUF_MAX (4096 / sizeof(struct LumaKbdEvent))
|
||||
|
||||
#endif
|
||||
254
luma/ps2/main.c
Normal file
254
luma/ps2/main.c
Normal file
@@ -0,0 +1,254 @@
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user