1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Attempts to implement transmission interrupts and ClockingHint::Source.

This commit is contained in:
Thomas Harte 2019-10-12 23:46:57 -04:00
parent 4e5b440145
commit a7ed357569
2 changed files with 33 additions and 8 deletions

View File

@ -18,12 +18,14 @@ ACIA::ACIA() {}
uint8_t ACIA::read(int address) { uint8_t ACIA::read(int address) {
if(address&1) { if(address&1) {
LOG("Read from receive register"); LOG("Read from receive register");
interrupt_request_ = false;
} else { } else {
LOG("Read status"); LOG("Read status");
return return
((next_transmission_ == NoTransmission) ? 0x02 : 0x00) | ((next_transmission_ == NoTransmission) ? 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) |
(interrupt_request_ ? 0x80 : 0x00)
; ;
// b0: receive data full. // b0: receive data full.
@ -42,6 +44,8 @@ void ACIA::write(int address, uint8_t value) {
if(address&1) { if(address&1) {
next_transmission_ = value; next_transmission_ = value;
consider_transmission(); consider_transmission();
update_clocking_observer();
interrupt_request_ = false;
} else { } else {
if((value&3) == 3) { if((value&3) == 3) {
transmit.reset_writing(); transmit.reset_writing();
@ -82,16 +86,22 @@ void ACIA::write(int address, uint8_t value) {
void ACIA::run_for(HalfCycles length) { void ACIA::run_for(HalfCycles length) {
// Transmission. // Transmission.
int transmit_advance = length.as_int(); const int transmit_advance = length.as_int();
if(next_transmission_ != NoTransmission) { const auto write_data_time_remaining = transmit.write_data_time_remaining();
const auto write_data_time_remaining = transmit.write_data_time_remaining();
if(transmit_advance > write_data_time_remaining) { if(transmit_advance > write_data_time_remaining) {
if(next_transmission_ != NoTransmission) {
transmit.flush_writing(); transmit.flush_writing();
transmit_advance -= write_data_time_remaining;
consider_transmission(); consider_transmission();
transmit.advance_writer(transmit_advance - write_data_time_remaining);
} else {
transmit.advance_writer(transmit_advance);
update_clocking_observer();
interrupt_request_ |= transmit_interrupt_enabled_;
} }
} else {
transmit.advance_writer(transmit_advance);
} }
transmit.advance_writer(transmit_advance);
// Reception. // Reception.
} }
@ -129,3 +139,11 @@ void ACIA::consider_transmission() {
next_transmission_ = NoTransmission; next_transmission_ = NoTransmission;
} }
} }
ClockingHint::Preference ACIA::preferred_clocking() {
return (transmit.write_data_time_remaining() > 0) ? ClockingHint::Preference::JustInTime : ClockingHint::Preference::None;
}
bool ACIA::get_interrupt_line() {
return interrupt_request_;
}

View File

@ -11,12 +11,13 @@
#include <cstdint> #include <cstdint>
#include "../../ClockReceiver/ClockReceiver.hpp" #include "../../ClockReceiver/ClockReceiver.hpp"
#include "../../ClockReceiver/ClockingHintSource.hpp"
#include "../SerialPort/SerialPort.hpp" #include "../SerialPort/SerialPort.hpp"
namespace Motorola { namespace Motorola {
namespace ACIA { namespace ACIA {
class ACIA { class ACIA: public ClockingHint::Source {
public: public:
ACIA(); ACIA();
@ -40,6 +41,8 @@ class ACIA {
void run_for(HalfCycles); void run_for(HalfCycles);
bool get_interrupt_line();
// Input lines. // Input lines.
Serial::Line receive; Serial::Line receive;
Serial::Line clear_to_send; Serial::Line clear_to_send;
@ -62,6 +65,10 @@ class ACIA {
bool receive_interrupt_enabled_ = false; bool receive_interrupt_enabled_ = false;
bool transmit_interrupt_enabled_ = false; bool transmit_interrupt_enabled_ = false;
bool interrupt_request_ = false;
ClockingHint::Preference preferred_clocking() final;
}; };
} }