Added interrupt support for ACIA
+ Added interrupt support for ACIA + Auto-formatting (in case anyone cares)
This commit is contained in:
1 parent
2e33756d49
commit
f2ced29979
3 files changed
+43
-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 statusReg);
|
||||||
|
|
||||||
@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
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ public class Acia6850 extends Acia {
|
|||||||
case RX_REG:
|
case RX_REG:
|
||||||
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.");
|
||||||
@@ -78,7 +78,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 +97,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 +109,14 @@ public class Acia6850 extends Acia {
|
|||||||
if (overrun) {
|
if (overrun) {
|
||||||
stat |= 0x20;
|
stat |= 0x20;
|
||||||
}
|
}
|
||||||
|
if (interrupt) {
|
||||||
|
stat |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpuAccess) {
|
||||||
|
interrupt = false;
|
||||||
|
}
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +125,7 @@ public class Acia6850 extends Acia {
|
|||||||
overrun = false;
|
overrun = false;
|
||||||
rxFull = false;
|
rxFull = false;
|
||||||
txEmpty = true;
|
txEmpty = true;
|
||||||
|
interrupt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user