adds docs

working on widetick
This commit is contained in:
Trevor Merritt 2025-07-26 11:02:36 -04:00
parent b40c3c503f
commit 8f6f9cb64d
49 changed files with 488 additions and 93 deletions

View File

@ -3,7 +3,7 @@ use crate::parts::via6522::VIA6522;
use core::constants::constants_system::*; use core::constants::constants_system::*;
use core::mos6502cpu::cpu::Mos6502Cpu; use core::mos6502cpu::cpu::Mos6502Cpu;
use core::periph::at28c256::At28C256; use core::periph::at28c256::At28C256;
use core::periph::rom_chip::RomChip; use core::traits::rom_chip::RomChip;
use core::constants::constants_via6522::*; use core::constants::constants_via6522::*;
/// Backplane /// Backplane

View File

@ -1,5 +1,5 @@
use core::computers::ram_rom::backplane::RamRomComputer; use core::computers::ram_rom::backplane::RamRomComputer;
use core::periph::backplane::Backplane; use core::traits::backplane::Backplane;
use std::fs; use std::fs;
fn main() { fn main() {

View File

@ -1,16 +1,11 @@
use std::fs; use std::fs;
use core::computers::ram_rom::RamRomComputer; use core::computers::ram_rom::RamRomComputer;
use core::periph::backplane::Backplane; use core::traits::backplane::Backplane;
fn main() { fn main() {
let bytes = include_bytes!("/home/tmerritt/Projects/mos6502/resources/test/periph/at28c256/checksum.bin");
println!("Taxation is theft"); 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()); let mut ramrom_computer = RamRomComputer::program_rom((&bytes[..]).to_vec());
@ -19,9 +14,17 @@ fn main() {
ramrom_computer.data_bus(), ramrom_computer.data_bus(),
ramrom_computer.address_bus() ramrom_computer.address_bus()
); );
println!("--TICK--");
ramrom_computer.tick2(0x4005, 0b0000_0001, ramrom_computer.data_bus()); ramrom_computer.tick2(0x4005, 0b0000_0001, ramrom_computer.data_bus());
println!("COMPUTER: Read {:02x} from ROM / {:04x} from Address bus", println!("COMPUTER: Read {:02x} from ROM / {:04x} from Address bus",
ramrom_computer.data_bus(), ramrom_computer.data_bus(),
ramrom_computer.address_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--");
} }

View File

@ -1,6 +1,6 @@
use std::fs; use std::fs;
use core::computers::rom_only::RomOnlyComputer; use core::computers::rom_only::RomOnlyComputer;
use core::periph::backplane::Backplane; use core::traits::backplane::Backplane;
fn main() { fn main() {
println!("Taxation is theft"); println!("Taxation is theft");

View File

@ -1,6 +1,6 @@
use std::fs; use std::fs;
use core::computers::rom_only::RomOnlyComputer; use core::computers::rom_only::RomOnlyComputer;
use core::periph::backplane::Backplane; use core::traits::backplane::Backplane;
fn main() { fn main() {
println!("Taxation is theft"); println!("Taxation is theft");

View File

@ -1,6 +1,6 @@
use crate::computers::ram_rom::RamRomComputer; use crate::computers::ram_rom::RamRomComputer;
use crate::periph::at28c256::At28C256; use crate::periph::at28c256::At28C256;
use crate::periph::backplane::Backplane; use crate::traits::backplane::Backplane;
use crate::periph::hm62256::Hm62256; 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!()
}
} }

View File

@ -2,26 +2,50 @@ use std::collections::BTreeMap;
use crate::computers::ram_rom::RamRomComputer; use crate::computers::ram_rom::RamRomComputer;
use crate::traits::bus_device::BusDevice; use crate::traits::bus_device::BusDevice;
struct ChipSignals {
cs: bool,
oe: bool,
we: bool
}
enum RomRamChips {
At28C256,
Hm62256
}
impl RamRomComputer { 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) { 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 // 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 // map of memory
// 0x0000 -> 0x3fff -> RAM (HM62256) // 0x0000 -> 0x3fff -> RAM (HM62256)
// 0x4000 -> 0x7fff -> ROM (At28C256) // 0x4000 -> 0x7fff -> ROM (At28C256)
match address { match address {
0x0000..=0x3fff => { 0x0000..=0x3fff => {
self.data_bus = new_data println!("__DATA TARGETTING ROM BEING STORED ON DATA BUS");
} }
0x4000 ..=0x7fff => { 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 0
} }
} }

View File

@ -1,5 +1,6 @@
use log::debug;
use crate::computers::rom_only::RomOnlyComputer; use crate::computers::rom_only::RomOnlyComputer;
use crate::periph::backplane::Backplane; use crate::traits::backplane::Backplane;
impl Backplane for RomOnlyComputer { impl Backplane for RomOnlyComputer {
fn data_bus(&self) -> u8 { self.data_bus } fn data_bus(&self) -> u8 { self.data_bus }
@ -17,7 +18,6 @@ impl Backplane for RomOnlyComputer {
fn tick(&mut self) { fn tick(&mut self) {
println!("COMPUTER: Preparing to tick."); println!("COMPUTER: Preparing to tick.");
// do are we being addressed? // do are we being addressed?
println!("COMPUTER: BUSSES PRE: 0x{:04x} 0x{:02x} {}", self.address_bus, self.data_bus, self.read_mode); 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); 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: BUSSES POST: 0x{:04x} 0x{:02x} {}", self.address_bus, self.data_bus, self.read_mode);
println!("COMPUTER: Done ticking."); 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)
}
} }

View File

@ -1,5 +1,5 @@
use crate::periph::at28c256::At28C256; use crate::periph::at28c256::At28C256;
use crate::periph::backplane::Backplane; use crate::traits::backplane::Backplane;
pub mod backplane; pub mod backplane;
pub mod new; pub mod new;

View File

@ -17,4 +17,8 @@ impl BusDevice for Mos6502Cpu {
fn set_data_bus(&mut self, new_value: u8) { fn set_data_bus(&mut self, new_value: u8) {
self.data_bus = new_value; self.data_bus = new_value;
} }
fn talking_to_me(&self, address: u16) -> bool {
todo!()
}
} }

9
core/src/periph/README Normal file
View File

@ -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)

View File

@ -21,7 +21,8 @@ mod test {
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use crate::constants::constants_system::SIZE_1KB; 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::*; use super::*;
#[test] #[test]

View File

@ -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 {}

View File

@ -15,6 +15,9 @@ impl Default for At28C256 {
data_bus: 0x00, data_bus: 0x00,
offset: 0x0000, offset: 0x0000,
max_offset: 0x3fff, max_offset: 0x3fff,
cs: false,
oe: false,
we: false
} }
} }
} }

View File

@ -6,9 +6,10 @@ pub mod program;
pub mod dump; pub mod dump;
pub mod checksum; pub mod checksum;
pub mod blocks; pub mod blocks;
pub mod control;
pub mod signal_tick;
use crate::constants::constants_system::SIZE_32KB; use crate::traits::rom_chip::RomChip;
use crate::periph::rom_chip::RomChip;
use std::io::Read; use std::io::Read;
/// At28C256 /// At28C256
@ -18,10 +19,15 @@ use std::io::Read;
/// 256kbit storage /// 256kbit storage
/// 32kbyte storage /// 32kbyte storage
pub struct At28C256 { pub struct At28C256 {
// Logical parts
data_bus: u8, data_bus: u8,
address_bus: u16, address_bus: u16,
data: Box<[u8]>, data: Box<[u8]>,
// where in the computer memory map do we live? // where in the computer memory map do we live?
offset: u16, offset: u16,
max_offset: u16 max_offset: u16,
// Physical Parts
cs: bool,
we: bool,
oe: bool
} }

View File

@ -10,7 +10,10 @@ impl At28C256 {
address_bus: 0x0000, address_bus: 0x0000,
data_bus: 0x00, data_bus: 0x00,
offset, offset,
max_offset max_offset,
cs: false,
oe: false,
we: false
} }
} }
} }

View File

@ -11,7 +11,8 @@ impl At28C256 {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::periph::rom_chip::RomChip; use crate::traits::memory_chip::MemoryChip;
use crate::traits::rom_chip::RomChip;
use super::*; use super::*;
#[test] #[test]
@ -26,5 +27,6 @@ mod test {
let new_data: Vec<u8> = vec![0xff, 0xff, 0xff, 0xff]; let new_data: Vec<u8> = vec![0xff, 0xff, 0xff, 0xff];
chip.program(new_data.into()); chip.program(new_data.into());
assert_eq!(0xff, chip.read(&0x0000)); assert_eq!(0xff, chip.read(&0x0000));
assert_eq!(0x00, chip.read(&0x05));
} }
} }

View File

@ -1,13 +1,14 @@
use crate::constants::constants_system::SIZE_32KB; use crate::constants::constants_system::SIZE_32KB;
use crate::periph::at28c256::At28C256; 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 { impl MemoryChip for At28C256 {
fn read(&self, offset: &u16) -> u8 {
/// read /// read
/// ///
/// Reads a byte from memory. /// Reads a byte from memory.
/// Returns a 0x00 if there is no data at that location but is still in ROM address range /// Returns a 0x00 if there is no data at that location but is still in ROM address range
fn read(&self, offset: &u16) -> u8 {
println!("STARTING READ FROM At28C256 ${:04x} | ${:04x} | ${:04x}", self.offset, offset, self.max_offset); println!("STARTING READ FROM At28C256 ${:04x} | ${:04x} | ${:04x}", self.offset, offset, self.max_offset);
if offset < &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."); println!("Unable to read from ${offset:04x} as it it out of range.");
@ -20,18 +21,18 @@ impl RomChip for At28C256 {
0x00 0x00
} else { } else {
self.data[*offset as usize] self.data[*offset as usize]
} }
} }
} impl RomChip for At28C256 {
/// program /// program
/// ///
/// Writes new data to the memory chip /// Writes new data to the memory chip
fn program(new_data: &[u8; SIZE_32KB]) -> Box<At28C256> { fn program(new_data: &[u8]) -> Box<At28C256> {
println!("Writing new chip."); println!("Writing new chip.");
let mut working = At28C256::default(); let mut working = At28C256::default();
working.data = Box::new(*new_data); working.data = new_data.to_vec().into_boxed_slice();
working.into() Box::new(working)
} }
} }

View File

@ -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));
}
}

View File

@ -8,8 +8,10 @@ impl At28C256 {
address >= self.offset && address < self.max_offset address >= self.offset && address < self.max_offset
} }
pub fn tick(&mut self, address_bus: u16, data_bus: u8, read_mode: bool) -> (u16, u8) { 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 // we aren't being addressed
// OR // OR
@ -17,7 +19,6 @@ impl At28C256 {
if !self.talking_to_me(address_bus) || if !self.talking_to_me(address_bus) ||
!read_mode { !read_mode {
// ...go away. // ...go away.
// println!("At28C256 Tick not for me.");
return (address_bus, data_bus) return (address_bus, data_bus)
} }
@ -42,7 +43,7 @@ impl At28C256 {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::fs; use std::fs;
use crate::periph::rom_chip::RomChip; use crate::traits::rom_chip::RomChip;
use super::*; use super::*;
#[test] #[test]

View File

@ -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);
}

View File

@ -1,3 +0,0 @@
pub trait BusDevice {
fn talking_to_me(&self, address: u16) -> bool;
}

View File

@ -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;

View File

@ -11,7 +11,10 @@ impl Default for Hm62256 {
offset: 0x0000, offset: 0x0000,
data: boxed_array, data: boxed_array,
address_bus: 0x0000, address_bus: 0x0000,
data_bus: 0x00 data_bus: 0x00,
cs: false,
oe: false,
we: false
} }
} }
} }

View File

@ -6,10 +6,11 @@ pub mod tick;
pub mod default; pub mod default;
pub mod new; pub mod new;
pub mod dump; pub mod dump;
mod control;
use crate::constants::constants_system::SIZE_32KB; use crate::constants::constants_system::SIZE_32KB;
use crate::periph::ram_chip::RamChip; use crate::traits::ram_chip::RamChip;
use crate::periph::rom_chip::RomChip; use crate::traits::rom_chip::RomChip;
use log::debug; use log::debug;
/// Hitachi Semiconductor /// Hitachi Semiconductor
@ -19,13 +20,20 @@ pub struct Hm62256 {
pub(crate) offset: u16, pub(crate) offset: u16,
pub(crate) data: Box<[u8]>, pub(crate) data: Box<[u8]>,
pub(crate) address_bus: u16, 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)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use rand::random; use rand::random;
use crate::traits::memory_chip::MemoryChip;
#[test] #[test]
fn smoke() { fn smoke() {

View File

@ -7,7 +7,10 @@ impl Hm62256 {
offset: base_offset, offset: base_offset,
data: vec![0; SIZE_32KB].into_boxed_slice(), data: vec![0; SIZE_32KB].into_boxed_slice(),
address_bus: 0x0000, address_bus: 0x0000,
data_bus: 0x00 data_bus: 0x00,
cs: false,
oe: false,
we: false
} }
} }
} }

View File

@ -1,6 +1,6 @@
use crate::constants::constants_system::SIZE_32KB; use crate::constants::constants_system::SIZE_32KB;
use crate::periph::hm62256::Hm62256; use crate::periph::hm62256::Hm62256;
use crate::periph::ram_chip::RamChip; use crate::traits::ram_chip::RamChip;
impl RamChip for Hm62256 { impl RamChip for Hm62256 {
fn write(&mut self, offset: &u16, value: &u8) { fn write(&mut self, offset: &u16, value: &u8) {

View File

@ -1,18 +1,19 @@
use log::debug; use log::debug;
use crate::constants::constants_system::SIZE_32KB; use crate::constants::constants_system::SIZE_32KB;
use crate::periph::hm62256::Hm62256; use crate::periph::hm62256::Hm62256;
use crate::periph::rom_chip::RomChip; use crate::traits::memory_chip::MemoryChip;
use crate::traits::rom_chip::RomChip;
impl RomChip for Hm62256 {
impl MemoryChip for Hm62256 {
fn read(&self, offset: &u16) -> u8 { fn read(&self, offset: &u16) -> u8 {
// loops memory around past 32k // loops memory around past 32k
let effective = *offset as i32 % SIZE_32KB as i32; let effective = *offset as i32 % SIZE_32KB as i32;
self.data[effective as usize] self.data[effective as usize]
} }
}
fn program(_: &[u8; SIZE_32KB]) -> Box<Self> { impl RomChip for Hm62256 {
fn program(_: &[u8]) -> Box<Self> {
debug!("Dont program ram."); debug!("Dont program ram.");
Hm62256::default().into() Hm62256::default().into()
} }

View File

@ -1,9 +1,6 @@
pub mod rom_chip;
pub mod at28c256; pub mod at28c256;
pub mod hm62256; pub mod hm62256;
pub mod ram_chip; pub mod mos6520;
pub mod mos6522; pub mod mos6522;
pub mod mos6530; pub mod mos6530;
pub mod kim1_keypad; pub mod kim1_keypad;
mod bus_device;
pub mod backplane;

View File

@ -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<Self> {
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!()
}
}

View File

@ -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;
}
}

View File

@ -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; }
_ => {}
}
}
}

View File

@ -2,3 +2,4 @@ pub mod mos6530;
pub mod tick; pub mod tick;
mod new; mod new;
mod dump; mod dump;
mod viachip;

View File

@ -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<Self> {
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}");
}
}

View File

@ -1,5 +0,0 @@
use crate::periph::rom_chip::RomChip;
pub trait RamChip: RomChip {
fn write(&mut self, offset: &u16, value: &u8);
}

View File

@ -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<Self>;
}

View File

@ -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);
}

View File

@ -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<T: BusDevice> {
fn from_byte(source: u8) -> T;
}

View File

@ -4,5 +4,5 @@ pub trait BusDevice {
fn set_address_bus(&mut self, new_value: u16); fn set_address_bus(&mut self, new_value: u16);
fn set_data_bus(&mut self, new_value: u8); fn set_data_bus(&mut self, new_value: u8);
fn talking_to_me(&self, address: u16) -> bool;
} }

View File

@ -0,0 +1,6 @@
pub trait MemoryChip {
/// Read
///
/// Reads a single byte from the specified address
fn read(&self, offset: &u16) -> u8;
}

View File

@ -1 +1,7 @@
pub mod bus_device; 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;

View File

@ -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);
}

View File

@ -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<Self>;
}

View File

@ -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);
}

View File

@ -0,0 +1,6 @@
use super::*;
#[test]
fn test123() {
}

Binary file not shown.

BIN
resources/docs/6530.pdf Normal file

Binary file not shown.

Binary file not shown.

BIN
resources/docs/w65c22.pdf Normal file

Binary file not shown.