1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-12 15:31:09 +00:00

Implements a fuller reset, takes a run at the overran flag.

This commit is contained in:
Thomas Harte 2019-12-08 21:20:06 -05:00
parent c785797da6
commit b192381928
2 changed files with 21 additions and 4 deletions

View File

@ -21,6 +21,7 @@ ACIA::ACIA(HalfCycles transmit_clock_rate, HalfCycles receive_clock_rate) :
uint8_t ACIA::read(int address) { uint8_t ACIA::read(int address) {
if(address&1) { if(address&1) {
overran_ = false;
received_data_ |= NoValueMask; received_data_ |= NoValueMask;
update_interrupt_line(); update_interrupt_line();
return uint8_t(received_data_); return uint8_t(received_data_);
@ -29,6 +30,19 @@ uint8_t ACIA::read(int address) {
} }
} }
void ACIA::reset() {
transmit.reset_writing();
transmit.write(true);
request_to_send.reset_writing();
bits_received_ = bits_incoming_ = 0;
receive_interrupt_enabled_ = transmit_interrupt_enabled_ = false;
overran_ = false;
next_transmission_ = received_data_ = NoValueMask;
update_interrupt_line();
}
void ACIA::write(int address, uint8_t value) { void ACIA::write(int address, uint8_t value) {
if(address&1) { if(address&1) {
next_transmission_ = value; next_transmission_ = value;
@ -36,9 +50,7 @@ void ACIA::write(int address, uint8_t value) {
update_interrupt_line(); update_interrupt_line();
} else { } else {
if((value&3) == 3) { if((value&3) == 3) {
transmit.reset_writing(); reset();
transmit.write(true);
request_to_send.reset_writing();
} else { } else {
switch(value & 3) { switch(value & 3) {
default: default:
@ -143,6 +155,7 @@ bool ACIA::serial_line_did_produce_bit(Serial::Line *line, int bit) {
const int bit_target = expected_bits(); const int bit_target = expected_bits();
if(bits_received_ >= bit_target) { if(bits_received_ >= bit_target) {
bits_received_ = 0; bits_received_ = 0;
overran_ |= get_status() & 1;
received_data_ = uint8_t(bits_incoming_ >> (12 - bit_target)); received_data_ = uint8_t(bits_incoming_ >> (12 - bit_target));
update_interrupt_line(); update_interrupt_line();
update_clocking_observer(); update_clocking_observer();
@ -186,8 +199,9 @@ void ACIA::update_interrupt_line() {
(receive_interrupt_enabled_ && (status & 0x25)) || (receive_interrupt_enabled_ && (status & 0x25)) ||
(transmit_interrupt_enabled_ && (status & 0x02)); (transmit_interrupt_enabled_ && (status & 0x02));
if(interrupt_delegate_ && old_line != interrupt_line_) if(interrupt_delegate_ && old_line != interrupt_line_) {
interrupt_delegate_->acia6850_did_change_interrupt_status(this); interrupt_delegate_->acia6850_did_change_interrupt_status(this);
}
} }
uint8_t ACIA::get_status() { uint8_t ACIA::get_status() {
@ -196,6 +210,7 @@ uint8_t ACIA::get_status() {
((next_transmission_ == NoValueMask) ? 0x02 : 0x00) | ((next_transmission_ == NoValueMask) ? 0x02 : 0x00) |
// (data_carrier_detect.read() ? 0x04 : 0x00) | // (data_carrier_detect.read() ? 0x04 : 0x00) |
// (clear_to_send.read() ? 0x08 : 0x00) | // (clear_to_send.read() ? 0x08 : 0x00) |
(overran_ ? 0x20 : 0x00) |
(interrupt_line_ ? 0x80 : 0x00) (interrupt_line_ ? 0x80 : 0x00)
; ;

View File

@ -74,6 +74,7 @@ class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelegate {
} }
bool get_interrupt_line() const; bool get_interrupt_line() const;
void reset();
// Input lines. // Input lines.
Serial::Line receive; Serial::Line receive;
@ -105,6 +106,7 @@ class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelegate {
int bits_received_ = 0; int bits_received_ = 0;
int bits_incoming_ = 0; int bits_incoming_ = 0;
bool overran_ = false;
void consider_transmission(); void consider_transmission();
int expected_bits(); int expected_bits();