2025-07-16 15:01:16 -04:00

110 lines
2.8 KiB
Rust

use std::time::Instant;
use log::debug;
use crate::constants::constants_via6522::*;
#[derive(Default)]
pub struct Mos6522 {
/// data direction
pub(crate) dda: u8,
pub(crate) ddb: u8,
/// bottom 4 address bits
pub(crate) rs0: u8,
pub(crate) rs1: u8,
pub(crate) rs2: u8,
pub(crate) rs3: u8,
/// external data bus
pub(crate) data_bus: u8,
pub(crate) cs1: bool,
pub(crate) cs2: bool,
// when true CPU is reading
pub(crate) rw: bool,
/// reset circuit - true when reset inited
pub(crate) reset: bool,
/// IRQ - true when interrupt waiting
pub(crate) irq: bool,
pub(crate) ira: u8,
pub(crate) ora: u8,
pub(crate) porta: u8,
pub(crate) irb: u8,
pub(crate) orb: u8,
pub(crate) portb: u8,
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 max_offset(&self) -> u16 {
self.offset + 0x10
}
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(VIA6522_DDRA as u16, 0b0000_0000, false, true);
assert_eq!(x.dda, 0b0000_0000);
x.tick(VIA6522_DDRA as u16, 0b1111_1111, false, true);
assert_eq!(x.dda, 0b1111_1111);
x.tick(VIA6522_DDRB as u16, 0b0000_0000, false, true);
assert_eq!(x.ddb, 0b0000_0000);
x.tick(VIA6522_DDRB as u16, 0b1111_1111, false, true);
assert_eq!(x.ddb, 0b1111_1111);
x.tick(VIA6522_ORA as u16, 0b0000_0000, false, true);
assert_eq!(x.ora, 0b0000_0000);
x.tick(VIA6522_ORA as u16, 0b1111_1111, false, true);
assert_eq!(x.ora, 0b1111_1111);
x.tick(VIA6522_ORB as u16, 0b0000_0000, false, true);
assert_eq!(x.orb, 0b0000_0000);
x.tick(VIA6522_ORB as u16, 0b1111_1111, false, true);
assert_eq!(x.orb, 0b1111_1111);
}
#[test]
fn partial_output_porta() {
let mut x = Mos6522::new();
x.tick(VIA6522_DDRA as u16, 0b1010_1010, false, true);
x.tick(VIA6522_ORA as u16,0b1111_1111, false, true);
assert_eq!(x.porta, 0b1010_1010);
}
#[test]
fn partial_output_portb() {
let mut x = Mos6522::new();
x.tick(VIA6522_DDRB as u16, 0b0101_0101, false, true);
x.tick(VIA6522_ORB as u16, 0b1111_1111, false, true);
assert_eq!(x.portb, 0b0101_0101);
}
}