diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 91e785aef..34bb53f74 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -112,17 +112,17 @@ template class MOS6522 { _registers.auxiliary_control = value; break; case 0xc: - printf("Peripheral control %02x\n", value); +// printf("Peripheral control %02x\n", value); _registers.peripheral_control = value; switch(value & 0x0e) { - default: break; + default: printf("Unimplemented control line mode %d\n", (value >> 1)&7); break; case 0x0c: static_cast(this)->set_control_line_output(Port::A, Line::Two, false); break; case 0x0e: static_cast(this)->set_control_line_output(Port::A, Line::Two, true); break; } switch(value & 0xe0) { - default: break; + default: printf("Unimplemented control line mode %d\n", (value >> 5)&7); break; case 0xc0: static_cast(this)->set_control_line_output(Port::B, Line::Two, false); break; case 0xe0: static_cast(this)->set_control_line_output(Port::B, Line::Two, true); break; } diff --git a/Machines/Vic-20/Vic20.cpp b/Machines/Vic-20/Vic20.cpp index ca19e6c70..c912908b4 100644 --- a/Machines/Vic-20/Vic20.cpp +++ b/Machines/Vic-20/Vic20.cpp @@ -15,8 +15,16 @@ using namespace Vic20; Machine::Machine() : _rom(nullptr) { - _userPortVIA.set_delegate(this); - _keyboardVIA.set_delegate(this); + _userPortVIA.reset(new UserPortVIA); + _keyboardVIA.reset(new KeyboardVIA); + _serialPort.reset(new SerialPort); + + _userPortVIA->set_serial_port(_serialPort); + _keyboardVIA->set_serial_port(_serialPort); + _serialPort->set_vias(_userPortVIA, _keyboardVIA); + + _userPortVIA->set_delegate(this); + _keyboardVIA->set_delegate(this); _tape.set_delegate(this); memset(_videoMemoryMap, 0, sizeof(_videoMemoryMap)); @@ -71,8 +79,8 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin if((address&0xfc00) == 0x9000) { if((address&0xff00) == 0x9000) result &= _mos6560->get_register(address); - if((address&0xfc10) == 0x9010) result &= _userPortVIA.get_register(address); - if((address&0xfc20) == 0x9020) result &= _keyboardVIA.get_register(address); + if((address&0xfc10) == 0x9010) result &= _userPortVIA->get_register(address); + if((address&0xfc20) == 0x9020) result &= _keyboardVIA->get_register(address); } *value = result; @@ -80,10 +88,10 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin if(_use_fast_tape_hack && address == 0xf92f && operation == CPU6502::BusOperation::ReadOpcode) { // advance time on the tape and the VIAs until an interrupt is signalled - while(!_userPortVIA.get_interrupt_line() && !_keyboardVIA.get_interrupt_line()) + while(!_userPortVIA->get_interrupt_line() && !_keyboardVIA->get_interrupt_line()) { - _userPortVIA.run_for_half_cycles(2); - _keyboardVIA.run_for_half_cycles(2); + _userPortVIA->run_for_half_cycles(2); + _keyboardVIA->run_for_half_cycles(2); _tape.run_for_cycles(1); } } @@ -95,13 +103,13 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin if((address&0xfc00) == 0x9000) { if((address&0xff00) == 0x9000) _mos6560->set_register(address, *value); - if((address&0xfc10) == 0x9010) _userPortVIA.set_register(address, *value); - if((address&0xfc20) == 0x9020) _keyboardVIA.set_register(address, *value); + if((address&0xfc10) == 0x9010) _userPortVIA->set_register(address, *value); + if((address&0xfc20) == 0x9020) _keyboardVIA->set_register(address, *value); } } - _userPortVIA.run_for_half_cycles(2); - _keyboardVIA.run_for_half_cycles(2); + _userPortVIA->run_for_half_cycles(2); + _keyboardVIA->run_for_half_cycles(2); if(_typer) _typer->update(1); _tape.run_for_cycles(1); return 1; @@ -111,8 +119,8 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin void Machine::mos6522_did_change_interrupt_status(void *mos6522) { - set_nmi_line(_userPortVIA.get_interrupt_line()); - set_irq_line(_keyboardVIA.get_interrupt_line()); + set_nmi_line(_userPortVIA->get_interrupt_line()); + set_irq_line(_keyboardVIA->get_interrupt_line()); } #pragma mark - Setup @@ -172,7 +180,7 @@ void Machine::set_tape(std::shared_ptr tape) void Machine::tape_did_change_input(Tape *tape) { - _keyboardVIA.set_control_line_input(KeyboardVIA::Port::A, KeyboardVIA::Line::One, tape->get_input()); + _keyboardVIA->set_control_line_input(KeyboardVIA::Port::A, KeyboardVIA::Line::One, tape->get_input()); } #pragma mark - Typer @@ -306,3 +314,35 @@ void Tape::process_input_pulse(Storage::Tape::Pulse pulse) if(_delegate) _delegate->tape_did_change_input(this); } } + +#pragma mark - Serial Port + +void SerialPort::set_clock_output(bool value) +{ + printf("Serial port clock output %s\n", value ? "on" : "off"); +} + +void SerialPort::set_data_output(bool value) +{ + printf("Serial port data output %s\n", value ? "on" : "off"); +} + +void SerialPort::set_attention_output(bool value) +{ + printf("Serial port attention output %s\n", value ? "on" : "off"); +} + +void SerialPort::set_clock_input(bool value) +{ + printf("Serial port clock input %s\n", value ? "on" : "off"); +} + +void SerialPort::set_data_input(bool value) +{ + printf("Serial port data input %s\n", value ? "on" : "off"); +} + +void SerialPort::set_attention_input(bool value) +{ + printf("Serial port attention input %s\n", value ? "on" : "off"); +} diff --git a/Machines/Vic-20/Vic20.hpp b/Machines/Vic-20/Vic20.hpp index 303c5d4be..4c298aa13 100644 --- a/Machines/Vic-20/Vic20.hpp +++ b/Machines/Vic-20/Vic20.hpp @@ -57,6 +57,28 @@ enum JoystickInput { Fire = 0x20 }; +class UserPortVIA; +class KeyboardVIA; + +class SerialPort { + public: + void set_clock_output(bool value); + void set_data_output(bool value); + void set_attention_output(bool value); + + void set_clock_input(bool value); + void set_data_input(bool value); + void set_attention_input(bool value); + + void set_vias(std::shared_ptr userPortVIA, std::shared_ptr keyboardVIA) { + _userPortVIA = userPortVIA; + _keyboardVIA = keyboardVIA; + } + + private: + std::weak_ptr _userPortVIA; + std::weak_ptr _keyboardVIA; +}; class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: @@ -68,9 +90,9 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg } void set_control_line_output(Port port, Line line, bool value) { - if(port == Port::A && line == Line::Two) { - printf("Tape motor %s\n", value ? "on" : "off"); - } +// if(port == Port::A && line == Line::Two) { +// printf("Tape motor %s\n", value ? "on" : "off"); +// } } void set_joystick_state(JoystickInput input, bool value) { @@ -80,12 +102,24 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg } } + void set_port_output(Port port, uint8_t value, uint8_t mask) { + if(!port) { + std::shared_ptr serialPort = _serialPort.lock(); + if(serialPort) serialPort->set_attention_output(!(value&0x80)); + } + } + using MOS6522IRQDelegate::set_interrupt_status; UserPortVIA() : _portA(0xbf) {} + void set_serial_port(std::shared_ptr serialPort) { + _serialPort = serialPort; + } + private: uint8_t _portA; + std::weak_ptr _serialPort; }; class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { @@ -126,8 +160,15 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg } void set_control_line_output(Port port, Line line, bool value) { - if(port == Port::A && line == Line::Two) { - printf("Blah Tape motor %s\n", value ? "on" : "off"); + if(line == Line::Two) { + std::shared_ptr serialPort = _serialPort.lock(); + if(serialPort) { + if(port == Port::A) { + serialPort->set_clock_output(value); + } else { + serialPort->set_data_output(value); + } + } } } @@ -140,10 +181,15 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg using MOS6522IRQDelegate::set_interrupt_status; + void set_serial_port(std::shared_ptr serialPort) { + _serialPort = serialPort; + } + private: uint8_t _portB; uint8_t _columns[8]; uint8_t _activation_mask; + std::weak_ptr _serialPort; }; class Tape: public Storage::TapePlayer { @@ -185,11 +231,11 @@ class Machine: void add_prg(size_t length, const uint8_t *data); void set_tape(std::shared_ptr tape); - void set_key_state(Key key, bool isPressed) { _keyboardVIA.set_key_state(key, isPressed); } - void clear_all_keys() { _keyboardVIA.clear_all_keys(); } + void set_key_state(Key key, bool isPressed) { _keyboardVIA->set_key_state(key, isPressed); } + void clear_all_keys() { _keyboardVIA->clear_all_keys(); } void set_joystick_state(JoystickInput input, bool isPressed) { - _userPortVIA.set_joystick_state(input, isPressed); - _keyboardVIA.set_joystick_state(input, isPressed); + _userPortVIA->set_joystick_state(input, isPressed); + _keyboardVIA->set_joystick_state(input, isPressed); } inline void set_use_fast_tape_hack(bool activate) { _use_fast_tape_hack = activate; } @@ -237,8 +283,9 @@ class Machine: void write_to_map(uint8_t **map, uint8_t *area, uint16_t address, uint16_t length); std::unique_ptr _mos6560; - UserPortVIA _userPortVIA; - KeyboardVIA _keyboardVIA; + std::shared_ptr _userPortVIA; + std::shared_ptr _keyboardVIA; + std::shared_ptr _serialPort; // Tape Tape _tape;