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:
parent
0d3d0fbe4d
commit
d2cded7b59
43
Machines/Commodore/SerialBus.cpp
Normal file
43
Machines/Commodore/SerialBus.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
Machines/Commodore/SerialBus.hpp
Normal file
67
Machines/Commodore/SerialBus.hpp
Normal 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 */
|
@ -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");
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 */,
|
||||||
|
Loading…
Reference in New Issue
Block a user