1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Fixed framing and first-byte-after-sync signalling. Hacked together as parts of it are, loading now appears to work!

This commit is contained in:
Thomas Harte 2016-08-01 04:25:11 -04:00
parent 41893b5ef6
commit b43a7381ae
4 changed files with 61 additions and 11 deletions

View File

@ -364,7 +364,7 @@ class MOS6522IRQDelegate {
virtual void mos6522_did_change_interrupt_status(void *mos6522) = 0; virtual void mos6522_did_change_interrupt_status(void *mos6522) = 0;
}; };
void set_delegate(Delegate *delegate) void set_interrupt_delegate(Delegate *delegate)
{ {
_delegate = delegate; _delegate = delegate;
} }

View File

@ -25,7 +25,8 @@ Machine::Machine() :
_serialPortVIA->set_serial_port(_serialPort); _serialPortVIA->set_serial_port(_serialPort);
// set this instance as the delegate to receive interrupt requests from both VIAs // set this instance as the delegate to receive interrupt requests from both VIAs
_serialPortVIA->set_delegate(this); _serialPortVIA->set_interrupt_delegate(this);
_driveVIA.set_interrupt_delegate(this);
_driveVIA.set_delegate(this); _driveVIA.set_delegate(this);
// set a bit rate // set a bit rate
@ -40,10 +41,10 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu
unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value)
{ {
// static bool log = false; // static bool log = false;
// if(operation == CPU6502::BusOperation::ReadOpcode) printf("%04x\n", address); // if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xF3C0)) log = true;
// if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xf3be)) log = true;
// if(operation == CPU6502::BusOperation::ReadOpcode && log) printf("%04x\n", address); // if(operation == CPU6502::BusOperation::ReadOpcode && log) printf("%04x\n", address);
// if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xF556 && address <= 0xF56D)) printf("%04x\n", address); // if(operation == CPU6502::BusOperation::ReadOpcode) printf("%04x\n", address);
// if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xF510 && address <= 0xF553)) printf("%04x\n", address);
// if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xE887)) printf("A: %02x\n", get_value_of_register(CPU6502::Register::A)); // if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xE887)) printf("A: %02x\n", get_value_of_register(CPU6502::Register::A));
/* static bool log = false; /* static bool log = false;
@ -121,8 +122,15 @@ void Machine::mos6522_did_change_interrupt_status(void *mos6522)
void Machine::process_input_bit(int value, unsigned int cycles_since_index_hole) void Machine::process_input_bit(int value, unsigned int cycles_since_index_hole)
{ {
_shift_register = (_shift_register << 1) | value; _shift_register = (_shift_register << 1) | value;
_driveVIA.set_sync_detected((_shift_register & 0x3ff) == 0x3ff); if((_shift_register & 0x3ff) == 0x3ff)
if((_shift_register & 0x7ff) == 0x7fe) _bit_window_offset = 0; {
_driveVIA.set_sync_detected(true);
_bit_window_offset = -1;
}
else
{
_driveVIA.set_sync_detected(false);
}
_bit_window_offset++; _bit_window_offset++;
if(_bit_window_offset == 8) if(_bit_window_offset == 8)
{ {
@ -139,3 +147,15 @@ void Machine::process_input_bit(int value, unsigned int cycles_since_index_hole)
// the 1540 does not recognise index holes // the 1540 does not recognise index holes
void Machine::process_index_hole() {} void Machine::process_index_hole() {}
#pragma mak - Drive VIA delegate
void Machine::drive_via_did_step_head(void *driveVIA, int direction)
{
step(direction);
}
void Machine::drive_via_did_set_data_density(void *driveVIA, int density)
{
set_expected_bit_length(Storage::Encodings::CommodoreGCR::length_of_a_bit_in_time_zone((unsigned int)density));
}

View File

@ -115,10 +115,20 @@ class SerialPortVIA: public MOS::MOS6522<SerialPortVIA>, public MOS::MOS6522IRQD
*/ */
class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate { class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
public: public:
class Delegate {
public:
virtual void drive_via_did_step_head(void *driveVIA, int direction) = 0;
virtual void drive_via_did_set_data_density(void *driveVIA, int density) = 0;
};
void set_delegate(Delegate *delegate)
{
_delegate = delegate;
}
using MOS6522IRQDelegate::set_interrupt_status; using MOS6522IRQDelegate::set_interrupt_status;
// write protect tab uncovered // write protect tab uncovered
DriveVIA() : _port_b(0xff), _port_a(0xff) {} DriveVIA() : _port_b(0xff), _port_a(0xff), _delegate(nullptr) {}
uint8_t get_port_input(Port port) { uint8_t get_port_input(Port port) {
return port ? _port_b : _port_a; return port ? _port_b : _port_a;
@ -152,10 +162,23 @@ class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
_drive_motor = !!(value&4); _drive_motor = !!(value&4);
// if(value&4) // if(value&4)
// { // {
printf("Head step: %d\n", value&3);
int step_difference = ((value&3) - (_previous_port_b_output&3))&3;
if(step_difference)
{
if(_delegate) _delegate->drive_via_did_step_head(this, (step_difference == 1) ? 1 : -1);
}
int density_difference = (_previous_port_b_output^value) & (3 << 5);
if(density_difference && _delegate)
{
_delegate->drive_via_did_set_data_density(this, (value >> 5)&3);
}
// printf("LED: %s\n", value&8 ? "On" : "Off"); // printf("LED: %s\n", value&8 ? "On" : "Off");
// printf("Density: %d\n", (value >> 5)&3); // printf("Density: %d\n", (value >> 5)&3);
// } // }
_previous_port_b_output = value;
} }
} }
@ -163,6 +186,8 @@ class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
uint8_t _port_b, _port_a; uint8_t _port_b, _port_a;
bool _should_set_overflow; bool _should_set_overflow;
bool _drive_motor; bool _drive_motor;
uint8_t _previous_port_b_output;
Delegate *_delegate;
}; };
/*! /*!
@ -189,6 +214,7 @@ class SerialPort : public ::Commodore::Serial::Port {
class Machine: class Machine:
public CPU6502::Processor<Machine>, public CPU6502::Processor<Machine>,
public MOS::MOS6522IRQDelegate::Delegate, public MOS::MOS6522IRQDelegate::Delegate,
public DriveVIA::Delegate,
public Storage::DiskDrive { public Storage::DiskDrive {
public: public:
@ -217,6 +243,10 @@ class Machine:
// to satisfy MOS::MOS6522::Delegate // to satisfy MOS::MOS6522::Delegate
virtual void mos6522_did_change_interrupt_status(void *mos6522); virtual void mos6522_did_change_interrupt_status(void *mos6522);
// to satisfy DriveVIA::Delegate
void drive_via_did_step_head(void *driveVIA, int direction);
void drive_via_did_set_data_density(void *driveVIA, int density);
private: private:
uint8_t _ram[0x800]; uint8_t _ram[0x800];
uint8_t _rom[0x4000]; uint8_t _rom[0x4000];

View File

@ -30,8 +30,8 @@ Machine::Machine() :
_serialPort->set_user_port_via(_userPortVIA); _serialPort->set_user_port_via(_userPortVIA);
// wire up the 6522s, tape and machine // wire up the 6522s, tape and machine
_userPortVIA->set_delegate(this); _userPortVIA->set_interrupt_delegate(this);
_keyboardVIA->set_delegate(this); _keyboardVIA->set_interrupt_delegate(this);
_tape.set_delegate(this); _tape.set_delegate(this);
// establish the memory maps // establish the memory maps