Skip to content

Commit

Permalink
Add SPoverSLIP to linux
Browse files Browse the repository at this point in the history
  • Loading branch information
markjfisher committed Jan 16, 2024
1 parent 9c136cc commit 627fee2
Show file tree
Hide file tree
Showing 70 changed files with 1,410 additions and 1,342 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.13)

project(applewin HOMEPAGE_URL "https://github.com/audetto/AppleWin")
project(applewin HOMEPAGE_URL "https://github.com/FujiNetWIFI/AppleWin")

option(BUILD_APPLEN "build ncurses frontend")
option(BUILD_QAPPLE "build Qt5 frontend")
Expand Down
5 changes: 5 additions & 0 deletions source/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
BasedOnStyle: LLVM
ColumnLimit: 160
BreakBeforeBraces: Allman
AllowShortBlocksOnASingleLine: true
AlwaysBreakAfterReturnType: None
65 changes: 65 additions & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ set(SOURCE_FILES
Utilities.cpp
FrameBase.cpp
CmdLine.cpp
SmartPortOverSlip.cpp

Configuration/PropertySheetHelper.cpp
Configuration/Config.cpp
Expand All @@ -119,6 +120,36 @@ set(SOURCE_FILES
linux/duplicates/SNESMAX.cpp
linux/duplicates/Keyboard.cpp

SPoverSLIP/CloseRequest.cpp
SPoverSLIP/CloseResponse.cpp
SPoverSLIP/Connection.cpp
SPoverSLIP/ControlRequest.cpp
SPoverSLIP/ControlResponse.cpp
SPoverSLIP/FormatRequest.cpp
SPoverSLIP/FormatResponse.cpp
SPoverSLIP/InitRequest.cpp
SPoverSLIP/InitResponse.cpp
SPoverSLIP/Listener.cpp
SPoverSLIP/OpenRequest.cpp
SPoverSLIP/OpenResponse.cpp
SPoverSLIP/ReadBlockRequest.cpp
SPoverSLIP/ReadBlockResponse.cpp
SPoverSLIP/ReadRequest.cpp
SPoverSLIP/ReadResponse.cpp
SPoverSLIP/Request.cpp
SPoverSLIP/Requestor.cpp
SPoverSLIP/ResetRequest.cpp
SPoverSLIP/ResetResponse.cpp
SPoverSLIP/Response.cpp
SPoverSLIP/SLIP.cpp
SPoverSLIP/StatusRequest.cpp
SPoverSLIP/StatusResponse.cpp
SPoverSLIP/TCPConnection.cpp
SPoverSLIP/WriteBlockRequest.cpp
SPoverSLIP/WriteBlockResponse.cpp
SPoverSLIP/WriteRequest.cpp
SPoverSLIP/WriteResponse.cpp

Z80VICE/z80.cpp
Z80VICE/z80mem.cpp
Z80VICE/daa.cpp
Expand Down Expand Up @@ -178,6 +209,7 @@ set(HEADER_FILES
FrameBase.h
FourPlay.h
SNESMAX.h
SmartPortOverSlip.h

Common.h
DiskDefs.h
Expand Down Expand Up @@ -215,6 +247,39 @@ set(HEADER_FILES
linux/network/slirp2.h
linux/network/portfwds.h

SPoverSLIP/CloseRequest.h
SPoverSLIP/CloseResponse.h
SPoverSLIP/Connection.h
SPoverSLIP/ControlRequest.h
SPoverSLIP/ControlResponse.h
SPoverSLIP/FormatRequest.h
SPoverSLIP/FormatResponse.h
SPoverSLIP/InitRequest.h
SPoverSLIP/InitResponse.h
SPoverSLIP/Listener.h
SPoverSLIP/OpenRequest.h
SPoverSLIP/OpenResponse.h
SPoverSLIP/Packet.h
SPoverSLIP/ReadBlockRequest.h
SPoverSLIP/ReadBlockResponse.h
SPoverSLIP/ReadRequest.h
SPoverSLIP/ReadResponse.h
SPoverSLIP/Request.h
SPoverSLIP/Requestor.h
SPoverSLIP/ResetRequest.h
SPoverSLIP/ResetResponse.h
SPoverSLIP/Response.h
SPoverSLIP/SLIP.h
SPoverSLIP/SmartPortCodes.h
SPoverSLIP/SPoSLIP.h
SPoverSLIP/StatusRequest.h
SPoverSLIP/StatusResponse.h
SPoverSLIP/TCPConnection.h
SPoverSLIP/WriteBlockRequest.h
SPoverSLIP/WriteBlockResponse.h
SPoverSLIP/WriteRequest.h
SPoverSLIP/WriteResponse.h

Z80VICE/z80.h
Z80VICE/z80mem.h
Z80VICE/z80regs.h
Expand Down
2 changes: 2 additions & 0 deletions source/CardManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#include "Log.h"
#include "StdAfx.h"

#include "CardManager.h"
Expand Down Expand Up @@ -117,6 +118,7 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type)
m_slot[slot] = new Uthernet2(slot);
break;
case CT_SmartPortOverSlip:
LogOutput("Inserting SP over SLIP in slot %d\n", slot);
m_slot[slot] = new SmartPortOverSlip(slot);
break;
case CT_LanguageCard:
Expand Down
29 changes: 13 additions & 16 deletions source/SPoverSLIP/CloseRequest.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
#include "stdafx.h"
#include "CloseRequest.h"

#include "CloseResponse.h"
#include "SmartPortCodes.h"


CloseRequest::CloseRequest(const uint8_t request_sequence_number, const uint8_t sp_unit)
: Request(request_sequence_number, SP_CLOSE, sp_unit) {}
CloseRequest::CloseRequest(const uint8_t request_sequence_number, const uint8_t sp_unit) : Request(request_sequence_number, SP_CLOSE, sp_unit) {}

std::vector<uint8_t> CloseRequest::serialize() const
{
std::vector<uint8_t> request_data;
request_data.push_back(this->get_request_sequence_number());
request_data.push_back(this->get_command_number());
request_data.push_back(this->get_sp_unit());
return request_data;
std::vector<uint8_t> request_data;
request_data.push_back(this->get_request_sequence_number());
request_data.push_back(this->get_command_number());
request_data.push_back(this->get_sp_unit());
return request_data;
}

std::unique_ptr<Response> CloseRequest::deserialize(const std::vector<uint8_t>& data) const
std::unique_ptr<Response> CloseRequest::deserialize(const std::vector<uint8_t> &data) const
{
if (data.size() < 2)
{
throw std::runtime_error("Not enough data to deserialize CloseResponse");
}
if (data.size() < 2)
{
throw std::runtime_error("Not enough data to deserialize CloseResponse");
}

auto response = std::make_unique<CloseResponse>(data[0], data[1]);
return response;
auto response = std::make_unique<CloseResponse>(data[0], data[1]);
return response;
}
8 changes: 4 additions & 4 deletions source/SPoverSLIP/CloseRequest.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#pragma once

#include <vector>
#include <cstdint>
#include <vector>

#include "Request.h"
#include "Response.h"

class CloseRequest : public Request
{
public:
CloseRequest(uint8_t request_sequence_number, uint8_t sp_unit);
std::vector<uint8_t> serialize() const override;
std::unique_ptr<Response> deserialize(const std::vector<uint8_t>& data) const override;
CloseRequest(uint8_t request_sequence_number, uint8_t sp_unit);
std::vector<uint8_t> serialize() const override;
std::unique_ptr<Response> deserialize(const std::vector<uint8_t> &data) const override;
};
9 changes: 4 additions & 5 deletions source/SPoverSLIP/CloseResponse.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#include "stdafx.h"
#include "CloseResponse.h"

CloseResponse::CloseResponse(const uint8_t request_sequence_number, const uint8_t status) : Response(request_sequence_number, status) {}

std::vector<uint8_t> CloseResponse::serialize() const
{
std::vector<uint8_t> data;
data.push_back(this->get_request_sequence_number());
data.push_back(this->get_status());
return data;
std::vector<uint8_t> data;
data.push_back(this->get_request_sequence_number());
data.push_back(this->get_status());
return data;
}
4 changes: 2 additions & 2 deletions source/SPoverSLIP/CloseResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
class CloseResponse : public Response
{
public:
explicit CloseResponse(uint8_t request_sequence_number, uint8_t status);
std::vector<uint8_t> serialize() const override;
explicit CloseResponse(uint8_t request_sequence_number, uint8_t status);
std::vector<uint8_t> serialize() const override;
};
48 changes: 24 additions & 24 deletions source/SPoverSLIP/Connection.cpp
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
#include "StdAfx.h"

#include <vector>
#include "Connection.h"
#include <condition_variable>
#include <cstdint>
#include <mutex>
#include <condition_variable>
#include "Connection.h"
#include <stdexcept>
#include <vector>

std::vector<uint8_t> Connection::wait_for_response(uint8_t request_id, std::chrono::seconds timeout)
{
std::unique_lock<std::mutex> lock(responses_mutex_);
// mutex is unlocked as it goes into a wait, so then the inserting thread can add to map, and this can then pick it up when notified, or timeout.
if (!response_cv_.wait_for(lock, timeout, [this, request_id]() { return responses_.count(request_id) > 0; }))
{
throw std::runtime_error("Timeout waiting for response");
}
std::vector<uint8_t> response_data = responses_[request_id];
responses_.erase(request_id);
return response_data;
std::unique_lock<std::mutex> lock(responses_mutex_);
// mutex is unlocked as it goes into a wait, so then the inserting thread can
// add to map, and this can then pick it up when notified, or timeout.
if (!response_cv_.wait_for(lock, timeout, [this, request_id]() { return responses_.count(request_id) > 0; }))
{
throw std::runtime_error("Timeout waiting for response");
}
std::vector<uint8_t> response_data = responses_[request_id];
responses_.erase(request_id);
return response_data;
}

std::vector<uint8_t> Connection::wait_for_request()
{
std::unique_lock<std::mutex> lock(responses_mutex_);
response_cv_.wait(lock, [this]() { return !responses_.empty(); });
const auto it = responses_.begin();
std::vector<uint8_t> request_data = it->second;
responses_.erase(it);
std::unique_lock<std::mutex> lock(responses_mutex_);
response_cv_.wait(lock, [this]() { return !responses_.empty(); });
const auto it = responses_.begin();
std::vector<uint8_t> request_data = it->second;
responses_.erase(it);

return request_data;
return request_data;
}

void Connection::join()
{
if (reading_thread_.joinable())
{
reading_thread_.join();
}
if (reading_thread_.joinable())
{
reading_thread_.join();
}
}
35 changes: 18 additions & 17 deletions source/SPoverSLIP/Connection.h
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
#pragma once

#include <vector>
#include <atomic>
#include <map>
#include <chrono>
#include <condition_variable>
#include <cstdint>
#include <map>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <thread>
#include <vector>

class Connection
{
public:
virtual ~Connection() = default;
virtual void send_data(const std::vector<uint8_t>& data) = 0;
virtual ~Connection() = default;
virtual void send_data(const std::vector<uint8_t> &data) = 0;

virtual void create_read_channel() = 0;
virtual void create_read_channel() = 0;

bool is_connected() const { return is_connected_; }
void set_is_connected(const bool is_connected) { is_connected_ = is_connected; }
bool is_connected() const { return is_connected_; }
void set_is_connected(const bool is_connected) { is_connected_ = is_connected; }

std::vector<uint8_t> wait_for_response(uint8_t request_id, std::chrono::seconds timeout);
std::vector<uint8_t> wait_for_request();
std::vector<uint8_t> wait_for_response(uint8_t request_id, std::chrono::seconds timeout);
std::vector<uint8_t> wait_for_request();

void join();
void join();

private:
std::atomic<bool> is_connected_{false};
std::atomic<bool> is_connected_{false};

protected:
std::map<uint8_t, std::vector<uint8_t>> responses_;
std::thread reading_thread_;
std::map<uint8_t, std::vector<uint8_t>> responses_;
std::thread reading_thread_;

std::mutex responses_mutex_;
std::condition_variable response_cv_;
std::mutex responses_mutex_;
std::condition_variable response_cv_;
};
36 changes: 18 additions & 18 deletions source/SPoverSLIP/ControlRequest.cpp
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#include "stdafx.h"
#include "ControlRequest.h"

#include "ControlResponse.h"
#include "SmartPortCodes.h"


ControlRequest::ControlRequest(const uint8_t request_sequence_number, const uint8_t sp_unit, const uint8_t control_code, std::vector<uint8_t>& data)
: Request(request_sequence_number, SP_CONTROL, sp_unit), control_code_(control_code), data_(std::move(data)) {}
ControlRequest::ControlRequest(const uint8_t request_sequence_number, const uint8_t sp_unit, const uint8_t control_code, std::vector<uint8_t> &data)
: Request(request_sequence_number, SP_CONTROL, sp_unit), control_code_(control_code), data_(std::move(data))
{
}

std::vector<uint8_t> ControlRequest::serialize() const
{
std::vector<uint8_t> request_data;
request_data.push_back(this->get_request_sequence_number());
request_data.push_back(this->get_command_number());
request_data.push_back(this->get_sp_unit());
request_data.push_back(this->get_control_code());
request_data.insert(request_data.end(), get_data().begin(), get_data().end());
return request_data;
std::vector<uint8_t> request_data;
request_data.push_back(this->get_request_sequence_number());
request_data.push_back(this->get_command_number());
request_data.push_back(this->get_sp_unit());
request_data.push_back(this->get_control_code());
request_data.insert(request_data.end(), get_data().begin(), get_data().end());
return request_data;
}

std::unique_ptr<Response> ControlRequest::deserialize(const std::vector<uint8_t>& data) const
std::unique_ptr<Response> ControlRequest::deserialize(const std::vector<uint8_t> &data) const
{
if (data.size() < 2)
{
throw std::runtime_error("Not enough data to deserialize ControlResponse");
}
if (data.size() < 2)
{
throw std::runtime_error("Not enough data to deserialize ControlResponse");
}

auto response = std::make_unique<ControlResponse>(data[0], data[1]);
return response;
auto response = std::make_unique<ControlResponse>(data[0], data[1]);
return response;
}
Loading

0 comments on commit 627fee2

Please sign in to comment.