diff --git a/beneater/src/parts/backplane.rs b/beneater/src/parts/backplane.rs index 86f9be8..d11f0cf 100644 --- a/beneater/src/parts/backplane.rs +++ b/beneater/src/parts/backplane.rs @@ -3,7 +3,7 @@ use crate::parts::via6522::VIA6522; use core::constants::constants_system::*; use core::mos6502cpu::cpu::Mos6502Cpu; use core::periph::at28c256::At28C256; -use core::periph::rom_chip::RomChip; +use core::traits::rom_chip::RomChip; use core::constants::constants_via6522::*; /// Backplane diff --git a/cli/src/bin/ram_rom.rs b/cli/src/bin/ram_rom.rs index 7519bb3..89fdd1d 100644 --- a/cli/src/bin/ram_rom.rs +++ b/cli/src/bin/ram_rom.rs @@ -1,5 +1,5 @@ use core::computers::ram_rom::backplane::RamRomComputer; -use core::periph::backplane::Backplane; +use core::traits::backplane::Backplane; use std::fs; fn main() { diff --git a/cli/src/bin/ram_rom_widetick.rs b/cli/src/bin/ram_rom_widetick.rs index ff32cd7..f4a477a 100644 --- a/cli/src/bin/ram_rom_widetick.rs +++ b/cli/src/bin/ram_rom_widetick.rs @@ -1,16 +1,11 @@ use std::fs; use core::computers::ram_rom::RamRomComputer; -use core::periph::backplane::Backplane; +use core::traits::backplane::Backplane; + + fn main() { + let bytes = include_bytes!("/home/tmerritt/Projects/mos6502/resources/test/periph/at28c256/checksum.bin"); println!("Taxation is theft"); - let path = "/home/tmerritt/Projects/mos6502/resources/test/periph/at28c256/checksum.bin"; - let bytes = match fs::read(path) { - Ok(bytes) => { - println!("Loaded {} bytes", bytes.len()); - bytes - }, - Err(e) => vec![] - }; let mut ramrom_computer = RamRomComputer::program_rom((&bytes[..]).to_vec()); @@ -19,9 +14,17 @@ fn main() { ramrom_computer.data_bus(), ramrom_computer.address_bus() ); + println!("--TICK--"); ramrom_computer.tick2(0x4005, 0b0000_0001, ramrom_computer.data_bus()); println!("COMPUTER: Read {:02x} from ROM / {:04x} from Address bus", ramrom_computer.data_bus(), ramrom_computer.address_bus() ); + println!("--TICK--"); + ramrom_computer.tick2(0x4005, 0b0000_0000, ramrom_computer.data_bus()); + println!("COMPUTER: Read {:02x} from ROM / {:04x} from Address bus", + ramrom_computer.data_bus(), + ramrom_computer.address_bus() + ); + println!("--TICK--"); } \ No newline at end of file diff --git a/cli/src/bin/rom_only.rs b/cli/src/bin/rom_only.rs index af192ce..5cca49b 100644 --- a/cli/src/bin/rom_only.rs +++ b/cli/src/bin/rom_only.rs @@ -1,6 +1,6 @@ use std::fs; use core::computers::rom_only::RomOnlyComputer; -use core::periph::backplane::Backplane; +use core::traits::backplane::Backplane; fn main() { println!("Taxation is theft"); diff --git a/cli/src/bin/rom_only_widetick.rs b/cli/src/bin/rom_only_widetick.rs index 02f180c..b3ca53d 100644 --- a/cli/src/bin/rom_only_widetick.rs +++ b/cli/src/bin/rom_only_widetick.rs @@ -1,6 +1,6 @@ use std::fs; use core::computers::rom_only::RomOnlyComputer; -use core::periph::backplane::Backplane; +use core::traits::backplane::Backplane; fn main() { println!("Taxation is theft"); diff --git a/core/src/computers/ram_rom/backplane.rs b/core/src/computers/ram_rom/backplane.rs index c40e380..2017e73 100644 --- a/core/src/computers/ram_rom/backplane.rs +++ b/core/src/computers/ram_rom/backplane.rs @@ -1,6 +1,6 @@ use crate::computers::ram_rom::RamRomComputer; use crate::periph::at28c256::At28C256; -use crate::periph::backplane::Backplane; +use crate::traits::backplane::Backplane; use crate::periph::hm62256::Hm62256; @@ -53,5 +53,17 @@ impl Backplane for RamRomComputer { } } } + + fn tick_ram(&mut self, address: u16, data: u8, cs: bool, oe: bool, we: bool) { + todo!() + } + + fn tick_rom(&mut self, address: u16, data: u8, cs: bool, oe: bool, we: bool) -> (u8) { + todo!() + } + + fn tick_via(&mut self, address: u16, data: u8, cs: bool, rw: bool, ce: bool) -> (u8, u8, bool) { + todo!() + } } diff --git a/core/src/computers/ram_rom/tick2.rs b/core/src/computers/ram_rom/tick2.rs index 078adb0..e314cdf 100644 --- a/core/src/computers/ram_rom/tick2.rs +++ b/core/src/computers/ram_rom/tick2.rs @@ -2,26 +2,50 @@ use std::collections::BTreeMap; use crate::computers::ram_rom::RamRomComputer; use crate::traits::bus_device::BusDevice; +struct ChipSignals { + cs: bool, + oe: bool, + we: bool +} + +enum RomRamChips { + At28C256, + Hm62256 +} + impl RamRomComputer { + pub fn signal_tick(&mut self, address: u16, data: u8) { + println!("⏲️RAM ROM COMPUTER SIGNAL TICK"); + + // no CPU to tick. + + let mut ram_state = ChipSignals { oe: false, we: false, cs: false}; + let mut rom_state = ChipSignals { oe: false, we: false, cs: false}; + + + // Tick the RAM + // Tick the ROM + } + pub fn tick2(&mut self, address: u16, control: u8, data: u8) -> (u8) { - println!("RAM ROM Computer tick starting"); + println!("RAM ROM Computer tick starting / {address:04x} {control:08b} {data:02x}"); // tick the parts - let (_, new_data) = self.rom.tick(address, data, control == 1); - let (_, new_data2) = self.ram.tick(address, data, control == 1, true); // map of memory // 0x0000 -> 0x3fff -> RAM (HM62256) // 0x4000 -> 0x7fff -> ROM (At28C256) match address { 0x0000..=0x3fff => { - self.data_bus = new_data + println!("__DATA TARGETTING ROM BEING STORED ON DATA BUS"); } 0x4000 ..=0x7fff => { - self.data_bus = new_data2 + println!("__DATA TARGETTING RRAAMM GETTING STORED ON DATA BUS"); } _ => {} }; + let (_, rom_data_bus) = self.rom.tick(address, data, control == 1); + let (_, ram_data_bus) = self.ram.tick(address, data, control == 1, true); 0 } } \ No newline at end of file diff --git a/core/src/computers/rom_only/backplane.rs b/core/src/computers/rom_only/backplane.rs index 13999d3..92f8b12 100644 --- a/core/src/computers/rom_only/backplane.rs +++ b/core/src/computers/rom_only/backplane.rs @@ -1,5 +1,6 @@ +use log::debug; use crate::computers::rom_only::RomOnlyComputer; -use crate::periph::backplane::Backplane; +use crate::traits::backplane::Backplane; impl Backplane for RomOnlyComputer { fn data_bus(&self) -> u8 { self.data_bus } @@ -17,7 +18,6 @@ impl Backplane for RomOnlyComputer { fn tick(&mut self) { println!("COMPUTER: Preparing to tick."); - // do are we being addressed? println!("COMPUTER: BUSSES PRE: 0x{:04x} 0x{:02x} {}", self.address_bus, self.data_bus, self.read_mode); let (new_addr, new_data) = self.rom.tick(self.address_bus, self.data_bus, self.read_mode); @@ -26,4 +26,18 @@ impl Backplane for RomOnlyComputer { println!("COMPUTER: BUSSES POST: 0x{:04x} 0x{:02x} {}", self.address_bus, self.data_bus, self.read_mode); println!("COMPUTER: Done ticking."); } + + fn tick_ram(&mut self, address: u16, data: u8, cs: bool, oe: bool, we: bool) { + debug!("This system has no ram. ROM only."); + } + + fn tick_rom(&mut self, address: u16, data: u8, cs: bool, oe: bool, we: bool) -> (u8) { + let (_, data) = self.rom.tick(address, data, true); + data + } + + fn tick_via(&mut self, address: u16, data: u8, cs: bool, rw: bool, ce: bool) -> (u8, u8, bool) { + debug!("This system has no VIA controllers. ROM only"); + (0,0,true) + } } diff --git a/core/src/computers/rom_only/mod.rs b/core/src/computers/rom_only/mod.rs index 6c9eb8d..d548820 100644 --- a/core/src/computers/rom_only/mod.rs +++ b/core/src/computers/rom_only/mod.rs @@ -1,5 +1,5 @@ use crate::periph::at28c256::At28C256; -use crate::periph::backplane::Backplane; +use crate::traits::backplane::Backplane; pub mod backplane; pub mod new; diff --git a/core/src/mos6502cpu/bus_device.rs b/core/src/mos6502cpu/bus_device.rs index 2659003..f001eb1 100644 --- a/core/src/mos6502cpu/bus_device.rs +++ b/core/src/mos6502cpu/bus_device.rs @@ -17,4 +17,8 @@ impl BusDevice for Mos6502Cpu { fn set_data_bus(&mut self, new_value: u8) { self.data_bus = new_value; } + + fn talking_to_me(&self, address: u16) -> bool { + todo!() + } } \ No newline at end of file diff --git a/core/src/periph/README b/core/src/periph/README new file mode 100644 index 0000000..ffbec35 --- /dev/null +++ b/core/src/periph/README @@ -0,0 +1,9 @@ +Peripherals + +At28C256 - 256 byte static ram +Hm682256 - 256 byte ROM +Kim1_Keypad - Keypad for KIM-1 Computer +mos6520 - Peripheral Adapter +mos6522 - Versatile Interface Adapter (6520++) +mos6530 - RRIOT (Ram, Rom, Input, Output, Timers) + diff --git a/core/src/periph/at28c256/checksum.rs b/core/src/periph/at28c256/checksum.rs index e333a96..e3298dc 100644 --- a/core/src/periph/at28c256/checksum.rs +++ b/core/src/periph/at28c256/checksum.rs @@ -21,7 +21,8 @@ mod test { use std::fs; use std::path::Path; use crate::constants::constants_system::SIZE_1KB; - use crate::periph::rom_chip::RomChip; + use crate::traits::memory_chip::MemoryChip; + use crate::traits::rom_chip::RomChip; use super::*; #[test] @@ -77,4 +78,4 @@ mod test { assert_eq!(0x58, checksum); println!("TEST COMPLETE"); } -} \ No newline at end of file +} diff --git a/core/src/periph/at28c256/control.rs b/core/src/periph/at28c256/control.rs new file mode 100644 index 0000000..e43c1e3 --- /dev/null +++ b/core/src/periph/at28c256/control.rs @@ -0,0 +1,8 @@ +use crate::periph::at28c256::At28C256; +use crate::traits::bus_control_byte::BusControlByte; + +const CTRL_CS: u8 = 0b0000_0001; +const CTRL_WE: u8 = 0b0000_0010; +const CTRL_OE: u8 = 0b0000_0100; + +pub struct At28c256Control {} diff --git a/core/src/periph/at28c256/default.rs b/core/src/periph/at28c256/default.rs index e8a255b..018161e 100644 --- a/core/src/periph/at28c256/default.rs +++ b/core/src/periph/at28c256/default.rs @@ -15,6 +15,9 @@ impl Default for At28C256 { data_bus: 0x00, offset: 0x0000, max_offset: 0x3fff, + cs: false, + oe: false, + we: false } } } diff --git a/core/src/periph/at28c256/mod.rs b/core/src/periph/at28c256/mod.rs index fb6db89..745ad39 100644 --- a/core/src/periph/at28c256/mod.rs +++ b/core/src/periph/at28c256/mod.rs @@ -6,9 +6,10 @@ pub mod program; pub mod dump; pub mod checksum; pub mod blocks; +pub mod control; +pub mod signal_tick; -use crate::constants::constants_system::SIZE_32KB; -use crate::periph::rom_chip::RomChip; +use crate::traits::rom_chip::RomChip; use std::io::Read; /// At28C256 @@ -18,10 +19,15 @@ use std::io::Read; /// 256kbit storage /// 32kbyte storage pub struct At28C256 { + // Logical parts data_bus: u8, address_bus: u16, data: Box<[u8]>, // where in the computer memory map do we live? offset: u16, - max_offset: u16 + max_offset: u16, + // Physical Parts + cs: bool, + we: bool, + oe: bool } diff --git a/core/src/periph/at28c256/new.rs b/core/src/periph/at28c256/new.rs index 13f4930..417504a 100644 --- a/core/src/periph/at28c256/new.rs +++ b/core/src/periph/at28c256/new.rs @@ -10,7 +10,10 @@ impl At28C256 { address_bus: 0x0000, data_bus: 0x00, offset, - max_offset + max_offset, + cs: false, + oe: false, + we: false } } } diff --git a/core/src/periph/at28c256/program.rs b/core/src/periph/at28c256/program.rs index 0fc9604..cd835c6 100644 --- a/core/src/periph/at28c256/program.rs +++ b/core/src/periph/at28c256/program.rs @@ -11,7 +11,8 @@ impl At28C256 { #[cfg(test)] mod test { - use crate::periph::rom_chip::RomChip; + use crate::traits::memory_chip::MemoryChip; + use crate::traits::rom_chip::RomChip; use super::*; #[test] @@ -26,5 +27,6 @@ mod test { let new_data: Vec = vec![0xff, 0xff, 0xff, 0xff]; chip.program(new_data.into()); assert_eq!(0xff, chip.read(&0x0000)); + assert_eq!(0x00, chip.read(&0x05)); } } diff --git a/core/src/periph/at28c256/rom_chip.rs b/core/src/periph/at28c256/rom_chip.rs index eec09db..d50002a 100644 --- a/core/src/periph/at28c256/rom_chip.rs +++ b/core/src/periph/at28c256/rom_chip.rs @@ -1,13 +1,14 @@ use crate::constants::constants_system::SIZE_32KB; use crate::periph::at28c256::At28C256; -use crate::periph::rom_chip::RomChip; +use crate::traits::memory_chip::MemoryChip; +use crate::traits::rom_chip::RomChip; -impl RomChip for At28C256 { - /// read - /// - /// Reads a byte from memory. - /// Returns a 0x00 if there is no data at that location but is still in ROM address range +impl MemoryChip for At28C256 { fn read(&self, offset: &u16) -> u8 { + /// read + /// + /// Reads a byte from memory. + /// Returns a 0x00 if there is no data at that location but is still in ROM address range println!("STARTING READ FROM At28C256 ${:04x} | ${:04x} | ${:04x}", self.offset, offset, self.max_offset); if offset < &self.offset || offset > &self.max_offset { println!("Unable to read from ${offset:04x} as it it out of range."); @@ -20,18 +21,18 @@ impl RomChip for At28C256 { 0x00 } else { self.data[*offset as usize] - } - - } + } } +} +impl RomChip for At28C256 { /// program /// /// Writes new data to the memory chip - fn program(new_data: &[u8; SIZE_32KB]) -> Box { + fn program(new_data: &[u8]) -> Box { println!("Writing new chip."); let mut working = At28C256::default(); - working.data = Box::new(*new_data); - working.into() + working.data = new_data.to_vec().into_boxed_slice(); + Box::new(working) } } diff --git a/core/src/periph/at28c256/signal_tick.rs b/core/src/periph/at28c256/signal_tick.rs new file mode 100644 index 0000000..685b6a4 --- /dev/null +++ b/core/src/periph/at28c256/signal_tick.rs @@ -0,0 +1,51 @@ +use crate::constants::constants_system::SIZE_32KB; +use crate::periph::at28c256::At28C256; + +const CHIP_SIZE: usize = SIZE_32KB ; + +impl At28C256 { + /// Tick the ROM + /// address_bus + /// data_bus + /// CS -> Chip Select + /// OE -> Output Enable + /// WE -> Write Enable + pub fn signal_tick(&mut self, address_bus: u16, data_bus: u8, cs: bool, oe: bool, we: bool) -> (u8) { + + // if we aren't selected and we aren't able to write to the bus... + if !cs || !we || !oe { return data_bus }; + + // if we aren't being addressed directly + if !(address_bus <= self.max_offset && address_bus >= self.offset) { + return data_bus + }; + + let internal_address = address_bus - self.offset; + + let result = if internal_address < CHIP_SIZE as u16 { + self.data[internal_address as usize] + } else { + data_bus + }; + println!("At28C256 EADDR: ${address_bus:04x} IADDR: ${internal_address:04x} = {result:02x}"); + result + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn smoke() { assert!(true) } + + #[test] + fn correct_flags_required() { + let mut chip = At28C256::new(0x0000, 0x3fff, vec![0xff]); + assert_eq!(0xab, chip.signal_tick(0x0000, 0xab, false, true, true)); + assert_eq!(0xab, chip.signal_tick(0x0000, 0xab, true, true, false)); + assert_eq!(0xab, chip.signal_tick(0x0000, 0xab, false, true, false)); + assert_eq!(0xff, chip.signal_tick(0x0000, 0xab, true, true, true)); + assert_eq!(0xab, chip.signal_tick(0x0000, 0xab, true, false, true)); + } +} diff --git a/core/src/periph/at28c256/tick.rs b/core/src/periph/at28c256/tick.rs index 1011a1f..5e978ee 100644 --- a/core/src/periph/at28c256/tick.rs +++ b/core/src/periph/at28c256/tick.rs @@ -8,8 +8,10 @@ impl At28C256 { address >= self.offset && address < self.max_offset } + + pub fn tick(&mut self, address_bus: u16, data_bus: u8, read_mode: bool) -> (u16, u8) { - print!("At28C256: Tick starting for A${address_bus:04x} D${data_bus:02x} R{read_mode}"); + println!("At28C256: Tick starting for A${address_bus:04x} D${data_bus:02x} R{read_mode}"); // we aren't being addressed // OR @@ -17,7 +19,6 @@ impl At28C256 { if !self.talking_to_me(address_bus) || !read_mode { // ...go away. - // println!("At28C256 Tick not for me."); return (address_bus, data_bus) } @@ -42,7 +43,7 @@ impl At28C256 { #[cfg(test)] mod test { use std::fs; - use crate::periph::rom_chip::RomChip; + use crate::traits::rom_chip::RomChip; use super::*; #[test] diff --git a/core/src/periph/backplane.rs b/core/src/periph/backplane.rs deleted file mode 100644 index 54f2995..0000000 --- a/core/src/periph/backplane.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub trait Backplane { - fn data_bus(&self) -> u8; - fn address_bus(&self) -> u16; - fn read_mode(&self) -> bool; - fn set_read_mode(&mut self, new_mode: bool); - fn set_data_bus(&mut self, new_value: u8); - fn set_address_bus(&mut self, new_value: u16); - fn tick(&mut self); -} - diff --git a/core/src/periph/bus_device.rs b/core/src/periph/bus_device.rs deleted file mode 100644 index 5934f0c..0000000 --- a/core/src/periph/bus_device.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait BusDevice { - fn talking_to_me(&self, address: u16) -> bool; -} \ No newline at end of file diff --git a/core/src/periph/hm62256/control.rs b/core/src/periph/hm62256/control.rs new file mode 100644 index 0000000..f31de33 --- /dev/null +++ b/core/src/periph/hm62256/control.rs @@ -0,0 +1,8 @@ +use crate::periph::hm62256::Hm62256; +use crate::traits::bus_control_byte::BusControlByte; + +const CTRL_CS: u8 = 0b0000_0001; +const CTRL_WE: u8 = 0b0000_0010; +const CTRL_OE: u8 = 0b0000_0100; + +pub struct Hm62256Control; diff --git a/core/src/periph/hm62256/default.rs b/core/src/periph/hm62256/default.rs index c81b268..46bf649 100644 --- a/core/src/periph/hm62256/default.rs +++ b/core/src/periph/hm62256/default.rs @@ -11,7 +11,10 @@ impl Default for Hm62256 { offset: 0x0000, data: boxed_array, address_bus: 0x0000, - data_bus: 0x00 + data_bus: 0x00, + cs: false, + oe: false, + we: false } } } diff --git a/core/src/periph/hm62256/mod.rs b/core/src/periph/hm62256/mod.rs index 4e5391d..775af1b 100644 --- a/core/src/periph/hm62256/mod.rs +++ b/core/src/periph/hm62256/mod.rs @@ -6,10 +6,11 @@ pub mod tick; pub mod default; pub mod new; pub mod dump; +mod control; use crate::constants::constants_system::SIZE_32KB; -use crate::periph::ram_chip::RamChip; -use crate::periph::rom_chip::RomChip; +use crate::traits::ram_chip::RamChip; +use crate::traits::rom_chip::RomChip; use log::debug; /// Hitachi Semiconductor @@ -19,13 +20,20 @@ pub struct Hm62256 { pub(crate) offset: u16, pub(crate) data: Box<[u8]>, pub(crate) address_bus: u16, - pub(crate) data_bus: u8 + pub(crate) data_bus: u8, + // Chip Select + pub(crate) cs: bool, + // Write Enable + pub(crate) we: bool, + // Output Enable + pub(crate) oe: bool } #[cfg(test)] mod test { use super::*; use rand::random; + use crate::traits::memory_chip::MemoryChip; #[test] fn smoke() { diff --git a/core/src/periph/hm62256/new.rs b/core/src/periph/hm62256/new.rs index ec70998..2b0af21 100644 --- a/core/src/periph/hm62256/new.rs +++ b/core/src/periph/hm62256/new.rs @@ -7,7 +7,10 @@ impl Hm62256 { offset: base_offset, data: vec![0; SIZE_32KB].into_boxed_slice(), address_bus: 0x0000, - data_bus: 0x00 + data_bus: 0x00, + cs: false, + oe: false, + we: false } } -} \ No newline at end of file +} diff --git a/core/src/periph/hm62256/ramchip.rs b/core/src/periph/hm62256/ramchip.rs index af27c86..9c29eca 100644 --- a/core/src/periph/hm62256/ramchip.rs +++ b/core/src/periph/hm62256/ramchip.rs @@ -1,6 +1,6 @@ use crate::constants::constants_system::SIZE_32KB; use crate::periph::hm62256::Hm62256; -use crate::periph::ram_chip::RamChip; +use crate::traits::ram_chip::RamChip; impl RamChip for Hm62256 { fn write(&mut self, offset: &u16, value: &u8) { diff --git a/core/src/periph/hm62256/romchip.rs b/core/src/periph/hm62256/romchip.rs index 66b240b..0abc6ea 100644 --- a/core/src/periph/hm62256/romchip.rs +++ b/core/src/periph/hm62256/romchip.rs @@ -1,18 +1,19 @@ use log::debug; use crate::constants::constants_system::SIZE_32KB; use crate::periph::hm62256::Hm62256; -use crate::periph::rom_chip::RomChip; - -impl RomChip for Hm62256 { - +use crate::traits::memory_chip::MemoryChip; +use crate::traits::rom_chip::RomChip; +impl MemoryChip for Hm62256 { fn read(&self, offset: &u16) -> u8 { // loops memory around past 32k let effective = *offset as i32 % SIZE_32KB as i32; self.data[effective as usize] } +} - fn program(_: &[u8; SIZE_32KB]) -> Box { +impl RomChip for Hm62256 { + fn program(_: &[u8]) -> Box { debug!("Dont program ram."); Hm62256::default().into() } diff --git a/core/src/periph/mod.rs b/core/src/periph/mod.rs index a6c2bec..f83a541 100644 --- a/core/src/periph/mod.rs +++ b/core/src/periph/mod.rs @@ -1,9 +1,6 @@ -pub mod rom_chip; pub mod at28c256; pub mod hm62256; -pub mod ram_chip; +pub mod mos6520; pub mod mos6522; pub mod mos6530; pub mod kim1_keypad; -mod bus_device; -pub mod backplane; diff --git a/core/src/periph/mos6520/mod.rs b/core/src/periph/mos6520/mod.rs new file mode 100644 index 0000000..5694c24 --- /dev/null +++ b/core/src/periph/mos6520/mod.rs @@ -0,0 +1,65 @@ +mod tod; +mod reset; + +use crate::traits::memory_chip::MemoryChip; +use crate::traits::ram_chip::RamChip; +use crate::traits::rom_chip::RomChip; +use crate::traits::via_chip::ViaChip; + +pub struct Mos6520 { + // Parallel ports A & B data registers + port_a: u8, + port_b: u8, + ddra: u8, + ddrb: u8, + // Timer registers and control + tmr_a: u16, + latch_a: u16, + ctrl_a: u8, + tmr_b: u16, + latch_b: u16, + ctrl_b: u8, + // Interrupt control register + icr: u8, + // TOD clock raw BCD registers + tod_hours: u8, + tod_minutes: u8, + tod_seconds: u8, + tod_tenths: u8, + tod_frozen: bool, +} + +impl RamChip for Mos6520 { + fn write(&mut self, offset: &u16, value: &u8) { + match offset & 0x0F { + 0x0 => { self.port_a = *value; } + 0x1 => { self.ddra = *value; } + 0x4 => { self.latch_a = (self.latch_a & 0xFF00) | *value as u16; } + 0x5 => { self.latch_a = (self.latch_a & 0x00FF) | ((*value as u16) << 8); } + 0x8..=0xB => { self.write_tod((offset & 0x03) as u8, *value); } + _ => {} + } + } +} + +impl MemoryChip for Mos6520 { + fn read(&self, offset: &u16) -> u8 { + todo!() + } +} + +impl RomChip for Mos6520 { + fn program(new_data: &[u8]) -> Box { + todo!() + } +} + +impl ViaChip for Mos6520 { + fn set_port_ddr(&mut self, port_index: u8, value: u8) { + todo!() + } + + fn set_port_data(&mut self, port_index: u8, value: u8) { + todo!() + } +} \ No newline at end of file diff --git a/core/src/periph/mos6520/reset.rs b/core/src/periph/mos6520/reset.rs new file mode 100644 index 0000000..b2161b8 --- /dev/null +++ b/core/src/periph/mos6520/reset.rs @@ -0,0 +1,26 @@ +use crate::periph::mos6520::Mos6520; + +impl Mos6520 { + /// reset + /// + /// Simulates holding Reset pin low + pub fn reset(&mut self) { + self.port_a = 0x00; + self.port_b = 0x00; + self.ddra = 0x00; + self.ddrb = 0x00; + self.tmr_a = 0x00; + self.latch_a = 0x00; + self.ctrl_a = 0x00; + self.tmr_b = 0x00; + self.latch_b = 0x00; + self.ctrl_b = 0x00; + self.icr = 0x00; + self.tod_hours = 0x01; + self.tod_minutes = 0x00; + self.tod_seconds = 0x00; + self.tod_tenths = 0x00; + self.tod_frozen = false; + } +} + diff --git a/core/src/periph/mos6520/tod.rs b/core/src/periph/mos6520/tod.rs new file mode 100644 index 0000000..c162425 --- /dev/null +++ b/core/src/periph/mos6520/tod.rs @@ -0,0 +1,26 @@ +use crate::periph::mos6520::Mos6520; + +impl Mos6520 { + fn read_tod(&mut self, sub: u8) -> u8 { + match sub { + 0 => { self.tod_frozen = true; self.tod_hours }, + 1 => self.tod_minutes, + 2 => self.tod_seconds, + 3 => { + self.tod_frozen = false; + self.tod_tenths + } + _ => 0 + } + } + + pub(crate) fn write_tod(&mut self, sub: u8, value: u8) { + match sub { + 0 => { self.tod_hours = value; self.tod_frozen = true; } + 1 => self.tod_minutes = value, + 2 => self.tod_seconds = value, + 3 => { self.tod_tenths = value; self.tod_frozen = false; } + _ => {} + } + } +} \ No newline at end of file diff --git a/core/src/periph/mos6530/mod.rs b/core/src/periph/mos6530/mod.rs index 15b4b48..c8f6431 100644 --- a/core/src/periph/mos6530/mod.rs +++ b/core/src/periph/mos6530/mod.rs @@ -1,4 +1,5 @@ pub mod mos6530; pub mod tick; mod new; -mod dump; \ No newline at end of file +mod dump; +mod viachip; \ No newline at end of file diff --git a/core/src/periph/mos6530/viachip.rs b/core/src/periph/mos6530/viachip.rs new file mode 100644 index 0000000..cb45ecc --- /dev/null +++ b/core/src/periph/mos6530/viachip.rs @@ -0,0 +1,52 @@ +use log::debug; +use crate::constants::constants_system::{SIZE_1KB, SIZE_32KB}; +use crate::periph::mos6530::mos6530::Mos6530; +use crate::traits::memory_chip::MemoryChip; +use crate::traits::ram_chip::RamChip; +use crate::traits::rom_chip::RomChip; +use crate::traits::via_chip::ViaChip; + +impl RamChip for Mos6530 { + fn write(&mut self, offset: &u16, value: &u8) { + debug!("🐙 Writing ${value:02x} to ${offset:04x}"); + } +} + +impl MemoryChip for Mos6530 { + fn read(&self, offset: &u16) -> u8 { + debug!("🐙 Reading from ${offset:04x}"); + 0 + } +} + +impl RomChip for Mos6530 { + fn program(new_data: &[u8]) -> Box { + debug!("🐙 programming {}b to ROM", new_data.len()); + Box::new(Mos6530 { + data: new_data.to_vec().try_into().unwrap(), + ram: [0x00; 64], + porta: 0, + portb: 0, + data_bus: 0, + address_bus: 0, + cs1: false, + cs2: false, + rw: false, + reset: false, + io_offset: 0, + ram_offset: 0, + rom_offset: 0, + }) + } +} + +impl ViaChip for Mos6530 { + fn set_port_ddr(&mut self, port_index: u8, value: u8) { + debug!("🐙Setting DDR{port_index} to {value:02x}"); + } + + fn set_port_data(&mut self, port_index: u8, value: u8) { + debug!("🐙Setting PORT{port_index} to {value:02x}"); + } +} + diff --git a/core/src/periph/ram_chip.rs b/core/src/periph/ram_chip.rs deleted file mode 100644 index 0ee3345..0000000 --- a/core/src/periph/ram_chip.rs +++ /dev/null @@ -1,5 +0,0 @@ -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 deleted file mode 100644 index 7569ff7..0000000 --- a/core/src/periph/rom_chip.rs +++ /dev/null @@ -1,12 +0,0 @@ -use crate::constants::constants_system::SIZE_32KB; - -pub trait RomChip { - /// Read - /// - /// Reads a single byte from the specified address - fn read(&self, offset: &u16) -> u8; - /// Program - /// - /// Replaces all data in the ROM chip - fn program(new_data: &[u8; SIZE_32KB]) -> Box; -} diff --git a/core/src/traits/backplane.rs b/core/src/traits/backplane.rs new file mode 100644 index 0000000..ce0b354 --- /dev/null +++ b/core/src/traits/backplane.rs @@ -0,0 +1,34 @@ +pub trait Backplane { + fn data_bus(&self) -> u8; + fn address_bus(&self) -> u16; + fn read_mode(&self) -> bool; + fn set_read_mode(&mut self, new_mode: bool); + fn set_data_bus(&mut self, new_value: u8); + fn set_address_bus(&mut self, new_value: u16); + + /// Tick + /// + /// Master tick method to handle ticking all subsystems. + fn tick(&mut self); + + /// tick_rom + /// + /// Tick a ROM chip + /// + /// returns (data_for_databus) + fn tick_ram(&mut self, address: u16, data: u8, cs: bool, oe: bool, we: bool); + + /// tick_rom + /// + /// Tick a ROM chip + /// + /// returns (data_for_databus) + fn tick_rom(&mut self, address: u16, data: u8, cs: bool, oe: bool, we: bool) -> (u8); + + /// tick_via + /// + /// Tick a VIA chip + /// + /// returns (portA, portB, interrupt) + fn tick_via(&mut self, address: u16, data: u8, cs: bool, rw: bool, ce: bool) -> (u8, u8, bool); +} diff --git a/core/src/traits/bus_control_byte.rs b/core/src/traits/bus_control_byte.rs new file mode 100644 index 0000000..d16952b --- /dev/null +++ b/core/src/traits/bus_control_byte.rs @@ -0,0 +1,10 @@ +use crate::traits::bus_device::BusDevice; + +/// BusControlByte +/// +/// Used to allow passing of a component specific set of +/// properties to be used with the universal tick +pub trait BusControlByte { + fn from_byte(source: u8) -> T; +} + diff --git a/core/src/traits/bus_device.rs b/core/src/traits/bus_device.rs index af76d98..848a307 100644 --- a/core/src/traits/bus_device.rs +++ b/core/src/traits/bus_device.rs @@ -4,5 +4,5 @@ pub trait BusDevice { fn set_address_bus(&mut self, new_value: u16); fn set_data_bus(&mut self, new_value: u8); - + fn talking_to_me(&self, address: u16) -> bool; } diff --git a/core/src/traits/memory_chip.rs b/core/src/traits/memory_chip.rs new file mode 100644 index 0000000..835871a --- /dev/null +++ b/core/src/traits/memory_chip.rs @@ -0,0 +1,6 @@ +pub trait MemoryChip { + /// Read + /// + /// Reads a single byte from the specified address + fn read(&self, offset: &u16) -> u8; +} diff --git a/core/src/traits/mod.rs b/core/src/traits/mod.rs index 0edf4c5..c26e9cf 100644 --- a/core/src/traits/mod.rs +++ b/core/src/traits/mod.rs @@ -1 +1,7 @@ -pub mod bus_device; \ No newline at end of file +pub mod bus_device; +pub mod bus_control_byte; +pub mod memory_chip; +pub mod rom_chip; +pub mod ram_chip; +pub mod via_chip; +pub mod backplane; diff --git a/core/src/traits/ram_chip.rs b/core/src/traits/ram_chip.rs new file mode 100644 index 0000000..16a5d8a --- /dev/null +++ b/core/src/traits/ram_chip.rs @@ -0,0 +1,7 @@ +use crate::periph::hm62256::Hm62256; +use crate::traits::memory_chip::MemoryChip; +use crate::traits::rom_chip::RomChip; + +pub trait RamChip: MemoryChip { + fn write(&mut self, offset: &u16, value: &u8); +} diff --git a/core/src/traits/rom_chip.rs b/core/src/traits/rom_chip.rs new file mode 100644 index 0000000..0041c3e --- /dev/null +++ b/core/src/traits/rom_chip.rs @@ -0,0 +1,9 @@ +use crate::constants::constants_system::SIZE_32KB; +use crate::traits::memory_chip::MemoryChip; + +pub trait RomChip: MemoryChip { + /// Program + /// + /// Replaces all data in the chip + fn program(new_data: &[u8]) -> Box; +} diff --git a/core/src/traits/via_chip.rs b/core/src/traits/via_chip.rs new file mode 100644 index 0000000..8606870 --- /dev/null +++ b/core/src/traits/via_chip.rs @@ -0,0 +1,15 @@ +use crate::traits::ram_chip::RamChip; +use crate::traits::rom_chip::RomChip; + +pub trait ViaChip: RamChip + RomChip { + /// set_port_ddr + /// + /// Sets the Data Direction Register in the VIA chip for the specified + /// port. + fn set_port_ddr(&mut self, port_index: u8, value: u8); + + /// set_port_data + /// + /// Sets the + fn set_port_data(&mut self, port_index: u8, value: u8); +} \ No newline at end of file diff --git a/core/tests/at28c256.rs b/core/tests/at28c256.rs index e69de29..1295628 100644 --- a/core/tests/at28c256.rs +++ b/core/tests/at28c256.rs @@ -0,0 +1,6 @@ +use super::*; + +#[test] +fn test123() { + +} \ No newline at end of file diff --git a/resources/docs/6530-Commodore.pdf b/resources/docs/6530-Commodore.pdf new file mode 100644 index 0000000..ca9b749 Binary files /dev/null and b/resources/docs/6530-Commodore.pdf differ diff --git a/resources/docs/6530.pdf b/resources/docs/6530.pdf new file mode 100644 index 0000000..8c0ed12 Binary files /dev/null and b/resources/docs/6530.pdf differ diff --git a/resources/docs/rockwell_r6520_pia.pdf b/resources/docs/rockwell_r6520_pia.pdf new file mode 100644 index 0000000..c93e77f Binary files /dev/null and b/resources/docs/rockwell_r6520_pia.pdf differ diff --git a/resources/docs/w65c22.pdf b/resources/docs/w65c22.pdf new file mode 100644 index 0000000..b35400a Binary files /dev/null and b/resources/docs/w65c22.pdf differ