From adcb88905956a2694bba6a78d11b0ab7635c7e3e Mon Sep 17 00:00:00 2001 From: Brooke Chalmers Date: Fri, 10 Nov 2023 00:54:05 -0500 Subject: [PATCH] Rework keyboard logic, it sorta kinda works Co-authored-by: ava-silver --- src/keyboard/apple.rs | 209 +++++++++++++++++++++++++++++++++++ src/keyboard/mod.rs | 3 + src/main.rs | 2 +- src/systems/aiie/keyboard.rs | 60 +++++++--- src/systems/aiie/mod.rs | 58 +++++++--- 5 files changed, 299 insertions(+), 33 deletions(-) create mode 100644 src/keyboard/apple.rs diff --git a/src/keyboard/apple.rs b/src/keyboard/apple.rs new file mode 100644 index 00000000..80c5a8b1 --- /dev/null +++ b/src/keyboard/apple.rs @@ -0,0 +1,209 @@ +use crate::keyboard::{KeyAdapter, KeyPosition, KeyState}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum AppleKeys { + Esc, + Digit1, + Digit2, + Digit3, + Digit4, + Digit5, + Digit6, + Digit7, + Digit8, + Digit9, + Digit0, + Minus, + Equals, + Del, + + Tab, + Q, + W, + E, + R, + T, + Y, + U, + I, + O, + P, + LeftBracket, + RightBracket, + + Ctrl, + A, + S, + D, + F, + G, + H, + J, + K, + L, + Semicolon, + Apostrophe, + Grave, + Return, + + LShift, + Slash, + Z, + X, + C, + V, + B, + N, + M, + Comma, + Period, + Backslash, + RShift, + + CapsLock, + OpenApple, + Space, + ClosedApple, + LeftArrow, + RightArrow, + DownArrow, + UpArrow, + + NumEsc, + NumLeft, + NumRight, + NumSpace, + + Num0, + Num1, + Num2, + Num3, + Num4, + Num5, + Num6, + Num7, + Num8, + Num9, + NumComma, + NumPeriod, + NumLeftParen, + NumRightParen, + NumMinus, + NumDivide, + NumPlus, + NumMultiply, + NumReturn, + NumPrint, +} + +/// An adapter for mapping positions on a standard keyboard to keys on an Apple IIe. +pub struct AppleKeyboardAdapter; + +impl KeyAdapter for AppleKeyboardAdapter { + fn map(state: &KeyState) -> KeyState { + let mut mapped = KeyState::new(); + + for symbol in state.pressed() { + use KeyPosition::*; + + mapped.press(match symbol { + Escape => AppleKeys::Esc, + Digit1 => AppleKeys::Digit1, + Digit2 => AppleKeys::Digit2, + Digit3 => AppleKeys::Digit3, + Digit4 => AppleKeys::Digit4, + Digit5 => AppleKeys::Digit5, + Digit6 => AppleKeys::Digit6, + Digit7 => AppleKeys::Digit7, + Digit8 => AppleKeys::Digit8, + Digit9 => AppleKeys::Digit9, + Digit0 => AppleKeys::Digit0, + Minus => AppleKeys::Minus, + Equals => AppleKeys::Equals, + Delete => AppleKeys::Del, + + Tab => AppleKeys::Tab, + Q => AppleKeys::Q, + W => AppleKeys::W, + E => AppleKeys::E, + R => AppleKeys::R, + T => AppleKeys::T, + Y => AppleKeys::Y, + U => AppleKeys::U, + I => AppleKeys::I, + O => AppleKeys::O, + P => AppleKeys::P, + LeftBracket => AppleKeys::LeftBracket, + RightBracket => AppleKeys::RightBracket, + + LControl | RControl => AppleKeys::Ctrl, + A => AppleKeys::A, + S => AppleKeys::S, + D => AppleKeys::D, + F => AppleKeys::F, + G => AppleKeys::G, + H => AppleKeys::H, + J => AppleKeys::J, + K => AppleKeys::K, + L => AppleKeys::L, + Semicolon => AppleKeys::Semicolon, + Apostrophe => AppleKeys::Apostrophe, + Grave => AppleKeys::Grave, + Enter => AppleKeys::Return, + + LShift => AppleKeys::LShift, + Slash => AppleKeys::Slash, + Z => AppleKeys::Z, + X => AppleKeys::X, + C => AppleKeys::C, + V => AppleKeys::V, + B => AppleKeys::B, + N => AppleKeys::N, + M => AppleKeys::M, + Comma => AppleKeys::Comma, + Period => AppleKeys::Period, + Backslash => AppleKeys::Backslash, + RShift => AppleKeys::RShift, + + CapsLock => AppleKeys::CapsLock, + LSuper => AppleKeys::OpenApple, + Space => AppleKeys::Space, + RSuper => AppleKeys::ClosedApple, + LeftArrow => AppleKeys::LeftArrow, + RightArrow => AppleKeys::RightArrow, + DownArrow => AppleKeys::DownArrow, + UpArrow => AppleKeys::UpArrow, + + NumLock => AppleKeys::NumEsc, + // NumLeft => AppleKeys::NumLeft, + // NumRight => AppleKeys::NumRight, + // NumSpace => AppleKeys::NumSpace, + Num0 => AppleKeys::Num0, + Num1 => AppleKeys::Num1, + Num2 => AppleKeys::Num2, + Num3 => AppleKeys::Num3, + Num4 => AppleKeys::Num4, + Num5 => AppleKeys::Num5, + Num6 => AppleKeys::Num6, + Num7 => AppleKeys::Num7, + Num8 => AppleKeys::Num8, + Num9 => AppleKeys::Num9, + // NumPeriod => AppleKeys::NumComma, + NumPeriod => AppleKeys::NumPeriod, + // NumLeftParen => AppleKeys::NumLeftParen, + // NumRightParen => AppleKeys::NumRightParen, + NumMinus => AppleKeys::NumMinus, + NumDivide => AppleKeys::NumDivide, + NumPlus => AppleKeys::NumPlus, + NumMultiply => AppleKeys::NumMultiply, + NumEnter => AppleKeys::NumReturn, + PrintScreen => AppleKeys::NumPrint, + + _ => continue, + }); + } + + mapped + } +} diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index d1309ccd..5441bd8c 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -1,3 +1,6 @@ +/// Keys and adapters for the Apple ][e and other early Apple machines. +pub mod apple; + /// Keys and adapters for the Commodore 64, VIC-20, and other Commodore machines. pub mod commodore; diff --git a/src/main.rs b/src/main.rs index 4a108bcc..e937f6a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -107,7 +107,7 @@ fn main() { ), SystemArg::Aiie => AiieSystemBuilder::build( AiieSystemRoms::from_disk(), - AiieSystemConfig { mapping }, + AiieSystemConfig {}, platform.provider(), ), }; diff --git a/src/systems/aiie/keyboard.rs b/src/systems/aiie/keyboard.rs index 5f36f101..8ab54acb 100644 --- a/src/systems/aiie/keyboard.rs +++ b/src/systems/aiie/keyboard.rs @@ -1,31 +1,55 @@ -use crate::keyboard::commodore::C64Keys; +use crate::keyboard::apple::AppleKeys; /// The keyboard matrix found on a Commodore 64. /// Source: . -pub const KEYBOARD_MAPPING: [[C64Keys; 8]; 8] = { - use C64Keys::*; +pub const KEYBOARD_MAPPING: [[AppleKeys; 10]; 8] = { + use AppleKeys::*; [ [ - InsertDelete, - Return, - CursorLeftRight, - F7, - F1, - F3, - F5, - CursorUpDown, + Esc, Digit1, Digit2, Digit3, Digit4, Digit6, Digit5, Digit7, Digit8, Digit9, + ], + [Tab, Q, W, E, R, Y, T, U, I, O], + [A, D, S, H, F, G, J, K, Semicolon, L], + [Z, X, C, V, B, N, M, Comma, Period, Backslash], + [ + NumDivide, NumLeft, Num0, Num1, Num2, Num3, Slash, Equals, Digit0, Minus, ], - [Digit3, W, A, Digit4, Z, S, E, LShift], - [Digit5, R, D, Digit6, C, F, T, X], - [Digit7, Y, G, Digit8, B, H, U, V], - [Digit9, I, J, Digit0, M, K, O, N], - [Plus, P, L, Minus, Period, Colon, At, Comma], [ - Pound, Asterisk, Semicolon, ClrHome, RShift, Equals, UpArrow, Slash, + NumRightParen, + NumEsc, + Num4, + Num5, + Num6, + Num7, + Grave, + P, + LeftBracket, + RightBracket, + ], + [ + NumMultiply, + NumRight, + Digit8, + Digit9, + NumPeriod, + NumPlus, + Return, + UpArrow, + Space, + Apostrophe, ], [ - Digit1, LeftArrow, Control, Digit2, Space, Commodore, Q, RunStop, + NumPrint, + NumSpace, + NumLeftParen, + NumMinus, + NumReturn, + NumComma, + Del, + DownArrow, + LeftArrow, + RightArrow, ], ] }; diff --git a/src/systems/aiie/mod.rs b/src/systems/aiie/mod.rs index b9eb8679..9ea2145c 100644 --- a/src/systems/aiie/mod.rs +++ b/src/systems/aiie/mod.rs @@ -2,10 +2,11 @@ use std::{io::Write, sync::Arc}; use crate::{ cpu::{MemoryIO, Mos6502}, - keyboard::KeyMappingStrategy, - memory::{ - ActiveInterrupt, BlockMemory, BranchMemory, LoggingMemory, Memory, NullMemory, SystemInfo, + keyboard::{ + apple::{AppleKeyboardAdapter, AppleKeys}, + KeyAdapter, KeyState, KeySymbol, SymbolAdapter, }, + memory::{ActiveInterrupt, BlockMemory, BranchMemory, Memory, NullMemory, SystemInfo}, platform::{Color, PlatformProvider, WindowConfig}, systems::System, }; @@ -28,6 +29,10 @@ const CHAR_HEIGHT: u32 = 8; const CHAR_WIDTH: u32 = 7; struct AiieSoftSwitches { + platform: Arc, + previous_state: KeyState, + + pub keypress_waiting: bool, pub eighty_col_memory: bool, pub read_aux_48k: bool, pub write_aux_48k: bool, @@ -44,8 +49,11 @@ struct AiieSoftSwitches { } impl AiieSoftSwitches { - fn new() -> Self { + fn new(platform: Arc) -> Self { Self { + platform, + previous_state: KeyState::new(), + keypress_waiting: false, eighty_col_memory: false, read_aux_48k: false, write_aux_48k: false, @@ -126,17 +134,41 @@ impl Memory for AiieSoftSwitches { fn read(&mut self, address: u16) -> u8 { match address % 0x100 { 0x00 => { - // println!("KEYBOARD: read data"); - 0 + use KeySymbol::*; + + let state = SymbolAdapter::map(&self.platform.get_key_state()); + + if state != self.previous_state { + self.keypress_waiting = true; + } + self.previous_state = state.clone(); + + (self.keypress_waiting as u8) << 7 + | state + .pressed() + .into_iter() + .find_map(|key| { + match key { + &Char(c) => Some(c as u8), + Return => Some(0x0D), // Carriage Return + Backspace => Some(0x08), + Escape => Some(0x1B), + _ => None, + } + }) + .unwrap_or(0) } 0x01..=0x0F | 0x50..=0x5F => { self.softswitch(address); 0 } - 0x10 => 0, + 0x10 => { + self.keypress_waiting = false; + + 0 + } 0x11..=0x1F => self.read_flag(address), 0x30 => { - // println!("SPEAKER : toggle speaker diaphragm"); print!("🔈"); std::io::stdout().flush().unwrap(); 0 @@ -148,7 +180,7 @@ impl Memory for AiieSoftSwitches { _ => unimplemented!(), } } - fn write(&mut self, address: u16, value: u8) { + fn write(&mut self, address: u16, _value: u8) { match address % 0x100 { 0x00..=0x0F | 0x50..=0x5F => self.softswitch(address), 0x10..=0x1F => (), @@ -184,9 +216,7 @@ impl Memory for AiieSoftSwitches { } /// Configuration for a Apple IIe system. -pub struct AiieSystemConfig { - pub mapping: KeyMappingStrategy, -} +pub struct AiieSystemConfig {} /// A factory for creating a Commodore 64 system. pub struct AiieSystemBuilder; @@ -194,7 +224,7 @@ pub struct AiieSystemBuilder; impl SystemBuilder for AiieSystemBuilder { fn build( roms: AiieSystemRoms, - config: AiieSystemConfig, + _config: AiieSystemConfig, platform: Arc, ) -> Box { platform.request_window(WindowConfig::new( @@ -204,7 +234,7 @@ impl SystemBuilder for AiieSystemB )); let ram = BlockMemory::ram(0xC000); - let io = AiieSoftSwitches::new(); + let io = AiieSoftSwitches::new(platform); let peripheral_card = NullMemory::new(); let applesoft_interpreter = BlockMemory::from_file(0x2800, roms.applesoft); let monitor = BlockMemory::from_file(0x800, roms.monitor);