#pragma once #include "Card.h" #include #include class NetworkBackend; struct MACAddress; struct Socket { #ifdef _MSC_VER typedef SOCKET socket_t; #else typedef int socket_t; #endif uint16_t transmitBase; uint16_t transmitSize; uint16_t receiveBase; uint16_t receiveSize; uint16_t registerAddress; uint16_t sn_rx_wr; uint16_t sn_rx_rsr; uint8_t sn_sr; socket_t myFD; int myErrno; bool isOpen() const; void clearFD(); void setFD(const socket_t fd, const int status); void process(); bool isThereRoomFor(const size_t len, const size_t header) const; uint16_t getFreeRoom() const; void SaveSnapshot(YamlSaveHelper &yamlSaveHelper); bool LoadSnapshot(YamlLoadHelper &yamlLoadHelper); Socket(); ~Socket(); }; /* * Documentation from * http://dserver.macgui.com/Uthernet%20II%20manual%2017%20Nov%2018.pdf * https://www.wiznet.io/wp-content/uploads/wiznethome/Chip/W5100/Document/W5100_DS_V128E.pdf * https://www.wiznet.io/wp-content/uploads/wiznethome/Chip/W5100/Document/3150Aplus_5100_ES_V260E.pdf */ class Uthernet2 : public Card { public: static const std::string& GetSnapshotCardName(); enum PacketDestination { HOST, BROADCAST, OTHER }; Uthernet2(UINT slot); virtual ~Uthernet2(); virtual void Destroy(void) {} virtual void InitializeIO(LPBYTE pCxRomPeripheral); 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); // global registry functions static void SetRegistryVirtualDNS(UINT slot, const bool enabled); static bool GetRegistryVirtualDNS(UINT slot); private: bool myVirtualDNSEnabled; // extended virtualisation of DNS (not present in the real U II card) #ifdef _MSC_VER int myWSAStartup; #endif std::vector myMemory; std::vector mySockets; uint8_t myModeRegister; uint16_t myDataAddress; std::shared_ptr myNetworkBackend; // the real Uthernet II card does not have a ARP Cache // but in the interest of speeding up the emulator // we introduce one std::map myARPCache; std::map myDNSCache; void getMACAddress(const uint32_t address, const MACAddress * & mac); void resolveDNS(const size_t i); 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 receiveOnePacketRaw(); void receiveOnePacketIPRaw(const size_t i, const size_t lengthOfPayload, const uint8_t * payload, const uint32_t destination, const uint8_t protocol, const int len); void receiveOnePacketMacRaw(const size_t i, const int size, uint8_t * data); void receiveOnePacketFromSocket(const size_t i); void receiveOnePacket(const size_t i); int receiveForMacAddress(const bool acceptAll, const int size, uint8_t * data, PacketDestination & packetDestination); void sendDataIPRaw(const size_t i, std::vector &data); void sendDataMacRaw(const size_t i, std::vector &data) const; void sendDataToSocket(const size_t i, std::vector &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 status); 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); };