From 69521d81ca7dcae43687cd42a26ff6d0427aad86 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sun, 25 Jan 2026 11:24:52 +1100 Subject: [PATCH] Keyboard on the Velvet is attached to CIAB --- cia.cpp | 111 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 38 deletions(-) diff --git a/cia.cpp b/cia.cpp index 430a3acf..37f65213 100644 --- a/cia.cpp +++ b/cia.cpp @@ -184,6 +184,8 @@ static bool cia_cycle_accurate; int cia_timer_hack_adjust = 1; +static void check_keyboard(void); + static bool acc_mode(void) { return cia_cycle_accurate; @@ -979,12 +981,51 @@ static void setcode(uae_u8 keycode) kbcode = ~((keycode << 1) | (keycode >> 7)); } +static int keyboard_cia_num(void) +{ + return currprefs.cs_compatible == CP_VELVET ? 1 : 0; +} + +static void keyboard_handshake_write(struct CIA *c, uae_u8 val) +{ + // keyboard handshake handling + bool handshake_start = (val & CR_INMODE1) != 0 && (c->t[0].cr & CR_INMODE1) == 0; + bool handshake_end = (val & CR_INMODE1) == 0 && (c->t[0].cr & CR_INMODE1) != 0; + + if (currprefs.cpuboard_type != 0 && (handshake_start || handshake_end)) { + /* bleh, Phase5 CPU timed early boot key check fix.. */ + if (m68k_getpc() >= 0xf00000 && m68k_getpc() < 0xf80000) + check_keyboard(); + } + if (handshake_start) { + if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { + kbhandshakestart = get_cycles(); + } +#if KB_DEBUG + write_log(_T("KB_ACK_START %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); +#endif + } else if (handshake_end) { + /* todo: check if low to high or high to low only */ + if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { + evt_t len = get_cycles() - kbhandshakestart; + if (len < currprefs.cs_kbhandshake * CYCLE_UNIT) { + write_log(_T("Keyboard handshake pulse length %d < %d (CCKs)\n"), len / CYCLE_UNIT, currprefs.cs_kbhandshake); + } + } + kblostsynccnt = 0; +#if KB_DEBUG + write_log(_T("KB_ACK_END %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); +#endif + } +} + static void sendrw(void) { + int num = keyboard_cia_num(); setcode(AK_RESETWARNING); - cia[0].sdr = kbcode; + cia[num].sdr = kbcode; kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. - CIA_sync_interrupt(0, ICR_SP); + CIA_sync_interrupt(num, ICR_SP); write_log(_T("KB: sent reset warning code (phase=%d)\n"), resetwarning_phase); } @@ -1009,6 +1050,8 @@ int resetwarning_do(int canreset) static void resetwarning_check(void) { + int num = keyboard_cia_num(); + if (resetwarning_timer > 0) { resetwarning_timer--; if (resetwarning_timer <= 0) { @@ -1026,14 +1069,14 @@ static void resetwarning_check(void) sendrw(); } } else if (resetwarning_phase == 2) { - if (cia[0].t[0].cr & CR_SPMODE) { /* second AK_RESETWARNING handshake active */ + if (cia[num].t[0].cr & CR_SPMODE) { /* second AK_RESETWARNING handshake active */ resetwarning_phase = 3; write_log(_T("KB: reset warning SP = output\n")); /* System won't reset until handshake signal becomes inactive or 10s has passed */ resetwarning_timer = (int)(10 * maxvpos_nom * vblank_hz); } } else if (resetwarning_phase == 3) { - if (!(cia[0].t[0].cr & CR_SPMODE)) { /* second AK_RESETWARNING handshake disabled */ + if (!(cia[num].t[0].cr & CR_SPMODE)) { /* second AK_RESETWARNING handshake disabled */ write_log(_T("KB: reset warning end by software. reset.\n")); resetwarning_phase = -1; kblostsynccnt = 0; @@ -1044,14 +1087,17 @@ static void resetwarning_check(void) void cia_keyreq(uae_u8 code) { + int num = keyboard_cia_num(); + #if KB_DEBUG write_log(_T("code=%02x (%02x)\n"), kbcode, (uae_u8)(~((kbcode >> 1) | (kbcode << 7)))); #endif - cia[0].sdr = code; + + cia[num].sdr = code; if (currprefs.keyboard_mode == 0) { kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. } - CIA_sync_interrupt(0, ICR_SP); + CIA_sync_interrupt(num, ICR_SP); } /* All this complexity to lazy evaluate CIA-B TOD increase. @@ -2150,7 +2196,7 @@ static void WriteCIAA(uae_u16 addr, uae_u8 val, uae_u32 *flags) case 13: case 15: CIA_update(); - if (currprefs.keyboard_mode > 0 && reg == 12) { + if (currprefs.keyboard_mode > 0 && reg == 12 && currprefs.cs_compatible != CP_VELVET) { keymcu_do(); } WriteCIAReg(0, reg, val); @@ -2160,39 +2206,12 @@ static void WriteCIAA(uae_u16 addr, uae_u8 val, uae_u32 *flags) { CIA_update(); bool handshake = (val & CR_INMODE1) != (c->t[0].cr & CR_INMODE1); - if (currprefs.keyboard_mode == 0) { - // keyboard handshake handling - if (currprefs.cpuboard_type != 0 && handshake) { - /* bleh, Phase5 CPU timed early boot key check fix.. */ - if (m68k_getpc() >= 0xf00000 && m68k_getpc() < 0xf80000) - check_keyboard(); - } - if ((val & CR_INMODE1) != 0 && (c->t[0].cr & CR_INMODE1) == 0) { - // handshake start - if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { - kbhandshakestart = get_cycles(); - } -#if KB_DEBUG - write_log(_T("KB_ACK_START %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); -#endif - } else if ((val & CR_INMODE1) == 0 && (c->t[0].cr & CR_INMODE1) != 0) { - // handshake end - /* todo: check if low to high or high to low only */ - if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { - evt_t len = get_cycles() - kbhandshakestart; - if (len < currprefs.cs_kbhandshake * CYCLE_UNIT) { - write_log(_T("Keyboard handshake pulse length %d < %d (CCKs)\n"), len / CYCLE_UNIT, currprefs.cs_kbhandshake); - } - } - kblostsynccnt = 0; -#if KB_DEBUG - write_log(_T("KB_ACK_END %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); -#endif - } + if (currprefs.keyboard_mode == 0 && currprefs.cs_compatible != CP_VELVET) { + keyboard_handshake_write(c, val); } WriteCIAReg(0, reg, val); CIA_calctimers(); - if (currprefs.keyboard_mode > 0 && handshake) { + if (currprefs.keyboard_mode > 0 && handshake && currprefs.cs_compatible != CP_VELVET) { keymcu_do(); } } @@ -2292,6 +2311,20 @@ static void WriteCIAB(uae_u16 addr, uae_u8 val, uae_u32 *flags) dongle_cia_write(1, reg, c->prb, val); c->drb = val; break; + case 14: + { + CIA_update(); + bool handshake = (val & CR_INMODE1) != (c->t[0].cr & CR_INMODE1); + if (currprefs.keyboard_mode == 0 && currprefs.cs_compatible == CP_VELVET) { + keyboard_handshake_write(c, val); + } + WriteCIAReg(1, reg, val); + CIA_calctimers(); + if (currprefs.keyboard_mode > 0 && handshake && currprefs.cs_compatible == CP_VELVET) { + keymcu_do(); + } + } + break; case 4: case 5: case 6: @@ -2302,9 +2335,11 @@ static void WriteCIAB(uae_u16 addr, uae_u8 val, uae_u32 *flags) case 11: case 12: case 13: - case 14: case 15: CIA_update(); + if (currprefs.keyboard_mode > 0 && reg == 12 && currprefs.cs_compatible == CP_VELVET) { + keymcu_do(); + } WriteCIAReg(1, reg, val); CIA_calctimers(); break; -- 2.47.3