mirror of
https://github.com/TomHarte/CLK.git
synced 2025-11-23 05:19:20 +00:00
Start to consolidate relationship around push.
This commit is contained in:
@@ -109,10 +109,7 @@ Cycles MachineBase::perform(const AddressT address, CPU::MOS6502Mk2::data_t<oper
|
||||
|
||||
void Machine::run_for(const Cycles cycles) {
|
||||
m6502_.run_for(cycles);
|
||||
|
||||
const bool drive_motor = drive_VIA_port_handler_.motor_enabled();
|
||||
get_drive().set_motor_on(drive_motor);
|
||||
if(drive_motor) {
|
||||
if(get_drive().get_motor_on()) {
|
||||
Storage::Disk::Controller::run_for(cycles);
|
||||
}
|
||||
}
|
||||
@@ -150,15 +147,16 @@ void MachineBase::process_input_bit(const int value) {
|
||||
} else {
|
||||
drive_VIA_port_handler_.set_sync_detected(false);
|
||||
}
|
||||
bit_window_offset_++;
|
||||
++bit_window_offset_;
|
||||
if(bit_window_offset_ == 8) {
|
||||
drive_VIA_port_handler_.set_data_input(uint8_t(shift_register_));
|
||||
bit_window_offset_ = 0;
|
||||
if(drive_VIA_port_handler_.should_set_overflow()) {
|
||||
if(set_cpu_overflow_) {
|
||||
m6502_.set<CPU::MOS6502Mk2::Line::Overflow>(true);
|
||||
}
|
||||
} else {
|
||||
m6502_.set<CPU::MOS6502Mk2::Line::Overflow>(false);
|
||||
}
|
||||
else m6502_.set<CPU::MOS6502Mk2::Line::Overflow>(false);
|
||||
}
|
||||
|
||||
// the 1540 does not recognise index holes
|
||||
@@ -174,6 +172,21 @@ void MachineBase::drive_via_did_set_data_density(DriveVIA &, const int density)
|
||||
set_expected_bit_length(Storage::Encodings::CommodoreGCR::length_of_a_bit_in_time_zone(unsigned(density)));
|
||||
}
|
||||
|
||||
void MachineBase::drive_via_did_set_drive_motor(DriveVIA &, const bool enabled) {
|
||||
get_drive().set_motor_on(enabled);
|
||||
}
|
||||
|
||||
void MachineBase::drive_via_did_set_write_mode(DriveVIA &, bool) {
|
||||
// TODO.
|
||||
}
|
||||
|
||||
void MachineBase::drive_via_should_set_cpu_overflow(DriveVIA &, const bool overflow) {
|
||||
set_cpu_overflow_ = overflow;
|
||||
if(!overflow) {
|
||||
m6502_.set<CPU::MOS6502Mk2::Line::Overflow>(false);
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SerialPortVIA
|
||||
|
||||
template <MOS::MOS6522::Port port>
|
||||
@@ -200,13 +213,17 @@ void SerialPortVIA::set_serial_line_state(
|
||||
const bool value,
|
||||
MOS::MOS6522::MOS6522<SerialPortVIA> &via
|
||||
) {
|
||||
const auto set = [&](const uint8_t mask) {
|
||||
port_b_ = (port_b_ & ~mask) | (value ? 0x00 : mask);
|
||||
};
|
||||
|
||||
switch(line) {
|
||||
default: break;
|
||||
case ::Commodore::Serial::Line::Data: port_b_ = (port_b_ & ~0x01) | (value ? 0x00 : 0x01); break;
|
||||
case ::Commodore::Serial::Line::Clock: port_b_ = (port_b_ & ~0x04) | (value ? 0x00 : 0x04); break;
|
||||
case ::Commodore::Serial::Line::Data: set(0x01); break;
|
||||
case ::Commodore::Serial::Line::Clock: set(0x04); break;
|
||||
case ::Commodore::Serial::Line::Attention:
|
||||
set(0x80);
|
||||
attention_level_input_ = !value;
|
||||
port_b_ = (port_b_ & ~0x80) | (value ? 0x00 : 0x80);
|
||||
via.set_control_line_input<MOS::MOS6522::Port::A, MOS::MOS6522::Line::One>(!value);
|
||||
update_data_line();
|
||||
break;
|
||||
@@ -249,24 +266,23 @@ void DriveVIA::set_data_input(const uint8_t value) {
|
||||
port_a_ = value;
|
||||
}
|
||||
|
||||
bool DriveVIA::should_set_overflow() {
|
||||
return should_set_overflow_;
|
||||
}
|
||||
|
||||
bool DriveVIA::motor_enabled() {
|
||||
return drive_motor_;
|
||||
}
|
||||
|
||||
template <MOS::MOS6522::Port port, MOS::MOS6522::Line line>
|
||||
void DriveVIA::set_control_line_output(const bool value) {
|
||||
if(port == MOS::MOS6522::Port::A && line == MOS::MOS6522::Line::Two) {
|
||||
should_set_overflow_ = value;
|
||||
if(set_cpu_overflow_ != value) {
|
||||
set_cpu_overflow_ = value;
|
||||
if(delegate_) {
|
||||
delegate_->drive_via_should_set_cpu_overflow(*this, set_cpu_overflow_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(port == MOS::MOS6522::Port::B && line == MOS::MOS6522::Line::Two) {
|
||||
// TODO: 0 = write, 1 = read.
|
||||
if(!value) {
|
||||
printf("NOT IMPLEMENTED: write mode\n");
|
||||
if(value != write_mode_) {
|
||||
write_mode_ = !value;
|
||||
if(delegate_) {
|
||||
delegate_->drive_via_did_set_write_mode(*this, write_mode_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +291,13 @@ template <>
|
||||
void DriveVIA::set_port_output<MOS::MOS6522::Port::B>(const uint8_t value, uint8_t) {
|
||||
if(previous_port_b_output_ != value) {
|
||||
// Record drive motor state.
|
||||
drive_motor_ = value&4;
|
||||
const bool new_drive_motor = value & 4;
|
||||
if(new_drive_motor != drive_motor_) {
|
||||
drive_motor_ = new_drive_motor;
|
||||
if(delegate_) {
|
||||
delegate_->drive_via_did_set_drive_motor(*this, drive_motor_);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a head step.
|
||||
const int step_difference = ((value&3) - (previous_port_b_output_&3))&3;
|
||||
|
||||
@@ -82,6 +82,9 @@ public:
|
||||
struct Delegate {
|
||||
virtual void drive_via_did_step_head(DriveVIA &, int direction) = 0;
|
||||
virtual void drive_via_did_set_data_density(DriveVIA &, int density) = 0;
|
||||
virtual void drive_via_did_set_drive_motor(DriveVIA &, bool enabled) = 0;
|
||||
virtual void drive_via_did_set_write_mode(DriveVIA &, bool write) = 0;
|
||||
virtual void drive_via_should_set_cpu_overflow(DriveVIA &, bool overflow) = 0;
|
||||
};
|
||||
void set_delegate(Delegate *);
|
||||
|
||||
@@ -91,8 +94,6 @@ public:
|
||||
void set_sync_detected(bool);
|
||||
void set_data_input(uint8_t);
|
||||
void set_is_read_only(bool);
|
||||
bool should_set_overflow();
|
||||
bool motor_enabled();
|
||||
|
||||
template <MOS::MOS6522::Port, MOS::MOS6522::Line>
|
||||
void set_control_line_output(bool value);
|
||||
@@ -104,8 +105,11 @@ public:
|
||||
|
||||
private:
|
||||
uint8_t port_b_ = 0xff, port_a_ = 0xff;
|
||||
bool should_set_overflow_ = false;
|
||||
|
||||
bool set_cpu_overflow_ = false;
|
||||
bool drive_motor_ = false;
|
||||
bool write_mode_ = false;
|
||||
|
||||
uint8_t previous_port_b_output_ = 0;
|
||||
Delegate *delegate_ = nullptr;
|
||||
Activity::Observer *observer_ = nullptr;
|
||||
@@ -144,8 +148,11 @@ protected:
|
||||
void mos6522_did_change_interrupt_status(void *mos6522) override;
|
||||
|
||||
// to satisfy DriveVIA::Delegate
|
||||
void drive_via_did_step_head(DriveVIA &, int direction) override;
|
||||
void drive_via_did_set_data_density(DriveVIA &, int density) override;
|
||||
void drive_via_did_step_head(DriveVIA &, int) override;
|
||||
void drive_via_did_set_data_density(DriveVIA &, int) override;
|
||||
void drive_via_did_set_drive_motor(DriveVIA &, bool) override;
|
||||
void drive_via_did_set_write_mode(DriveVIA &, bool) override;
|
||||
void drive_via_should_set_cpu_overflow(DriveVIA &, bool) override;
|
||||
|
||||
struct M6502Traits {
|
||||
static constexpr auto uses_ready_line = false;
|
||||
@@ -164,6 +171,7 @@ protected:
|
||||
MOS::MOS6522::MOS6522<DriveVIA> drive_VIA_;
|
||||
MOS::MOS6522::MOS6522<SerialPortVIA> serial_port_VIA_;
|
||||
|
||||
bool set_cpu_overflow_ = false;
|
||||
int shift_register_ = 0, bit_window_offset_;
|
||||
void process_input_bit(int value) override;
|
||||
void process_index_hole() override;
|
||||
|
||||
Reference in New Issue
Block a user