diff --git a/src/main/java/com/loomcom/symon/devices/Acia.java b/src/main/java/com/loomcom/symon/devices/Acia.java index 12dc498..02fe0ea 100644 --- a/src/main/java/com/loomcom/symon/devices/Acia.java +++ b/src/main/java/com/loomcom/symon/devices/Acia.java @@ -33,7 +33,7 @@ import com.loomcom.symon.exceptions.MemoryRangeException; public abstract class Acia extends Device { private String name; - + /** * Register addresses */ @@ -42,13 +42,14 @@ public abstract class Acia extends Device { boolean receiveIrqEnabled = false; boolean transmitIrqEnabled = false; boolean overrun = false; - - long lastTxWrite = 0; + boolean interrupt = false; + + long lastTxWrite = 0; long lastRxRead = 0; int baudRate = 0; long baudRateDelay = 0; - - /** + + /** * Read/Write buffers */ int rxChar = 0; @@ -56,8 +57,8 @@ public abstract class Acia extends Device { boolean rxFull = false; boolean txEmpty = true; - - + + public Acia(int address, int size, String name) throws MemoryRangeException { super(address, address + size - 1, name); this.name = name; @@ -100,7 +101,7 @@ public abstract class Acia extends Device { /** * @return The contents of the status register. */ - public abstract int statusReg(); + public abstract int statusReg(boolean cpuAccess); @Override public String toString() { @@ -117,13 +118,14 @@ public abstract class Acia extends Device { } public synchronized void rxWrite(int data) { - if(rxFull) { + if (rxFull) { overrun = true; } - + rxFull = true; if (receiveIrqEnabled) { + interrupt = true; getBus().assertIrq(); } @@ -132,11 +134,12 @@ public abstract class Acia extends Device { public synchronized int txRead(boolean cpuAccess) { if (cpuAccess) { - txEmpty = true; + txEmpty = true; - if (transmitIrqEnabled) { - getBus().assertIrq(); - } + if (transmitIrqEnabled) { + interrupt = true; + getBus().assertIrq(); + } } return txChar; } diff --git a/src/main/java/com/loomcom/symon/devices/Acia6551.java b/src/main/java/com/loomcom/symon/devices/Acia6551.java index 9586b3c..b6c0b24 100644 --- a/src/main/java/com/loomcom/symon/devices/Acia6551.java +++ b/src/main/java/com/loomcom/symon/devices/Acia6551.java @@ -61,7 +61,7 @@ public class Acia6551 extends Acia { case DATA_REG: return rxRead(cpuAccess); case STAT_REG: - return statusReg(); + return statusReg(cpuAccess); case CMND_REG: return commandRegister; case CTRL_REG: @@ -178,8 +178,8 @@ public class Acia6551 extends Acia { * @return The contents of the status register. */ @Override - public int statusReg() { - // TODO: Parity Error, Framing Error, DTR, DSR, and Interrupt flags. + public int statusReg(boolean cpuAccess) { + // TODO: Parity Error, Framing Error, DTR, and DSR flags. int stat = 0; if (rxFull && System.nanoTime() >= (lastRxRead + baudRateDelay)) { stat |= 0x08; @@ -190,6 +190,14 @@ public class Acia6551 extends Acia { if (overrun) { stat |= 0x04; } + if (interrupt) { + stat |= 0x80; + } + + if (cpuAccess) { + interrupt = false; + } + return stat; } @@ -201,6 +209,7 @@ public class Acia6551 extends Acia { rxFull = false; receiveIrqEnabled = false; transmitIrqEnabled = false; + interrupt = false; } } diff --git a/src/main/java/com/loomcom/symon/devices/Acia6850.java b/src/main/java/com/loomcom/symon/devices/Acia6850.java index f904f94..bd70eed 100644 --- a/src/main/java/com/loomcom/symon/devices/Acia6850.java +++ b/src/main/java/com/loomcom/symon/devices/Acia6850.java @@ -43,7 +43,7 @@ public class Acia6850 extends Acia { static final int STAT_REG = 0; // read-only static final int CTRL_REG = 0; // write-only - + static final int RX_REG = 1; // read-only static final int TX_REG = 1; // write-only @@ -56,9 +56,12 @@ 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(); + return statusReg(cpuAccess); default: throw new MemoryAccessException("No register."); @@ -69,6 +72,9 @@ 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: @@ -78,7 +84,7 @@ public class Acia6850 extends Acia { throw new MemoryAccessException("No register."); } } - + private void setCommandRegister(int data) { // Bits 0 & 1 control the master reset if((data & 0x01) != 0 && (data & 0x02) != 0) { @@ -97,8 +103,8 @@ public class Acia6850 extends Acia { * @return The contents of the status register. */ @Override - public int statusReg() { - // TODO: Parity Error, Framing Error, DTR, DSR, and Interrupt flags. + public int statusReg(boolean cpuAccess) { + // TODO: Parity Error, Framing Error, DTR, and DSR flags. int stat = 0; if (rxFull && System.nanoTime() >= (lastRxRead + baudRateDelay)) { stat |= 0x01; @@ -109,7 +115,10 @@ public class Acia6850 extends Acia { if (overrun) { stat |= 0x20; } - + if (interrupt) { + stat |= 0x80; + } + return stat; } @@ -118,6 +127,7 @@ public class Acia6850 extends Acia { overrun = false; rxFull = false; txEmpty = true; + interrupt = false; } }