diff --git a/Makefile b/Makefile index 8f45708..0284aff 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ CFILES = src/main.c \ src/cpu.c \ src/disk.c \ src/framebuffer.c \ + src/keyboard.c \ src/mouse.c \ src/screen.c diff --git a/fox32rom.h b/fox32rom.h index b80087f..f712c05 100644 --- a/fox32rom.h +++ b/fox32rom.h @@ -19,7 +19,7 @@ unsigned char fox32rom[] = { 0x02, 0x97, 0xd0, 0x01, 0x00, 0x00, 0x02, 0x02, 0x97, 0xff, 0xff, 0xff, 0xff, 0x03, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x97, 0x05, 0x00, 0x00, 0x00, 0x0b, 0x02, - 0x97, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0xa9, 0x05, 0x00, 0xf0, + 0x97, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0xa9, 0x05, 0x00, 0xf0, 0x02, 0x98, 0x4a, 0x0e, 0x00, 0xf0, 0x02, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x87, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x97, 0x37, 0xf2, 0x06, 0xf0, 0x00, 0x12, 0x98, @@ -32,7 +32,7 @@ unsigned char fox32rom[] = { 0x00, 0x00, 0x00, 0x03, 0x10, 0x9c, 0x10, 0x90, 0x00, 0xaa, 0x02, 0x97, 0x00, 0x10, 0x00, 0x80, 0x00, 0x02, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x97, 0x05, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x97, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x8a, 0x00, 0x00, 0x8a, 0x01, 0x02, 0x87, 0x00, 0x00, 0x00, 0x00, 0x03, 0x12, 0x88, 0xd9, 0x01, 0x00, 0xf0, 0x02, 0x87, 0x01, 0x00, 0x00, 0x00, 0x03, 0x12, 0x88, 0x23, 0x02, 0x00, 0xf0, 0x02, 0x87, 0x02, @@ -149,7 +149,7 @@ unsigned char fox32rom[] = { 0x10, 0x00, 0x00, 0x00, 0x01, 0x02, 0x97, 0xd0, 0x01, 0x00, 0x00, 0x02, 0x02, 0x97, 0xff, 0xff, 0xff, 0xff, 0x03, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x97, 0x05, - 0x00, 0x00, 0x00, 0x0b, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, + 0x00, 0x00, 0x00, 0x0b, 0x02, 0x97, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0xa9, 0x05, 0x00, 0xf0, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x97, 0x00, 0x08, 0x00, 0x00, 0x02, 0x02, 0x97, 0x00, 0x30, 0x00, 0x80, 0x03, 0x02, 0x97, 0x00, 0x20, 0x00, 0x80, 0x04, 0x00, 0x9b, 0x02, @@ -172,7 +172,7 @@ unsigned char fox32rom[] = { 0x00, 0x00, 0x01, 0x02, 0x97, 0xd0, 0x01, 0x00, 0x00, 0x02, 0x02, 0x97, 0xff, 0xff, 0xff, 0xff, 0x03, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x97, 0x05, 0x00, 0x00, - 0x00, 0x0b, 0x02, 0x97, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0xa9, + 0x00, 0x0b, 0x02, 0x97, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0xa9, 0x05, 0x00, 0xf0, 0x00, 0xaa, 0x02, 0x97, 0x64, 0x47, 0x67, 0xff, 0x00, 0x02, 0x98, 0xcd, 0x04, 0x00, 0xf0, 0x02, 0x98, 0xa4, 0x16, 0x00, 0xf0, 0x00, 0xaa, 0x00, 0x8a, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x8a, 0x1f, 0x02, diff --git a/src/bus.c b/src/bus.c index 33f0ff3..92aba43 100644 --- a/src/bus.c +++ b/src/bus.c @@ -12,6 +12,7 @@ #include "cpu.h" #include "disk.h" #include "framebuffer.h" +#include "keyboard.h" #include "mouse.h" extern fox32_vm_t vm; @@ -74,6 +75,12 @@ int bus_io_read(void *user, uint32_t *value, uint32_t port) { break; }; + case 0x80000500: { + *value = (uint32_t) key_take(); + + break; + } + case 0x80001000 ... 0x80002003: { // disk controller port size_t id = port & 0xFF; uint8_t operation = (port & 0x0000F000) >> 8; diff --git a/src/keyboard.c b/src/keyboard.c new file mode 100644 index 0000000..5b9eec0 --- /dev/null +++ b/src/keyboard.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "keyboard.h" + +typedef struct node_s { + struct node_s *prev; + struct node_s *next; + key_t code; +} node_t; + +static node_t *head = NULL; +static node_t *tail = NULL; + +key_t key_take(void) { + node_t *node = head; + + if (node == NULL) { + return 0; + } + + if (node == tail) { + head = NULL; + tail = NULL; + } else { + head = node->next; + head->prev = NULL; + } + + key_t code = node->code; + return free(node), code; +} + +void key_put(key_t code) { + if (code == 0) abort(); + + node_t *node = malloc(sizeof(node_t)); + + node->prev = tail; + node->next = NULL; + node->code = code; + + if (head == NULL) { + head = node; + } else { + tail->next = node; + } + + tail = node; +} + +static const key_t key_map[SDL_NUM_SCANCODES] = { + [SDL_SCANCODE_ESCAPE] = 0x01, + [SDL_SCANCODE_1] = 0x02, + [SDL_SCANCODE_KP_1] = 0x02, + [SDL_SCANCODE_2] = 0x03, + [SDL_SCANCODE_KP_2] = 0x03, + [SDL_SCANCODE_3] = 0x04, + [SDL_SCANCODE_KP_3] = 0x04, + [SDL_SCANCODE_4] = 0x05, + [SDL_SCANCODE_KP_4] = 0x05, + [SDL_SCANCODE_5] = 0x06, + [SDL_SCANCODE_KP_5] = 0x06, + [SDL_SCANCODE_6] = 0x07, + [SDL_SCANCODE_KP_6] = 0x07, + [SDL_SCANCODE_7] = 0x08, + [SDL_SCANCODE_KP_7] = 0x08, + [SDL_SCANCODE_8] = 0x09, + [SDL_SCANCODE_KP_8] = 0x09, + [SDL_SCANCODE_9] = 0x0A, + [SDL_SCANCODE_KP_9] = 0x0A, + [SDL_SCANCODE_0] = 0x0B, + [SDL_SCANCODE_KP_0] = 0x0B, + [SDL_SCANCODE_MINUS] = 0x0C, + [SDL_SCANCODE_EQUALS] = 0x0D, + [SDL_SCANCODE_BACKSPACE] = 0x0E, + [SDL_SCANCODE_TAB] = 0x0F, + [SDL_SCANCODE_Q] = 0x10, + [SDL_SCANCODE_W] = 0x11, + [SDL_SCANCODE_E] = 0x12, + [SDL_SCANCODE_R] = 0x13, + [SDL_SCANCODE_T] = 0x14, + [SDL_SCANCODE_Y] = 0x15, + [SDL_SCANCODE_U] = 0x16, + [SDL_SCANCODE_I] = 0x17, + [SDL_SCANCODE_O] = 0x18, + [SDL_SCANCODE_P] = 0x19, + [SDL_SCANCODE_LEFTBRACKET] = 0x1A, + [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, + [SDL_SCANCODE_RETURN] = 0x1C, + [SDL_SCANCODE_LCTRL] = 0x1D, + [SDL_SCANCODE_A] = 0x1E, + [SDL_SCANCODE_S] = 0x1F, + [SDL_SCANCODE_D] = 0x20, + [SDL_SCANCODE_F] = 0x21, + [SDL_SCANCODE_G] = 0x22, + [SDL_SCANCODE_H] = 0x23, + [SDL_SCANCODE_J] = 0x24, + [SDL_SCANCODE_K] = 0x25, + [SDL_SCANCODE_L] = 0x26, + [SDL_SCANCODE_SEMICOLON] = 0x27, + [SDL_SCANCODE_APOSTROPHE] = 0x28, + [SDL_SCANCODE_GRAVE] = 0x29, + [SDL_SCANCODE_LSHIFT] = 0x2A, + [SDL_SCANCODE_BACKSLASH] = 0x2B, + [SDL_SCANCODE_Z] = 0x2C, + [SDL_SCANCODE_X] = 0x2D, + [SDL_SCANCODE_C] = 0x2E, + [SDL_SCANCODE_V] = 0x2F, + [SDL_SCANCODE_B] = 0x30, + [SDL_SCANCODE_N] = 0x31, + [SDL_SCANCODE_M] = 0x32, + [SDL_SCANCODE_COMMA] = 0x33, + [SDL_SCANCODE_PERIOD] = 0x34, + [SDL_SCANCODE_SLASH] = 0x35, + [SDL_SCANCODE_RSHIFT] = 0x36, + [SDL_SCANCODE_KP_HASH] = 0x37, + [SDL_SCANCODE_LALT] = 0x38, + [SDL_SCANCODE_SPACE] = 0x39, + [SDL_SCANCODE_CAPSLOCK] = 0x3A, + [SDL_SCANCODE_F1] = 0x3B, + [SDL_SCANCODE_F2] = 0x3C, + [SDL_SCANCODE_F3] = 0x3D, + [SDL_SCANCODE_F4] = 0x3E, + [SDL_SCANCODE_F5] = 0x3F, + [SDL_SCANCODE_F6] = 0x40, + [SDL_SCANCODE_F7] = 0x41, + [SDL_SCANCODE_F8] = 0x42, + [SDL_SCANCODE_F9] = 0x43, + [SDL_SCANCODE_F10] = 0x44, + [SDL_SCANCODE_F11] = 0x57, + [SDL_SCANCODE_F12] = 0x58, + [SDL_SCANCODE_UP] = 0x67, + [SDL_SCANCODE_DOWN] = 0x6C, + [SDL_SCANCODE_LEFT] = 0x69, + [SDL_SCANCODE_RIGHT] = 0x6A, +}; + +key_t key_convert(int sdlcode) { + if (sdlcode < 0 || sdlcode > SDL_NUM_SCANCODES) abort(); + return key_map[sdlcode]; +} + +void key_pressed(int sdlcode) { + key_put(key_convert(sdlcode)); +} + +void key_released(int sdlcode) { + key_put(key_convert(sdlcode) | 0x80); +} diff --git a/src/keyboard.h b/src/keyboard.h new file mode 100644 index 0000000..eeeb221 --- /dev/null +++ b/src/keyboard.h @@ -0,0 +1,10 @@ +#pragma once + +typedef unsigned char key_t; + +key_t key_take(void); +void key_put(key_t code); + +key_t key_convert(int sdlcode); +void key_pressed(int sdlcode); +void key_released(int sdlcode); diff --git a/src/main.c b/src/main.c index 23b1438..5142242 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include "cpu.h" #include "disk.h" #include "framebuffer.h" +#include "keyboard.h" #include "mouse.h" #include "screen.h" @@ -54,8 +55,8 @@ int main(int argc, char *argv[]) { ScreenCreate( FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, draw_framebuffer, - 0, - 0, + key_pressed, + key_released, mouse_pressed, mouse_released, mouse_moved @@ -97,8 +98,7 @@ void main_loop(void) { if (i == dt - 1) cycles_left += extra_cycles; - const char *msg = fox32_strerr(fox32_resume(&vm, cycles_left)); - //puts(msg != NULL ? msg : "NULL"); + fox32_resume(&vm, cycles_left); } if ((ticks % TPF) == 0) {