Correct status handling in the MC6850, and improve documentation.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-09-30 23:07:07 +01:00
parent 8ea7bf5d68
commit 042e066a0c
2 changed files with 143 additions and 30 deletions

View File

@ -93,51 +93,164 @@ namespace EightBit {
ReceiveInterruptEnable = 0b1, // Triggers on: RDR full, overrun, DCD low -> high
};
// STATUS REGISTER Information on the status of the ACIA is
// available to the MPU by reading the ACIA Status Register.
// This read-only register is selected when RS is low and R/W is high.
// Information stored in this register indicates the status of the
// Transmit Data Register, the Receive Data Register and error logic,
// and the peripheral/modem status inputs of the ACIA
enum StatusRegisters {
STATUS_RDRF = 0b1,
STATUS_TDRE = 0b10,
STATUS_DCD = 0b100,
STATUS_CTS = 0b1000,
STATUS_FE = 0b10000,
STATUS_OVRN = 0b100000,
STATUS_PE = 0b1000000,
STATUS_IRQ = 0b10000000,
// Receive Data Register Full (RDRF), Bit 0 - Receive Data
// Register Full indicates that received data has been
// transferred to the Receive Data Register. RDRF is cleared
// after an MPU read of the Receive Data Register or by a
// master reset. The cleared or empty state indicates that the
// contents of the Receive Data Register are not current.
// Data Carrier Detect being high also causes RDRF to indicate
// empty.
STATUS_RDRF = 0b1,
// Transmit Data Register Empty (TDRE), Bit 1 - The Transmit
// Data Register Empty bit being set high indicates that the
// Transmit Data Register contents have been transferred and
// that new data may be entered. The low state indicates that
// the register is full and that transmission of a new
// character has not begun since the last write data command.
STATUS_TDRE = 0b10,
// ___
// Data Carrier Detect (DCD), Bit 2 - The Data Carrier Detect
// bit will be high when the DCD (low) input from a modem has gone
// high to indicate that a carrier is not present. This bit
// going high causes an Interrupt Request to be generated when
// the Receive Interrupt Enable is set. It remains high after
// the DCD (low) input is returned low until cleared by first reading
// the Status Register and then the Data Register or until a
// master reset occurs. If the DCD (low) input remains high after
// read status and read data or master reset has occurred, the
// interrupt is cleared, the DCD (low) status bit remains high and
// will follow the DCD (low) input.
STATUS_DCD = 0b100,
// ___
// Clear-to-Send (CTS), Bit 3 - The Clear-to-Send bit indicates
// the state of the Clear-to-Send input from a modem. A low CTS (low)
// indicates that there is a Clear-to-Send from the modem. In
// the high state, the Transmit Data Register Empty bit is
// inhibited and the Clear-to-Send status bit will be high.
// Master reset does not affect the Clear-to-Send status bit.
STATUS_CTS = 0b1000,
// Framing Error (FE), Bit 4 - Framing error indicates that the
// received character is improperly framed by a start and a
// stop bit and is detected by the absence of the first stop
// bit. This error indicates a synchronization error, faulty
// transmission, or a break condition. The framing error flag
// is set or reset during the receive data transfer time.
// Therefore, this error indicator is present throughout the
// time that the associated character is available.
STATUS_FE = 0b10000,
// Receiver Overrun (OVRN), Bit 5- Overrun is an error flag
// that indicates that one or more characters in the data
// stream were lost. That is, a character or a number of
// characters were received but not read from the Receive
// Data Register (RDR) prior to subsequent characters being
// received. The overrun condition begins at the midpoint of
// the last bit of the second character received in succession
// without a read of the RDR having occurred. The Overrun does
// not occur in the Status Register until the valid character
// prior to Overrun has been read. The RDRF bit remains set
// until the Overrun is reset. Character synchronization is
// maintained during the Overrun condition. The Overrun
// indication is reset after the reading of data from the
// Receive Data Register or by a Master Reset.
STATUS_OVRN = 0b100000,
// Parity Error (PE), Bit 6 - The parity error flag indicates
// that the number of highs {ones) in the character does not
// agree with the preselected odd or even parity. Odd parity
// is defined to be when the total number of ones is odd. The
// parity error indication will be present as long as the data
// character is in the RDR. If no parity is selected, then both
// the transmitter parity generator output and the receiver
// parity check results are inhibited
STATUS_PE = 0b1000000,
// ___
// Interrupt Request (IRQ), Bit 7- The IRQ (low) bit indicates the
// state of the IRQ (low) output. Any interrupt condition with its
// applicable enable will be indicated in this status bit.
// Anytime the IRQ (low) output is low the IRQ bit will be high to
// indicate the interrupt or service request status. IRQ (low) is
// cleared by a read operation to the Receive Data Register or
// a write operation to the Transmit Data Register.
STATUS_IRQ = 0b10000000,
};
PinLevel& RXDATA() { return m_RXDATA; } // Receive data, (I) Active high
PinLevel& TXDATA() { return m_TXDATA; } // Transmit data, (O) Active high
// Receive data, (I) Active high
PinLevel& RXDATA() { return m_RXDATA; }
PinLevel& RTS() { return m_RTS; } // Request to send, (O) Active low
PinLevel& CTS() { return m_CTS; } // Clear to send, (I) Active low
PinLevel& DCD() { return m_DCD; } // Data carrier detect, (I) Active low
// Transmit data, (O) Active high
PinLevel& TXDATA() { return m_TXDATA; }
PinLevel& RXCLK() { return m_RXCLK; } // Transmit clock, (I) Active high
PinLevel& TXCLK() { return m_TXCLK; } // Receive clock, (I) Active high
// Request to send, (O) Active low
PinLevel& RTS() { return m_RTS; }
// Clear to send, (I) Active low
PinLevel& CTS() { return m_CTS; }
PinLevel& CS0() { return m_CS0; } // Chip select, bit 0, (I) Active high
PinLevel& CS1() { return m_CS1; } // Chip select, bit 1, (I) Active high
PinLevel& CS2() { return m_CS2; } // Chip select, bit 2, (I) Active low
// Data carrier detect, (I) Active low
PinLevel& DCD() { return m_DCD; }
PinLevel& RS() { return m_RS; } // Register select, (I) Active high
PinLevel& RW() { return m_RW; } // Read/Write, (I) Read high, write low
// Transmit clock, (I) Active high
PinLevel& RXCLK() { return m_RXCLK; }
PinLevel& E() { return m_E; } // ACIA Enable, (I) Active high
PinLevel& IRQ() { return m_IRQ; } // Interrupt request, (O) Active low
// Receive clock, (I) Active high
PinLevel& TXCLK() { return m_TXCLK; }
uint8_t& DATA() { return m_data; } // Data, (I/O)
// Chip select, bit 0, (I) Active high
PinLevel& CS0() { return m_CS0; }
// Chip select, bit 1, (I) Active high
PinLevel& CS1() { return m_CS1; }
// Chip select, bit 2, (I) Active low
PinLevel& CS2() { return m_CS2; }
// Register select, (I) Active high
PinLevel& RS() { return m_RS; }
// Read/Write, (I) Read high, write low
PinLevel& RW() { return m_RW; }
// ACIA Enable, (I) Active high
PinLevel& E() { return m_E; }
// Interrupt request, (O) Active low
PinLevel& IRQ() { return m_IRQ; }
// Data, (I/O)
uint8_t& DATA() { return m_data; }
// Expose these internal registers, so we can update internal state
uint8_t& TDR() { return m_TDR; } // Transmit data register;
uint8_t& RDR() { return m_RDR; } // Receive data register;
void step(int cycles);
// Transmit data register;
uint8_t& TDR() { return m_TDR; }
// Receive data register;
uint8_t& RDR() { return m_RDR; }
bool access();
bool selected();
void markTransmitComplete();
void markReceiveStarting();
std::string dumpStatus();
Signal<EventArgs> Accessing;
Signal<EventArgs> Accessed;
@ -148,12 +261,10 @@ namespace EightBit {
Signal<EventArgs> Received;
private:
uint8_t& status() { return m_status; }
uint8_t status();
void reset();
void step();
void startTransmit();
void markTransmitStarting();
@ -189,7 +300,9 @@ namespace EightBit {
ReceiveControl m_receiveControl;
// Status registers
uint8_t m_status;
bool m_statusRDRF = false;
bool m_statusTDRE = true;
bool m_statusOVRN = false;
// Data registers
uint8_t m_TDR;

Binary file not shown.