Started work on tui debugger!

This commit is contained in:
august kline 2024-06-15 22:45:27 -04:00
parent b1b9c64468
commit 0ec54d6672
13 changed files with 725 additions and 68 deletions

331
Cargo.lock generated
View File

@ -2,6 +2,24 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "allocator-api2"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "anstream"
version = "0.6.13"
@ -117,6 +135,21 @@ version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "cassowary"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "castaway"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
dependencies = [
"rustversion",
]
[[package]]
name = "cc"
version = "1.0.83"
@ -178,6 +211,44 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "compact_str"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
dependencies = [
"castaway",
"cfg-if",
"itoa",
"ryu",
"static_assertions",
]
[[package]]
name = "crossterm"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
dependencies = [
"bitflags 2.4.2",
"crossterm_winapi",
"libc",
"mio",
"parking_lot",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]]
name = "cty"
version = "0.2.2"
@ -199,6 +270,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "either"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
[[package]]
name = "equivalent"
version = "1.0.1"
@ -324,7 +401,9 @@ dependencies = [
"bdf",
"bitvec",
"clap",
"crossterm",
"minifb",
"ratatui",
"serde",
"toml",
]
@ -334,6 +413,10 @@ name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "heck"
@ -363,6 +446,21 @@ dependencies = [
"web-sys",
]
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "js-sys"
version = "0.3.67"
@ -402,7 +500,7 @@ checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607"
dependencies = [
"bitflags 2.4.2",
"libc",
"redox_syscall",
"redox_syscall 0.4.1",
]
[[package]]
@ -411,12 +509,31 @@ version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "lru"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
dependencies = [
"hashbrown",
]
[[package]]
name = "memchr"
version = "2.7.1"
@ -458,6 +575,18 @@ dependencies = [
"x11-dl",
]
[[package]]
name = "mio"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.48.0",
]
[[package]]
name = "nix"
version = "0.24.3"
@ -488,6 +617,35 @@ dependencies = [
"sdl2-sys",
]
[[package]]
name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.5.2",
"smallvec",
"windows-targets 0.52.0",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pin-project-lite"
version = "0.2.13"
@ -530,6 +688,26 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "ratatui"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f44c9e68fd46eda15c646fbb85e1040b657a58cdc8c98db1d97a55930d991eef"
dependencies = [
"bitflags 2.4.2",
"cassowary",
"compact_str",
"crossterm",
"itertools",
"lru",
"paste",
"stability",
"strum",
"unicode-segmentation",
"unicode-truncate",
"unicode-width",
]
[[package]]
name = "raw-window-handle"
version = "0.4.3"
@ -548,6 +726,15 @@ dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
dependencies = [
"bitflags 2.4.2",
]
[[package]]
name = "rustix"
version = "0.38.31"
@ -561,12 +748,30 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rustversion"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sdl2"
version = "0.35.2"
@ -619,6 +824,36 @@ dependencies = [
"serde",
]
[[package]]
name = "signal-hook"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
dependencies = [
"libc",
"mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -634,12 +869,50 @@ version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "stability"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]]
name = "syn"
version = "2.0.48"
@ -665,7 +938,7 @@ checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall",
"redox_syscall 0.4.1",
"rustix",
"windows-sys 0.52.0",
]
@ -730,6 +1003,28 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-truncate"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5fbabedabe362c618c714dbefda9927b5afc8e2a8102f47f081089a9019226"
dependencies = [
"itertools",
"unicode-width",
]
[[package]]
name = "unicode-width"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "utf8parse"
version = "0.2.1"
@ -742,6 +1037,18 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.90"
@ -1085,3 +1392,23 @@ name = "xml-rs"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
[[package]]
name = "zerocopy"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@ -10,6 +10,8 @@ anyhow = "1.0.81"
bdf = "0.6.0"
bitvec = "1.0.1"
clap = { version = "4.5.4", features = ["derive"] }
crossterm = "0.27.0"
minifb = "0.25.0"
ratatui = "0.26.3"
serde = { version = "1.0.197", features = ["serde_derive", "derive"] }
toml = "0.8.12"

View File

@ -1,2 +1,3 @@
char_rom = "./src/roms/cozette.rom"
rom = "./src/roms/george.rom"
rom = "./src/roms/test.rom"

2
run.sh
View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
vasm6502_oldstyle ./src/george.asm -dotdir -wdc02 -ldots -Fbin -o ./src/george.rom;
vasm6502_oldstyle ./src/roms/george.asm -dotdir -wdc02 -ldots -Fbin -o ./src/roms/george.rom;
cargo run;
# hexdump -C ./cpu_dump.bin;

View File

@ -1,8 +1,9 @@
// use crate::error::{ExecutionError, GeorgeError, GeorgeErrorKind, MemoryError};
use crate::instructions::{get_instruction, Instruction};
use crate::memory::Mem;
use crate::types::{Byte, Word};
use std::cell::RefCell;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use std::sync::mpsc::Receiver;
use std::sync::Arc;
@ -157,9 +158,9 @@ impl Cpu {
sleep(Duration::from_nanos(100));
self.pending_cycles -= 1;
}
if !self.get_flag(StatusFlag::IrqDisable) && self.irq.recv().unwrap() {
self.interrupt();
}
// if !self.get_flag(StatusFlag::IrqDisable) && self.irq.recv().unwrap() {
// self.interrupt();
// }
let opcode = match self.read(self.pc) {
Ok(byte) => byte,
Err(_) => {
@ -170,12 +171,12 @@ impl Cpu {
let instruction = get_instruction(opcode);
match instruction {
Instruction::Valid(valid_instruction) => {
//println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq, nmi = self.nmi);
//println!(
// "Instruction: {:?}, {:#04x}",
// valid_instruction.opcode, opcode
//);
//println!("");
// println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq, nmi = self.nmi);
// println!(
// "Instruction: {:?}, {:#04x}",
// valid_instruction.opcode, opcode
// );
// println!("");
self.pc += 1;
match valid_instruction.opcode.call(self) {
Ok(_) => {
@ -196,7 +197,7 @@ impl Cpu {
}
};
println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq.try_recv().unwrap_or_default(), nmi = self.nmi);
// println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq.try_recv().unwrap_or_default(), nmi = self.nmi);
memory
.dump(PathBuf::from_str("./cpu_dump.bin").unwrap())
.unwrap();

View File

@ -1,10 +1,5 @@
use minifb::{InputCallback, Key};
use std::{
path::PathBuf,
process::exit,
str::FromStr,
sync::{Arc, Mutex},
};
use std::sync::{Arc, Mutex};
use crate::memory::Mem;

View File

@ -5,6 +5,7 @@ mod error;
mod instructions;
mod keyboard;
mod memory;
mod tui;
mod types;
mod video;
@ -13,18 +14,28 @@ use crate::keyboard::Keyboard;
use crate::memory::Mem;
use crate::video::Crtc;
use clap::Parser;
// use clap::Parser;
use minifb::{Scale, ScaleMode, Window, WindowOptions};
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::Read;
use std::process::exit;
use std::str::FromStr;
use std::sync::{mpsc, Mutex};
use std::{path::PathBuf, sync::Arc, thread};
use std::{
fs::File,
io::{stdout, Read, Result},
path::PathBuf,
str::FromStr,
sync::{mpsc, Arc, Mutex},
thread,
};
use toml::Table;
use crossterm::{
event::{self, KeyCode, KeyEventKind},
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
};
use ratatui::prelude::{CrosstermBackend, Terminal};
// use toml::Table;
//#[derive(Parser)]
//struct Cli {
@ -39,16 +50,21 @@ struct Config {
rom: String,
}
fn main() {
fn main() -> Result<()> {
stdout().execute(EnterAlternateScreen)?;
enable_raw_mode()?;
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
terminal.clear()?;
let config: Config = match File::open("./config.toml") {
Ok(mut file) => {
let mut string = String::new();
file.read_to_string(&mut string).unwrap();
toml::from_str(string.as_str()).unwrap()
}
Err(_) => return,
Err(_) => return Ok(()),
};
println!("{config:#?}");
let mut memory = Mem::new();
let rom = match std::fs::File::open(config.rom) {
Ok(file) => file,
@ -58,23 +74,18 @@ fn main() {
println!("{:?}", error);
};
let (interrupt_tx, interrupt_rx) = mpsc::channel();
let (window_tx, window_rx) = mpsc::channel();
memory
.dump(PathBuf::from_str("./coredump.bin").unwrap())
.unwrap();
let shared_memory = Arc::new(Mutex::new(memory));
let cpu_memory = shared_memory.clone();
let display_memory = shared_memory.clone();
let keyboard_memory = shared_memory.clone();
thread::spawn(move || {
let mut cpu = Cpu::new(cpu_memory, interrupt_rx);
cpu.reset().unwrap();
cpu.execute();
});
let (interrupt_tx, interrupt_rx) = mpsc::channel();
let (window_tx, window_rx) = mpsc::channel();
thread::spawn(move || {
let mut screen = Crtc::new(
@ -105,8 +116,23 @@ fn main() {
window.set_input_callback(Box::new(Keyboard::new(keyboard_memory)));
while window.is_open() {
let cpu = Cpu::new(cpu_memory, interrupt_rx);
let mut tui = tui::App::new(cpu);
tui.init();
loop {
if event::poll(std::time::Duration::from_millis(16))? {
if let event::Event::Key(key) = event::read()? {
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
break;
}
}
}
let buffer = window_rx.recv().unwrap();
window.update_with_buffer(&buffer, 512, 380).unwrap();
tui.update(&mut terminal)?;
}
stdout().execute(LeaveAlternateScreen)?;
disable_raw_mode()?;
Ok(())
}

Binary file not shown.

View File

@ -10,7 +10,7 @@ cursor = $202
char_buffer = $300 ; 256 byte character buffer
kb_row = $4400 ; keyboard hardware register, there are 5 more but i can just increment from here
kb_row = $4400 ; keyboard hardware register
kb_row_cache = $203 ; cache
.org $8000
@ -34,32 +34,188 @@ cleardisplay:
sta $6700,y ; this goes slightly over but it's fine
iny
bne cleardisplay
cli
; cli
main:
jsr draw
jsr keyboard
; key_zero:
; stz keyboard_cache, x
; dex
; bpl key_zero
; fim:
; cli
; bra fim
; jsr kitty_keys
jmp main
; ; copying @smal rn: https://github.com/smaldragon/KittyEMU/blob/main/roms/foxmon.asm
; char_timer = $10
; line_buffer = $0200
; char_cur = $11
; line_buffer_i = $12
; line_buffer_l = $13
; keyboard_cache = $14
; line_cur = $20
; irq:
; lda line_buffer_i
; lda $e0
; lda $6f
; sei
; stz char_cur
; lda line_buffer_i
; sta line_buffer_l
; ldx #4
; kitty_keys: ; reads pressed key and writes keymap value to char_cur
; phx
; txa
; asl
; asl
; asl
; asl
; asl ; i think this is supposed to be once for every keyboard row
; tax
; lda kb_row, x
; plx
; pha
; cmp keyboard_cache, x
; bne change
; jmp nochange
; change:
; bit7:
; asl keyboard_cache, x
; bcs bit6
; bit #0b10000000
; beq bit6
; pha
; lda keymap_7, x
; sta char_cur
; pla
; bit6:
; asl keyboard_cache, x
; bcs bit5
; bit #0b01000000
; beq bit5
; pha
; lda keymap_6, x
; sta char_cur
; pla
; bit5:
; asl keyboard_cache, x
; bcs bit4
; bit #0b00100000
; beq bit4
; pha
; lda keymap_5, x
; sta char_cur
; pla
; bit4:
; asl keyboard_cache, x
; bcs bit3
; bit #0b00010000
; beq bit3
; pha
; lda keymap_4, x
; sta char_cur
; pla
; bit3:
; asl keyboard_cache, x
; bcs bit2
; bit #0b00001000
; beq bit2
; pha
; lda keymap_3, x
; sta char_cur
; pla
; bit2:
; asl keyboard_cache, x
; bcs bit1
; bit #0b00000100
; beq bit1
; pha
; lda keymap_2, x
; sta char_cur
; pla
; bit1:
; asl keyboard_cache, x
; bcs bit0
; bit #0b00000010
; beq bit0
; pha
; lda keymap_1, x
; sta char_cur
; pla
; bit0:
; asl keyboard_cache, x
; bcs bitend
; bit #0b00000001
; beq bitend
; pha
; lda keymap_0, x
; sta char_cur
; pla
; bitend:
; nochange:
; pla
; sta keyboard_cache, x
; dex
; bmi keyend
; jmp kitty_keys
; keyend:
; write:
; lda char_cur
; ldy cursor
; sta $6000, y
; inc cursor
; rts
; ; col = keyboard row, row = keyboard bit placement inverted
; keymap_0:
; .byte "??????"
; keymap_1:
; .byte "wqdzx "
; keymap_2:
; .byte "esvfc "
; keymap_3:
; .byte "rghbn?"
; keymap_4:
; .byte "tykjm?"
; keymap_5:
; .byte "ui?l??"
; keymap_6:
; .byte "op?21?"
; keymap_7:
; .byte "??a43?"
;
;
keyboard:
ldy #0
x
not_keyboard:
ldy #0
.loop: ; loop through each row
.check_row: ; loop through each row
lda kb_row, y
beq .skip ; if row has no key pressed, skip checking which key
beq .skip_row ; if row has no key pressed, skip checking which key
sta kb_row_cache, y ; if key pressed, cache it
lda kb_row, y
cmp kb_row_cache, y ; has key changed?
beq key_down
.skip:
.skip_row:
iny
cpy #5
bne .loop
bne .check_row
rts
key_down: ; a is loaded with the row byte
sty key_row ; store character row
inc cursor
pha
phy
sty key_row ; store character row
ldy #0
.find_col: ; test each row bit, store column if key pressed
lsr ; test bit 7
@ -90,12 +246,12 @@ keymap_index:
lda 0, x
tay
do_something_w_key: ; we've stored the character position, now let's
print: ; we've stored the character position, now let's
lda keymap, y
ldy cursor
sta $6000, y
inc cursor
ply
pla
rts
keymap:
@ -107,9 +263,9 @@ keymap:
.byte "????? m"
draw:
push_coords #0, #0
push_char #$00
jsr draw_char
; push_coords #0, #0
; push_char #$00
; jsr draw_char
rts
draw_char: ; draw a character c at (x, y) (n1: x n2: y n3: c -- )
@ -151,7 +307,7 @@ isr: ; interrupt service routine
pha
phx
phy
jsr keyboard
; jsr irq
ply
plx
pla

Binary file not shown.

View File

@ -26,7 +26,7 @@
dex
.endm
.macro push_char, char ; pushes an ascii character code onto the stack
.macro push_char, char; pushes an ascii character code onto the stack
lda \char
push
sta 0, x ; char low byte

150
src/tui/mod.rs Normal file
View File

@ -0,0 +1,150 @@
// use std::time::Duration;
mod tabs;
mod term;
use std::{io::Result, time::Duration};
use crossterm::event::{self, poll, Event, KeyCode, KeyEvent, KeyEventKind};
use ratatui::{
prelude::*,
widgets::{Block, Cell, Paragraph, Row, Table, TableState},
};
use crate::cpu::Cpu;
pub struct App {
cpu: Cpu,
running: bool,
table_state: TableState,
}
impl App {
pub fn new(cpu: Cpu) -> Self {
Self {
cpu,
running: true,
table_state: TableState::default(),
}
}
pub fn init(&mut self) {
let _ = self.cpu.reset();
}
pub fn update(&mut self, terminal: &mut Terminal<impl Backend>) -> Result<()> {
self.draw(terminal)?;
self.handle_events()?;
self.handle_cpu()?;
Ok(())
}
fn handle_cpu(&mut self) -> Result<()> {
if self.running {
self.cpu.cycle();
}
Ok(())
}
/// Draw a single frame of the app.
fn draw(&self, terminal: &mut Terminal<impl Backend>) -> Result<()> {
terminal
.draw(|frame| {
frame.render_widget(self, frame.size());
})
.unwrap();
Ok(())
}
fn handle_events(&mut self) -> Result<()> {
if poll(Duration::from_secs_f32(1.0 / 25.0))? {
match event::read()? {
Event::Key(key) if key.kind == KeyEventKind::Press => self.handle_key_press(key),
_ => {}
}
}
Ok(())
}
fn handle_key_press(&mut self, key: KeyEvent) {
match key.code {
KeyCode::Enter => {
if !self.running {
self.cpu.cycle()
}
}
KeyCode::Char(' ') => {
self.running = !self.running;
}
_ => {}
};
}
}
/// Implement Widget for &App rather than for App as we would otherwise have to clone or copy the
/// entire app state on every frame. For this example, the app state is small enough that it doesn't
/// matter, but for larger apps this can be a significant performance improvement.
impl Widget for &App {
fn render(self, area: Rect, buf: &mut Buffer) {
let [cpu_area, memory_area] =
Layout::horizontal([Constraint::Percentage(50), Constraint::Fill(1)]).areas(area);
let cpu_info = format!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.cpu.a, x = self.cpu.x, y = self.cpu.y, pc = self.cpu.pc, s = self.cpu.s, p = self.cpu.p, irq = self.cpu.irq, nmi = self.cpu.nmi);
Paragraph::new(cpu_info)
.block(Block::bordered().title("cpu info!"))
.render(cpu_area, buf);
let memory = self.cpu.memory.lock().unwrap();
let table_height = memory_area.rows().count() - 2;
let rows: Vec<Row> = memory.data[0..table_height * 16]
.chunks(16)
.map(|chunk| {
chunk
.iter()
.map(|content| Cell::from(Text::from(format!("{content:#02}"))))
.collect::<Row>()
})
.collect();
let widths = vec![Constraint::Length(2); 16];
Widget::render(
Table::new(rows, widths)
.header(
Row::new(vec![
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e",
"f",
])
.style(Style::new().bold())
// To add space between the header and the rest of the rows, specify the margin
.bottom_margin(1),
)
.block(Block::bordered().title("memory!")),
memory_area,
buf,
);
}
}
// impl Widget for App {
// fn render_title_bar(&self, area: Rect, buf: &mut Buffer) {
// // let layout = Layout::horizontal([Constraint::Min(0), Constraint::Length(43)]);
// // let [title] = layout.areas(area);
// Span::styled("Ratatui", Style::default()).render(area, buf);
// // let titles = Tab::iter().map(Tab::title);
// // Tabs::new(titles)
// // .style(THEME.tabs)
// // .highlight_style(THEME.tabs_selected)
// // .select(self.tab as usize)
// // .divider("")
// // .padding("", "")
// // .render(tabs, buf);
// }
// // fn render_selected_tab(&self, area: Rect, buf: &mut Buffer) {
// // match self.tab {
// // Tab::About => self.about_tab.render(area, buf),
// // Tab::Recipe => self.recipe_tab.render(area, buf),
// // Tab::Email => self.email_tab.render(area, buf),
// // Tab::Traceroute => self.traceroute_tab.render(area, buf),
// // Tab::Weather => self.weather_tab.render(area, buf),
// // };
// // }
// }

View File

@ -3,12 +3,9 @@ use std::{
fs::File,
io::Read,
path::Path,
sync::{
mpsc::{Sender, SyncSender},
Arc, Mutex,
},
sync::{mpsc::Sender, Arc, Mutex},
thread::sleep,
time::{Duration, Instant},
time::Duration,
};
const FG_COLOR: u32 = 0xFFCC00;
@ -31,7 +28,7 @@ where
let mut file = File::open(path).unwrap();
let mut bin = vec![0; 0x8000];
file.read_exact(&mut bin).unwrap();
println!("reading char rom");
// println!("reading char rom");
bin
}
None => include_bytes!("./roms/cozette.rom").to_vec(),
@ -65,7 +62,9 @@ impl Crtc {
return;
}
};
// the rest of this function is arcane wizardry based on the specifics of george's weird
// the rest of this function is arcane wizardry
// based on the specifics of george's weird
// display and characters... don't fuck around w it
let mut i = 0;
for char_row in 0..29 {
@ -88,15 +87,15 @@ impl Crtc {
let buffer = self.buffer.to_owned();
self.window.send(buffer).unwrap();
let _ = self.window.send(buffer);
}
pub fn run(&mut self) {
loop {
self.interrupt.send(false).unwrap();
let _ = self.interrupt.send(false);
sleep(Duration::from_millis(16));
self.draw();
self.interrupt.send(true).unwrap();
let _ = self.interrupt.send(true);
}
}
}