1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-23 03:32:32 +00:00

Attempted to separate out the concept of a serial port and a serial bus, since the bus may be shared, and to establish half duplex communications from the Vic.

This commit is contained in:
Thomas Harte 2016-07-05 14:55:20 -04:00
parent 0d3d0fbe4d
commit d2cded7b59
5 changed files with 134 additions and 39 deletions

View File

@ -0,0 +1,43 @@
//
// SerialPort.cpp
// Clock Signal
//
// Created by Thomas Harte on 05/07/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#include "SerialBus.hpp"
using namespace Commodore::Serial;
void Bus::add_port(std::shared_ptr<Port> port)
{
_ports.push_back(port);
}
void Bus::set_line_output_did_change(Line line)
{
bool new_line_value = false;
for(std::weak_ptr<Port> port : _ports)
{
std::shared_ptr<Port> locked_port = port.lock();
if(locked_port)
{
new_line_value |= locked_port->get_output(line);
}
}
if(new_line_value != _line_values[line])
{
_line_values[line] = new_line_value;
for(std::weak_ptr<Port> port : _ports)
{
std::shared_ptr<Port> locked_port = port.lock();
if(locked_port)
{
locked_port->set_input(line, new_line_value);
}
}
}
}

View File

@ -0,0 +1,67 @@
//
// SerialPort.hpp
// Clock Signal
//
// Created by Thomas Harte on 05/07/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#ifndef SerialBus_hpp
#define SerialBus_hpp
#import <vector>
namespace Commodore {
namespace Serial {
enum Line {
ServiceRequest = 0,
Attention,
Clock,
Data,
Reset
};
class Port;
class Bus {
public:
Bus() : _line_values{false, false, false, false, false} {}
void add_port(std::shared_ptr<Port> port);
void set_line_output_did_change(Line line);
private:
bool _line_values[5];
std::vector<std::weak_ptr<Port>> _ports;
};
class Port {
public:
Port() : _line_values{false, false, false, false, false} {}
void set_output(Line line, bool value) {
_line_values[line] = value;
std::shared_ptr<Bus> bus = _serial_bus.lock();
if(bus) bus->set_line_output_did_change(line);
}
bool get_output(Line line) {
return _line_values[line];
}
virtual void set_input(Line line, bool value) = 0;
inline void set_serial_bus(std::shared_ptr<Bus> serial_bus) {
_serial_bus = serial_bus;
}
private:
std::weak_ptr<Bus> _serial_bus;
bool _line_values[5];
};
}
}
#endif /* SerialPort_hpp */

View File

@ -15,18 +15,27 @@ using namespace Commodore::Vic20;
Machine::Machine() : Machine::Machine() :
_rom(nullptr) _rom(nullptr)
{ {
// create 6522s, serial port and bus
_userPortVIA.reset(new UserPortVIA); _userPortVIA.reset(new UserPortVIA);
_keyboardVIA.reset(new KeyboardVIA); _keyboardVIA.reset(new KeyboardVIA);
_serialPort.reset(new SerialPort); _serialPort.reset(new SerialPort);
_serialBus.reset(new ::Commodore::Serial::Bus);
// wire up the serial bus and serial port
_serialBus->add_port(_serialPort);
_serialPort->set_serial_bus(_serialBus);
// wire up 6522s and serial port
_userPortVIA->set_serial_port(_serialPort); _userPortVIA->set_serial_port(_serialPort);
_keyboardVIA->set_serial_port(_serialPort); _keyboardVIA->set_serial_port(_serialPort);
_serialPort->set_vias(_userPortVIA, _keyboardVIA); _serialPort->set_vias(_userPortVIA, _keyboardVIA);
// wire up the 6522s, tape and machine
_userPortVIA->set_delegate(this); _userPortVIA->set_delegate(this);
_keyboardVIA->set_delegate(this); _keyboardVIA->set_delegate(this);
_tape.set_delegate(this); _tape.set_delegate(this);
// establish the memory maps
memset(_videoMemoryMap, 0, sizeof(_videoMemoryMap)); memset(_videoMemoryMap, 0, sizeof(_videoMemoryMap));
memset(_processorReadMemoryMap, 0, sizeof(_processorReadMemoryMap)); memset(_processorReadMemoryMap, 0, sizeof(_processorReadMemoryMap));
memset(_processorWriteMemoryMap, 0, sizeof(_processorWriteMemoryMap)); memset(_processorWriteMemoryMap, 0, sizeof(_processorWriteMemoryMap));
@ -317,32 +326,7 @@ void Tape::process_input_pulse(Storage::Tape::Pulse pulse)
#pragma mark - Serial Port #pragma mark - Serial Port
void SerialPort::set_clock_output(bool value) void SerialPort::set_input(::Commodore::Serial::Line line, bool value)
{ {
printf("Serial port clock output %s\n", value ? "on" : "off"); printf("Serial port line %d: %s\n", line, 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");
} }

View File

@ -13,6 +13,7 @@
#include "../../../Storage/Tape/Tape.hpp" #include "../../../Storage/Tape/Tape.hpp"
#include "../../../Components/6560/6560.hpp" #include "../../../Components/6560/6560.hpp"
#include "../../../Components/6522/6522.hpp" #include "../../../Components/6522/6522.hpp"
#include "../SerialBus.hpp"
#include "../../CRTMachine.hpp" #include "../../CRTMachine.hpp"
#include "../../Typer.hpp" #include "../../Typer.hpp"
@ -26,7 +27,6 @@ enum ROMSlot {
ROMSlotCharacters, ROMSlotCharacters,
}; };
#define key(line, mask) (((mask) << 3) | (line)) #define key(line, mask) (((mask) << 3) | (line))
enum Key: uint16_t { enum Key: uint16_t {
@ -61,15 +61,9 @@ enum JoystickInput {
class UserPortVIA; class UserPortVIA;
class KeyboardVIA; class KeyboardVIA;
class SerialPort { class SerialPort : public ::Commodore::Serial::Port {
public: public:
void set_clock_output(bool value); void set_input(::Commodore::Serial::Line line, 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> userPortVIA, std::shared_ptr<KeyboardVIA> keyboardVIA) { void set_vias(std::shared_ptr<UserPortVIA> userPortVIA, std::shared_ptr<KeyboardVIA> keyboardVIA) {
_userPortVIA = userPortVIA; _userPortVIA = userPortVIA;
@ -106,7 +100,7 @@ class UserPortVIA: public MOS::MOS6522<UserPortVIA>, public MOS::MOS6522IRQDeleg
void set_port_output(Port port, uint8_t value, uint8_t mask) { void set_port_output(Port port, uint8_t value, uint8_t mask) {
if(!port) { if(!port) {
std::shared_ptr<SerialPort> serialPort = _serialPort.lock(); std::shared_ptr<SerialPort> serialPort = _serialPort.lock();
if(serialPort) serialPort->set_attention_output(!(value&0x80)); if(serialPort) serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x80));
} }
} }
@ -165,9 +159,9 @@ class KeyboardVIA: public MOS::MOS6522<KeyboardVIA>, public MOS::MOS6522IRQDeleg
std::shared_ptr<SerialPort> serialPort = _serialPort.lock(); std::shared_ptr<SerialPort> serialPort = _serialPort.lock();
if(serialPort) { if(serialPort) {
if(port == Port::A) { if(port == Port::A) {
serialPort->set_clock_output(value); serialPort->set_output(::Commodore::Serial::Line::Clock, value);
} else { } else {
serialPort->set_data_output(value); serialPort->set_output(::Commodore::Serial::Line::Data, value);
} }
} }
} }
@ -287,6 +281,7 @@ class Machine:
std::shared_ptr<UserPortVIA> _userPortVIA; std::shared_ptr<UserPortVIA> _userPortVIA;
std::shared_ptr<KeyboardVIA> _keyboardVIA; std::shared_ptr<KeyboardVIA> _keyboardVIA;
std::shared_ptr<SerialPort> _serialPort; std::shared_ptr<SerialPort> _serialPort;
std::shared_ptr<::Commodore::Serial::Bus> _serialBus;
// Tape // Tape
Tape _tape; Tape _tape;

View File

@ -27,6 +27,7 @@
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; };
4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; };
4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */; }; 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */; };
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */; }; 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */; };
4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */; }; 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */; };
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */; }; 4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */; };
@ -389,6 +390,8 @@
4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = "<group>"; }; 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = "<group>"; };
4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Commodore1540.cpp; sourceTree = "<group>"; }; 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Commodore1540.cpp; sourceTree = "<group>"; };
4B4DC8271D2C2470003C5BF8 /* Commodore1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Commodore1540.hpp; sourceTree = "<group>"; }; 4B4DC8271D2C2470003C5BF8 /* Commodore1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Commodore1540.hpp; sourceTree = "<group>"; };
4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = "<group>"; };
4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = "<group>"; };
4B55CE561C3B7D360093A61B /* Atari2600Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atari2600Document.swift; sourceTree = "<group>"; }; 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atari2600Document.swift; sourceTree = "<group>"; };
4B55CE571C3B7D360093A61B /* ElectronDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronDocument.swift; sourceTree = "<group>"; }; 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronDocument.swift; sourceTree = "<group>"; };
4B55CE5B1C3B7D6F0093A61B /* CSOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSOpenGLView.h; sourceTree = "<group>"; }; 4B55CE5B1C3B7D6F0093A61B /* CSOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSOpenGLView.h; sourceTree = "<group>"; };
@ -867,6 +870,8 @@
children = ( children = (
4B4DC8251D2C2470003C5BF8 /* 1540 */, 4B4DC8251D2C2470003C5BF8 /* 1540 */,
4B4DC81E1D2C2425003C5BF8 /* Vic-20 */, 4B4DC81E1D2C2425003C5BF8 /* Vic-20 */,
4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */,
4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */,
); );
path = Commodore; path = Commodore;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1801,6 +1806,7 @@
4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */, 4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */,
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */, 4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */,
4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */, 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */,
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */,
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */, 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */,
4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */, 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */,
4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */, 4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */,