mirror of
https://github.com/sethm/symon.git
synced 2025-03-13 13:30:37 +00:00
Merge pull request #18 from izuannazrin/master
Interrupt bit support for ACIA
This commit is contained in:
commit
3c3aee30a7
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user