mirror of
https://github.com/sethm/symon.git
synced 2025-04-21 06:37:08 +00:00
* Add ACIA Interrupt tests.
* Fix ACIA6850 Interrupt behavior, Interrupt should be cleared on status register read. * Remove unneeded cpuAccess if statement from Acia6850 write that was preventing build completion * Fix ACIA6850 Tests so they run.
This commit is contained in:
parent
3c3aee30a7
commit
faf5d22660
@ -30,8 +30,8 @@ import com.loomcom.symon.exceptions.MemoryRangeException;
|
||||
|
||||
/**
|
||||
* This is a simulation of the Motorola 6850 ACIA, with limited
|
||||
* functionality. Interrupts are not supported.
|
||||
* <p/>
|
||||
* functionality.
|
||||
*
|
||||
* Unlike a 16550 UART, the 6850 ACIA has only one-byte transmit and
|
||||
* receive buffers. It is the programmer's responsibility to check the
|
||||
* status (full or empty) for transmit and receive buffers before
|
||||
@ -56,9 +56,6 @@ public class Acia6850 extends Acia {
|
||||
public int read(int address, boolean cpuAccess) throws MemoryAccessException {
|
||||
switch (address) {
|
||||
case RX_REG:
|
||||
if (cpuAccess) {
|
||||
interrupt = false;
|
||||
}
|
||||
return rxRead(cpuAccess);
|
||||
case STAT_REG:
|
||||
return statusReg(cpuAccess);
|
||||
@ -72,9 +69,6 @@ public class Acia6850 extends Acia {
|
||||
public void write(int address, int data) throws MemoryAccessException {
|
||||
switch (address) {
|
||||
case TX_REG:
|
||||
if (cpuAccess) {
|
||||
interrupt = false;
|
||||
}
|
||||
txWrite(data);
|
||||
break;
|
||||
case CTRL_REG:
|
||||
@ -119,6 +113,10 @@ public class Acia6850 extends Acia {
|
||||
stat |= 0x80;
|
||||
}
|
||||
|
||||
if (cpuAccess) {
|
||||
interrupt = false;
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class AciaTest6850 {
|
||||
public class Acia6850Test {
|
||||
|
||||
private final static int CMD_STAT_REG = 0;
|
||||
private final static int DATA_REG = 1;
|
||||
@ -91,6 +91,78 @@ public class AciaTest6850 {
|
||||
verify(mockBus, never()).assertIrq();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldTriggerInterruptFlagOnRxFullIfRxIrqEnabled() 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');
|
||||
|
||||
// Receive should cause IRQ flag to be set
|
||||
assertEquals(0x80, acia.read(0x0000, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotTriggerInterruptFlagOnRxFullIfRxIrqNotEnabled() 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');
|
||||
|
||||
// Receive should not cause IRQ flag to be set
|
||||
assertEquals(0x00, acia.read(0x0000, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldTriggerInterruptFlagOnTxEmptyIfTxIrqEnabled() 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 flag to be set
|
||||
acia.txRead(true);
|
||||
|
||||
assertEquals(0x80, acia.read(0x0000, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotTriggerInterruptFlagOnTxEmptyIfTxIrqNotEnabled() 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 not cause IRQ flag to be set
|
||||
acia.txRead(true);
|
||||
|
||||
assertEquals(0x00, acia.read(0x0000, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newAciaShouldHaveTxEmptyStatus() throws Exception {
|
||||
Acia acia = newAcia();
|
||||
@ -129,6 +201,24 @@ public class AciaTest6850 {
|
||||
@Test
|
||||
public void aciaShouldOverrunAndReadShouldReset()
|
||||
throws Exception {
|
||||
|
||||
Acia acia = newAcia();
|
||||
|
||||
// overrun ACIA
|
||||
acia.rxWrite('a');
|
||||
acia.rxWrite('b');
|
||||
|
||||
assertEquals(0x20, acia.read(CMD_STAT_REG, true) & 0x20);
|
||||
|
||||
// read should reset
|
||||
acia.rxRead(true);
|
||||
assertEquals(0x00, acia.read(CMD_STAT_REG, true) & 0x20);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aciaShouldOverrunAndMemoryWindowReadShouldNotReset()
|
||||
throws Exception {
|
||||
|
||||
Acia acia = newAcia();
|
||||
|
||||
@ -138,9 +228,9 @@ public class AciaTest6850 {
|
||||
|
||||
assertEquals(0x20, acia.read(CMD_STAT_REG, true) & 0x20);
|
||||
|
||||
// read should reset
|
||||
acia.rxRead(true);
|
||||
assertEquals(0x00, acia.read(CMD_STAT_REG, true) & 0x20);
|
||||
// memory window read should not reset
|
||||
acia.rxRead(false);
|
||||
assertEquals(0x20, acia.read(CMD_STAT_REG, true) & 0x20);
|
||||
|
||||
}
|
||||
|
@ -73,12 +73,84 @@ public class AciaTest {
|
||||
// Write data
|
||||
acia.write(0, 'a');
|
||||
|
||||
// Transmission should cause IRQ
|
||||
// Transmission should not cause IRQ
|
||||
acia.txRead(true);
|
||||
|
||||
verify(mockBus, never()).assertIrq();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldTriggerInterruptFlagOnRxFullIfRxIrqEnabled() throws Exception {
|
||||
Bus mockBus = mock(Bus.class);
|
||||
|
||||
Acia acia = new Acia6551(0x000);
|
||||
acia.setBus(mockBus);
|
||||
|
||||
// Disable TX IRQ, Enable RX IRQ
|
||||
acia.write(2, 0x00);
|
||||
|
||||
acia.rxWrite('a');
|
||||
|
||||
// Receive should cause IRQ flag to be set
|
||||
assertEquals(0x80, acia.read(0x0001, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotTriggerInterruptFlagOnRxFullIfRxIrqNotEnabled() throws Exception {
|
||||
Bus mockBus = mock(Bus.class);
|
||||
|
||||
Acia acia = new Acia6551(0x000);
|
||||
acia.setBus(mockBus);
|
||||
|
||||
// Disable TX IRQ, Disable RX IRQ
|
||||
acia.write(2, 0x02);
|
||||
|
||||
acia.rxWrite('a');
|
||||
|
||||
// Receive should not cause IRQ flag to be set
|
||||
assertEquals(0x00, acia.read(0x0001, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldTriggerInterruptFlagOnTxEmptyIfTxIrqEnabled() throws Exception {
|
||||
Bus mockBus = mock(Bus.class);
|
||||
|
||||
Acia acia = new Acia6551(0x000);
|
||||
acia.setBus(mockBus);
|
||||
|
||||
// Enable TX IRQ, Disable RX IRQ
|
||||
acia.write(2, 0x06);
|
||||
|
||||
// Write data
|
||||
acia.write(0, 'a');
|
||||
|
||||
verify(mockBus, never()).assertIrq();
|
||||
|
||||
// Transmission should cause IRQ flag to be set
|
||||
acia.txRead(true);
|
||||
|
||||
assertEquals(0x80, acia.read(0x0001, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotTriggerInterruptFlagOnTxEmptyIfTxIrqNotEnabled() throws Exception {
|
||||
Bus mockBus = mock(Bus.class);
|
||||
|
||||
Acia acia = new Acia6551(0x000);
|
||||
acia.setBus(mockBus);
|
||||
|
||||
// Disable TX IRQ, Disable RX IRQ
|
||||
acia.write(2, 0x02);
|
||||
|
||||
// Write data
|
||||
acia.write(0, 'a');
|
||||
|
||||
// Transmission should not cause IRQ flag to be set
|
||||
acia.txRead(true);
|
||||
|
||||
assertEquals(0x00, acia.read(0x0001, true) & 0x80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newAciaShouldHaveTxEmptyStatus() throws Exception {
|
||||
Acia acia = new Acia6551(0x000);
|
||||
|
Loading…
x
Reference in New Issue
Block a user