diff --git a/Cargo.lock b/Cargo.lock index fb7ade2..af35df4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,6 +185,7 @@ name = "core" version = "0.1.0" dependencies = [ "log", + "rand", ] [[package]] @@ -474,6 +475,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "pretty_env_logger" version = "0.5.0" @@ -514,6 +524,35 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + [[package]] name = "regex" version = "1.11.1" @@ -823,3 +862,23 @@ checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags 2.9.1", ] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/beneater/src/parts/ben_eater_pc.rs b/beneater/src/parts/ben_eater_pc.rs index 770c891..1e2c92d 100644 --- a/beneater/src/parts/ben_eater_pc.rs +++ b/beneater/src/parts/ben_eater_pc.rs @@ -24,6 +24,8 @@ impl BenEaterPC { // tick the clock. // tick the memory // tick the VIA + } else { + self.cpu.tick(); } } } diff --git a/beneater/src/parts/via6522.rs b/beneater/src/parts/via6522.rs index 2ccf8fa..5a7af90 100644 --- a/beneater/src/parts/via6522.rs +++ b/beneater/src/parts/via6522.rs @@ -1,5 +1,12 @@ +pub enum Via6522Port { + A(u8), + B(u8) +} + #[derive(Default)] pub struct Via6522 { + data_bus: u8, + address_bus: u16, port_a_state: u8, port_b_data: u8, port_a_direction: u8, @@ -15,8 +22,15 @@ impl Via6522 { } } - pub fn set_a_direction(&mut self, new_direction: u8) { - + pub fn set_port_direction(&mut self, port: Via6522Port) { + match port { + Via6522Port::A(x) => { + self.port_a_direction = x; + }, + Via6522Port::B(x) => { + self.port_b_direction = x; + } + } } /// check for output pins and see what they say diff --git a/core/Cargo.toml b/core/Cargo.toml index eb6323e..46439ac 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -3,4 +3,5 @@ name = "core" version = "0.1.0" edition = "2024" [dependencies] -log = "0.4" \ No newline at end of file +log = "0.4" +rand = "0.9.0" \ No newline at end of file diff --git a/core/src/address_mode.rs b/core/src/address_mode.rs index 6c3ce0d..9062aa1 100644 --- a/core/src/address_mode.rs +++ b/core/src/address_mode.rs @@ -1,4 +1,3 @@ -use std::fmt::{Display}; #[derive(PartialEq, Debug, Copy, Clone)] pub enum AddressMode { diff --git a/core/src/mos6502cpu.rs b/core/src/mos6502cpu.rs index aa95535..8042697 100644 --- a/core/src/mos6502cpu.rs +++ b/core/src/mos6502cpu.rs @@ -1,5 +1,9 @@ +use crate::address_mode::AddressMode; use crate::instruction::Instruction; use crate::mos6502flags::{Mos6502Flag, Mos6502Flags}; +use crate::operand::Operand; +use crate::operation::Operation; +use crate::operation::Operation::NOP; pub const SIZE_1KB: usize = 1024 * 1024; pub const SIZE_32KB: usize = SIZE_1KB * 32; @@ -17,7 +21,7 @@ pub struct Mos6502Cpu { pub microcode_step: u8, pub address_bus: u16, pub data_bus: u8, - ir: u8 // Instruction Register + ir: Instruction // Instruction Register } impl Default for Mos6502Cpu { @@ -37,7 +41,11 @@ impl Default for Mos6502Cpu { microcode_step: 0, address_bus: 0, data_bus: 0, - ir: 0x00 + ir: Instruction { + op: Operation::NOP, + mode: AddressMode::Implied, + operand: Operand::None, + } } } } @@ -58,7 +66,11 @@ impl Mos6502Cpu { microcode_step: 0, address_bus: 0x0000, data_bus: 0x00, - ir: 0x00 + ir: Instruction { + op: Operation::NOP, + mode: AddressMode::Implied, + operand: Operand::None, + } } } @@ -105,13 +117,19 @@ impl Mos6502Cpu { /// AddressBus, DataBus, RW flag pub fn tick(&mut self) -> (u16, u8, bool) { - let num_microsteps_left = 0; + println!("PREPARiNG TO TICK CPU AT {:04x}", self.pc); + + let mut num_microsteps_left = 0; if num_microsteps_left == 0 { + println!("OUT OF MICROSTEPS. Time To do something that isnt microstep."); // load the microstep buffer with what steps to run // set the counter to the number of steps left + } else { + // run 1 microcode step + println!("Microstep {num_microsteps_left}"); + num_microsteps_left -= 1; } - // run 1 microcode step (0,0,false) } diff --git a/core/src/periph/at28c256.rs b/core/src/periph/at28c256.rs index a386925..c5de2b6 100644 --- a/core/src/periph/at28c256.rs +++ b/core/src/periph/at28c256.rs @@ -1,4 +1,4 @@ -use crate::mos6502cpu::{SIZE_32KB, SIZE_64KB}; +use crate::mos6502cpu::{SIZE_32KB}; use crate::periph::rom_chip::RomChip; /// At28C256 @@ -48,20 +48,14 @@ mod test { #[test] fn programmed_data_reads_back_same() { - print!("Starting test..."); let mut data = At28C256::default(); for i in 0..SIZE_32KB { data.data[i] = 0xea; } - print!("allocated data for rom..."); - println!("programmed chip..."); - print!("testing"); for offset in 0..SIZE_32KB { if offset.is_multiple_of(SIZE_1KB) { - print!("."); }; assert_eq!(0xea, data.read(&(offset as u16))); } - println!("passed!"); } } diff --git a/core/src/periph/hm62256.rs b/core/src/periph/hm62256.rs new file mode 100644 index 0000000..f192af0 --- /dev/null +++ b/core/src/periph/hm62256.rs @@ -0,0 +1,88 @@ +// HM62256 Static Ram + +use log::debug; +use crate::mos6502cpu::SIZE_32KB; +use crate::periph::ram_chip::RamChip; +use crate::periph::rom_chip::RomChip; + +struct Hm62256 { + base_offset: u16, + data: Box<[u8]> +} + +impl Default for Hm62256 { + 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("Unable to box the ram"); + Hm62256 { + base_offset: 0x0000, + data: boxed_array + } + } +} + +impl RomChip for Hm62256 { + fn read(&self, offset: &u16) -> u8 { + //println!("READING FROM RAM AT [{offset:04x}]"); + self.data[*offset as usize] + } + + fn program(_: Box<[u8; SIZE_32KB]>) -> Box { + debug!("Dont program ram."); + Hm62256::default().into() + } +} + +impl RamChip for Hm62256 { + fn write(&mut self, offset: &u16, value: &u8) { + let effective = *offset as i32 % SIZE_32KB as i32; + println!("Writing at E[{effective:04x}] / O[{offset:04x}]"); + self.data[effective as usize] = *value; + } +} + +#[cfg(test)] +mod test { + use rand::random; + use super::*; + + #[test] + fn smoke() { assert!(true) } + + #[test] + fn written_data_comes_back() { + let mut ram = Hm62256::default(); + + // 100,000 random read/writes to ram that all read back right + for _ in 0..100_000 { + let mut offset: u16 = random(); + println!("SIze = {SIZE_32KB}"); + let value: u8 =random(); + println!("Wrote [{value:02x}] to [{offset:04x}]"); + ram.write(&offset, &value); + + assert_eq!(ram.read(&offset), value) + } + } + + #[test] + fn address_space_is_round() { + // addresses written past the last address 'loop' back to 0+(offset - MAX_SIZE) + let max_offset = SIZE_32KB; + let test_offset = max_offset; + + // all zero + let mut ram = Hm62256::default(); + // write FF to the addresss after the last + ram.write(&(test_offset as u16), &0xff); + + // check all the ram for anything that isn't 0x00 + + assert_eq!(ram.read(&(0x0000)), 0xff); + for offset in 1..SIZE_32KB { + println!("Testing offset {offset:04x} for 0x00"); + assert_eq!(ram.read(&(offset as u16)), 0x00); + } + } +} diff --git a/core/src/periph/mod.rs b/core/src/periph/mod.rs index 3c6c493..8fc0050 100644 --- a/core/src/periph/mod.rs +++ b/core/src/periph/mod.rs @@ -1,3 +1,6 @@ pub mod rom_chip; pub mod at28c256; +pub mod ram_chip; +mod hm62256; + diff --git a/core/src/periph/ram_chip.rs b/core/src/periph/ram_chip.rs new file mode 100644 index 0000000..0ee3345 --- /dev/null +++ b/core/src/periph/ram_chip.rs @@ -0,0 +1,5 @@ +use crate::periph::rom_chip::RomChip; + +pub trait RamChip: RomChip { + fn write(&mut self, offset: &u16, value: &u8); +} diff --git a/core/src/periph/rom_chip.rs b/core/src/periph/rom_chip.rs index 5ecdc46..0283f10 100644 --- a/core/src/periph/rom_chip.rs +++ b/core/src/periph/rom_chip.rs @@ -10,7 +10,3 @@ pub trait RomChip { /// Replaces all data in the ROM chip fn program(new_data: Box<[u8; SIZE_32KB]>) -> Box; } - -pub trait RamChip: RomChip { - fn write(&mut self, offset: &u16, value: &u8); -}