adds docs
working on widetick
This commit is contained in:
parent
b40c3c503f
commit
8f6f9cb64d
@ -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
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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--");
|
||||
}
|
||||
@ -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");
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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!()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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!()
|
||||
}
|
||||
}
|
||||
9
core/src/periph/README
Normal file
9
core/src/periph/README
Normal 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)
|
||||
|
||||
@ -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]
|
||||
|
||||
8
core/src/periph/at28c256/control.rs
Normal file
8
core/src/periph/at28c256/control.rs
Normal 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 {}
|
||||
@ -15,6 +15,9 @@ impl Default for At28C256 {
|
||||
data_bus: 0x00,
|
||||
offset: 0x0000,
|
||||
max_offset: 0x3fff,
|
||||
cs: false,
|
||||
oe: false,
|
||||
we: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -10,7 +10,10 @@ impl At28C256 {
|
||||
address_bus: 0x0000,
|
||||
data_bus: 0x00,
|
||||
offset,
|
||||
max_offset
|
||||
max_offset,
|
||||
cs: false,
|
||||
oe: false,
|
||||
we: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<u8> = vec![0xff, 0xff, 0xff, 0xff];
|
||||
chip.program(new_data.into());
|
||||
assert_eq!(0xff, chip.read(&0x0000));
|
||||
assert_eq!(0x00, chip.read(&0x05));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<At28C256> {
|
||||
fn program(new_data: &[u8]) -> Box<At28C256> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
51
core/src/periph/at28c256/signal_tick.rs
Normal file
51
core/src/periph/at28c256/signal_tick.rs
Normal 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));
|
||||
}
|
||||
}
|
||||
@ -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]
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
pub trait BusDevice {
|
||||
fn talking_to_me(&self, address: u16) -> bool;
|
||||
}
|
||||
8
core/src/periph/hm62256/control.rs
Normal file
8
core/src/periph/hm62256/control.rs
Normal 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;
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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<Self> {
|
||||
impl RomChip for Hm62256 {
|
||||
fn program(_: &[u8]) -> Box<Self> {
|
||||
debug!("Dont program ram.");
|
||||
Hm62256::default().into()
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
65
core/src/periph/mos6520/mod.rs
Normal file
65
core/src/periph/mos6520/mod.rs
Normal 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!()
|
||||
}
|
||||
}
|
||||
26
core/src/periph/mos6520/reset.rs
Normal file
26
core/src/periph/mos6520/reset.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
26
core/src/periph/mos6520/tod.rs
Normal file
26
core/src/periph/mos6520/tod.rs
Normal 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; }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,3 +2,4 @@ pub mod mos6530;
|
||||
pub mod tick;
|
||||
mod new;
|
||||
mod dump;
|
||||
mod viachip;
|
||||
52
core/src/periph/mos6530/viachip.rs
Normal file
52
core/src/periph/mos6530/viachip.rs
Normal 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}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
use crate::periph::rom_chip::RomChip;
|
||||
|
||||
pub trait RamChip: RomChip {
|
||||
fn write(&mut self, offset: &u16, value: &u8);
|
||||
}
|
||||
@ -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>;
|
||||
}
|
||||
34
core/src/traits/backplane.rs
Normal file
34
core/src/traits/backplane.rs
Normal 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);
|
||||
}
|
||||
10
core/src/traits/bus_control_byte.rs
Normal file
10
core/src/traits/bus_control_byte.rs
Normal 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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
6
core/src/traits/memory_chip.rs
Normal file
6
core/src/traits/memory_chip.rs
Normal file
@ -0,0 +1,6 @@
|
||||
pub trait MemoryChip {
|
||||
/// Read
|
||||
///
|
||||
/// Reads a single byte from the specified address
|
||||
fn read(&self, offset: &u16) -> u8;
|
||||
}
|
||||
@ -1 +1,7 @@
|
||||
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;
|
||||
|
||||
7
core/src/traits/ram_chip.rs
Normal file
7
core/src/traits/ram_chip.rs
Normal 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);
|
||||
}
|
||||
9
core/src/traits/rom_chip.rs
Normal file
9
core/src/traits/rom_chip.rs
Normal 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>;
|
||||
}
|
||||
15
core/src/traits/via_chip.rs
Normal file
15
core/src/traits/via_chip.rs
Normal 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);
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test123() {
|
||||
|
||||
}
|
||||
BIN
resources/docs/6530-Commodore.pdf
Normal file
BIN
resources/docs/6530-Commodore.pdf
Normal file
Binary file not shown.
BIN
resources/docs/6530.pdf
Normal file
BIN
resources/docs/6530.pdf
Normal file
Binary file not shown.
BIN
resources/docs/rockwell_r6520_pia.pdf
Normal file
BIN
resources/docs/rockwell_r6520_pia.pdf
Normal file
Binary file not shown.
BIN
resources/docs/w65c22.pdf
Normal file
BIN
resources/docs/w65c22.pdf
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user