From 7c996a6d51bd929ee508b6352459498ab2268d8a Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Sun, 27 Apr 2025 14:03:33 -0400 Subject: remove pit fixme --- kernel/drivers/pit.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'kernel/drivers') diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index d77df08..53a9263 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -22,9 +22,8 @@ uint16_t pit_read_divider(void) void pit_set_divider(uint16_t count) { (void)count; - // FIXME: broken on -O0 - // cli(); - // outb(CHAN_0, count & 0xFF); // low byte - // outb(CHAN_0, (count & 0xFF00) >> 8); // high byte - // sti(); + cli(); + outb(CHAN_0, count & 0xFF); // low byte + outb(CHAN_0, (count & 0xFF00) >> 8); // high byte + sti(); } -- cgit v1.2.3-freya From 5ee82510b5fefd10fd8de1fa85adb38c9fa87975 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Sun, 27 Apr 2025 15:00:29 -0400 Subject: lba48 for more then 256 sectors --- kernel/drivers/ata.c | 19 +++++++++++-------- kernel/include/comus/drivers/ata.h | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'kernel/drivers') diff --git a/kernel/drivers/ata.c b/kernel/drivers/ata.c index 63c4559..022ec81 100644 --- a/kernel/drivers/ata.c +++ b/kernel/drivers/ata.c @@ -506,7 +506,7 @@ static uint8_t get_ata_cmd_for_access(enum lba_mode lba_mode, static enum ide_error ide_device_ata_access(struct ide_device *dev, enum access_mode mode, uint32_t lba, - uint8_t numsects, + uint16_t numsects, uint16_t buf[numsects * 256]) { struct ide_channel *chan = channel(dev->channel_idx); @@ -521,7 +521,7 @@ static enum ide_error ide_device_ata_access(struct ide_device *dev, chan->no_interrupt = (ide_irq_invoked = 0x0) + 0x02); // select one from LBA28, LBA48 or CHS - if (lba >= 0x10000000) { + if (lba >= 0x10000000 || numsects > UINT8_MAX) { // drive should support LBA in this case, or you are giving a bad LBA lba_mode = LBA48; lba_io[0] = (lba & 0x000000FF) >> 0; @@ -565,19 +565,22 @@ static enum ide_error ide_device_ata_access(struct ide_device *dev, if (lba_mode == CHS) { ide_channel_write(chan, ATA_REG_HDDEVSEL, 0xA0 | (dev->drive_idx << 4) | head); - } else { + } else if (lba_mode == LBA28) { ide_channel_write(chan, ATA_REG_HDDEVSEL, 0xE0 | (dev->drive_idx << 4) | head); + } else { + ide_channel_write(chan, ATA_REG_HDDEVSEL, + 0x40 | (dev->drive_idx << 4)); } // write Parameters - if (lba_mode == 2) { - ide_channel_write(chan, ATA_REG_SECCOUNT1, 0); + if (lba_mode == LBA48) { + ide_channel_write(chan, ATA_REG_SECCOUNT1, (numsects >> 8) & 0xff); ide_channel_write(chan, ATA_REG_LBA3, lba_io[3]); ide_channel_write(chan, ATA_REG_LBA4, lba_io[4]); ide_channel_write(chan, ATA_REG_LBA5, lba_io[5]); } - ide_channel_write(chan, ATA_REG_SECCOUNT0, numsects); + ide_channel_write(chan, ATA_REG_SECCOUNT0, numsects & 0xff); ide_channel_write(chan, ATA_REG_LBA0, lba_io[0]); ide_channel_write(chan, ATA_REG_LBA1, lba_io[1]); ide_channel_write(chan, ATA_REG_LBA2, lba_io[2]); @@ -624,7 +627,7 @@ static enum ide_error ide_device_ata_access(struct ide_device *dev, } enum ide_error ide_device_read_sectors(ide_device_t dev_identifier, - uint8_t numsects, uint32_t lba, + uint16_t numsects, uint32_t lba, uint16_t buf[numsects * 256]) { struct ide_device *dev = device(dev_identifier); @@ -656,7 +659,7 @@ enum ide_error ide_device_read_sectors(ide_device_t dev_identifier, } enum ide_error ide_device_write_sectors(ide_device_t device_identifier, - uint8_t numsects, uint32_t lba, + uint16_t numsects, uint32_t lba, uint16_t buf[numsects * 256]) { struct ide_device *dev = device(device_identifier); diff --git a/kernel/include/comus/drivers/ata.h b/kernel/include/comus/drivers/ata.h index 2f35e03..c404d84 100644 --- a/kernel/include/comus/drivers/ata.h +++ b/kernel/include/comus/drivers/ata.h @@ -44,7 +44,7 @@ enum ide_error ata_init(void); * * @returns IDE_ERROR_OK (0) on success or an error code on failure */ -enum ide_error ide_device_read_sectors(ide_device_t, uint8_t numsects, +enum ide_error ide_device_read_sectors(ide_device_t, uint16_t numsects, uint32_t lba, uint16_t buf[numsects * 256]); @@ -53,7 +53,7 @@ enum ide_error ide_device_read_sectors(ide_device_t, uint8_t numsects, * * @returns 0 on success or an error code on failure */ -enum ide_error ide_device_write_sectors(ide_device_t, uint8_t numsects, +enum ide_error ide_device_write_sectors(ide_device_t, uint16_t numsects, uint32_t lba, uint16_t buf[numsects * 256]); -- cgit v1.2.3-freya From 91fb39db553dea9d07bb124f38c83460abc48d21 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Sun, 27 Apr 2025 16:11:54 -0400 Subject: fmt --- kernel/drivers/ata.c | 3 +-- kernel/include/comus/asm.h | 5 ++++- kernel/syscall.c | 6 ++---- user/apple.c | 7 +++++-- 4 files changed, 12 insertions(+), 9 deletions(-) (limited to 'kernel/drivers') diff --git a/kernel/drivers/ata.c b/kernel/drivers/ata.c index 022ec81..6c8de86 100644 --- a/kernel/drivers/ata.c +++ b/kernel/drivers/ata.c @@ -569,8 +569,7 @@ static enum ide_error ide_device_ata_access(struct ide_device *dev, ide_channel_write(chan, ATA_REG_HDDEVSEL, 0xE0 | (dev->drive_idx << 4) | head); } else { - ide_channel_write(chan, ATA_REG_HDDEVSEL, - 0x40 | (dev->drive_idx << 4)); + ide_channel_write(chan, ATA_REG_HDDEVSEL, 0x40 | (dev->drive_idx << 4)); } // write Parameters diff --git a/kernel/include/comus/asm.h b/kernel/include/comus/asm.h index a6a8a45..4f376b1 100644 --- a/kernel/include/comus/asm.h +++ b/kernel/include/comus/asm.h @@ -36,7 +36,10 @@ static inline uint16_t inw(uint16_t port) static inline void rep_inw(uint16_t port, uint16_t *buffer, size_t count) { - __asm__ volatile("rep insw" : "+D"(buffer), "+c"(count) : "d"(port) : "memory"); + __asm__ volatile("rep insw" + : "+D"(buffer), "+c"(count) + : "d"(port) + : "memory"); } static inline void outw(uint16_t port, uint16_t val) diff --git a/kernel/syscall.c b/kernel/syscall.c index 7a57353..11db5e5 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -13,8 +13,7 @@ #define ARG3(type, name) type name = (type)(current_pcb->regs->rdx) #define ARG4(type, name) type name = (type)(current_pcb->regs->rcx) -__attribute__((noreturn)) -static int sys_exit(void) +__attribute__((noreturn)) static int sys_exit(void) { ARG1(int, status); @@ -57,8 +56,7 @@ static int sys_write(void) return nbytes; } -__attribute__((noreturn)) -static int sys_poweroff(void) +__attribute__((noreturn)) static int sys_poweroff(void) { // TODO: we should probably // kill all user processes diff --git a/user/apple.c b/user/apple.c index d0a5cc4..000718c 100644 --- a/user/apple.c +++ b/user/apple.c @@ -8,7 +8,7 @@ INCBIN(APPLE, "data/apple.bin"); #define APPLE_WIDTH 256 #define APPLE_HEIGHT 144 #define APPLE_FPS 12 -#define APPLE_FRAMES 5259 +#define APPLE_FRAMES 2630 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -33,7 +33,10 @@ static void draw_frame(void) } } - frame = ((ticks() - ticks_off) / (1000 / APPLE_FPS)) % APPLE_FRAMES; + frame = ((ticks() - ticks_off) / (1000 / APPLE_FPS)); + + if (frame >= APPLE_FRAMES) + exit(0); } int main(void) -- cgit v1.2.3-freya From 747546a0bd92d98988741ce9868791735bbd9044 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Mon, 28 Apr 2025 21:30:43 -0400 Subject: change struct gpu to gpu_dev --- kernel/drivers/gpu.c | 2 +- kernel/drivers/gpu/bochs.c | 4 ++-- kernel/drivers/gpu/gop.c | 4 ++-- kernel/include/comus/drivers/gpu.h | 4 ++-- kernel/include/comus/drivers/gpu/bochs.h | 2 +- kernel/include/comus/drivers/gpu/gop.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'kernel/drivers') diff --git a/kernel/drivers/gpu.c b/kernel/drivers/gpu.c index 3d79b99..fc6ec8e 100644 --- a/kernel/drivers/gpu.c +++ b/kernel/drivers/gpu.c @@ -7,7 +7,7 @@ #include #include -struct gpu *gpu_dev = NULL; +struct gpu_dev *gpu_dev = NULL; int gpu_init(void) { diff --git a/kernel/drivers/gpu/bochs.c b/kernel/drivers/gpu/bochs.c index f8e5820..2dfe62e 100644 --- a/kernel/drivers/gpu/bochs.c +++ b/kernel/drivers/gpu/bochs.c @@ -31,7 +31,7 @@ #define BOCHS_HEIGHT 768 #define BOCHS_BIT_DEPTH 32 -struct gpu bochs_dev = { 0 }; +struct gpu_dev bochs_dev = { 0 }; static void write(uint16_t index, uint16_t data) { @@ -45,7 +45,7 @@ static uint16_t read(uint16_t value) return inw(DATA); } -int bochs_init(struct gpu **gpu_dev) +int bochs_init(struct gpu_dev **gpu_dev) { struct pci_device bochs = { 0 }; bool found = diff --git a/kernel/drivers/gpu/gop.c b/kernel/drivers/gpu/gop.c index 47da952..a57766d 100644 --- a/kernel/drivers/gpu/gop.c +++ b/kernel/drivers/gpu/gop.c @@ -5,11 +5,11 @@ #include #include -struct gpu gop_dev = { 0 }; +struct gpu_dev gop_dev = { 0 }; static EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; -int gop_init(struct gpu **gpu_dev) +int gop_init(struct gpu_dev **gpu_dev) { gop = efi_get_gop(); if (gop == NULL || gop->Mode == NULL) diff --git a/kernel/include/comus/drivers/gpu.h b/kernel/include/comus/drivers/gpu.h index 39c633f..0a8f4fa 100644 --- a/kernel/include/comus/drivers/gpu.h +++ b/kernel/include/comus/drivers/gpu.h @@ -11,7 +11,7 @@ #include -struct gpu { +struct gpu_dev { const char *name; uint16_t width; uint16_t height; @@ -31,7 +31,7 @@ struct psf2_font { uint8_t data[]; }; -extern struct gpu *gpu_dev; +extern struct gpu_dev *gpu_dev; extern struct psf2_font en_font; /** diff --git a/kernel/include/comus/drivers/gpu/bochs.h b/kernel/include/comus/drivers/gpu/bochs.h index 7d26b60..ec70060 100644 --- a/kernel/include/comus/drivers/gpu/bochs.h +++ b/kernel/include/comus/drivers/gpu/bochs.h @@ -15,6 +15,6 @@ * Loads the bochs graphics driver * @returns 0 on success, NULL on error */ -int bochs_init(struct gpu **gpu_dev); +int bochs_init(struct gpu_dev **gpu_dev); #endif /* bochs.h */ diff --git a/kernel/include/comus/drivers/gpu/gop.h b/kernel/include/comus/drivers/gpu/gop.h index 6475f05..d3af921 100644 --- a/kernel/include/comus/drivers/gpu/gop.h +++ b/kernel/include/comus/drivers/gpu/gop.h @@ -15,6 +15,6 @@ * Loads the uefi gop graphics driver * @returns 0 on success, NULL on error */ -int gop_init(struct gpu **gpu_dev); +int gop_init(struct gpu_dev **gpu_dev); #endif /* gop.h */ -- cgit v1.2.3-freya From 5d52bae4a9e42d5d53f397f0088fd4879e2ff02d Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 29 Apr 2025 10:36:54 -0400 Subject: ps2 --- kernel/cpu/idt.c | 3 + kernel/drivers.c | 2 + kernel/drivers/ps2.c | 296 +++++++++++++++++++++++++++++++++++++ kernel/include/comus/drivers/ps2.h | 49 ++++++ kernel/include/comus/keycodes.h | 143 ++++++++++++++++++ 5 files changed, 493 insertions(+) create mode 100644 kernel/drivers/ps2.c create mode 100644 kernel/include/comus/drivers/ps2.h create mode 100644 kernel/include/comus/keycodes.h (limited to 'kernel/drivers') diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index d071d29..2eab7ec 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -185,8 +186,10 @@ void idt_pic_timer(void) void idt_pic_keyboard(void) { + ps2kb_recv(); } void idt_pic_mouse(void) { + ps2mouse_recv(); } diff --git a/kernel/drivers.c b/kernel/drivers.c index 98bf1bd..3d6ec10 100644 --- a/kernel/drivers.c +++ b/kernel/drivers.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -11,6 +12,7 @@ void drivers_init(void) { pit_set_divider(1193); // 1ms uart_init(); + ps2_init(); pci_init(); ata_init(); acpi_init(mboot_get_rsdp()); diff --git a/kernel/drivers/ps2.c b/kernel/drivers/ps2.c new file mode 100644 index 0000000..5c18b5b --- /dev/null +++ b/kernel/drivers/ps2.c @@ -0,0 +1,296 @@ +#include +#include +#include +#include + +#define STATUS_OUT_BUF ((uint8_t)0x01) +#define STATUS_IN_BUF ((uint8_t)0x02) + +#define CONFIG_INT_0 ((uint8_t)0x01) +#define CONFIG_INT_1 ((uint8_t)0x02) +#define CONFIG_SYS ((uint8_t)0x04) +#define CONFIG_CLOCK_0 ((uint8_t)0x10) +#define CONFIG_CLOCK_1 ((uint8_t)0x20) +#define CONFIG_TRANS ((uint8_t)0x40) + +static uint8_t scancodes[] = { + KEY_NONE, KEY_F9, KEY_NONE, KEY_F5, KEY_F3, + KEY_F1, KEY_F2, KEY_F12, KEY_NONE, KEY_F10, + KEY_F8, KEY_F6, KEY_F4, KEY_TAB, KEY_BACKTICK, + KEY_NONE, KEY_NONE, KEY_L_ALT, KEY_L_SHIFT, KEY_NONE, + KEY_L_CTRL, KEY_Q, KEY_1, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_Z, KEY_S, KEY_A, KEY_W, + KEY_2, KEY_NONE, KEY_NONE, KEY_C, KEY_X, + KEY_D, KEY_E, KEY_4, KEY_3, KEY_NONE, + KEY_NONE, KEY_SPACE, KEY_V, KEY_F, KEY_T, + KEY_R, KEY_5, KEY_NONE, KEY_NONE, KEY_N, + KEY_B, KEY_H, KEY_G, KEY_Y, KEY_6, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_M, KEY_J, + KEY_U, KEY_7, KEY_8, KEY_NONE, KEY_NONE, + KEY_COMMA, KEY_K, KEY_I, KEY_O, KEY_0, + KEY_9, KEY_NONE, KEY_NONE, KEY_PERIOD, KEY_SLASH, + KEY_L, KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_QUOTE, KEY_NONE, KEY_L_BRACE, + KEY_EQUAL, KEY_NONE, KEY_NONE, KEY_CAPS_LOCK, KEY_R_SHIFT, + KEY_ENTER, KEY_R_BRACE, KEY_NONE, KEY_BACKSLASH, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_BACKSPACE, KEY_NONE, KEY_NONE, + KEY_NP_1, KEY_NONE, KEY_NP_4, KEY_NP_7, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_NP_0, KEY_NP_PERIOD, KEY_NP_2, + KEY_NP_5, KEY_NP_6, KEY_NP_8, KEY_ESCAPE, KEY_NUM_LOCK, + KEY_F11, KEY_NP_PLUS, KEY_NP_3, KEY_NP_MINUS, KEY_NP_ASTERISK, + KEY_NP_9, KEY_SCROLL_LOCK, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_F7, +}; +static uint8_t scancodes_ext[] = { + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_UNKNOWN, KEY_R_ALT, KEY_PRINT_SCREEN, KEY_NONE, + KEY_R_CTRL, KEY_UNKNOWN, KEY_NONE, KEY_NONE, KEY_UNKNOWN, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_L_META, KEY_UNKNOWN, KEY_UNKNOWN, KEY_NONE, + KEY_UNKNOWN, KEY_NONE, KEY_NONE, KEY_NONE, KEY_R_META, + KEY_UNKNOWN, KEY_NONE, KEY_NONE, KEY_UNKNOWN, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_MENU, KEY_UNKNOWN, KEY_NONE, + KEY_UNKNOWN, KEY_NONE, KEY_UNKNOWN, KEY_NONE, KEY_NONE, + KEY_UNKNOWN, KEY_UNKNOWN, KEY_NONE, KEY_UNKNOWN, KEY_UNKNOWN, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_UNKNOWN, KEY_UNKNOWN, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_UNKNOWN, KEY_NONE, KEY_NP_SLASH, + KEY_NONE, KEY_NONE, KEY_UNKNOWN, KEY_NONE, KEY_NONE, + KEY_UNKNOWN, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NP_ENTER, KEY_NONE, KEY_NONE, KEY_NONE, KEY_UNKNOWN, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_END, KEY_NONE, KEY_LEFT, KEY_HOME, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_INSERT, KEY_DELETE, KEY_DOWN, + KEY_NONE, KEY_RIGHT, KEY_UP, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_PAGE_DOWN, KEY_NONE, KEY_NONE, + KEY_PAGE_UP, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, + KEY_NONE, +}; + +// ctrl +static bool has_kbd = false; +static bool has_mouse = false; + +// kbd +static struct keycode last_keycode = { + .key = KEY_NONE, + .flags = 0, +}; +static bool state_keyup = false; +static bool state_ext = false; + +// mouse +static struct mouse_event last_mouse_ev = { + .updated = false, + .lmb = false, + .mmb = false, + .rmb = false, + .relx = 0, + .rely = 0, +}; +static uint8_t first_b, second_b, third_b; + +static uint8_t ps2ctrl_in_status(void) +{ + return inb(0x64); +} + +static uint8_t ps2ctrl_in(void) +{ + while ((ps2ctrl_in_status() & STATUS_OUT_BUF) == 0) { + io_wait(); + } + return inb(0x60); +} + +static void ps2ctrl_out_cmd(uint8_t cmd) +{ + while ((ps2ctrl_in_status() & STATUS_IN_BUF) != 0) { + io_wait(); + } + outb(0x64, cmd); +} + +static void ps2ctrl_out_data(uint8_t data) +{ + while ((ps2ctrl_in_status() & STATUS_IN_BUF) != 0) { + io_wait(); + } + outb(0x60, data); +} + +static void ps2ctrl_set_port2(void) +{ + outb(0x64, 0xD4); +} + +static int ps2kb_init(void) +{ + uint8_t result; + + ps2ctrl_out_data(0xFF); + if ((result = ps2ctrl_in()) != 0xFA) + return 1; + + if ((result = ps2ctrl_in()) != 0xAA) + return 1; + + ps2ctrl_out_data(0xF4); + if ((result = ps2ctrl_in()) != 0xFA) + return 1; + + has_kbd = true; + return 0; +} + +static int ps2mouse_init(void) +{ + uint8_t result; + + ps2ctrl_set_port2(); + ps2ctrl_out_data(0xFF); + if ((result = ps2ctrl_in()) != 0xFA) + return 1; + + if ((result = ps2ctrl_in()) != 0xAA) + return 1; + + ps2ctrl_set_port2(); + ps2ctrl_out_data(0xF4); + + has_mouse = true; + return 0; +} + +void ps2kb_recv(void) +{ + uint8_t code; + + if (!has_kbd) + return; + + code = ps2ctrl_in(); + if (code == 0x00 || code == 0x0F) { + last_keycode.key = KEY_NONE; + last_keycode.flags = KC_FLAG_ERROR; + } else if (code == 0xF0) { + state_keyup = true; + } else if (code == 0xE0) { + state_ext = true; + } else if (code <= 0x84) { + uint8_t *scancode_table = state_ext ? scancodes_ext : scancodes; + uint8_t keycode = scancode_table[code]; + if (keycode != KEY_NONE) { + last_keycode.key = keycode; + last_keycode.flags = state_keyup ? KC_FLAG_KEY_UP : + KC_FLAG_KEY_DOWN; + } + state_keyup = false; + state_ext = false; + } +} + +struct keycode ps2kb_get(void) +{ + struct keycode code; + + if (!has_kbd) + return last_keycode; + + code = last_keycode; + last_keycode.key = KEY_NONE; + last_keycode.flags = 0; + return code; +} + +void ps2mouse_recv(void) +{ + static uint8_t packet_num = 0; + uint8_t code; + + if (!has_mouse) + return; + + code = ps2ctrl_in(); + switch (packet_num) { + case 0: + first_b = code; + break; + case 1: + second_b = code; + break; + case 2: { + int state, d; + + third_b = code; + state = first_b; + d = second_b; + last_mouse_ev.relx = d - ((state << 4) & 0x100); + d = third_b; + last_mouse_ev.rely = d - ((state << 3) & 0x100); + + last_mouse_ev.lmb = first_b & 0x01; + last_mouse_ev.rmb = first_b & 0x02; + last_mouse_ev.mmb = first_b & 0x04; + last_mouse_ev.updated = true; + break; + } + } + + packet_num += 1; + packet_num %= 3; +} + +struct mouse_event ps2mouse_get(void) +{ + struct mouse_event event = last_mouse_ev; + last_mouse_ev.updated = false; + return event; +} + +int ps2_init(void) +{ + uint8_t result; + + cli(); + + inb(0x60); + + // self-test + ps2ctrl_out_cmd(0xAA); + if ((result = ps2ctrl_in()) != 0x55) { + WARN("PS/2 Controller failed to initalize."); + return 1; + } + + // set config + ps2ctrl_out_cmd(0x20); + uint8_t config = ps2ctrl_in(); + config = (config | CONFIG_INT_0 | CONFIG_INT_1) & ~CONFIG_TRANS; + // config = 0xFF; + ps2ctrl_out_cmd(0x60); + ps2ctrl_out_data(config); + + // enable port 0 + ps2ctrl_out_cmd(0xAE); + + // enable port 2 + ps2ctrl_out_cmd(0xA9); + if ((result != ps2ctrl_in()) != 0x01) { + WARN("PS/2 port 2 not supported"); + return 1; + } + + ps2ctrl_out_cmd(0xA8); + + ps2kb_init(); + ps2mouse_init(); + sti(); + return 0; +} diff --git a/kernel/include/comus/drivers/ps2.h b/kernel/include/comus/drivers/ps2.h new file mode 100644 index 0000000..6e594e9 --- /dev/null +++ b/kernel/include/comus/drivers/ps2.h @@ -0,0 +1,49 @@ +/** + * @file ps2.h + * + * @author Freya Murphy + * + * PS/2 Mouse & Keyboard + */ + +#ifndef PS2_H_ +#define PS2_H_ + +#include +#include + +struct mouse_event { + bool updated; + bool lmb; + bool rmb; + bool mmb; + int relx; + int rely; +}; + +/** + * Initalize the ps2 controller + */ +int ps2_init(void); + +/** + * Recieve input from ps2 keyboard during interrupt + */ +void ps2kb_recv(void); + +/** + * Return last read keycode + */ +struct keycode ps2kb_get(void); + +/** + * Recieve input from ps2 mouse during interrupt + */ +void ps2mouse_recv(void); + +/** + * Return last read mouse event + */ +struct mouse_event ps2mouse_get(void); + +#endif /* ps2.h */ diff --git a/kernel/include/comus/keycodes.h b/kernel/include/comus/keycodes.h new file mode 100644 index 0000000..8930937 --- /dev/null +++ b/kernel/include/comus/keycodes.h @@ -0,0 +1,143 @@ +/** + * @file keycodes.h + * + * @author Tristan Miller + * + * Kernel keycodes + */ + +#ifndef KEYCODES_H_ +#define KEYCODES_H_ + +struct keycode { + char key; + char flags; +}; + +#define KC_FLAG_KEY_DOWN 0x01 +#define KC_FLAG_KEY_UP 0x02 +#define KC_FLAG_ERROR 0x04 + +#define KEY_NONE 0x00 +#define KEY_UNKNOWN 0x01 + +#define KEY_ESCAPE 0x10 +#define KEY_1 0x11 +#define KEY_2 0x12 +#define KEY_3 0x13 +#define KEY_4 0x14 +#define KEY_5 0x15 +#define KEY_6 0x16 +#define KEY_7 0x17 +#define KEY_8 0x18 +#define KEY_9 0x19 +#define KEY_0 0x1A +#define KEY_MINUS 0x1B +#define KEY_EQUAL 0x1C +#define KEY_BACKSPACE 0x1D +#define KEY_L_SHIFT 0x1E +#define KEY_R_SHIFT 0x1F + +#define KEY_TAB 0x20 +#define KEY_Q 0x21 +#define KEY_W 0x22 +#define KEY_E 0x23 +#define KEY_R 0x24 +#define KEY_T 0x25 +#define KEY_Y 0x26 +#define KEY_U 0x27 +#define KEY_I 0x28 +#define KEY_O 0x29 +#define KEY_P 0x2A +#define KEY_L_BRACE 0x2B +#define KEY_R_BRACE 0x2C +#define KEY_BACKSLASH 0x2D +#define KEY_L_CTRL 0x2E +#define KEY_R_CTRL 0x2F + +#define KEY_CAPS_LOCK 0x30 +#define KEY_A 0x31 +#define KEY_S 0x32 +#define KEY_D 0x33 +#define KEY_F 0x34 +#define KEY_G 0x35 +#define KEY_H 0x36 +#define KEY_J 0x37 +#define KEY_K 0x38 +#define KEY_L 0x39 +#define KEY_SEMICOLON 0x3A +#define KEY_QUOTE 0x3B +#define KEY_ENTER 0x3C +#define KEY_MENU 0x3D +#define KEY_L_ALT 0x3E +#define KEY_R_ALT 0x3F + +#define KEY_SPACE 0x40 +#define KEY_Z 0x41 +#define KEY_X 0x42 +#define KEY_C 0x43 +#define KEY_V 0x44 +#define KEY_B 0x45 +#define KEY_N 0x46 +#define KEY_M 0x47 +#define KEY_COMMA 0x48 +#define KEY_PERIOD 0x49 +#define KEY_SLASH 0x4A +#define KEY_BACKTICK 0x4B +#define KEY_NUM_LOCK 0x4C +#define KEY_SCROLL_LOCK 0x4D +#define KEY_L_META 0x4E +#define KEY_R_META 0x4F + +#define KEY_NP_SLASH 0x50 +#define KEY_NP_7 0x51 +#define KEY_NP_8 0x52 +#define KEY_NP_9 0x53 +#define KEY_NP_ASTERISK 0x54 +#define KEY_NP_4 0x55 +#define KEY_NP_5 0x56 +#define KEY_NP_6 0x57 +#define KEY_NP_MINUS 0x58 +#define KEY_NP_1 0x59 +#define KEY_NP_2 0x5A +#define KEY_NP_3 0x5B +#define KEY_NP_PLUS 0x5C +#define KEY_NP_0 0x5D +#define KEY_NP_PERIOD 0x5E +#define KEY_NP_ENTER 0x5F + +#define KEY_PRINT_SCREEN 0x60 +#define KEY_PAUSE 0x61 +#define KEY_INSERT 0x62 +#define KEY_HOME 0x63 +#define KEY_PAGE_UP 0x64 +#define KEY_DELETE 0x65 +#define KEY_END 0x66 +#define KEY_PAGE_DOWN 0x67 +#define KEY_UP 0x68 +#define KEY_DOWN 0x69 +#define KEY_LEFT 0x6A +#define KEY_RIGHT 0x6B +// #define _ 0x6C +// #define _ 0x6D +// #define _ 0x6E +// #define _ 0x6F + +#define KEY_F1 0x70 +#define KEY_F2 0x71 +#define KEY_F3 0x72 +#define KEY_F4 0x73 +#define KEY_F5 0x74 +#define KEY_F6 0x75 +#define KEY_F7 0x76 +#define KEY_F8 0x77 +#define KEY_F9 0x78 +#define KEY_F10 0x79 +#define KEY_F11 0x7A +#define KEY_F12 0x7B +// #define _ 0x7C +// #define _ 0x7D +// #define _ 0x7E +// #define _ 0x7F + +#endif /* keycodes */ -- cgit v1.2.3-freya From 7602ce3b97c893359406655afa515a616084655e Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 29 Apr 2025 12:17:32 -0400 Subject: input manager --- kernel/drivers/ps2.c | 62 +++++++------------------ kernel/include/comus/drivers/ps2.h | 22 --------- kernel/include/comus/input.h | 36 +++++++++++++++ kernel/include/comus/keycodes.h | 5 -- kernel/include/comus/limits.h | 4 ++ kernel/input.c | 93 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 150 insertions(+), 72 deletions(-) create mode 100644 kernel/include/comus/input.h create mode 100644 kernel/input.c (limited to 'kernel/drivers') diff --git a/kernel/drivers/ps2.c b/kernel/drivers/ps2.c index 5c18b5b..e260f6b 100644 --- a/kernel/drivers/ps2.c +++ b/kernel/drivers/ps2.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -78,22 +79,10 @@ static bool has_kbd = false; static bool has_mouse = false; // kbd -static struct keycode last_keycode = { - .key = KEY_NONE, - .flags = 0, -}; static bool state_keyup = false; static bool state_ext = false; // mouse -static struct mouse_event last_mouse_ev = { - .updated = false, - .lmb = false, - .mmb = false, - .rmb = false, - .relx = 0, - .rely = 0, -}; static uint8_t first_b, second_b, third_b; static uint8_t ps2ctrl_in_status(void) @@ -170,6 +159,7 @@ static int ps2mouse_init(void) void ps2kb_recv(void) { + static struct keycode keycode; uint8_t code; if (!has_kbd) @@ -177,40 +167,28 @@ void ps2kb_recv(void) code = ps2ctrl_in(); if (code == 0x00 || code == 0x0F) { - last_keycode.key = KEY_NONE; - last_keycode.flags = KC_FLAG_ERROR; + keycode.key = KEY_NONE; + keycode.flags = KC_FLAG_ERROR; } else if (code == 0xF0) { state_keyup = true; } else if (code == 0xE0) { state_ext = true; } else if (code <= 0x84) { uint8_t *scancode_table = state_ext ? scancodes_ext : scancodes; - uint8_t keycode = scancode_table[code]; - if (keycode != KEY_NONE) { - last_keycode.key = keycode; - last_keycode.flags = state_keyup ? KC_FLAG_KEY_UP : - KC_FLAG_KEY_DOWN; + uint8_t kcode = scancode_table[code]; + if (kcode != KEY_NONE) { + keycode.key = kcode; + keycode.flags = state_keyup ? KC_FLAG_KEY_UP : KC_FLAG_KEY_DOWN; + keycode_push(&keycode); } state_keyup = false; state_ext = false; } } -struct keycode ps2kb_get(void) -{ - struct keycode code; - - if (!has_kbd) - return last_keycode; - - code = last_keycode; - last_keycode.key = KEY_NONE; - last_keycode.flags = 0; - return code; -} - void ps2mouse_recv(void) { + static struct mouse_event mouse_ev; static uint8_t packet_num = 0; uint8_t code; @@ -231,14 +209,15 @@ void ps2mouse_recv(void) third_b = code; state = first_b; d = second_b; - last_mouse_ev.relx = d - ((state << 4) & 0x100); + mouse_ev.relx = d - ((state << 4) & 0x100); d = third_b; - last_mouse_ev.rely = d - ((state << 3) & 0x100); + mouse_ev.rely = d - ((state << 3) & 0x100); - last_mouse_ev.lmb = first_b & 0x01; - last_mouse_ev.rmb = first_b & 0x02; - last_mouse_ev.mmb = first_b & 0x04; - last_mouse_ev.updated = true; + mouse_ev.lmb = first_b & 0x01; + mouse_ev.rmb = first_b & 0x02; + mouse_ev.mmb = first_b & 0x04; + mouse_ev.updated = true; + mouse_event_push(&mouse_ev); break; } } @@ -247,13 +226,6 @@ void ps2mouse_recv(void) packet_num %= 3; } -struct mouse_event ps2mouse_get(void) -{ - struct mouse_event event = last_mouse_ev; - last_mouse_ev.updated = false; - return event; -} - int ps2_init(void) { uint8_t result; diff --git a/kernel/include/comus/drivers/ps2.h b/kernel/include/comus/drivers/ps2.h index 6e594e9..7634e5f 100644 --- a/kernel/include/comus/drivers/ps2.h +++ b/kernel/include/comus/drivers/ps2.h @@ -9,18 +9,6 @@ #ifndef PS2_H_ #define PS2_H_ -#include -#include - -struct mouse_event { - bool updated; - bool lmb; - bool rmb; - bool mmb; - int relx; - int rely; -}; - /** * Initalize the ps2 controller */ @@ -31,19 +19,9 @@ int ps2_init(void); */ void ps2kb_recv(void); -/** - * Return last read keycode - */ -struct keycode ps2kb_get(void); - /** * Recieve input from ps2 mouse during interrupt */ void ps2mouse_recv(void); -/** - * Return last read mouse event - */ -struct mouse_event ps2mouse_get(void); - #endif /* ps2.h */ diff --git a/kernel/include/comus/input.h b/kernel/include/comus/input.h new file mode 100644 index 0000000..b2b3053 --- /dev/null +++ b/kernel/include/comus/input.h @@ -0,0 +1,36 @@ +/** + * @file input.h + */ + +#ifndef INPUT_H_ +#define INPUT_H_ + +#include +#include +#include +#include + +struct keycode { + char key; + char flags; +}; + +struct mouse_event { + bool updated; + bool lmb; + bool rmb; + bool mmb; + int relx; + int rely; +}; + +void keycode_push(struct keycode *ev); +int keycode_pop(struct keycode *ev); +size_t keycode_len(void); +char keycode_to_char(struct keycode *ev); + +void mouse_event_push(struct mouse_event *ev); +int mouse_event_pop(struct mouse_event *ev); +size_t mouse_event_len(void); + +#endif /* input.h */ diff --git a/kernel/include/comus/keycodes.h b/kernel/include/comus/keycodes.h index 8930937..ebf296a 100644 --- a/kernel/include/comus/keycodes.h +++ b/kernel/include/comus/keycodes.h @@ -9,11 +9,6 @@ #ifndef KEYCODES_H_ #define KEYCODES_H_ -struct keycode { - char key; - char flags; -}; - #define KC_FLAG_KEY_DOWN 0x01 #define KC_FLAG_KEY_UP 0x02 #define KC_FLAG_ERROR 0x04 diff --git a/kernel/include/comus/limits.h b/kernel/include/comus/limits.h index cadfc93..732873e 100644 --- a/kernel/include/comus/limits.h +++ b/kernel/include/comus/limits.h @@ -25,6 +25,10 @@ /// elf limits #define N_ELF_SEGMENTS 16 +/// input buffer +#define N_KEYCODE 64 +#define N_MOUSEEV 64 + /// length of terminal buffer #define TERM_MAX_WIDTH 1920 #define TERM_MAX_HEIGHT 1080 diff --git a/kernel/input.c b/kernel/input.c new file mode 100644 index 0000000..2073950 --- /dev/null +++ b/kernel/input.c @@ -0,0 +1,93 @@ +#include + +struct mouse_event_buf { + struct mouse_event data[N_MOUSEEV]; + size_t start; + size_t end; + size_t len; +}; + +struct keycode_buf { + struct keycode data[N_KEYCODE]; + size_t start; + size_t end; + size_t len; +}; + +static struct keycode_buf keycode_buffer = { + .start = 0, + .end = 0, + .len = 0, +}; + +static struct mouse_event_buf mouse_event_buffer = { + .start = 0, + .end = 0, + .len = 0, +}; + +void keycode_push(struct keycode *ev) +{ + // save keycode + keycode_buffer.data[keycode_buffer.end] = *ev; + + // update pointers + keycode_buffer.end++; + keycode_buffer.end %= N_KEYCODE; + if (keycode_buffer.len < N_KEYCODE) { + keycode_buffer.len++; + } else { + keycode_buffer.start++; + keycode_buffer.start %= N_KEYCODE; + } +} + +int keycode_pop(struct keycode *ev) +{ + if (keycode_buffer.len < 1) + return 1; + + *ev = keycode_buffer.data[keycode_buffer.start]; + keycode_buffer.len--; + keycode_buffer.start++; + keycode_buffer.start %= N_KEYCODE; + return 0; +} + +size_t keycode_len(void) +{ + return keycode_buffer.len; +} + +void mouse_event_push(struct mouse_event *ev) +{ + // save mouse_event + mouse_event_buffer.data[mouse_event_buffer.end] = *ev; + + // update pointers + mouse_event_buffer.end++; + mouse_event_buffer.end %= N_KEYCODE; + if (mouse_event_buffer.len < N_KEYCODE) { + mouse_event_buffer.len++; + } else { + mouse_event_buffer.start++; + mouse_event_buffer.start %= N_KEYCODE; + } +} + +int mouse_event_pop(struct mouse_event *ev) +{ + if (mouse_event_buffer.len < 1) + return 1; + + *ev = mouse_event_buffer.data[mouse_event_buffer.start]; + mouse_event_buffer.len--; + mouse_event_buffer.start++; + mouse_event_buffer.start %= N_KEYCODE; + return 0; +} + +size_t mouse_event_len(void) +{ + return mouse_event_buffer.len; +} -- cgit v1.2.3-freya