mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Implements a fuller reset, takes a run at the overran flag.
This commit is contained in:
parent
c785797da6
commit
b192381928
@ -21,6 +21,7 @@ ACIA::ACIA(HalfCycles transmit_clock_rate, HalfCycles receive_clock_rate) :
|
||||
|
||||
uint8_t ACIA::read(int address) {
|
||||
if(address&1) {
|
||||
overran_ = false;
|
||||
received_data_ |= NoValueMask;
|
||||
update_interrupt_line();
|
||||
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) {
|
||||
if(address&1) {
|
||||
next_transmission_ = value;
|
||||
@ -36,9 +50,7 @@ void ACIA::write(int address, uint8_t value) {
|
||||
update_interrupt_line();
|
||||
} else {
|
||||
if((value&3) == 3) {
|
||||
transmit.reset_writing();
|
||||
transmit.write(true);
|
||||
request_to_send.reset_writing();
|
||||
reset();
|
||||
} else {
|
||||
switch(value & 3) {
|
||||
default:
|
||||
@ -143,6 +155,7 @@ bool ACIA::serial_line_did_produce_bit(Serial::Line *line, int bit) {
|
||||
const int bit_target = expected_bits();
|
||||
if(bits_received_ >= bit_target) {
|
||||
bits_received_ = 0;
|
||||
overran_ |= get_status() & 1;
|
||||
received_data_ = uint8_t(bits_incoming_ >> (12 - bit_target));
|
||||
update_interrupt_line();
|
||||
update_clocking_observer();
|
||||
@ -186,8 +199,9 @@ void ACIA::update_interrupt_line() {
|
||||
(receive_interrupt_enabled_ && (status & 0x25)) ||
|
||||
(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);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ACIA::get_status() {
|
||||
@ -196,6 +210,7 @@ uint8_t ACIA::get_status() {
|
||||
((next_transmission_ == NoValueMask) ? 0x02 : 0x00) |
|
||||
// (data_carrier_detect.read() ? 0x04 : 0x00) |
|
||||
// (clear_to_send.read() ? 0x08 : 0x00) |
|
||||
(overran_ ? 0x20 : 0x00) |
|
||||
(interrupt_line_ ? 0x80 : 0x00)
|
||||
;
|
||||
|
||||
|
@ -74,6 +74,7 @@ class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelegate {
|
||||
}
|
||||
|
||||
bool get_interrupt_line() const;
|
||||
void reset();
|
||||
|
||||
// Input lines.
|
||||
Serial::Line receive;
|
||||
@ -105,6 +106,7 @@ class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelegate {
|
||||
|
||||
int bits_received_ = 0;
|
||||
int bits_incoming_ = 0;
|
||||
bool overran_ = false;
|
||||
|
||||
void consider_transmission();
|
||||
int expected_bits();
|
||||
|
Loading…
x
Reference in New Issue
Block a user