diff --git a/src/main/java/com/loomcom/symon/devices/Acia6850.java b/src/main/java/com/loomcom/symon/devices/Acia6850.java index 0eb7917..3621887 100644 --- a/src/main/java/com/loomcom/symon/devices/Acia6850.java +++ b/src/main/java/com/loomcom/symon/devices/Acia6850.java @@ -97,9 +97,9 @@ public class Acia6850 extends Acia { } // Bit 7 controls receiver IRQ behavior - receiveIrqEnabled = (commandRegister & 0x80) == 0; + receiveIrqEnabled = (commandRegister & 0x80) != 0; // Bits 5 & 6 controls transmit IRQ behavior - transmitIrqEnabled = (commandRegister & 0x20) == 0 && (commandRegister & 0x40) != 0; + transmitIrqEnabled = (commandRegister & 0x20) != 0 && (commandRegister & 0x40) == 0; } @@ -127,6 +127,8 @@ public class Acia6850 extends Acia { private synchronized void reset() { overrun = false; + rxFull = false; + txEmpty = true; } } diff --git a/src/test/java/com/loomcom/symon/AciaTest6850.java b/src/test/java/com/loomcom/symon/AciaTest6850.java new file mode 100644 index 0000000..487bf53 --- /dev/null +++ b/src/test/java/com/loomcom/symon/AciaTest6850.java @@ -0,0 +1,145 @@ +package com.loomcom.symon; + +import com.loomcom.symon.devices.Acia; +import com.loomcom.symon.devices.Acia6850; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class AciaTest6850 { + + private final static int CMD_STAT_REG = 0; + private final static int DATA_REG = 1; + + + private Acia newAcia() throws Exception { + Acia acia = new Acia6850(0x0000); + // by default rate is limited, have it unlimited for testing + acia.setBaudRate(0); + return acia; + } + + + @Test + public void shouldTriggerInterruptOnRxFullIfRxIrqEnabled() throws Exception { + Bus mockBus = mock(Bus.class); + + Acia acia = newAcia(); + acia.setBus(mockBus); + + // Disable TX IRQ, Enable RX IRQ + acia.write(CMD_STAT_REG, 0x80); + + acia.rxWrite('a'); + + verify(mockBus, atLeastOnce()).assertIrq(); + } + + @Test + public void shouldNotTriggerInterruptOnRxFullIfRxIrqNotEnabled() throws Exception { + Bus mockBus = mock(Bus.class); + + Acia acia = newAcia(); + acia.setBus(mockBus); + + // Disable TX IRQ, Disable RX IRQ + acia.write(CMD_STAT_REG, 0x00); + + acia.rxWrite('a'); + + verify(mockBus, never()).assertIrq(); + } + + @Test + public void shouldTriggerInterruptOnTxEmptyIfTxIrqEnabled() throws Exception { + Bus mockBus = mock(Bus.class); + + Acia acia = newAcia(); + acia.setBus(mockBus); + + // Enable TX IRQ, Disable RX IRQ + acia.write(CMD_STAT_REG, 0x20); + + // Write data + acia.write(1, 'a'); + + verify(mockBus, never()).assertIrq(); + + // Transmission should cause IRQ + acia.txRead(); + + verify(mockBus, atLeastOnce()).assertIrq(); + } + + @Test + public void shouldNotTriggerInterruptOnTxEmptyIfTxIrqNotEnabled() throws Exception { + Bus mockBus = mock(Bus.class); + + Acia acia = newAcia(); + acia.setBus(mockBus); + + // Disable TX IRQ, Disable RX IRQ + acia.write(CMD_STAT_REG, 0x02); + + // Write data + acia.write(DATA_REG, 'a'); + + // Transmission should cause IRQ + acia.txRead(); + + verify(mockBus, never()).assertIrq(); + } + + @Test + public void newAciaShouldHaveTxEmptyStatus() throws Exception { + Acia acia = newAcia(); + + assertEquals(0x02, acia.read(CMD_STAT_REG) & 0x02); + } + + @Test + public void aciaShouldHaveTxEmptyStatusOffIfTxHasData() throws Exception { + Acia acia = newAcia(); + + acia.txWrite('a'); + assertEquals(0x00, acia.read(CMD_STAT_REG) & 0x02); + } + + @Test + public void aciaShouldHaveRxFullStatusOnIfRxHasData() throws Exception { + Acia acia = newAcia(); + + acia.rxWrite('a'); + + assertEquals(0x01, acia.read(CMD_STAT_REG) & 0x01); + } + + @Test + public void aciaShouldHaveTxEmptyAndRxFullStatusOffIfRxAndTxHaveData() + throws Exception { + Acia acia = newAcia(); + + acia.rxWrite('a'); + acia.txWrite('b'); + + assertEquals(0x01, acia.read(CMD_STAT_REG) & 0x03); + } + + @Test + public void readingBuffersShouldResetStatus() + throws Exception { + Acia acia = newAcia(); + + assertEquals(0x00, acia.read(CMD_STAT_REG) & 0x01); + + acia.rxWrite('a'); + + assertEquals(0x01, acia.read(CMD_STAT_REG) & 0x01); + + acia.rxRead(); + + assertEquals(0x00, acia.read(CMD_STAT_REG) & 0x01); + + } +}