writes bins better now

This commit is contained in:
2025-07-07 16:28:13 -04:00
parent 9c672741ed
commit 8c08555003
29 changed files with 1381 additions and 108 deletions
+165
View File
@@ -0,0 +1,165 @@
use std::time::Instant;
use log::debug;
use crate::constants::constants_via6522::*;
#[derive(Default)]
pub struct Mos6522 {
/// data direction
dda: u8,
ddb: u8,
/// bottom 4 address bits
rs0: u8,
rs1: u8,
rs2: u8,
rs3: u8,
/// external data bus
data_bus: u8,
cs1: bool,
cs2: bool,
rw: bool,
/// reset circuit - true when reset inited
reset: bool,
/// IRQ - true when interrupt waiting
irq: bool,
ira: u8,
ora: u8,
porta: u8,
irb: u8,
orb: u8,
portb: u8,
ca1: bool,
ca2: bool,
cb1: bool,
cb2: bool,
}
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();
// let duration = cycle_start.duration_since(self.clock);
// set the time to the new time.
// self.clock = cycle_start;
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn smoke() { assert!(true); }
#[test]
fn registers() {
let mut x = Mos6522::new();
x.tick(0b0000_0000, VIA6522_DDRA, true);
assert_eq!(x.dda, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_DDRA, true);
assert_eq!(x.dda, 0b1111_1111);
x.tick(0b0000_0000, VIA6522_DDRB, true);
assert_eq!(x.ddb, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_DDRB, true);
assert_eq!(x.ddb, 0b1111_1111);
x.tick(0b0000_0000, VIA6522_ORA, true);
assert_eq!(x.porta, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_ORA, true);
assert_eq!(x.porta, 0b1111_1111);
x.tick(0b0000_0000, VIA6522_ORB, true);
assert_eq!(x.portb, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_ORB, 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);
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);
assert_eq!(x.portb, 0b0101_0101);
}
}