Skip to content

Commit

Permalink
Allow disconnecting reset line from PIA/CIA/VIA
Browse files Browse the repository at this point in the history
  • Loading branch information
breqdev committed Apr 27, 2024
1 parent 1ac18f9 commit ce03a82
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 27 deletions.
47 changes: 39 additions & 8 deletions src/memory/mos652x/cia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ pub struct Cia {
time_clock: TimeClock,
shift_register: ShiftRegister,
interrupts: InterruptRegister,
interrupt_connected: bool,
}

impl Cia {
pub fn new(port_a: Box<dyn Port>, port_b: Box<dyn Port>) -> Self {
pub fn new(port_a: Box<dyn Port>, port_b: Box<dyn Port>, interrupt_connected: bool) -> Self {
Self {
a: PortRegisters::new(port_a),
b: PortRegisters::new(port_b),
Expand All @@ -86,6 +87,7 @@ impl Cia {
time_clock: TimeClock::new(),
shift_register: ShiftRegister::new(),
interrupts: InterruptRegister::new(),
interrupt_connected,
}
}
}
Expand Down Expand Up @@ -228,7 +230,11 @@ impl Memory for Cia {

// TODO: stuff based on ca1, ca2, cb1, cb2

active_interrupt
if self.interrupt_connected {
active_interrupt
} else {
ActiveInterrupt::None
}
}
}

Expand All @@ -240,7 +246,7 @@ mod tests {

#[test]
fn test_read_write() {
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// writes without DDR shouldn't be reflected in reads
cia.write(0x00, 0b10101010);
Expand All @@ -266,7 +272,7 @@ mod tests {

#[test]
fn test_timer_a() {
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer A interrupts
cia.write(0x0D, interrupt_bits::MASTER | interrupt_bits::TIMER_A);
Expand All @@ -290,9 +296,34 @@ mod tests {
}
}

#[test]
fn test_interrupt_disconnected() {
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), false);

// enable timer A interrupts
cia.write(0x0D, interrupt_bits::MASTER | interrupt_bits::TIMER_A);

// set the timer to count down from 0x10
cia.write(0x04, 0x10);
cia.write(0x05, 0x00);

// start the timer, and disable continuous operation
cia.write(0x0E, 0b0000_1001);

for _ in 0..0x0F {
assert_eq!(ActiveInterrupt::None, cia.poll(1, 0));
}

assert_eq!(ActiveInterrupt::None, cia.poll(1, 0));

for _ in 0..0x20 {
assert_eq!(ActiveInterrupt::None, cia.poll(1, 0));
}
}

#[test]
fn test_timer_b() {
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer B interrupts
cia.write(0x0D, interrupt_bits::MASTER | interrupt_bits::TIMER_B);
Expand All @@ -313,7 +344,7 @@ mod tests {

#[test]
fn test_timer_a_continuous() {
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer A interrupts
cia.write(0x0D, interrupt_bits::MASTER | interrupt_bits::TIMER_A);
Expand All @@ -336,7 +367,7 @@ mod tests {

#[test]
fn test_ier_timers() {
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer 1 interrupts
cia.write(0x0D, interrupt_bits::MASTER | interrupt_bits::TIMER_A);
Expand All @@ -363,7 +394,7 @@ mod tests {

#[test]
fn test_interrupt_flags() {
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut cia = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer 1 interrupts
cia.write(0x0D, interrupt_bits::MASTER | interrupt_bits::TIMER_A);
Expand Down
10 changes: 6 additions & 4 deletions src/memory/mos652x/pia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,16 @@ pub mod pia_control_bits {
pub struct Pia {
a: PiaPortRegisters,
b: PiaPortRegisters,
interrupt_connected: bool,
}

impl Pia {
/// Create a new PIA with the two given port implementations.
pub fn new(a: Box<dyn Port>, b: Box<dyn Port>) -> Self {
pub fn new(a: Box<dyn Port>, b: Box<dyn Port>, interrupt_connected: bool) -> Self {
Self {
a: PiaPortRegisters::new(a),
b: PiaPortRegisters::new(b),
interrupt_connected,
}
}
}
Expand Down Expand Up @@ -170,7 +172,7 @@ impl Memory for Pia {
let a = self.a.poll(cycles_since_poll, total_cycle_count);
let b = self.b.poll(cycles_since_poll, total_cycle_count);

if a || b {
if self.interrupt_connected && (a || b) {

Check warning on line 175 in src/memory/mos652x/pia.rs

View check run for this annotation

Codecov / codecov/patch

src/memory/mos652x/pia.rs#L175

Added line #L175 was not covered by tests
ActiveInterrupt::IRQ
} else {
ActiveInterrupt::None
Expand All @@ -186,7 +188,7 @@ mod tests {

#[test]
fn test_read() {
let mut pia = Pia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut pia = Pia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// deselect the DDR
pia.write(0x01, pia_control_bits::DDR_SELECT);
Expand All @@ -210,7 +212,7 @@ mod tests {

#[test]
fn test_write() {
let mut pia = Pia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut pia = Pia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// deselect the DDR
pia.write(0x01, pia_control_bits::DDR_SELECT);
Expand Down
42 changes: 33 additions & 9 deletions src/memory/mos652x/via.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub struct Via {
sr: ShiftRegister,
interrupts: InterruptRegister,
pcr: u8, // peripheral control register
interrupt_connected: bool,
}

#[allow(dead_code)]
Expand All @@ -61,7 +62,7 @@ pub mod interrupt_bits {
}

impl Via {
pub fn new(a: Box<dyn Port>, b: Box<dyn Port>) -> Self {
pub fn new(a: Box<dyn Port>, b: Box<dyn Port>, interrupt_connected: bool) -> Self {
Self {
a: PortRegisters::new(a),
b: PortRegisters::new(b),
Expand All @@ -70,6 +71,7 @@ impl Via {
sr: ShiftRegister::new(),
interrupts: InterruptRegister::new(),
pcr: 0,
interrupt_connected,
}
}
}
Expand Down Expand Up @@ -250,7 +252,11 @@ impl Memory for Via {
}

Check warning on line 252 in src/memory/mos652x/via.rs

View check run for this annotation

Codecov / codecov/patch

src/memory/mos652x/via.rs#L248-L252

Added lines #L248 - L252 were not covered by tests
}

active_interrupt
if self.interrupt_connected {
active_interrupt
} else {
ActiveInterrupt::None
}
}
}

Expand All @@ -262,7 +268,7 @@ mod tests {

#[test]
fn test_read_write() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// writes without DDR shouldn't be reflected in reads
via.write(0x00, 0b10101010);
Expand All @@ -288,7 +294,7 @@ mod tests {

#[test]
fn test_timer_1() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer 1 interrupts
via.write(0x0e, interrupt_bits::MASTER | interrupt_bits::T1);
Expand All @@ -311,7 +317,7 @@ mod tests {

#[test]
fn test_timer_2() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer 2 interrupts
via.write(0x0e, interrupt_bits::MASTER | interrupt_bits::T2);
Expand All @@ -334,7 +340,7 @@ mod tests {

#[test]
fn test_t1_continuous() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer 1 interrupts
via.write(0x0e, interrupt_bits::MASTER | interrupt_bits::T1);
Expand All @@ -361,7 +367,7 @@ mod tests {

#[test]
fn test_ier_register() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// put something in the register
via.write(
Expand Down Expand Up @@ -389,7 +395,7 @@ mod tests {

#[test]
fn test_ier_timers() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer 1 interrupts
via.write(0x0e, interrupt_bits::MASTER | interrupt_bits::T1);
Expand All @@ -410,9 +416,27 @@ mod tests {
assert_eq!(ActiveInterrupt::IRQ, via.poll(1, 0));
}

#[test]
fn test_interrupt_disconnected() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), false);

// enable timer 1 interrupts
via.write(0x0e, interrupt_bits::MASTER | interrupt_bits::T1);

// set timer 1 to count down from 0x10
via.write(0x04, 0x10);
via.write(0x05, 0x00);
// timer 1 should interrupt first
for _ in 0..0x0F {
assert_eq!(ActiveInterrupt::None, via.poll(1, 0));
}

assert_eq!(ActiveInterrupt::None, via.poll(1, 0));
}

#[test]
fn test_ifr() {
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let mut via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

// enable timer 1 interrupts
via.write(0x0e, interrupt_bits::MASTER | interrupt_bits::T1);
Expand Down
3 changes: 2 additions & 1 deletion src/systems/c64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,10 @@ impl BuildableSystem<C64SystemRoms, C64SystemConfig> for C64System {
config.mapping,
platform.clone(),
)),
true,

Check warning on line 266 in src/systems/c64/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/systems/c64/mod.rs#L266

Added line #L266 was not covered by tests
);

let cia_2 = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let cia_2 = Cia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

Check warning on line 269 in src/systems/c64/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/systems/c64/mod.rs#L269

Added line #L269 was not covered by tests

let region6 = BankedMemory::new(selector6.clone())
.bank(
Expand Down
6 changes: 3 additions & 3 deletions src/systems/pet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,9 @@ impl BuildableSystem<PetSystemRoms, PetSystemConfig> for PetSystem {

let port_a = PetPia1PortA::new();
let port_b = PetPia1PortB::new(port_a.get_keyboard_row(), config.mapping, platform);
let pia1 = Pia::new(Box::new(port_a), Box::new(port_b));
let pia2 = Pia::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()));
let pia1 = Pia::new(Box::new(port_a), Box::new(port_b), true);
let pia2 = Pia::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);
let via = Via::new(Box::new(NullPort::new()), Box::new(NullPort::new()), true);

Check warning on line 185 in src/systems/pet/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/systems/pet/mod.rs#L183-L185

Added lines #L183 - L185 were not covered by tests

let kernel_rom = BlockMemory::from_file(0x1000, roms.kernal);

Expand Down
4 changes: 2 additions & 2 deletions src/systems/vic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ impl BuildableSystem<Vic20SystemRoms, Vic20SystemConfig> for Vic20System {
let v2b = VicVia2PortB::new(v1a.get_joy_pin_3());
let v2a = VicVia2PortA::new(v2b.get_keyboard_col(), config.mapping, platform);

let via1 = Via::new(Box::new(v1a), Box::new(NullPort::new()));
let via2 = Via::new(Box::new(v2a), Box::new(v2b));
let via1 = Via::new(Box::new(v1a), Box::new(NullPort::new()), true);
let via2 = Via::new(Box::new(v2a), Box::new(v2b), true);

Check warning on line 274 in src/systems/vic/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/systems/vic/mod.rs#L273-L274

Added lines #L273 - L274 were not covered by tests

let basic_rom = BlockMemory::from_file(0x2000, roms.basic);
let kernel_rom = BlockMemory::from_file(0x2000, roms.kernal);
Expand Down

0 comments on commit ce03a82

Please sign in to comment.