1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Made an attempt to allow the 1540 to talk back to the Vic, and to receive interrupts. Also slightly disambiguated debugging logging.

This commit is contained in:
Thomas Harte 2016-07-05 19:12:43 -04:00
parent d16b79073e
commit 11fc43aa04
3 changed files with 59 additions and 2 deletions

View File

@ -15,7 +15,9 @@ Machine::Machine()
{
_serialPortVIA.reset(new SerialPortVIA);
_serialPort.reset(new SerialPort);
_serialPort->set_serial_port_via(_serialPortVIA);
_serialPortVIA->set_serial_port(_serialPort);
}
void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus)
@ -55,3 +57,10 @@ void Machine::set_rom(const uint8_t *rom)
{
memcpy(_rom, rom, sizeof(_rom));
}
#pragma mark - 6522 delegate
void Machine::mos6522_did_change_interrupt_status(void *mos6522)
{
set_irq_line(_serialPortVIA->get_interrupt_line());
}

View File

@ -19,11 +19,55 @@ namespace C1540 {
class SerialPortVIA: public MOS::MOS6522<SerialPortVIA>, public MOS::MOS6522IRQDelegate {
public:
using MOS6522IRQDelegate::set_interrupt_status;
SerialPortVIA() : _portB(0x1f) {}
uint8_t get_port_input(Port port) {
if(port) {
return _portB;
}
return 0xff;
}
void set_port_output(Port port, uint8_t value, uint8_t mask) {
if(port) {
std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock();
if(serialPort) {
serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10));
serialPort->set_output(::Commodore::Serial::Line::Clock, !(value&0x08));
serialPort->set_output(::Commodore::Serial::Line::Data, !(value&0x02));
}
printf("1540 serial port VIA port B: %02x\n", value);
}
else
printf("1540 serial port VIA port A: %02x\n", value);
}
void set_serial_line_state(::Commodore::Serial::Line line, bool value) {
printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off");
switch(line) {
default: break;
case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0 : 0x01); break;
case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break;
case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); break;
}
}
void set_serial_port(std::shared_ptr<::Commodore::Serial::Port> serialPort) {
_serialPort = serialPort;
}
private:
uint8_t _portB;
std::weak_ptr<::Commodore::Serial::Port> _serialPort;
};
class SerialPort : public ::Commodore::Serial::Port {
public:
void set_input(::Commodore::Serial::Line line, bool value) {
std::shared_ptr<SerialPortVIA> serialPortVIA = _serialPortVIA.lock();
if(serialPortVIA) serialPortVIA->set_serial_line_state(line, value);
}
void set_serial_port_via(std::shared_ptr<SerialPortVIA> serialPortVIA) {
@ -35,7 +79,8 @@ class SerialPort : public ::Commodore::Serial::Port {
};
class Machine:
public CPU6502::Processor<Machine> {
public CPU6502::Processor<Machine>,
public MOS::MOS6522IRQDelegate::Delegate {
public:
Machine();
@ -44,6 +89,9 @@ class Machine:
void set_rom(const uint8_t *rom);
void set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus);
// to satisfy MOS::MOS6522::Delegate
virtual void mos6522_did_change_interrupt_status(void *mos6522);
private:
uint8_t _ram[0x800];
uint8_t _rom[0x4000];

View File

@ -76,7 +76,7 @@ class UserPortVIA: public MOS::MOS6522<UserPortVIA>, public MOS::MOS6522IRQDeleg
}
void set_serial_line_state(::Commodore::Serial::Line line, bool value) {
printf("Serial port line %d: %s\n", line, value ? "on" : "off");
printf("VIC Serial port line %d: %s\n", line, value ? "on" : "off");
switch(line) {
default: break;
case ::Commodore::Serial::Line::Data: _portA = (_portA & ~0x02) | (value ? 0 : 0x02); break;