From e5c231980367b23977254358ba3e4c20913b61ba Mon Sep 17 00:00:00 2001 From: Trevor Merritt Date: Sat, 28 Jun 2025 12:37:01 -0400 Subject: [PATCH] removes sccache updates display of ben eater pc doesnt blow up when creating a rom chip anymore doesnt blow up when creating a pc anymore --- .cargo/config.toml | 3 -- Cargo.lock | 4 +- beneater/src/bin/beneater.rs | 27 ++++++++++ beneater/src/parts/address_bus.rs | 9 ++++ beneater/src/parts/ben_eater_pc.rs | 8 ++- beneater/src/parts/cpu_display.rs | 28 ++++++++++ beneater/src/parts/data_bus.rs | 9 ++++ beneater/src/parts/display_matrix.rs | 79 ++++++++++++++++++++++++++++ beneater/src/parts/mod.rs | 9 +++- beneater/src/parts/ram_display.rs | 20 +++++++ beneater/src/parts/via6522.rs | 4 +- core/src/mos6502cpu.rs | 24 ++++++--- core/src/periph/at28c256.rs | 35 ++++++++---- core/src/periph/rom_chip.rs | 3 +- 14 files changed, 232 insertions(+), 30 deletions(-) create mode 100644 beneater/src/parts/address_bus.rs create mode 100644 beneater/src/parts/cpu_display.rs create mode 100644 beneater/src/parts/data_bus.rs create mode 100644 beneater/src/parts/display_matrix.rs create mode 100644 beneater/src/parts/ram_display.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 9bb778c..320b8e2 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,2 @@ [alias] coverage = "tarpaulin --out Html --skip-clean --output-dir coverage" - -[build] -rustc-wrapper = "sccache" diff --git a/Cargo.lock b/Cargo.lock index 0aca508..fb7ade2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,9 +75,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "beneater" diff --git a/beneater/src/bin/beneater.rs b/beneater/src/bin/beneater.rs index fe408ff..2525fab 100644 --- a/beneater/src/bin/beneater.rs +++ b/beneater/src/bin/beneater.rs @@ -1,5 +1,10 @@ // This is the GUI for the BenEater PC +use beneater::parts::cpu_display::CpuDisplay; use macroquad::prelude::*; +use macroquad::telemetry::frame; +use beneater::parts::ben_eater_pc::BenEaterPC; +use beneater::parts::display_matrix::DisplayMatrix; + #[macroquad::main("Ben Eaters PC")] async fn main() { @@ -7,10 +12,32 @@ async fn main() { let computer = BenEaterPC::new(); + + let mut dm = DisplayMatrix::new(200.0, 50.0); + let message_to_show = "Taxation is theft"; + let mut message_index = 0; + + dm.push_letter('T'); + let mut frame_number: u32 = 0x00; + loop { clear_background(BLUE); draw_text("Ben Eater", 20.0, 20.0, 30.0, BLACK); + dm.render(20.0, 40.0); + CpuDisplay::render(&computer.cpu, 20.0, 120.0); + + frame_number += 1; + + if frame_number.is_multiple_of(60) { + dm.push_letter('X'); + } + + if frame_number.is_multiple_of(60 * 6) { + dm.clear_display() + } + next_frame().await + } } diff --git a/beneater/src/parts/address_bus.rs b/beneater/src/parts/address_bus.rs new file mode 100644 index 0000000..d20bc44 --- /dev/null +++ b/beneater/src/parts/address_bus.rs @@ -0,0 +1,9 @@ +pub struct AddressBus { + pub address: u16 +} + +impl AddressBus { + pub fn new() -> Self { + AddressBus { address: 0x0000 } + } +} \ No newline at end of file diff --git a/beneater/src/parts/ben_eater_pc.rs b/beneater/src/parts/ben_eater_pc.rs index 7117b1e..770c891 100644 --- a/beneater/src/parts/ben_eater_pc.rs +++ b/beneater/src/parts/ben_eater_pc.rs @@ -1,13 +1,17 @@ use crate::parts::clock::Clock; use core::mos6502cpu::Mos6502Cpu; -struct BenEaterPC { +pub struct BenEaterPC { clock: Clock, - cpu: Mos6502Cpu, + // pub because i am rendering it. + // there should be a proper interface to get the data + // for ui out of this. + pub cpu: Mos6502Cpu, } impl BenEaterPC { pub fn new() -> Self { + println!("New BENEATERPC"); BenEaterPC { clock: Clock::new(), cpu: Mos6502Cpu::default() diff --git a/beneater/src/parts/cpu_display.rs b/beneater/src/parts/cpu_display.rs new file mode 100644 index 0000000..4dbccd5 --- /dev/null +++ b/beneater/src/parts/cpu_display.rs @@ -0,0 +1,28 @@ +use macroquad::color::{BLACK, Color}; +use macroquad::prelude::*; +use macroquad::text::draw_text; +use core::mos6502cpu::Mos6502Cpu; + +pub struct CpuDisplay {} +impl CpuDisplay { + pub fn render(cpu: &Mos6502Cpu, x_offset: f32, y_offset: f32) { + // get the data to display... + let (pc, a, x, y, address_bus, data_bus) = cpu.dump_data(); + + // ...build the interface + Self::draw_square(x_offset, y_offset, x_offset + 300.0, y_offset + 85.0, BLACK); + + draw_text(format!("PC: 0x{:04x} / {}", pc, pc).as_str(), x_offset + 5.0, y_offset + 18.0, 15.0, BLACK); + draw_text(format!("A: 0x{:02x} X: 0x{:02x} Y: 0x{:02x}", a, x, y).as_str(), x_offset + 5.0, y_offset + 35.0, 15.0, BLACK); + draw_text(format!("Address: {:016b} | {:04x}", address_bus, address_bus).as_str(), x_offset + 5.0, y_offset + 55.0, 15.0, BLACK); + draw_text(format!("Data: {:08b} | {:02x}", data_bus, data_bus).as_str(), x_offset + 5.0, y_offset + 75.0, 15.0, BLACK); + } + + fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) { + // println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color); + draw_line(x1, y1, x2, y1, 1.0, color); + draw_line(x1, y1, x1, y2, 1.0, color); + draw_line(x1, y2, x2, y2, 1.0, color); + draw_line(x2, y1, x2, y2, 1.0, color); + } +} \ No newline at end of file diff --git a/beneater/src/parts/data_bus.rs b/beneater/src/parts/data_bus.rs new file mode 100644 index 0000000..2ed9056 --- /dev/null +++ b/beneater/src/parts/data_bus.rs @@ -0,0 +1,9 @@ +pub struct DataBus { + pub data: u8 +} + +impl DataBus { + pub fn new() -> Self { + DataBus { data: 0x00 } + } +} \ No newline at end of file diff --git a/beneater/src/parts/display_matrix.rs b/beneater/src/parts/display_matrix.rs new file mode 100644 index 0000000..80026b6 --- /dev/null +++ b/beneater/src/parts/display_matrix.rs @@ -0,0 +1,79 @@ +use macroquad::prelude::*; +use crate::parts::address_bus::AddressBus; +use crate::parts::data_bus::DataBus; + +pub struct DisplayMatrix { + width: f32, + height: f32, + text_buffer: String, + data_bus: DataBus, + rs: bool, + rw: bool, + cursor_position: u8 +} + +impl DisplayMatrix { + pub fn new(width: f32, height: f32) -> DisplayMatrix { + DisplayMatrix { + width, + height, + text_buffer: String::from(""), + data_bus: DataBus::new(), + rs: false, + rw: false, + cursor_position: 0x00 + } + } + + /// Tick + /// + /// Checks the data bus and sees what the setup is. + /// + /// 0 0 0 0 0 0 0 1 -> Clear Display + /// 0 0 0 0 0 0 1 - -> Return Home + /// 0 0 0 0 0 0 A B -> Sets cursor move direction and shift + /// A -> 0 = Insert, 1 = Delete + /// B -> Scroll bool + /// 0 0 0 0 1 D C B -> Sets display mode + /// D -> Display On/Off + /// C -> Cursor On/Off + /// B -> Blink + pub fn tick(&mut self) { + // parse whats on the data bus. + + } + + pub fn set_busses(&mut self, address_bus: &mut AddressBus, data_bus: &mut DataBus) { + + } + + pub fn push_letter(&mut self, letter_to_push: char) { + self.cursor_position += 1; + self.text_buffer.push(letter_to_push) + } + + pub fn clear_display(&mut self) { + self.cursor_position = 0; + self.text_buffer.clear() + } + + pub fn render(&self, x_offset: f32, y_offset: f32) { + DisplayMatrix::draw_square(x_offset, + y_offset, + x_offset + self.width , + y_offset + self.height, + BLACK); + + let mut tmp = self.text_buffer.clone(); + tmp.push('#'); + draw_text(&*tmp, x_offset + 5.0, y_offset + 20.0, 20.0, BLACK); + } + + fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) { + // println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color); + draw_line(x1, y1, x2, y1, 1.0, color); + draw_line(x1, y1, x1, y2, 1.0, color); + draw_line(x1, y2, x2, y2, 1.0, color); + draw_line(x2, y1, x2, y2, 1.0, color); + } +} \ No newline at end of file diff --git a/beneater/src/parts/mod.rs b/beneater/src/parts/mod.rs index 2540ffd..f4dfe12 100644 --- a/beneater/src/parts/mod.rs +++ b/beneater/src/parts/mod.rs @@ -1,3 +1,8 @@ pub mod clock; -mod ben_eater_pc; -mod via6522; +pub mod ben_eater_pc; +pub mod via6522; +pub mod display_matrix; +pub mod address_bus; +pub mod data_bus; +pub mod cpu_display; +mod ram_display; diff --git a/beneater/src/parts/ram_display.rs b/beneater/src/parts/ram_display.rs new file mode 100644 index 0000000..104389e --- /dev/null +++ b/beneater/src/parts/ram_display.rs @@ -0,0 +1,20 @@ +use macroquad::prelude::*; + +pub struct RamDisplay {} + +impl RamDisplay { + pub fn render(ram: &Box<[u8]>, x_offset: f32, y_offset: f32) { + Self::draw_square(x_offset, y_offset, x_offset + 200.0, y_offset + 300.0, BLACK); + + draw_text("RAM", x_offset + 5.0, y_offset + 5.0, 15.0, BLACK); + + } + + fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) { + // println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color); + draw_line(x1, y1, x2, y1, 1.0, color); + draw_line(x1, y1, x1, y2, 1.0, color); + draw_line(x1, y2, x2, y2, 1.0, color); + draw_line(x2, y1, x2, y2, 1.0, color); + } +} \ No newline at end of file diff --git a/beneater/src/parts/via6522.rs b/beneater/src/parts/via6522.rs index 4efe640..2ccf8fa 100644 --- a/beneater/src/parts/via6522.rs +++ b/beneater/src/parts/via6522.rs @@ -19,12 +19,12 @@ impl Via6522 { } - // check for output pins and see what they say + /// check for output pins and see what they say pub fn update_pins(&mut self) { } - // check for input mode pins and see what they say + /// check for input mode pins and see what they say pub fn read_pins(&self) { } diff --git a/core/src/mos6502cpu.rs b/core/src/mos6502cpu.rs index 7ce38c1..faf2537 100644 --- a/core/src/mos6502cpu.rs +++ b/core/src/mos6502cpu.rs @@ -5,7 +5,8 @@ pub const SIZE_32KB: usize = SIZE_1KB * 32; pub const SIZE_64KB: usize = SIZE_1KB * 64; pub struct Mos6502Cpu { - memory: [u8; SIZE_64KB], + // this is public for rendering quickly. + pub memory: Box<[u8]>, a: u8, x: u8, y: u8, @@ -13,20 +14,24 @@ pub struct Mos6502Cpu { pc: u16, s: u8, pub microcode_step: u8, - address_bus: u16, - data_bus: u8, + pub address_bus: u16, + pub data_bus: u8, ir: u8 // Instruction Register } impl Default for Mos6502Cpu { fn default() -> Self { + let vec = vec![0x00; SIZE_64KB]; + let boxed_slize: Box<[u8]> = vec.into_boxed_slice(); + let boxed_array: Box<[u8; SIZE_64KB]> = boxed_slize.try_into().expect("Failed to allocate system memory"); + Mos6502Cpu { - memory: [0x00; SIZE_64KB], + memory: boxed_array, a: 0, x: 0, y: 0, flags: Default::default(), - pc: 0, + pc: 0xfffd, s: 0, microcode_step: 0, address_bus: 0, @@ -38,8 +43,11 @@ impl Default for Mos6502Cpu { impl Mos6502Cpu { pub fn new() -> Mos6502Cpu { + let vec = vec![0x00; SIZE_64KB]; + let boxed_slize: Box<[u8]> = vec.into_boxed_slice(); + let boxed_array: Box<[u8; SIZE_64KB]> = boxed_slize.try_into().expect("Failed to allocate system memory"); Mos6502Cpu { - memory: [0; SIZE_64KB], + memory: boxed_array, a: 0, x: 0, y: 0, @@ -103,5 +111,7 @@ impl Mos6502Cpu { self.pc, self.a, self.x, self.y, self.address_bus, self.data_bus); } - + pub fn dump_data(&self) -> ( u16, u8, u8, u8, u16, u8) { + (self.pc, self.a, self.x, self.y, self.address_bus, self.data_bus) + } } diff --git a/core/src/periph/at28c256.rs b/core/src/periph/at28c256.rs index 9a5c1a5..a386925 100644 --- a/core/src/periph/at28c256.rs +++ b/core/src/periph/at28c256.rs @@ -1,4 +1,4 @@ -use crate::mos6502cpu::SIZE_32KB; +use crate::mos6502cpu::{SIZE_32KB, SIZE_64KB}; use crate::periph::rom_chip::RomChip; /// At28C256 @@ -8,24 +8,37 @@ use crate::periph::rom_chip::RomChip; /// 256kbit storage /// 32kbyte storage pub struct At28C256 { - data: [u8; SIZE_32KB] + data: Box<[u8; SIZE_32KB]>, +} + +impl Default for At28C256 { + fn default() -> Self { + let vec = vec![0x00; SIZE_32KB]; + let boxed_slice: Box<[u8]> = vec.into_boxed_slice(); + let boxed_array: Box<[u8; SIZE_32KB]> = boxed_slice.try_into().expect("Failed to convert Vec to boxed array"); + At28C256 { + data: boxed_array, + } + } } impl RomChip for At28C256 { + fn read(&self, offset: &u16) -> u8 { self.data[*offset as usize] } - fn program(new_data: &[u8; SIZE_32KB]) -> Self { + fn program(new_data: Box<[u8; 33554432]>) -> Box { println!("Writing new chip."); - At28C256 { - data: *new_data - } + let mut working = At28C256::default(); + working.data = Box::new(*new_data); + working.into() } } #[cfg(test)] mod test { + use crate::mos6502cpu::SIZE_1KB; use super::*; #[test] @@ -36,16 +49,18 @@ mod test { #[test] fn programmed_data_reads_back_same() { print!("Starting test..."); - let data_to_write = [0xea; SIZE_32KB]; + let mut data = At28C256::default(); + for i in 0..SIZE_32KB { + data.data[i] = 0xea; + } print!("allocated data for rom..."); - let chip: At28C256 = At28C256::program(&data_to_write); println!("programmed chip..."); print!("testing"); for offset in 0..SIZE_32KB { - if offset.is_multiple_of(1000) { + if offset.is_multiple_of(SIZE_1KB) { print!("."); }; - assert_eq!(0xea, chip.read(&(offset as u16))); + assert_eq!(0xea, data.read(&(offset as u16))); } println!("passed!"); } diff --git a/core/src/periph/rom_chip.rs b/core/src/periph/rom_chip.rs index cff8ea8..5ecdc46 100644 --- a/core/src/periph/rom_chip.rs +++ b/core/src/periph/rom_chip.rs @@ -8,10 +8,9 @@ pub trait RomChip { /// Program /// /// Replaces all data in the ROM chip - fn program(new_data: &[u8; SIZE_32KB]) -> Self; + fn program(new_data: Box<[u8; SIZE_32KB]>) -> Box; } pub trait RamChip: RomChip { fn write(&mut self, offset: &u16, value: &u8); } -