From 438abd992663739335aabcf273c9c1dabdf03859 Mon Sep 17 00:00:00 2001 From: kub Date: Sat, 11 Jan 2025 17:08:43 +0100 Subject: [PATCH] sms, sc-3000 keyboard support (WIP) --- pico/sms.c | 123 +++++++++++++++++++++++++++++++-- platform/common/config_file.c | 2 + platform/common/input_pico.h | 8 +++ platform/common/inputmap_kbd.c | 7 ++ platform/common/menu_pico.c | 4 +- 5 files changed, 138 insertions(+), 6 deletions(-) diff --git a/pico/sms.c b/pico/sms.c index fe06f63f..a9f9aacd 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -132,6 +132,112 @@ static u8 vdp_hcounter(int cycles) return hc; } +#include + +// keyboard matrix: +// port A @0xdc: +// row 0: 1 2 3 4 5 6 7 +// row 1: q w e r t y u +// row 2: a s d f g h j +// row 3: z x c v b n m +// row 4: ED SP CL DL +// row 5: , . / PI v < > +// row 6: k l ; : ] CR ^ +// row 7: i o p @ [ +// port B @0xdd: +// row 8: 8 9 0 - ^ YN BR +// row 9: GR +// row 10: CTL +// row 11: FN SFT +static unsigned char kbd_matrix[12]; + +// row | col +static unsigned char kbd_map[] = { + [PEVB_PICO_PS2_1] = 0x00, + [PEVB_PICO_PS2_2] = 0x01, + [PEVB_PICO_PS2_3] = 0x02, + [PEVB_PICO_PS2_4] = 0x03, + [PEVB_PICO_PS2_5] = 0x04, + [PEVB_PICO_PS2_6] = 0x05, + [PEVB_PICO_PS2_7] = 0x06, + [PEVB_PICO_PS2_8] = 0x80, + [PEVB_PICO_PS2_9] = 0x81, + [PEVB_PICO_PS2_0] = 0x82, + [PEVB_PICO_PS2_MINUS] = 0x83, + [PEVB_PICO_PS2_CARET] = 0x84, + [PEVB_PICO_PS2_YEN] = 0x85, + [PEVB_PICO_PS2_ESCAPE] = 0x86, // break + + [PEVB_PICO_PS2_q] = 0x10, + [PEVB_PICO_PS2_w] = 0x11, + [PEVB_PICO_PS2_e] = 0x12, + [PEVB_PICO_PS2_r] = 0x13, + [PEVB_PICO_PS2_t] = 0x14, + [PEVB_PICO_PS2_y] = 0x15, + [PEVB_PICO_PS2_u] = 0x16, + [PEVB_PICO_PS2_i] = 0x70, + [PEVB_PICO_PS2_o] = 0x71, + [PEVB_PICO_PS2_p] = 0x72, + [PEVB_PICO_PS2_AT] = 0x73, + [PEVB_PICO_PS2_LEFTBRACKET] = 0x74, + + [PEVB_PICO_PS2_a] = 0x20, + [PEVB_PICO_PS2_s] = 0x21, + [PEVB_PICO_PS2_d] = 0x22, + [PEVB_PICO_PS2_f] = 0x23, + [PEVB_PICO_PS2_g] = 0x24, + [PEVB_PICO_PS2_h] = 0x25, + [PEVB_PICO_PS2_j] = 0x26, + [PEVB_PICO_PS2_k] = 0x60, + [PEVB_PICO_PS2_l] = 0x61, + [PEVB_PICO_PS2_SEMICOLON] = 0x62, + [PEVB_PICO_PS2_COLON] = 0x63, + [PEVB_PICO_PS2_RIGHTBRACKET] = 0x64, + [PEVB_PICO_PS2_RETURN] = 0x65, + [PEVB_PICO_PS2_UP] = 0x66, // up + + [PEVB_PICO_PS2_z] = 0x30, + [PEVB_PICO_PS2_x] = 0x31, + [PEVB_PICO_PS2_c] = 0x32, + [PEVB_PICO_PS2_v] = 0x33, + [PEVB_PICO_PS2_b] = 0x34, + [PEVB_PICO_PS2_n] = 0x35, + [PEVB_PICO_PS2_m] = 0x36, + [PEVB_PICO_PS2_COMMA] = 0x50, + [PEVB_PICO_PS2_PERIOD] = 0x51, + [PEVB_PICO_PS2_SLASH] = 0x52, + [PEVB_PICO_PS2_RO] = 0x53, // pi + [PEVB_PICO_PS2_DOWN] = 0x54, // down + [PEVB_PICO_PS2_LEFT] = 0x55, // left + [PEVB_PICO_PS2_RIGHT] = 0x56, // right + + [PEVB_PICO_PS2_CJK] = 0x40, // kana + [PEVB_PICO_PS2_SPACE] = 0x41, // space + [PEVB_PICO_PS2_HOME] = 0x42, // clear/home + [PEVB_PICO_PS2_BACKSPACE] = 0x43, // del/ins + + [PEVB_PICO_PS2_SOUND] = 0x96, // graph + [PEVB_PICO_PS2_CTRL] = 0xa6, // ctrl + [PEVB_PICO_PS2_CAPSLOCK] = 0xb5, // func + [PEVB_PICO_PS2_LSHIFT] = 0xb6, // shift +}; + +static void kbd_update(void) +{ + u32 key = (PicoIn.ps2 & 0x00ff); + u32 sft = (PicoIn.ps2 & 0xff00) >> 8; + + memset(kbd_matrix, 0, sizeof(kbd_matrix)); + if (/*PicoPicohw.kb.active &&*/ sft) { + int rc = kbd_map[sft]; + kbd_matrix[rc>>4] = (1 << (rc&0x7)); + } + if (/*PicoPicohw.kb.active &&*/ key) { + int rc = kbd_map[key]; + kbd_matrix[rc>>4] = (1 << (rc&0x7)); + } +} + static unsigned char z80_sms_in(unsigned short a) { unsigned char d = 0xff; @@ -193,8 +299,12 @@ static unsigned char z80_sms_in(unsigned short a) d = ~((PicoIn.pad[0] & 0x3f) | (PicoIn.pad[1] << 6)); if (!(Pico.ms.io_ctl & 0x01)) // TR as output d = (d & ~0x20) | ((Pico.ms.io_ctl << 1) & 0x20); - } else - ; // read kbd 8 bits + } else { + int i; // read kbd 8 bits + kbd_update(); + for (i = 7; i >= 0; i--) + d = (d<<1) | !(kbd_matrix[i] & (1<<(Pico.ms.io_sg&7))); + } break; case 0xc1: /* I/O port B and miscellaneous */ @@ -205,8 +315,12 @@ static unsigned char z80_sms_in(unsigned short a) d = (d & ~0x08) | ((Pico.ms.io_ctl >> 3) & 0x08); if (Pico.ms.io_ctl & 0x08) d |= 0x80; // TH as input is unconnected if (Pico.ms.io_ctl & 0x02) d |= 0x40; - } else - ; // read kbd 4 bits + } else { + int i; // read kbd 4 bits + kbd_update(); + for (i = 11; i >= 8; i--) + d = (d<<1) | !(kbd_matrix[i] & (1<<(Pico.ms.io_sg&7))); + } break; } } @@ -274,6 +388,7 @@ static void z80_sms_out(unsigned short a, unsigned char d) break; case 0xc0: + // SG-1000 has a 8255 chip, mapped to 0xdc-0xdf if ((PicoIn.AHW & PAHW_SC) && (a & 0x2)) Pico.ms.io_sg = d; // 0xc2 = kbd/pad select } diff --git a/platform/common/config_file.c b/platform/common/config_file.c index 7425b845..e08a4751 100644 --- a/platform/common/config_file.c +++ b/platform/common/config_file.c @@ -67,6 +67,7 @@ static void keys_write(FILE *fn, int dev_id, const int *binds, const int *ps2_bi act[0] = act[31] = 0; name = in_get_key_name(dev_id, k); + if (strcmp(name, "#") == 0) name = "\\x23"; // replace comment sign for (i = 0; me_ctrl_actions[i].name != NULL; i++) { mask = me_ctrl_actions[i].mask; @@ -105,6 +106,7 @@ static void keys_write(FILE *fn, int dev_id, const int *binds, const int *ps2_bi for (k = 0; k < key_count; k++) { const char *name = in_get_key_name(dev_id, k); + if (strcmp(name, "#") == 0) name = "\\x23"; // replace comment sign if (ps2_binds[k]) fprintf(fn, "bind %s = key%02x" NL, name, ps2_binds[k]); } diff --git a/platform/common/input_pico.h b/platform/common/input_pico.h index d906c66d..b1b09f84 100644 --- a/platform/common/input_pico.h +++ b/platform/common/input_pico.h @@ -141,4 +141,12 @@ #define PEVB_PICO_PS2_CJK 0x13 #define PEVB_PICO_PS2_ROMAJI 0x17 +// Other buttons, for SC-3000 +#define PEVB_PICO_PS2_CTRL 0x14 +#define PEVB_PICO_PS2_ALT 0x11 +#define PEVB_PICO_PS2_UP 0x75 +#define PEVB_PICO_PS2_DOWN 0x72 +#define PEVB_PICO_PS2_LEFT 0x6b +#define PEVB_PICO_PS2_RIGHT 0x74 + #endif /* INCLUDE_c48097f3ff2a6a9af1cce8fd7a9b3f0c */ diff --git a/platform/common/inputmap_kbd.c b/platform/common/inputmap_kbd.c index dbe8c2f0..9271967f 100644 --- a/platform/common/inputmap_kbd.c +++ b/platform/common/inputmap_kbd.c @@ -126,6 +126,13 @@ const struct in_default_bind in_sdl_pico_ps2_map[] = { { SDLK_PAGEUP, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_CJK }, // CJK Scripts: Hiragana / Katakana / Kanji (Keyboard Pico); Hangul (Kibodeu Piko) { SDLK_PAGEDOWN, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_ROMAJI }, // English Script + // Others + { SDLK_LALT, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_ALT }, + { SDLK_UP, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_UP }, + { SDLK_DOWN, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_DOWN }, + { SDLK_LEFT, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_LEFT }, + { SDLK_RIGHT, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_RIGHT }, + { 0, 0, 0 } }; const struct in_default_bind *in_sdl_defbinds = _in_sdl_defbinds; diff --git a/platform/common/menu_pico.c b/platform/common/menu_pico.c index e2331993..f7da2e49 100644 --- a/platform/common/menu_pico.c +++ b/platform/common/menu_pico.c @@ -490,7 +490,7 @@ struct key pico_row4[] = { { 28, ",", "<", PEVB_PICO_PS2_COMMA }, { 31, ".", ">", PEVB_PICO_PS2_PERIOD }, { 34, "/", "?", PEVB_PICO_PS2_SLASH }, - { 37, "_", "_", PEVB_PICO_PS2_COLON }, + { 37, "_", "_", PEVB_PICO_PS2_RO }, { 41, "enter", "enter", PEVB_PICO_PS2_RETURN }, { 0 }, }; @@ -515,7 +515,7 @@ static void kbd_draw(struct key *desc[], int shift, int xoffs, int yoffs, struct for (i = 0; desc[i]; i++) { // clear line? for (j = 0, key = &desc[i][j]; key->lower; j++, key++) { - int color = (key == hi ? PXMAKE(0xff, 0x00, 0xff) : + int color = (key == hi ? PXMAKE(0xff, 0x00, 0x00) : PXMAKE(0xff, 0xff, 0xff)); char *text = (shift ? key->upper : key->lower); smalltext_out16(xoffs + key->xpos*me_sfont_w, yoffs + i*me_sfont_h, text, color); -- 2.39.5