boxswap
This commit is contained in:
@@ -5,106 +5,47 @@ use crate::constants::constants_via6522::*;
|
||||
#[derive(Default)]
|
||||
pub struct Mos6522 {
|
||||
/// data direction
|
||||
dda: u8,
|
||||
ddb: u8,
|
||||
pub(crate) dda: u8,
|
||||
pub(crate) ddb: u8,
|
||||
|
||||
/// bottom 4 address bits
|
||||
rs0: u8,
|
||||
rs1: u8,
|
||||
rs2: u8,
|
||||
rs3: u8,
|
||||
pub(crate) rs0: u8,
|
||||
pub(crate) rs1: u8,
|
||||
pub(crate) rs2: u8,
|
||||
pub(crate) rs3: u8,
|
||||
|
||||
/// external data bus
|
||||
data_bus: u8,
|
||||
pub(crate) data_bus: u8,
|
||||
|
||||
cs1: bool,
|
||||
cs2: bool,
|
||||
rw: bool,
|
||||
pub(crate) cs1: bool,
|
||||
pub(crate) cs2: bool,
|
||||
// when true CPU is reading
|
||||
pub(crate) rw: bool,
|
||||
|
||||
/// reset circuit - true when reset inited
|
||||
reset: bool,
|
||||
pub(crate) reset: bool,
|
||||
|
||||
/// IRQ - true when interrupt waiting
|
||||
irq: bool,
|
||||
pub(crate) irq: bool,
|
||||
|
||||
ira: u8,
|
||||
ora: u8,
|
||||
porta: u8,
|
||||
irb: u8,
|
||||
orb: u8,
|
||||
portb: u8,
|
||||
pub(crate) ira: u8,
|
||||
pub(crate) ora: u8,
|
||||
pub(crate) porta: u8,
|
||||
pub(crate) irb: u8,
|
||||
pub(crate) orb: u8,
|
||||
pub(crate) portb: u8,
|
||||
|
||||
ca1: bool,
|
||||
ca2: bool,
|
||||
cb1: bool,
|
||||
cb2: bool,
|
||||
pub(crate) ca1: bool,
|
||||
pub(crate) ca2: bool,
|
||||
pub(crate) cb1: bool,
|
||||
pub(crate) cb2: bool,
|
||||
|
||||
// memory offset for where in the computers memory map this fits
|
||||
pub(crate) offset: u16,
|
||||
pub(crate) address_bus: u16,
|
||||
}
|
||||
|
||||
impl Mos6522 {
|
||||
pub fn new() -> Self {
|
||||
Mos6522::default()
|
||||
}
|
||||
|
||||
/// tick
|
||||
///
|
||||
/// data_bus -> 8 bits from the data bus
|
||||
/// control -> 4 bits to identify which register to control
|
||||
pub fn tick(&mut self, data_bus: u8, control: u8, rw: bool) -> (u8) {
|
||||
println!("Mos6522 Tick Start -> 0x{data_bus:02x} / 0x{control:02x} / {rw}");
|
||||
if rw {
|
||||
// RW true = CPU is writing
|
||||
self.data_bus = data_bus;
|
||||
match control {
|
||||
VIA6522_DDRA => {
|
||||
debug!("Setting DDA to 0x{data_bus:02x}");
|
||||
// setting the Data Direction for Port A
|
||||
self.dda = data_bus;
|
||||
},
|
||||
VIA6522_DDRB => {
|
||||
debug!("Setting DDB to 0x{data_bus:02x}");
|
||||
// setting the data direction for port b
|
||||
self.ddb = data_bus;
|
||||
},
|
||||
VIA6522_ORB => {
|
||||
// writing data to ORB
|
||||
let masked_data = data_bus & self.ddb;
|
||||
debug!("Setting ORB to 0x{data_bus:02x} / masked at 0x{masked_data:02x}");
|
||||
self.portb = masked_data;
|
||||
},
|
||||
VIA6522_ORA => {
|
||||
// writing data to ORA
|
||||
let masked_data = data_bus & self.dda;
|
||||
debug!("Setting ORA to 0x{data_bus:02x} / masked at 0x{masked_data:02x}");
|
||||
self.porta = masked_data;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
// RW false = CPU is reading
|
||||
self.data_bus = match control {
|
||||
VIA6522_DDRA => {
|
||||
self.dda
|
||||
}
|
||||
VIA6522_DDRB => {
|
||||
self.ddb
|
||||
}
|
||||
VIA6522_ORA => {
|
||||
self.porta & self.dda
|
||||
}
|
||||
VIA6522_ORB => {
|
||||
self.portb & self.ddb
|
||||
}
|
||||
_ => {
|
||||
debug!("VIA got request for b{:08b} / 0x{:02x}", control, control);
|
||||
// do nothing. bad address for VIA
|
||||
self.data_bus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(self.data_bus)
|
||||
}
|
||||
|
||||
pub fn start_clocks(&mut self) {
|
||||
loop {
|
||||
let cycle_start = Instant::now();
|
||||
@@ -115,7 +56,6 @@ impl Mos6522 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
@@ -126,40 +66,40 @@ mod test {
|
||||
#[test]
|
||||
fn registers() {
|
||||
let mut x = Mos6522::new();
|
||||
x.tick(0b0000_0000, VIA6522_DDRA, true);
|
||||
x.tick(0b0000_0000, VIA6522_DDRA, false, true);
|
||||
assert_eq!(x.dda, 0b0000_0000);
|
||||
x.tick(0b1111_1111, VIA6522_DDRA, true);
|
||||
x.tick(0b1111_1111, VIA6522_DDRA, false, true);
|
||||
assert_eq!(x.dda, 0b1111_1111);
|
||||
|
||||
x.tick(0b0000_0000, VIA6522_DDRB, true);
|
||||
x.tick(0b0000_0000, VIA6522_DDRB, false, true);
|
||||
assert_eq!(x.ddb, 0b0000_0000);
|
||||
x.tick(0b1111_1111, VIA6522_DDRB, true);
|
||||
x.tick(0b1111_1111, VIA6522_DDRB, false, true);
|
||||
assert_eq!(x.ddb, 0b1111_1111);
|
||||
|
||||
x.tick(0b0000_0000, VIA6522_ORA, true);
|
||||
x.tick(0b0000_0000, VIA6522_ORA, false, true);
|
||||
assert_eq!(x.porta, 0b0000_0000);
|
||||
x.tick(0b1111_1111, VIA6522_ORA, true);
|
||||
x.tick(0b1111_1111, VIA6522_ORA, false, true);
|
||||
assert_eq!(x.porta, 0b1111_1111);
|
||||
|
||||
x.tick(0b0000_0000, VIA6522_ORB, true);
|
||||
x.tick(0b0000_0000, VIA6522_ORB, false, true);
|
||||
assert_eq!(x.portb, 0b0000_0000);
|
||||
x.tick(0b1111_1111, VIA6522_ORB, true);
|
||||
x.tick(0b1111_1111, VIA6522_ORB, false, true);
|
||||
assert_eq!(x.portb, 0b1111_1111);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partial_output_porta() {
|
||||
let mut x = Mos6522::new();
|
||||
x.tick(0b1010_1010, VIA6522_DDRA, true);
|
||||
x.tick(0b1111_1111, VIA6522_ORA, true);
|
||||
x.tick(0b1010_1010, VIA6522_DDRA, false, true);
|
||||
x.tick(0b1111_1111, VIA6522_ORA, false, true);
|
||||
assert_eq!(x.porta, 0b1010_1010);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partial_output_portb() {
|
||||
let mut x = Mos6522::new();
|
||||
x.tick(0b0101_0101, VIA6522_DDRB, true);
|
||||
x.tick(0b1111_1111, VIA6522_ORB, true);
|
||||
x.tick(0b0101_0101, VIA6522_DDRB, false, true);
|
||||
x.tick(0b1111_1111, VIA6522_ORB, false, true);
|
||||
assert_eq!(x.portb, 0b0101_0101);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user