Merge pull request #18 from izuannazrin/master

Interrupt bit support for ACIA
This commit is contained in:
Seth Morabito authored and GitHub committed 2017-06-04 18:53:44 -07:00
commit 3c3aee30a7
3 files changed
+45 -23

No files matched your search

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