mod bus_device;
mod new;

use log::debug;
use crate::traits::backplane::Backplane;
use crate::traits::bus_device::BusDevice;

pub struct Mos6532 {
    // R
    ram: Box<[u8; 64]>,
    // IO
    ddra: u8,
    porta: u8,
    in_a: u8,
    out_a: u8,
    ddrb: u8,
    portb: u8,
    in_b: u8,
    out_b: u8,
    // T

    // Generic 6502 stuff
    read_mode: bool,
    data_bus: u8,
    address_bus: u16,

    // Part Specific
    ram_offset: u16,
    io_offset: u16,
}

const MOS6532_DDRA_OFFSET: u8 = 0x00;
const MOS6532_DDRB_OFFSET: u8 = 0x02;
const MOS6532_PRTA_OFFSET: u8 = 0x01;
const MOS6532_PRTB_OFFSET: u8 = 0x03;

impl Mos6532 {
    fn targets_ram(&self, offset: u16) -> bool {
        // we are at or above the offset AND we are under the end of ram
        offset >= self.ram_offset && offset <= self.ram_offset + 64
    }

    fn targets_io(&self, offset: u16) -> bool {
        offset >= self.io_offset && offset <= self.io_offset + 4
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn targetting_parts() {
        // RAM from 0x0000 -> 0x0040
        // IO  from 0x1000 -> 0x1004
        let via = Mos6532::new(0x0000, 0x1000);

        assert!(via.targets_io(0x1000));
        assert!(!via.targets_ram(0x1000));

        assert!(!via.targets_io(0x0000));
        assert!(via.targets_ram(0x0000));

        assert!(!via.targets_io(0x4000));
        assert!(!via.targets_ram(0x4000));
    }
}
