Merge native support for Uthernet II from AppleWin.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
parent
9006e39eaa
commit
bbb5783fa6
16 changed files with 96 additions and 1385 deletions
|
@ -31,9 +31,10 @@ endif()
|
||||||
find_package(Boost REQUIRED)
|
find_package(Boost REQUIRED)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
Tfe/tfe.cpp
|
|
||||||
Tfe/tfearch.cpp
|
Tfe/tfearch.cpp
|
||||||
Tfe/tfesupp.cpp
|
Tfe/tfesupp.cpp
|
||||||
|
Tfe/NetworkBackend.cpp
|
||||||
|
Tfe/PCapBackend.cpp
|
||||||
|
|
||||||
Debugger/Debug.cpp
|
Debugger/Debug.cpp
|
||||||
Debugger/Debugger_Help.cpp
|
Debugger/Debugger_Help.cpp
|
||||||
|
@ -48,6 +49,8 @@ set(SOURCE_FILES
|
||||||
Debugger/Debugger_Commands.cpp
|
Debugger/Debugger_Commands.cpp
|
||||||
Debugger/Util_MemoryTextFile.cpp
|
Debugger/Util_MemoryTextFile.cpp
|
||||||
|
|
||||||
|
Uthernet1.cpp
|
||||||
|
Uthernet2.cpp
|
||||||
StrFormat.cpp
|
StrFormat.cpp
|
||||||
6522.cpp
|
6522.cpp
|
||||||
VidHD.cpp
|
VidHD.cpp
|
||||||
|
@ -99,8 +102,6 @@ set(SOURCE_FILES
|
||||||
linux/linuxframe.cpp
|
linux/linuxframe.cpp
|
||||||
linux/context.cpp
|
linux/context.cpp
|
||||||
linux/tape.cpp
|
linux/tape.cpp
|
||||||
linux/network/uthernet2.cpp
|
|
||||||
linux/network/tfe2.cpp
|
|
||||||
linux/network/slirp2.cpp
|
linux/network/slirp2.cpp
|
||||||
|
|
||||||
linux/duplicates/Debugger_Display.cpp
|
linux/duplicates/Debugger_Display.cpp
|
||||||
|
@ -119,6 +120,14 @@ set(SOURCE_FILES
|
||||||
)
|
)
|
||||||
|
|
||||||
set(HEADER_FILES
|
set(HEADER_FILES
|
||||||
|
Tfe/tfearch.h
|
||||||
|
Tfe/tfesupp.h
|
||||||
|
Tfe/NetworkBackend.h
|
||||||
|
Tfe/PCapBackend.h
|
||||||
|
|
||||||
|
Uthernet1.h
|
||||||
|
Uthernet2.h
|
||||||
|
W5100.h
|
||||||
6522.h
|
6522.h
|
||||||
VidHD.h
|
VidHD.h
|
||||||
SSI263.h
|
SSI263.h
|
||||||
|
@ -195,10 +204,7 @@ set(HEADER_FILES
|
||||||
linux/keyboard.h
|
linux/keyboard.h
|
||||||
linux/linuxframe.h
|
linux/linuxframe.h
|
||||||
linux/tape.h
|
linux/tape.h
|
||||||
linux/network/uthernet2.h
|
|
||||||
linux/network/tfe2.h
|
|
||||||
linux/network/slirp2.h
|
linux/network/slirp2.h
|
||||||
linux/network/registers.h
|
|
||||||
|
|
||||||
Z80VICE/z80.h
|
Z80VICE/z80.h
|
||||||
Z80VICE/z80mem.h
|
Z80VICE/z80mem.h
|
||||||
|
|
|
@ -43,7 +43,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Uthernet1.h"
|
#include "Uthernet1.h"
|
||||||
#include "Uthernet2.h"
|
#include "Uthernet2.h"
|
||||||
#include "VidHD.h"
|
#include "VidHD.h"
|
||||||
#include "linux/network/uthernet2.h"
|
|
||||||
#include "LanguageCard.h"
|
#include "LanguageCard.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
|
||||||
|
@ -96,9 +95,6 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type)
|
||||||
case CT_Uthernet:
|
case CT_Uthernet:
|
||||||
m_slot[slot] = new Uthernet1(slot);
|
m_slot[slot] = new Uthernet1(slot);
|
||||||
break;
|
break;
|
||||||
case CT_Uthernet2:
|
|
||||||
m_slot[slot] = new Uthernet2(slot);
|
|
||||||
break;
|
|
||||||
case CT_FourPlay:
|
case CT_FourPlay:
|
||||||
m_slot[slot] = new FourPlayCard(slot);
|
m_slot[slot] = new FourPlayCard(slot);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -71,6 +71,7 @@ typedef UINT64 uint64_t;
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,7 @@ void TfePcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const
|
||||||
/* determine the count of bytes which has been returned,
|
/* determine the count of bytes which has been returned,
|
||||||
* but make sure not to overrun the buffer
|
* but make sure not to overrun the buffer
|
||||||
*/
|
*/
|
||||||
pinternal->rxlength = min(pinternal->size, header->caplen);
|
pinternal->rxlength = std::min(pinternal->size, header->caplen);
|
||||||
|
|
||||||
memcpy(pinternal->buffer, pkt_data, pinternal->rxlength);
|
memcpy(pinternal->buffer, pkt_data, pinternal->rxlength);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
|
|
||||||
#include "Debugger/Debugger_Types.h"
|
#include "Debugger/Debugger_Types.h"
|
||||||
|
|
||||||
#include "Tfe/tfe.h"
|
|
||||||
#include "Tfe/tfesupp.h"
|
#include "Tfe/tfesupp.h"
|
||||||
|
#include "Tfe/PCapBackend.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -359,22 +359,22 @@ namespace sa2
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
const std::string current_interface = get_tfe_interface();
|
const std::string current_interface = PCapBackend::tfe_interface;
|
||||||
|
|
||||||
if (ImGui::BeginCombo("pcap", current_interface.c_str()))
|
if (ImGui::BeginCombo("pcap", current_interface.c_str()))
|
||||||
{
|
{
|
||||||
std::vector<char *> ifaces;
|
std::vector<char *> ifaces;
|
||||||
if (tfe_enumadapter_open())
|
if (PCapBackend::tfe_enumadapter_open())
|
||||||
{
|
{
|
||||||
char *pname;
|
char *pname;
|
||||||
char *pdescription;
|
char *pdescription;
|
||||||
|
|
||||||
while (tfe_enumadapter(&pname, &pdescription))
|
while (PCapBackend::tfe_enumadapter(&pname, &pdescription))
|
||||||
{
|
{
|
||||||
ifaces.push_back(pname);
|
ifaces.push_back(pname);
|
||||||
lib_free(pdescription);
|
lib_free(pdescription);
|
||||||
}
|
}
|
||||||
tfe_enumadapter_close();
|
PCapBackend::tfe_enumadapter_close();
|
||||||
|
|
||||||
for (const auto & iface : ifaces)
|
for (const auto & iface : ifaces)
|
||||||
{
|
{
|
||||||
|
@ -382,8 +382,8 @@ namespace sa2
|
||||||
if (ImGui::Selectable(iface, isSelected))
|
if (ImGui::Selectable(iface, isSelected))
|
||||||
{
|
{
|
||||||
// the following line interacts with tfe_enumadapter, so we must run it outside the above loop
|
// the following line interacts with tfe_enumadapter, so we must run it outside the above loop
|
||||||
update_tfe_interface(iface);
|
PCapBackend::tfe_interface = iface;
|
||||||
tfe_SetRegistryInterface(SLOT3, iface);
|
PCapBackend::tfe_SetRegistryInterface(SLOT3, PCapBackend::tfe_interface);
|
||||||
}
|
}
|
||||||
if (isSelected)
|
if (isSelected)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "Interface.h"
|
#include "Interface.h"
|
||||||
#include "Debugger/Debug.h"
|
#include "Debugger/Debug.h"
|
||||||
|
|
||||||
#include "Tfe/tfe.h"
|
|
||||||
#include "frontends/sdl/imgui/settingshelper.h"
|
#include "frontends/sdl/imgui/settingshelper.h"
|
||||||
|
|
||||||
#include "frontends/sdl/imgui/glselector.h"
|
#include "frontends/sdl/imgui/glselector.h"
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "linux/paddle.h"
|
#include "linux/paddle.h"
|
||||||
#include "linux/duplicates/PropertySheet.h"
|
#include "linux/duplicates/PropertySheet.h"
|
||||||
|
|
||||||
|
#include "Debugger/Debug.h"
|
||||||
|
|
||||||
#include "Interface.h"
|
#include "Interface.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
|
@ -17,8 +19,9 @@
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
#include "MouseInterface.h"
|
#include "MouseInterface.h"
|
||||||
#include "Debugger/Debug.h"
|
|
||||||
#include "Mockingboard.h"
|
#include "Mockingboard.h"
|
||||||
|
#include "Uthernet1.h"
|
||||||
|
#include "Uthernet2.h"
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -147,11 +150,20 @@ void DestroyEmulator()
|
||||||
MB_Destroy();
|
MB_Destroy();
|
||||||
DSUninit();
|
DSUninit();
|
||||||
|
|
||||||
tfe_shutdown();
|
for (UINT i = 0; i < NUM_SLOTS; ++i)
|
||||||
|
|
||||||
if (cardManager.QuerySlot(SLOT7) == CT_GenericHDD)
|
|
||||||
{
|
{
|
||||||
dynamic_cast<HarddiskInterfaceCard&>(cardManager.GetRef(SLOT7)).Destroy();
|
switch (cardManager.QuerySlot(i))
|
||||||
|
{
|
||||||
|
case CT_GenericHDD:
|
||||||
|
dynamic_cast<HarddiskInterfaceCard&>(cardManager.GetRef(i)).Destroy();
|
||||||
|
break;
|
||||||
|
case CT_Uthernet:
|
||||||
|
dynamic_cast<Uthernet1&>(cardManager.GetRef(i)).Destroy();
|
||||||
|
break;
|
||||||
|
case CT_Uthernet2:
|
||||||
|
dynamic_cast<Uthernet2&>(cardManager.GetRef(i)).Destroy();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintDestroy();
|
PrintDestroy();
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "linux/linuxframe.h"
|
#include "linux/linuxframe.h"
|
||||||
#include "linux/context.h"
|
#include "linux/context.h"
|
||||||
|
#include "linux/network/slirp2.h"
|
||||||
|
#include "Tfe/PCapBackend.h"
|
||||||
#include "Interface.h"
|
#include "Interface.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
|
@ -128,6 +130,15 @@ void LinuxFrame::Restart()
|
||||||
Begin();
|
Begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<NetworkBackend> LinuxFrame::CreateNetworkBackend()
|
||||||
|
{
|
||||||
|
#ifdef U2_USE_SLIRP
|
||||||
|
return std::make_shared<SlirpBackend>();
|
||||||
|
#else
|
||||||
|
return std::make_shared<PCapBackend>(PCapBackend::tfe_interface);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int MessageBox(HWND, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
|
int MessageBox(HWND, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
|
||||||
{
|
{
|
||||||
return GetFrame().FrameMessageBox(lpText, lpCaption, uType);
|
return GetFrame().FrameMessageBox(lpText, lpCaption, uType);
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
void Restart() override; // calls End() - Begin()
|
void Restart() override; // calls End() - Begin()
|
||||||
void GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) override;
|
void GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) override;
|
||||||
|
|
||||||
|
std::shared_ptr<NetworkBackend> CreateNetworkBackend() override;
|
||||||
|
|
||||||
void CycleVideoType();
|
void CycleVideoType();
|
||||||
void Cycle50ScanLines();
|
void Cycle50ScanLines();
|
||||||
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Uthernet II registers
|
|
||||||
|
|
||||||
#define C0X_MODE_REGISTER 0x04
|
|
||||||
#define C0X_ADDRESS_HIGH 0x05
|
|
||||||
#define C0X_ADDRESS_LOW 0x06
|
|
||||||
#define C0X_DATA_PORT 0x07
|
|
||||||
|
|
||||||
// W5100 registers and values
|
|
||||||
|
|
||||||
#define MR 0x0000
|
|
||||||
#define GAR0 0x0001
|
|
||||||
#define GAR3 0x0004
|
|
||||||
#define SUBR0 0x0005
|
|
||||||
#define SUBR3 0x0008
|
|
||||||
#define SHAR0 0x0009
|
|
||||||
#define SHAR5 0x000E
|
|
||||||
#define SIPR0 0x000F
|
|
||||||
#define SIPR3 0x0012
|
|
||||||
#define RTR0 0x0017
|
|
||||||
#define RTR1 0x0018
|
|
||||||
#define RMSR 0x001A
|
|
||||||
#define TMSR 0x001B
|
|
||||||
#define UPORT1 0x002F
|
|
||||||
#define S0_BASE 0x0400
|
|
||||||
#define S3_MAX 0x07FF
|
|
||||||
#define TX_BASE 0x4000
|
|
||||||
#define RX_BASE 0x6000
|
|
||||||
#define MEM_MAX 0x7FFF
|
|
||||||
#define MEM_SIZE 0x8000
|
|
||||||
|
|
||||||
#define MR_IND 0x01 // 0
|
|
||||||
#define MR_AI 0x02 // 1
|
|
||||||
#define MR_PPOE 0x08 // 3
|
|
||||||
#define MR_PB 0x10 // 4
|
|
||||||
#define MR_RST 0x80 // 7
|
|
||||||
|
|
||||||
#define SN_MR_PROTO_MASK 0x0F
|
|
||||||
#define SN_MR_CLOSED 0x00
|
|
||||||
#define SN_MR_TCP 0x01
|
|
||||||
#define SN_MR_UDP 0x02
|
|
||||||
#define SN_MR_IPRAW 0x03
|
|
||||||
#define SN_MR_MACRAW 0x04
|
|
||||||
#define SN_MR_PPPOE 0x05
|
|
||||||
|
|
||||||
#define SN_CR_OPEN 0x01
|
|
||||||
#define SN_CR_LISTENT 0x02
|
|
||||||
#define SN_CR_CONNECT 0x04
|
|
||||||
#define SN_CR_DISCON 0x08
|
|
||||||
#define SN_CR_CLOSE 0x10
|
|
||||||
#define SN_CR_SEND 0x20
|
|
||||||
#define SN_CR_RECV 0x40
|
|
||||||
|
|
||||||
#define SN_MR 0x00
|
|
||||||
#define SN_CR 0x01
|
|
||||||
#define SN_SR 0x03
|
|
||||||
#define SN_PORT0 0x04
|
|
||||||
#define SN_PORT1 0x05
|
|
||||||
#define SN_DIPR0 0x0C
|
|
||||||
#define SN_DIPR3 0x0F
|
|
||||||
#define SN_DPORT0 0x10
|
|
||||||
#define SN_DPORT1 0x11
|
|
||||||
#define SN_PROTO 0x14
|
|
||||||
#define SN_TOS 0x15
|
|
||||||
#define SN_TTL 0x16
|
|
||||||
#define SN_TX_FSR0 0x20
|
|
||||||
#define SN_TX_FSR1 0x21
|
|
||||||
#define SN_TX_RD0 0x22
|
|
||||||
#define SN_TX_RD1 0x23
|
|
||||||
#define SN_TX_WR0 0x24
|
|
||||||
#define SN_TX_WR1 0x25
|
|
||||||
#define SN_RX_RSR0 0x26
|
|
||||||
#define SN_RX_RSR1 0x27
|
|
||||||
#define SN_RX_RD0 0x28
|
|
||||||
#define SN_RX_RD1 0x29
|
|
||||||
|
|
||||||
#define SN_SR_CLOSED 0x00
|
|
||||||
#define SN_SR_SOCK_INIT 0x13
|
|
||||||
#define SN_SR_ESTABLISHED 0x17
|
|
||||||
#define SN_SR_SOCK_UDP 0x22
|
|
||||||
#define SN_SR_SOCK_IPRAW 0x32
|
|
||||||
#define SN_SR_SOCK_MACRAW 0x42
|
|
|
@ -39,7 +39,7 @@ namespace
|
||||||
|
|
||||||
ssize_t net_slirp_send_packet(const void *buf, size_t len, void *opaque)
|
ssize_t net_slirp_send_packet(const void *buf, size_t len, void *opaque)
|
||||||
{
|
{
|
||||||
SlirpNet * slirp = reinterpret_cast<SlirpNet *>(opaque);
|
SlirpBackend * slirp = reinterpret_cast<SlirpBackend *>(opaque);
|
||||||
slirp->sendToGuest(reinterpret_cast<const uint8_t *>(buf), len);
|
slirp->sendToGuest(reinterpret_cast<const uint8_t *>(buf), len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -88,19 +88,19 @@ namespace
|
||||||
|
|
||||||
int net_slirp_add_poll(int fd, int events, void *opaque)
|
int net_slirp_add_poll(int fd, int events, void *opaque)
|
||||||
{
|
{
|
||||||
SlirpNet * slirp = reinterpret_cast<SlirpNet *>(opaque);
|
SlirpBackend * slirp = reinterpret_cast<SlirpBackend *>(opaque);
|
||||||
return slirp->addPoll(fd, events);
|
return slirp->addPoll(fd, events);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_slirp_get_revents(int idx, void *opaque)
|
int net_slirp_get_revents(int idx, void *opaque)
|
||||||
{
|
{
|
||||||
const SlirpNet * slirp = reinterpret_cast<SlirpNet *>(opaque);
|
const SlirpBackend * slirp = reinterpret_cast<SlirpBackend *>(opaque);
|
||||||
return slirp->getREvents(idx);
|
return slirp->getREvents(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SlirpNet::SlirpNet()
|
SlirpBackend::SlirpBackend()
|
||||||
{
|
{
|
||||||
const SlirpConfig cfg =
|
const SlirpConfig cfg =
|
||||||
{
|
{
|
||||||
|
@ -128,12 +128,33 @@ SlirpNet::SlirpNet()
|
||||||
mySlirp.reset(slirp, slirp_cleanup);
|
mySlirp.reset(slirp, slirp_cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlirpNet::sendFromGuest(const uint8_t *pkt, const int pkt_len)
|
void SlirpBackend::transmit(const int txlength, uint8_t *txframe)
|
||||||
{
|
{
|
||||||
slirp_input(mySlirp.get(), pkt, pkt_len);
|
slirp_input(mySlirp.get(), txframe, txlength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlirpNet::sendToGuest(const uint8_t *pkt, int pkt_len)
|
int SlirpBackend::receive(const int size, uint8_t * rxframe)
|
||||||
|
{
|
||||||
|
if (!myQueue.empty())
|
||||||
|
{
|
||||||
|
const std::vector<uint8_t> & packet = myQueue.front();
|
||||||
|
int received = std::min(static_cast<int>(packet.size()), size);
|
||||||
|
memcpy(rxframe, packet.data(), received);
|
||||||
|
if (received & 1)
|
||||||
|
{
|
||||||
|
rxframe[received] = 0;
|
||||||
|
++received;
|
||||||
|
}
|
||||||
|
myQueue.pop();
|
||||||
|
return received;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlirpBackend::sendToGuest(const uint8_t *pkt, int pkt_len)
|
||||||
{
|
{
|
||||||
if (myQueue.size() < ourQueueSize)
|
if (myQueue.size() < ourQueueSize)
|
||||||
{
|
{
|
||||||
|
@ -145,8 +166,9 @@ void SlirpNet::sendToGuest(const uint8_t *pkt, int pkt_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlirpNet::process(uint32_t timeout)
|
void SlirpBackend::update(const ULONG /* nExecutedCycles */)
|
||||||
{
|
{
|
||||||
|
uint32_t timeout = 0;
|
||||||
myFDs.clear();
|
myFDs.clear();
|
||||||
slirp_pollfds_fill(mySlirp.get(), &timeout, net_slirp_add_poll, this);
|
slirp_pollfds_fill(mySlirp.get(), &timeout, net_slirp_add_poll, this);
|
||||||
int pollout;
|
int pollout;
|
||||||
|
@ -161,26 +183,21 @@ void SlirpNet::process(uint32_t timeout)
|
||||||
slirp_pollfds_poll(mySlirp.get(), (pollout <= 0), net_slirp_get_revents, this);
|
slirp_pollfds_poll(mySlirp.get(), (pollout <= 0), net_slirp_get_revents, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SlirpNet::addPoll(const int fd, const int events)
|
int SlirpBackend::addPoll(const int fd, const int events)
|
||||||
{
|
{
|
||||||
const pollfd ff = { .fd = fd, .events = vdeslirp_slirp_to_poll(events) };
|
const pollfd ff = { .fd = fd, .events = vdeslirp_slirp_to_poll(events) };
|
||||||
myFDs.push_back(ff);
|
myFDs.push_back(ff);
|
||||||
return myFDs.size() - 1;
|
return myFDs.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SlirpNet::getREvents(const int idx) const
|
int SlirpBackend::getREvents(const int idx) const
|
||||||
{
|
{
|
||||||
return vdeslirp_poll_to_slirp(myFDs[idx].revents);
|
return vdeslirp_poll_to_slirp(myFDs[idx].revents);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::queue<std::vector<uint8_t>> & SlirpNet::getQueue()
|
bool SlirpBackend::isValid()
|
||||||
{
|
{
|
||||||
return myQueue;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
void SlirpNet::clearQueue()
|
|
||||||
{
|
|
||||||
std::queue<std::vector<uint8_t>>().swap(myQueue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Tfe/NetworkBackend.h"
|
||||||
|
|
||||||
#include "linux/config.h"
|
#include "linux/config.h"
|
||||||
|
|
||||||
#ifdef SLIRP_FOUND
|
#ifdef SLIRP_FOUND
|
||||||
|
@ -17,19 +19,21 @@
|
||||||
|
|
||||||
struct Slirp;
|
struct Slirp;
|
||||||
|
|
||||||
class SlirpNet
|
class SlirpBackend : public NetworkBackend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SlirpNet();
|
SlirpBackend();
|
||||||
void sendFromGuest(const uint8_t *pkt, int pkt_len);
|
|
||||||
|
void transmit(const int txlength, uint8_t *txframe) override;
|
||||||
|
int receive(const int size, uint8_t * rxframe) override;
|
||||||
|
|
||||||
|
void update(const ULONG nExecutedCycles) override;
|
||||||
|
bool isValid() override;
|
||||||
|
|
||||||
void sendToGuest(const uint8_t *pkt, int pkt_len);
|
void sendToGuest(const uint8_t *pkt, int pkt_len);
|
||||||
|
|
||||||
void process(const uint32_t timeout);
|
|
||||||
int addPoll(const int fd, const int events);
|
int addPoll(const int fd, const int events);
|
||||||
int getREvents(const int idx) const;
|
int getREvents(const int idx) const;
|
||||||
|
|
||||||
std::queue<std::vector<uint8_t>> & getQueue();
|
|
||||||
void clearQueue();
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static constexpr size_t ourQueueSize = 10;
|
static constexpr size_t ourQueueSize = 10;
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "linux/network/tfe2.h"
|
|
||||||
|
|
||||||
#include "Tfe/tfearch.h"
|
|
||||||
#include "Tfe/tfe.h"
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
bool shouldAccept(const uint8_t * mac, const BYTE *buffer, const int len)
|
|
||||||
{
|
|
||||||
if (len < 6)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer[0] == mac[0] &&
|
|
||||||
buffer[1] == mac[1] &&
|
|
||||||
buffer[2] == mac[2] &&
|
|
||||||
buffer[3] == mac[3] &&
|
|
||||||
buffer[4] == mac[4] &&
|
|
||||||
buffer[5] == mac[5])
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer[0] == 0xFF &&
|
|
||||||
buffer[1] == 0xFF &&
|
|
||||||
buffer[2] == 0xFF &&
|
|
||||||
buffer[3] == 0xFF &&
|
|
||||||
buffer[4] == 0xFF &&
|
|
||||||
buffer[5] == 0xFF)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void tfeTransmitOnePacket(const BYTE * buffer, const int len)
|
|
||||||
{
|
|
||||||
if (tfe_enabled)
|
|
||||||
{
|
|
||||||
tfe_arch_transmit(0, 0, 0, 0, len, const_cast<BYTE *>(buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tfeReceiveOnePacket(const uint8_t * mac, const int size, BYTE * buffer, int & len)
|
|
||||||
{
|
|
||||||
if (!tfe_enabled)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool done;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
done = true;
|
|
||||||
int hashed;
|
|
||||||
int hash_index;
|
|
||||||
int rx_ok;
|
|
||||||
int correct_mac;
|
|
||||||
int broadcast;
|
|
||||||
int multicast = 0;
|
|
||||||
int crc_error;
|
|
||||||
|
|
||||||
len = size;
|
|
||||||
const int newframe = tfe_arch_receive(
|
|
||||||
buffer, /* where to store a frame */
|
|
||||||
&len, /* length of received frame */
|
|
||||||
&hashed, /* set if the dest. address is accepted by the hash filter */
|
|
||||||
&hash_index, /* hash table index if hashed == TRUE */
|
|
||||||
&rx_ok, /* set if good CRC and valid length */
|
|
||||||
&correct_mac, /* set if dest. address is exactly our IA */
|
|
||||||
&broadcast, /* set if dest. address is a broadcast address */
|
|
||||||
&crc_error /* set if received frame had a CRC error */
|
|
||||||
);
|
|
||||||
|
|
||||||
if (newframe)
|
|
||||||
{
|
|
||||||
/* determine ourself the type of frame */
|
|
||||||
if (shouldAccept(mac, buffer, len))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
done = false; /* try another frame */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (!done);
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
bool tfeReceiveOnePacket(const uint8_t * mac, const int size, BYTE * buffer, int & len);
|
|
||||||
void tfeTransmitOnePacket(const BYTE * buffer, const int len);
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,100 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Card.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class SlirpNet;
|
|
||||||
|
|
||||||
struct Socket
|
|
||||||
{
|
|
||||||
uint16_t transmitBase;
|
|
||||||
uint16_t transmitSize;
|
|
||||||
uint16_t receiveBase;
|
|
||||||
uint16_t receiveSize;
|
|
||||||
uint16_t registers;
|
|
||||||
|
|
||||||
uint16_t sn_rx_wr;
|
|
||||||
uint16_t sn_rx_rsr;
|
|
||||||
|
|
||||||
uint8_t sn_sr;
|
|
||||||
|
|
||||||
int myFD;
|
|
||||||
int myErrno;
|
|
||||||
|
|
||||||
void clearFD();
|
|
||||||
void setFD(const int fd, const int status);
|
|
||||||
void process();
|
|
||||||
|
|
||||||
bool isThereRoomFor(const size_t len, const size_t header) const;
|
|
||||||
uint16_t getFreeRoom() const;
|
|
||||||
|
|
||||||
Socket();
|
|
||||||
|
|
||||||
~Socket();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Uthernet2 : public Card
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Uthernet2(UINT slot);
|
|
||||||
|
|
||||||
virtual void InitializeIO(LPBYTE pCxRomPeripheral);
|
|
||||||
virtual void Init();
|
|
||||||
virtual void Reset(const bool powerCycle);
|
|
||||||
virtual void Update(const ULONG nExecutedCycles);
|
|
||||||
virtual void SaveSnapshot(YamlSaveHelper& yamlSaveHelper);
|
|
||||||
virtual bool LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version);
|
|
||||||
|
|
||||||
BYTE IO_C0(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<uint8_t> myMemory;
|
|
||||||
std::vector<Socket> mySockets;
|
|
||||||
uint8_t myModeRegister;
|
|
||||||
uint16_t myDataAddress;
|
|
||||||
std::shared_ptr<SlirpNet> mySlirp;
|
|
||||||
|
|
||||||
void setSocketModeRegister(const size_t i, const uint16_t address, const uint8_t value);
|
|
||||||
void setTXSizes(const uint16_t address, uint8_t value);
|
|
||||||
void setRXSizes(const uint16_t address, uint8_t value);
|
|
||||||
uint16_t getTXDataSize(const size_t i) const;
|
|
||||||
uint8_t getTXFreeSizeRegister(const size_t i, const size_t shift) const;
|
|
||||||
uint8_t getRXDataSizeRegister(const size_t i, const size_t shift) const;
|
|
||||||
|
|
||||||
void receiveOnePacketMacRaw(const size_t i);
|
|
||||||
void receiveOnePacketFromSocket(const size_t i);
|
|
||||||
void receiveOnePacket(const size_t i);
|
|
||||||
|
|
||||||
void sendDataMacRaw(const size_t i, const std::vector<uint8_t> & data) const;
|
|
||||||
void sendDataToSocket(const size_t i, std::vector<uint8_t> & data);
|
|
||||||
void sendData(const size_t i);
|
|
||||||
|
|
||||||
void resetRXTXBuffers(const size_t i);
|
|
||||||
void updateRSR(const size_t i);
|
|
||||||
|
|
||||||
void openSystemSocket(const size_t i, const int type, const int protocol, const int state);
|
|
||||||
void openSocket(const size_t i);
|
|
||||||
void closeSocket(const size_t i);
|
|
||||||
void connectSocket(const size_t i);
|
|
||||||
|
|
||||||
void setCommandRegister(const size_t i, const uint8_t value);
|
|
||||||
|
|
||||||
uint8_t readSocketRegister(const uint16_t address);
|
|
||||||
uint8_t readValueAt(const uint16_t address);
|
|
||||||
|
|
||||||
void autoIncrement();
|
|
||||||
uint8_t readValue();
|
|
||||||
|
|
||||||
void setIPProtocol(const size_t i, const uint16_t address, const uint8_t value);
|
|
||||||
void setIPTypeOfService(const size_t i, const uint16_t address, const uint8_t value);
|
|
||||||
void setIPTTL(const size_t i, const uint16_t address, const uint8_t value);
|
|
||||||
void writeSocketRegister(const uint16_t address, const uint8_t value);
|
|
||||||
|
|
||||||
void setModeRegister(const uint16_t address, const uint8_t value);
|
|
||||||
void writeCommonRegister(const uint16_t address, const uint8_t value);
|
|
||||||
void writeValueAt(const uint16_t address, const uint8_t value);
|
|
||||||
void writeValue(const uint8_t value);
|
|
||||||
|
|
||||||
void processEvents(uint32_t timeout);
|
|
||||||
};
|
|
Loading…
Add table
Reference in a new issue