1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 18:30:21 +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;
};
void set_delegate(Delegate *delegate)
void set_interrupt_delegate(Delegate *delegate)
{
_delegate = delegate;
}

View File

@ -25,7 +25,8 @@ Machine::Machine() :
_serialPortVIA->set_serial_port(_serialPort);
// 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);
// 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)
{
// static bool log = false;
// if(operation == CPU6502::BusOperation::ReadOpcode) printf("%04x\n", address);
// if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xf3be)) log = true;
// if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xF3C0)) log = true;
// 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));
/* 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)
{
_shift_register = (_shift_register << 1) | value;
_driveVIA.set_sync_detected((_shift_register & 0x3ff) == 0x3ff);
if((_shift_register & 0x7ff) == 0x7fe) _bit_window_offset = 0;
if((_shift_register & 0x3ff) == 0x3ff)
{
_driveVIA.set_sync_detected(true);
_bit_window_offset = -1;
}
else
{
_driveVIA.set_sync_detected(false);
}
_bit_window_offset++;
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
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 {
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;
// 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) {
return port ? _port_b : _port_a;
@ -152,10 +162,23 @@ class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
_drive_motor = !!(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("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;
bool _should_set_overflow;
bool _drive_motor;
uint8_t _previous_port_b_output;
Delegate *_delegate;
};
/*!
@ -189,6 +214,7 @@ class SerialPort : public ::Commodore::Serial::Port {
class Machine:
public CPU6502::Processor<Machine>,
public MOS::MOS6522IRQDelegate::Delegate,
public DriveVIA::Delegate,
public Storage::DiskDrive {
public:
@ -217,6 +243,10 @@ class Machine:
// to satisfy MOS::MOS6522::Delegate
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:
uint8_t _ram[0x800];
uint8_t _rom[0x4000];

View File

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