Add Uthernet II support and make Uthernet I a Card. (PR #1047)
. tfe.cpp renamed to Uthernet1.cpp. . add class NetworkBackend: common to both U1 and U2 cards, and abstracts Windows/Linux backends. . modernise error message if WPCAP.DLL is not installed.
This commit is contained in:
parent
514d2adb79
commit
9f8c4d99af
32 changed files with 3210 additions and 1823 deletions
|
@ -302,6 +302,22 @@
|
|||
RelativePath=".\source\StrFormat.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Uthernet1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Uthernet1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Uthernet2.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Uthernet2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Utilities.cpp"
|
||||
>
|
||||
|
@ -437,6 +453,14 @@
|
|||
<Filter
|
||||
Name="Uthernet"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\source\Tfe\NetworkBackend.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Tfe\NetworkBackend.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Tfe\Bpf.h"
|
||||
>
|
||||
|
@ -450,27 +474,11 @@
|
|||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Tfe\tfe.cpp"
|
||||
RelativePath=".\source\Tfe\PCapBackend.h"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Tfe\tfe.h"
|
||||
RelativePath=".\source\Tfe\PCapBackend.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
@ -1025,6 +1033,10 @@
|
|||
RelativePath=".\source\VidHD.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\W5100.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Windows"
|
||||
|
|
|
@ -114,16 +114,20 @@
|
|||
<ClInclude Include="source\StrFormat.h" />
|
||||
<ClInclude Include="source\SynchronousEventManager.h" />
|
||||
<ClInclude Include="source\Tape.h" />
|
||||
<ClInclude Include="source\Tfe\NetworkBackend.h" />
|
||||
<ClInclude Include="source\Tfe\Bpf.h" />
|
||||
<ClInclude Include="source\Tfe\Ip6_misc.h" />
|
||||
<ClInclude Include="source\Tfe\Pcap.h" />
|
||||
<ClInclude Include="source\Tfe\tfe.h" />
|
||||
<ClInclude Include="source\Tfe\PCapBackend.h" />
|
||||
<ClInclude Include="source\Tfe\tfearch.h" />
|
||||
<ClInclude Include="source\Tfe\tfesupp.h" />
|
||||
<ClInclude Include="source\Tfe\Uilib.h" />
|
||||
<ClInclude Include="source\Uthernet1.h" />
|
||||
<ClInclude Include="source\Uthernet2.h" />
|
||||
<ClInclude Include="source\Utilities.h" />
|
||||
<ClInclude Include="source\Video.h" />
|
||||
<ClInclude Include="Source\VidHD.h" />
|
||||
<ClInclude Include="source\W5100.h" />
|
||||
<ClInclude Include="source\Windows\AppleWin.h" />
|
||||
<ClInclude Include="source\Windows\DirectInput.h" />
|
||||
<ClInclude Include="source\Windows\HookFilter.h" />
|
||||
|
@ -218,14 +222,8 @@
|
|||
<ClCompile Include="source\StrFormat.cpp" />
|
||||
<ClCompile Include="source\SynchronousEventManager.cpp" />
|
||||
<ClCompile Include="source\Tape.cpp" />
|
||||
<ClCompile Include="source\Tfe\tfe.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug v141_xp|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug NoDX|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release v141_xp|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release NoDX|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Tfe\NetworkBackend.cpp" />
|
||||
<ClCompile Include="source\Tfe\PCapBackend.cpp" />
|
||||
<ClCompile Include="source\Tfe\tfearch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug v141_xp|Win32'">NotUsing</PrecompiledHeader>
|
||||
|
@ -250,6 +248,8 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release v141_xp|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release NoDX|Win32'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Uthernet1.cpp" />
|
||||
<ClCompile Include="source\Uthernet2.cpp" />
|
||||
<ClCompile Include="source\Utilities.cpp" />
|
||||
<ClCompile Include="source\Video.cpp" />
|
||||
<ClCompile Include="Source\VidHD.cpp" />
|
||||
|
|
|
@ -142,9 +142,6 @@
|
|||
<ClCompile Include="source\Tape.cpp">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Tfe\tfe.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Tfe\tfearch.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
|
@ -250,6 +247,18 @@
|
|||
<ClCompile Include="source\StrFormat.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Uthernet1.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Tfe\NetworkBackend.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Tfe\PCapBackend.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Uthernet2.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="source\CommonVICE\6510core.h">
|
||||
|
@ -444,9 +453,6 @@
|
|||
<ClInclude Include="source\Tape.h">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Tfe\tfe.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Tfe\tfearch.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
|
@ -573,6 +579,21 @@
|
|||
<ClInclude Include="source\StrFormat.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Uthernet1.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Tfe\NetworkBackend.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Tfe\PCapBackend.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\W5100.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Uthernet2.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="resource\Applewin.bmp">
|
||||
|
|
|
@ -212,7 +212,7 @@ CAPTION "Ethernet Settings"
|
|||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Ethernet",IDC_TFE_SETTINGS_ENABLE_T,9,7,30,8
|
||||
COMBOBOX IDC_TFE_SETTINGS_ENABLE,45,5,50,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_TFE_SETTINGS_ENABLE,45,5,60,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Interface",IDC_TFE_SETTINGS_INTERFACE_T,9,24,30,8
|
||||
COMBOBOX IDC_TFE_SETTINGS_INTERFACE,45,22,210,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "",IDC_TFE_SETTINGS_INTERFACE_NAME,9,44,250,8
|
||||
|
|
|
@ -21,7 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "StdAfx.h"
|
||||
#include "Card.h"
|
||||
|
||||
#include "Tfe/tfe.h"
|
||||
#include "Uthernet1.h"
|
||||
#include "Uthernet2.h"
|
||||
#include "Mockingboard.h"
|
||||
#include "ParallelPrinter.h"
|
||||
#include "z80emu.h"
|
||||
|
@ -71,9 +72,6 @@ void DummyCard::InitializeIO(LPBYTE pCxRomPeripheral)
|
|||
case CT_GenericPrinter:
|
||||
PrintLoadRom(pCxRomPeripheral, m_slot);
|
||||
break;
|
||||
case CT_Uthernet:
|
||||
tfe_InitializeIO(pCxRomPeripheral, m_slot);
|
||||
break;
|
||||
case CT_GenericClock:
|
||||
break; // nothing to do
|
||||
case CT_MockingboardC:
|
||||
|
@ -124,9 +122,6 @@ void DummyCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
|||
case CT_Z80:
|
||||
Z80_SaveSnapshot(yamlSaveHelper, m_slot);
|
||||
break;
|
||||
case CT_Uthernet:
|
||||
tfe_SaveSnapshot(yamlSaveHelper, m_slot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,8 +137,6 @@ bool DummyCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
return Phasor_LoadSnapshot(yamlLoadHelper, m_slot, version);
|
||||
case CT_Z80:
|
||||
return Z80_LoadSnapshot(yamlLoadHelper, m_slot, version);
|
||||
case CT_Uthernet:
|
||||
return tfe_LoadSnapshot(yamlLoadHelper, m_slot, version);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -186,13 +179,15 @@ std::string Card::GetCardName(const SS_CARDTYPE cardType)
|
|||
case CT_SAM:
|
||||
return SAMCard::GetSnapshotCardName();
|
||||
case CT_Uthernet:
|
||||
return tfe_GetSnapshotCardName();
|
||||
return Uthernet1::GetSnapshotCardName();
|
||||
case CT_FourPlay:
|
||||
return FourPlayCard::GetSnapshotCardName();
|
||||
case CT_SNESMAX:
|
||||
return SNESMAXCard::GetSnapshotCardName();
|
||||
case CT_VidHD:
|
||||
return VidHDCard::GetSnapshotCardName();
|
||||
case CT_Uthernet2:
|
||||
return Uthernet2::GetSnapshotCardName();
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
@ -236,7 +231,7 @@ SS_CARDTYPE Card::GetCardType(const std::string & card)
|
|||
{
|
||||
return CT_GenericHDD;
|
||||
}
|
||||
else if (card == tfe_GetSnapshotCardName())
|
||||
else if (card == Uthernet1::GetSnapshotCardName())
|
||||
{
|
||||
return CT_Uthernet;
|
||||
}
|
||||
|
@ -260,6 +255,10 @@ SS_CARDTYPE Card::GetCardType(const std::string & card)
|
|||
{
|
||||
return CT_VidHD;
|
||||
}
|
||||
else if (card == Uthernet2::GetSnapshotCardName())
|
||||
{
|
||||
return CT_Uthernet2;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Slots: Unknown card: " + card); // todo: don't throw - just ignore & continue
|
||||
|
|
|
@ -24,6 +24,7 @@ enum SS_CARDTYPE
|
|||
CT_FourPlay, // 4 port Atari 2600 style digital joystick card
|
||||
CT_SNESMAX, // 2 port Nintendo NES/SNES controller serial interface card
|
||||
CT_VidHD,
|
||||
CT_Uthernet2,
|
||||
};
|
||||
|
||||
enum SLOTS { SLOT0=0, SLOT1, SLOT2, SLOT3, SLOT4, SLOT5, SLOT6, SLOT7, NUM_SLOTS, SLOT_AUX };
|
||||
|
|
|
@ -40,6 +40,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "SAM.h"
|
||||
#include "SerialComms.h"
|
||||
#include "SNESMAX.h"
|
||||
#include "Uthernet1.h"
|
||||
#include "Uthernet2.h"
|
||||
#include "VidHD.h"
|
||||
#include "LanguageCard.h"
|
||||
#include "Memory.h"
|
||||
|
@ -91,7 +93,7 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type)
|
|||
m_slot[slot] = new SAMCard(slot);
|
||||
break;
|
||||
case CT_Uthernet:
|
||||
m_slot[slot] = new DummyCard(type, slot);
|
||||
m_slot[slot] = new Uthernet1(slot);
|
||||
break;
|
||||
case CT_FourPlay:
|
||||
m_slot[slot] = new FourPlayCard(slot);
|
||||
|
@ -102,6 +104,9 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type)
|
|||
case CT_VidHD:
|
||||
m_slot[slot] = new VidHDCard(slot);
|
||||
break;
|
||||
case CT_Uthernet2:
|
||||
m_slot[slot] = new Uthernet2(slot);
|
||||
break;
|
||||
|
||||
case CT_LanguageCard:
|
||||
_ASSERT(m_pLanguageCard == NULL);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "../DiskImage.h" // Disk_Status_e
|
||||
#include "../Harddisk.h"
|
||||
#include "../Interface.h" // VideoRefreshRate_e, GetVideoRefreshRate()
|
||||
#include "../Tfe/tfe.h"
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
|
||||
class CConfigNeedingRestart
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ public:
|
|||
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
||||
m_Slot[slot] = cardManager.QuerySlot(slot);
|
||||
m_SlotAux = cardManager.QueryAux();
|
||||
m_tfeInterface = get_tfe_interface();
|
||||
m_tfeInterface = PCapBackend::tfe_interface;
|
||||
m_bEnableTheFreezesF8Rom = GetPropertySheet().GetTheFreezesF8Rom();
|
||||
m_uSaveLoadStateMsg = 0;
|
||||
m_videoRefreshRate = GetVideo().GetVideoRefreshRate();
|
||||
|
|
|
@ -112,7 +112,8 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
|
|||
|
||||
case IDC_ETHERNET:
|
||||
ui_tfe_settings_dialog(hWnd);
|
||||
m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT3] = m_PageConfigTfe.m_tfe_enabled ? CT_Uthernet : CT_Empty;
|
||||
m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT3] = m_PageConfigTfe.m_tfe_selected;
|
||||
m_PropertySheetHelper.GetConfigNew().m_tfeInterface = m_PageConfigTfe.m_tfe_interface_name;
|
||||
InitOptions(hWnd);
|
||||
break;
|
||||
|
||||
|
@ -249,8 +250,18 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
|
|||
}
|
||||
|
||||
{
|
||||
m_PageConfigTfe.m_tfe_enabled = get_tfe_enabled();
|
||||
m_PageConfigTfe.m_tfe_interface_name = get_tfe_interface();
|
||||
SS_CARDTYPE cardInSlot3 = GetCardMgr().QuerySlot(SLOT3);
|
||||
switch (cardInSlot3) {
|
||||
case CT_Uthernet:
|
||||
case CT_Uthernet2:
|
||||
m_PageConfigTfe.m_tfe_selected = cardInSlot3;
|
||||
break;
|
||||
default:
|
||||
m_PageConfigTfe.m_tfe_selected = CT_Empty;
|
||||
break;
|
||||
}
|
||||
|
||||
m_PageConfigTfe.m_tfe_interface_name = PCapBackend::tfe_interface;
|
||||
}
|
||||
|
||||
InitOptions(hWnd);
|
||||
|
@ -325,8 +336,6 @@ void CPageConfig::DlgOK(HWND hWnd)
|
|||
m_PropertySheetHelper.GetConfigNew().m_videoRefreshRate = isNewVideoRate50Hz ? VR_50HZ : VR_60HZ;
|
||||
}
|
||||
|
||||
m_PropertySheetHelper.GetConfigNew().m_tfeInterface = m_PageConfigTfe.m_tfe_interface_name;
|
||||
|
||||
if (bVideoReinit)
|
||||
{
|
||||
win32Frame.FrameRefreshStatus(DRAW_TITLE);
|
||||
|
@ -381,7 +390,7 @@ void CPageConfig::DlgOK(HWND hWnd)
|
|||
void CPageConfig::InitOptions(HWND hWnd)
|
||||
{
|
||||
const SS_CARDTYPE slot3 = m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT3];
|
||||
const BOOL enableUthernetDialog = slot3 == CT_Empty || slot3 == CT_Uthernet;
|
||||
const BOOL enableUthernetDialog = slot3 == CT_Empty || slot3 == CT_Uthernet || slot3 == CT_Uthernet2;
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_ETHERNET), enableUthernetDialog);
|
||||
|
||||
const bool bIsSlot3VidHD = slot3 == CT_VidHD;
|
||||
|
|
|
@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "../Common.h"
|
||||
#include "../Registry.h"
|
||||
#include "../resource/resource.h"
|
||||
#include "../Tfe/tfe.h"
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
#include "../Tfe/tfesupp.h"
|
||||
|
||||
CPageConfigTfe* CPageConfigTfe::ms_this = 0; // reinit'd in ctor
|
||||
|
@ -111,29 +111,29 @@ void CPageConfigTfe::DlgCANCEL(HWND window)
|
|||
|
||||
BOOL CPageConfigTfe::get_tfename(int number, char **ppname, char **ppdescription)
|
||||
{
|
||||
if (tfe_enumadapter_open())
|
||||
if (PCapBackend::tfe_enumadapter_open())
|
||||
{
|
||||
char *pname = NULL;
|
||||
char *pdescription = NULL;
|
||||
|
||||
while (number--)
|
||||
{
|
||||
if (!tfe_enumadapter(&pname, &pdescription))
|
||||
if (!PCapBackend::tfe_enumadapter(&pname, &pdescription))
|
||||
break;
|
||||
|
||||
lib_free(pname);
|
||||
lib_free(pdescription);
|
||||
}
|
||||
|
||||
if (tfe_enumadapter(&pname, &pdescription))
|
||||
if (PCapBackend::tfe_enumadapter(&pname, &pdescription))
|
||||
{
|
||||
*ppname = pname;
|
||||
*ppdescription = pdescription;
|
||||
tfe_enumadapter_close();
|
||||
PCapBackend::tfe_enumadapter_close();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
tfe_enumadapter_close();
|
||||
PCapBackend::tfe_enumadapter_close();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -145,7 +145,7 @@ int CPageConfigTfe::gray_ungray_items(HWND hwnd)
|
|||
int number;
|
||||
|
||||
int disabled = 0;
|
||||
get_disabled_state(&disabled);
|
||||
PCapBackend::get_disabled_state(&disabled);
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
|
@ -199,14 +199,26 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
uilib_adjust_group_width(hwnd, ms_leftgroup);
|
||||
uilib_move_group(hwnd, ms_rightgroup, xsize + 30);
|
||||
|
||||
active_value = (m_tfe_enabled > 0 ? 1 : 0);
|
||||
switch (m_tfe_selected)
|
||||
{
|
||||
case CT_Uthernet:
|
||||
active_value = 1;
|
||||
break;
|
||||
case CT_Uthernet2:
|
||||
active_value = 2;
|
||||
break;
|
||||
default:
|
||||
active_value = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_ENABLE);
|
||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Disabled");
|
||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Uthernet");
|
||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Uthernet II");
|
||||
SendMessage(temp_hwnd, CB_SETCURSEL, (WPARAM)active_value, 0);
|
||||
|
||||
if (tfe_enumadapter_open())
|
||||
if (PCapBackend::tfe_enumadapter_open())
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
|
@ -215,7 +227,7 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
|
||||
temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE);
|
||||
|
||||
for (cnt = 0; tfe_enumadapter(&pname, &pdescription); cnt++)
|
||||
for (cnt = 0; PCapBackend::tfe_enumadapter(&pname, &pdescription); cnt++)
|
||||
{
|
||||
BOOL this_entry = FALSE;
|
||||
|
||||
|
@ -237,7 +249,7 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
}
|
||||
}
|
||||
|
||||
tfe_enumadapter_close();
|
||||
PCapBackend::tfe_enumadapter_close();
|
||||
}
|
||||
|
||||
if (gray_ungray_items(hwnd))
|
||||
|
@ -246,12 +258,12 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
// TC (18 Dec 2017) this vicekb URL is a broken link now, so I copied it to the AppleWin repo, here:
|
||||
// . https://github.com/AppleWin/AppleWin/blob/master/docs/VICE%20Knowledge%20Base%20-%20Article%2013-005.htm
|
||||
MessageBox( hwnd,
|
||||
"TFE support is not available on your system,\n"
|
||||
"there is some important part missing. Please have a\n"
|
||||
"look at the VICE knowledge base support page\n"
|
||||
"\n http://vicekb.trikaliotis.net/13-005\n\n"
|
||||
"for possible reasons and to activate networking with VICE.",
|
||||
"TFE support", MB_ICONINFORMATION|MB_OK);
|
||||
"Uthernet support is not available on your system,\n"
|
||||
"WPCAP.DLL cannot be loaded.\n\n"
|
||||
"Install Npcap from\n\n"
|
||||
" https://npcap.com\n\n"
|
||||
"to activate networking with AppleWin.",
|
||||
"Uthernet support", MB_ICONINFORMATION|MB_OK);
|
||||
|
||||
/* just quit the dialog before it is open */
|
||||
SendMessage( hwnd, WM_COMMAND, IDCANCEL, 0);
|
||||
|
@ -271,11 +283,22 @@ void CPageConfigTfe::save_tfe_dialog(HWND hwnd)
|
|||
{
|
||||
m_tfe_interface_name = buffer;
|
||||
active_value = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0);
|
||||
m_tfe_enabled = active_value > 0 ? 1 : 0;
|
||||
switch (active_value)
|
||||
{
|
||||
case 1:
|
||||
m_tfe_selected = CT_Uthernet;
|
||||
break;
|
||||
case 2:
|
||||
m_tfe_selected = CT_Uthernet2;
|
||||
break;
|
||||
default:
|
||||
m_tfe_selected = CT_Empty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tfe_enabled = 0;
|
||||
m_tfe_selected = CT_Empty;
|
||||
m_tfe_interface_name.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "IPropertySheetPage.h"
|
||||
#include "../Tfe/Uilib.h"
|
||||
#include "../Card.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -11,13 +12,13 @@ public:
|
|||
CPageConfigTfe()
|
||||
{
|
||||
CPageConfigTfe::ms_this = this;
|
||||
m_tfe_enabled = 0;
|
||||
m_tfe_selected = CT_Empty;
|
||||
}
|
||||
virtual ~CPageConfigTfe(){}
|
||||
|
||||
static INT_PTR CALLBACK DlgProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
int m_tfe_enabled;
|
||||
SS_CARDTYPE m_tfe_selected;
|
||||
std::string m_tfe_interface_name;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "../Log.h"
|
||||
#include "../Registry.h"
|
||||
#include "../SaveState.h"
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
|
||||
/*
|
||||
Config causing AfterClose msgs:
|
||||
|
@ -330,12 +331,10 @@ void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew
|
|||
|
||||
UINT slot = SLOT3;
|
||||
if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
|
||||
{
|
||||
SetSlot(slot, ConfigNew.m_Slot[slot]);
|
||||
|
||||
if (ConfigNew.m_Slot[slot] == CT_Uthernet) // TODO: move this to UthernetCard object
|
||||
tfe_SetRegistryInterface(slot, ConfigNew.m_tfeInterface);
|
||||
}
|
||||
// unconditionally save it, as the previous SetSlot might have removed the setting
|
||||
PCapBackend::tfe_SetRegistryInterface(slot, ConfigNew.m_tfeInterface);
|
||||
|
||||
slot = SLOT4;
|
||||
if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
|
||||
|
@ -451,6 +450,9 @@ bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
|||
if (CONFIG_CHANGED(m_Slot[SLOT3]))
|
||||
strMsgMain += GetSlot(SLOT3);
|
||||
|
||||
if (CONFIG_CHANGED(m_tfeInterface))
|
||||
strMsgMain += ". Uthernet interface has changed\n";
|
||||
|
||||
if (CONFIG_CHANGED(m_Slot[SLOT4]))
|
||||
strMsgMain += GetSlot(SLOT4);
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "Video.h"
|
||||
|
||||
class NetworkBackend;
|
||||
|
||||
class FrameBase
|
||||
{
|
||||
public:
|
||||
|
@ -41,6 +43,10 @@ public:
|
|||
// this function merges LoadBitmap and GetBitmapBits from windows.h
|
||||
virtual void GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) = 0;
|
||||
|
||||
// create the network backed for Uthernet 1 and 2
|
||||
// useful to use libslirp in Linux
|
||||
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend() = 0;
|
||||
|
||||
// FindResource, MAKEINTRESOURCE, SizeofResource, LoadResource, LockResource
|
||||
// Return pointer to resource if size is correct.
|
||||
// NULL if resource is invalid or size check fails
|
||||
|
|
|
@ -54,7 +54,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "SerialComms.h"
|
||||
#include "Speaker.h"
|
||||
#include "Tape.h"
|
||||
#include "Tfe/tfe.h"
|
||||
#include "RGBMonitor.h"
|
||||
#include "VidHD.h"
|
||||
|
||||
|
|
26
source/Tfe/NetworkBackend.cpp
Normal file
26
source/Tfe/NetworkBackend.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
AppleWin : An Apple //e emulator for Windows
|
||||
|
||||
Copyright (C) 2022, Andrea Odetti
|
||||
|
||||
AppleWin is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
AppleWin is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with AppleWin; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "NetworkBackend.h"
|
||||
|
||||
NetworkBackend::~NetworkBackend()
|
||||
{
|
||||
}
|
31
source/Tfe/NetworkBackend.h
Normal file
31
source/Tfe/NetworkBackend.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#define MAX_TXLENGTH 1518
|
||||
#define MIN_TXLENGTH 4
|
||||
|
||||
#define MAX_RXLENGTH 1518
|
||||
#define MIN_RXLENGTH 64
|
||||
|
||||
class NetworkBackend
|
||||
{
|
||||
public:
|
||||
virtual ~NetworkBackend();
|
||||
|
||||
// transmit a packet
|
||||
virtual void transmit(
|
||||
const int txlength, /* Frame length */
|
||||
uint8_t *txframe /* Pointer to the frame to be transmitted */
|
||||
) = 0;
|
||||
|
||||
// receive a single packet, return size (>0) or missing (-1)
|
||||
virtual int receive(
|
||||
const int size, /* Buffer size */
|
||||
uint8_t * rxframe /* Pointer to the buffer */
|
||||
) = 0;
|
||||
|
||||
// process pending packets
|
||||
virtual void update(const ULONG nExecutedCycles) = 0;
|
||||
|
||||
// if the backend is usable
|
||||
virtual bool isValid() = 0;
|
||||
};
|
98
source/Tfe/PCapBackend.cpp
Normal file
98
source/Tfe/PCapBackend.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
AppleWin : An Apple //e emulator for Windows
|
||||
|
||||
Copyright (C) 2022, Andrea Odetti
|
||||
|
||||
AppleWin is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
AppleWin is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with AppleWin; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "PCapBackend.h"
|
||||
#include "tfearch.h"
|
||||
#include "../Common.h"
|
||||
#include "../Registry.h"
|
||||
|
||||
std::string PCapBackend::tfe_interface;
|
||||
|
||||
PCapBackend::PCapBackend(const std::string & pcapInterface)
|
||||
{
|
||||
tfePcapFP = TfePcapOpenAdapter(pcapInterface);
|
||||
}
|
||||
|
||||
PCapBackend::~PCapBackend()
|
||||
{
|
||||
TfePcapCloseAdapter(tfePcapFP);
|
||||
tfePcapFP = NULL;
|
||||
}
|
||||
|
||||
void PCapBackend::transmit(
|
||||
const int txlength, /* Frame length */
|
||||
uint8_t *txframe /* Pointer to the frame to be transmitted */
|
||||
)
|
||||
{
|
||||
if (tfePcapFP)
|
||||
{
|
||||
tfe_arch_transmit(tfePcapFP, txlength, txframe);
|
||||
}
|
||||
}
|
||||
|
||||
int PCapBackend::receive(const int size, uint8_t * rxframe)
|
||||
{
|
||||
if (tfePcapFP)
|
||||
{
|
||||
return tfe_arch_receive(tfePcapFP, size, rxframe);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool PCapBackend::isValid()
|
||||
{
|
||||
return tfePcapFP;
|
||||
}
|
||||
|
||||
void PCapBackend::update(const ULONG /* nExecutedCycles */)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
int PCapBackend::tfe_enumadapter_open(void)
|
||||
{
|
||||
return tfe_arch_enumadapter_open();
|
||||
}
|
||||
|
||||
int PCapBackend::tfe_enumadapter(char **ppname, char **ppdescription)
|
||||
{
|
||||
return tfe_arch_enumadapter(ppname, ppdescription);
|
||||
}
|
||||
|
||||
int PCapBackend::tfe_enumadapter_close(void)
|
||||
{
|
||||
return tfe_arch_enumadapter_close();
|
||||
}
|
||||
|
||||
void PCapBackend::tfe_SetRegistryInterface(UINT slot, const std::string& name)
|
||||
{
|
||||
std::string regSection = RegGetConfigSlotSection(slot);
|
||||
RegSaveString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, 1, name);
|
||||
}
|
||||
|
||||
void PCapBackend::get_disabled_state(int * param)
|
||||
{
|
||||
*param = tfe_cannot_use;
|
||||
}
|
64
source/Tfe/PCapBackend.h
Normal file
64
source/Tfe/PCapBackend.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
|
||||
#include "NetworkBackend.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
struct pcap;
|
||||
typedef struct pcap pcap_t;
|
||||
|
||||
class PCapBackend : public NetworkBackend
|
||||
{
|
||||
public:
|
||||
PCapBackend(const std::string & pcapInterface);
|
||||
|
||||
virtual ~PCapBackend();
|
||||
|
||||
// transmit a packet
|
||||
virtual void transmit(
|
||||
const int txlength, /* Frame length */
|
||||
uint8_t *txframe /* Pointer to the frame to be transmitted */
|
||||
);
|
||||
|
||||
// receive a single packet, return size (>0) or missing (-1)
|
||||
virtual int receive(const int size, uint8_t * rxframe);
|
||||
|
||||
// receive all pending packets (to the queue)
|
||||
virtual void update(const ULONG nExecutedCycles);
|
||||
|
||||
// process pending packets
|
||||
virtual bool isValid();
|
||||
|
||||
static void tfe_SetRegistryInterface(UINT slot, const std::string& name);
|
||||
static void get_disabled_state(int * param);
|
||||
|
||||
/*
|
||||
These functions let the UI enumerate the available interfaces.
|
||||
|
||||
First, tfe_enumadapter_open() is used to start enumeration.
|
||||
|
||||
tfe_enum_adapter is then used to gather information for each adapter present
|
||||
on the system, where:
|
||||
|
||||
ppname points to a pointer which will hold the name of the interface
|
||||
ppdescription points to a pointer which will hold the description of the interface
|
||||
|
||||
For each of these parameters, new memory is allocated, so it has to be
|
||||
freed with lib_free().
|
||||
|
||||
tfe_enumadapter_close() must be used to stop processing.
|
||||
|
||||
Each function returns 1 on success, and 0 on failure.
|
||||
tfe_enumadapter() only fails if there is no more adpater; in this case,
|
||||
*ppname and *ppdescription are not altered.
|
||||
*/
|
||||
|
||||
static int tfe_enumadapter_open(void);
|
||||
static int tfe_enumadapter(char **ppname, char **ppdescription);
|
||||
static int tfe_enumadapter_close(void);
|
||||
|
||||
static std::string tfe_interface;
|
||||
|
||||
private:
|
||||
pcap_t * tfePcapFP;
|
||||
};
|
1489
source/Tfe/tfe.cpp
1489
source/Tfe/tfe.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* tfe.h - TFE ("The final ethernet" emulation.
|
||||
*
|
||||
* Written by
|
||||
* Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>
|
||||
*
|
||||
* This file is part of VICE, the Versatile Commodore Emulator.
|
||||
* See README for copyright notice.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TFE_H
|
||||
#define _TFE_H
|
||||
|
||||
#include "../CommonVICE/types.h"
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
/* define this only if VICE should write each and every frame received
|
||||
and send into the VICE log
|
||||
WARNING: The log grows very fast!
|
||||
*/
|
||||
/** #define TFE_DEBUG_FRAMES **/
|
||||
|
||||
extern int tfe_enabled;
|
||||
|
||||
extern void tfe_init(bool reset);
|
||||
extern int tfe_resources_init(void);
|
||||
extern int tfe_cmdline_options_init(void);
|
||||
extern int update_tfe_interface(const std::string & name);
|
||||
void get_disabled_state(int * param);
|
||||
|
||||
extern void tfe_shutdown(void);
|
||||
extern BYTE REGPARM1 tfe_read(WORD addr);
|
||||
extern void REGPARM2 tfe_store(WORD addr, BYTE byte);
|
||||
void tfe_InitializeIO(LPBYTE pCxRomPeripheral, UINT slot);
|
||||
void tfe_SetRegistryInterface(UINT slot, const std::string& name);
|
||||
|
||||
std::string tfe_GetSnapshotCardName(void);
|
||||
void tfe_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
|
||||
bool tfe_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||
|
||||
/*
|
||||
These functions let the UI enumerate the available interfaces.
|
||||
|
||||
First, tfe_enumadapter_open() is used to start enumeration.
|
||||
|
||||
tfe_enum_adapter is then used to gather information for each adapter present
|
||||
on the system, where:
|
||||
|
||||
ppname points to a pointer which will hold the name of the interface
|
||||
ppdescription points to a pointer which will hold the description of the interface
|
||||
|
||||
For each of these parameters, new memory is allocated, so it has to be
|
||||
freed with lib_free().
|
||||
|
||||
tfe_enumadapter_close() must be used to stop processing.
|
||||
|
||||
Each function returns 1 on success, and 0 on failure.
|
||||
tfe_enumadapter() only fails if there is no more adpater; in this case,
|
||||
*ppname and *ppdescription are not altered.
|
||||
*/
|
||||
extern int tfe_enumadapter_open(void);
|
||||
extern int tfe_enumadapter(char **ppname, char **ppdescription);
|
||||
extern int tfe_enumadapter_close(void);
|
||||
|
||||
extern int get_tfe_enabled(void);
|
||||
extern const std::string & get_tfe_interface(void);
|
||||
|
||||
extern FILE* g_fh; // Filehandle for log file
|
||||
|
||||
#endif
|
|
@ -40,7 +40,6 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <StdAfx.h> // this is necessary in linux, but in MSVC windows.h MUST come after winsock2.h (from pcap.h above)
|
||||
#include "tfe.h"
|
||||
#include "tfearch.h"
|
||||
#include "tfesupp.h"
|
||||
#include "../Log.h"
|
||||
|
@ -53,6 +52,8 @@
|
|||
|
||||
#define TFE_DEBUG_WARN 1 /* this should not be deactivated */
|
||||
|
||||
int tfe_cannot_use = 0;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
typedef pcap_t *(*pcap_open_live_t)(const char *, int, int, int, char *);
|
||||
|
@ -121,6 +122,7 @@ BOOL TfePcapLoadLibrary(void)
|
|||
pcap_library = LoadLibrary("wpcap.dll");
|
||||
|
||||
if (!pcap_library) {
|
||||
tfe_cannot_use = 1;
|
||||
if(g_fh) fprintf(g_fh, "LoadLibrary WPCAP.DLL failed!\n" );
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -179,7 +181,6 @@ static BOOL TfePcapLoadLibrary(void)
|
|||
|
||||
static pcap_if_t *TfePcapNextDev = NULL;
|
||||
static pcap_if_t *TfePcapAlldevs = NULL;
|
||||
static pcap_t *TfePcapFP = NULL;
|
||||
|
||||
static char TfePcapErrbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
|
@ -284,13 +285,13 @@ int tfe_arch_enumadapter_close(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
BOOL TfePcapOpenAdapter(const std::string & interface_name)
|
||||
|
||||
pcap_t * TfePcapOpenAdapter(const std::string & interface_name)
|
||||
{
|
||||
pcap_if_t *TfePcapDevice = NULL;
|
||||
|
||||
if (!tfe_enumadapter_open()) {
|
||||
return FALSE;
|
||||
if (!tfe_arch_enumadapter_open()) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* look if we can find the specified adapter */
|
||||
|
@ -302,7 +303,7 @@ BOOL TfePcapOpenAdapter(const std::string & interface_name)
|
|||
/* we have an interface name, try it */
|
||||
TfePcapDevice = TfePcapAlldevs;
|
||||
|
||||
while (tfe_enumadapter(&pname, &pdescription)) {
|
||||
while (tfe_arch_enumadapter(&pname, &pdescription)) {
|
||||
if (strcmp(pname, interface_name.c_str())==0) {
|
||||
found = TRUE;
|
||||
}
|
||||
|
@ -319,12 +320,12 @@ BOOL TfePcapOpenAdapter(const std::string & interface_name)
|
|||
}
|
||||
}
|
||||
|
||||
TfePcapFP = (*p_pcap_open_live)(TfePcapDevice->name, 1700, 1, 20, TfePcapErrbuf);
|
||||
pcap_t * TfePcapFP = (*p_pcap_open_live)(TfePcapDevice->name, 1700, 1, 20, TfePcapErrbuf);
|
||||
if ( TfePcapFP == NULL)
|
||||
{
|
||||
if(g_fh) fprintf(g_fh, "ERROR opening adapter: '%s'\n", TfePcapErrbuf);
|
||||
tfe_enumadapter_close();
|
||||
return FALSE;
|
||||
tfe_arch_enumadapter_close();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((*p_pcap_setnonblock)(TfePcapFP, 1, TfePcapErrbuf)<0)
|
||||
|
@ -336,68 +337,29 @@ BOOL TfePcapOpenAdapter(const std::string & interface_name)
|
|||
if((*p_pcap_datalink)(TfePcapFP) != DLT_EN10MB)
|
||||
{
|
||||
if(g_fh) fprintf(g_fh, "ERROR: TFE works only on Ethernet networks.\n");
|
||||
tfe_enumadapter_close();
|
||||
tfe_arch_enumadapter_close();
|
||||
(*p_pcap_close)(TfePcapFP);
|
||||
TfePcapFP = NULL;
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tfe_enumadapter_close();
|
||||
return TRUE;
|
||||
if(g_fh) fprintf(g_fh, "PCAP: Succesfully opened adapter: '%s'\n", TfePcapDevice->name);
|
||||
|
||||
tfe_arch_enumadapter_close();
|
||||
return TfePcapFP;
|
||||
}
|
||||
|
||||
void TfePcapCloseAdapter(pcap_t * TfePcapFP)
|
||||
{
|
||||
if (TfePcapFP)
|
||||
{
|
||||
(*p_pcap_close)(TfePcapFP);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* the architecture-dependend functions */
|
||||
|
||||
|
||||
int tfe_arch_init(void)
|
||||
{
|
||||
// g_fh = log_open("TFEARCH");
|
||||
|
||||
if (!TfePcapLoadLibrary()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void tfe_arch_pre_reset( void )
|
||||
{
|
||||
#ifdef TFE_DEBUG_ARCH
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_pre_reset().\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
void tfe_arch_post_reset( void )
|
||||
{
|
||||
#ifdef TFE_DEBUG_ARCH
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_post_reset().\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
int tfe_arch_activate(const std::string & interface_name)
|
||||
{
|
||||
#ifdef TFE_DEBUG_ARCH
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_activate().\n" );
|
||||
#endif
|
||||
if (!TfePcapOpenAdapter(interface_name)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void tfe_arch_deactivate( void )
|
||||
{
|
||||
#ifdef TFE_DEBUG_ARCH
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_deactivate().\n" );
|
||||
#endif
|
||||
if (TfePcapFP) {
|
||||
(*p_pcap_close)(TfePcapFP);
|
||||
TfePcapFP = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void tfe_arch_set_mac( const BYTE mac[6] )
|
||||
{
|
||||
#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
|
||||
|
@ -460,9 +422,9 @@ void tfe_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver )
|
|||
|
||||
|
||||
typedef struct TFE_PCAP_INTERNAL_tag {
|
||||
|
||||
unsigned int len;
|
||||
const unsigned int size;
|
||||
BYTE *buffer;
|
||||
unsigned int rxlength;
|
||||
|
||||
} TFE_PCAP_INTERNAL;
|
||||
|
||||
|
@ -476,10 +438,9 @@ void TfePcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const
|
|||
/* determine the count of bytes which has been returned,
|
||||
* but make sure not to overrun the buffer
|
||||
*/
|
||||
if (header->caplen < pinternal->len)
|
||||
pinternal->len = header->caplen;
|
||||
pinternal->rxlength = min(pinternal->size, header->caplen);
|
||||
|
||||
memcpy(pinternal->buffer, pkt_data, pinternal->len);
|
||||
memcpy(pinternal->buffer, pkt_data, pinternal->rxlength);
|
||||
}
|
||||
|
||||
/* the following function receives a frame.
|
||||
|
@ -493,7 +454,7 @@ void TfePcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const
|
|||
At most 'len' bytes are copied.
|
||||
*/
|
||||
static
|
||||
int tfe_arch_receive_frame(TFE_PCAP_INTERNAL *pinternal)
|
||||
int tfe_arch_receive_frame(pcap_t * TfePcapFP, TFE_PCAP_INTERNAL *pinternal)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
|
@ -501,7 +462,7 @@ int tfe_arch_receive_frame(TFE_PCAP_INTERNAL *pinternal)
|
|||
/* RGJ changed from void to u_char for AppleWin */
|
||||
if ((*p_pcap_dispatch)(TfePcapFP, 1, TfePcapPacketHandler, (u_char *)pinternal)!=0) {
|
||||
/* Something has been received */
|
||||
ret = pinternal->len;
|
||||
ret = pinternal->rxlength;
|
||||
}
|
||||
|
||||
#ifdef TFE_DEBUG_ARCH
|
||||
|
@ -511,23 +472,13 @@ int tfe_arch_receive_frame(TFE_PCAP_INTERNAL *pinternal)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void tfe_arch_transmit(int force, /* FORCE: Delete waiting frames in transmit buffer */
|
||||
int onecoll, /* ONECOLL: Terminate after just one collision */
|
||||
int inhibit_crc, /* INHIBITCRC: Do not append CRC to the transmission */
|
||||
int tx_pad_dis, /* TXPADDIS: Disable padding to 60 Bytes */
|
||||
void tfe_arch_transmit(pcap_t * TfePcapFP,
|
||||
int txlength, /* Frame length */
|
||||
BYTE *txframe /* Pointer to the frame to be transmitted */
|
||||
)
|
||||
{
|
||||
#ifdef TFE_DEBUG_ARCH
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_transmit() called, with: "
|
||||
"force = %s, onecoll = %s, inhibit_crc=%s, tx_pad_dis=%s, txlength=%u\n",
|
||||
force ? "TRUE" : "FALSE",
|
||||
onecoll ? "TRUE" : "FALSE",
|
||||
inhibit_crc ? "TRUE" : "FALSE",
|
||||
tx_pad_dis ? "TRUE" : "FALSE",
|
||||
txlength
|
||||
);
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_transmit() called, with: txlength=%u\n", txlength);
|
||||
#endif
|
||||
|
||||
#ifdef TFE_DEBUG_PKTDUMP
|
||||
|
@ -543,7 +494,7 @@ void tfe_arch_transmit(int force, /* FORCE: Delete waiting frames in trans
|
|||
tfe_arch_receive()
|
||||
|
||||
This function checks if there was a frame received.
|
||||
If so, it returns 1, else 0.
|
||||
If so, it returns its size, else -1.
|
||||
|
||||
If there was no frame, none of the parameters is changed!
|
||||
|
||||
|
@ -564,31 +515,20 @@ void tfe_arch_transmit(int force, /* FORCE: Delete waiting frames in trans
|
|||
*pbroadcast is set, else cleared.
|
||||
- if the received frame had a crc error, *pcrc_error is set, else cleared
|
||||
*/
|
||||
int tfe_arch_receive(BYTE *pbuffer , /* where to store a frame */
|
||||
int *plen, /* IN: maximum length of frame to copy;
|
||||
OUT: length of received frame
|
||||
OUT can be bigger than IN if received frame was
|
||||
longer than supplied buffer */
|
||||
int *phashed, /* set if the dest. address is accepted by the hash filter */
|
||||
int *phash_index, /* hash table index if hashed == TRUE */
|
||||
int *prx_ok, /* set if good CRC and valid length */
|
||||
int *pcorrect_mac, /* set if dest. address is exactly our IA */
|
||||
int *pbroadcast, /* set if dest. address is a broadcast address */
|
||||
int *pcrc_error /* set if received frame had a CRC error */
|
||||
int tfe_arch_receive(pcap_t * TfePcapFP,
|
||||
const int size , /* Size of buffer */
|
||||
BYTE *pbuffer /* where to store a frame */
|
||||
)
|
||||
{
|
||||
int len;
|
||||
|
||||
TFE_PCAP_INTERNAL internal = { static_cast<unsigned int>(*plen), pbuffer };
|
||||
|
||||
TFE_PCAP_INTERNAL internal = { static_cast<unsigned int>(size), pbuffer, 0 };
|
||||
|
||||
#ifdef TFE_DEBUG_ARCH
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_receive() called, with *plen=%u.\n", *plen );
|
||||
if(g_fh) fprintf( g_fh, "tfe_arch_receive() called, with size=%u.\n", size );
|
||||
#endif
|
||||
|
||||
assert((*plen&1)==0);
|
||||
assert((size & 1)==0);
|
||||
|
||||
len = tfe_arch_receive_frame(&internal);
|
||||
int len = tfe_arch_receive_frame(TfePcapFP, &internal);
|
||||
|
||||
if (len!=-1) {
|
||||
|
||||
|
@ -599,25 +539,10 @@ int tfe_arch_receive(BYTE *pbuffer , /* where to store a frame */
|
|||
if (len&1)
|
||||
++len;
|
||||
|
||||
*plen = len;
|
||||
|
||||
/* we don't decide if this frame fits the needs;
|
||||
* by setting all zero, we let tfe.c do the work
|
||||
* for us
|
||||
*/
|
||||
*phashed =
|
||||
*phash_index =
|
||||
*pbroadcast =
|
||||
*pcorrect_mac =
|
||||
*pcrc_error = 0;
|
||||
|
||||
/* this frame has been received correctly */
|
||||
*prx_ok = 1;
|
||||
|
||||
return 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//#endif /* #ifdef HAVE_TFE */
|
||||
|
|
|
@ -31,14 +31,18 @@
|
|||
#include "../CommonVICE/types.h"
|
||||
#include <string>
|
||||
|
||||
extern int tfe_arch_init(void);
|
||||
extern void tfe_arch_pre_reset(void);
|
||||
extern void tfe_arch_post_reset(void);
|
||||
extern int tfe_arch_activate(const std::string & interface_name);
|
||||
extern void tfe_arch_deactivate(void);
|
||||
extern void tfe_arch_set_mac(const BYTE mac[6]);
|
||||
extern void tfe_arch_set_hashfilter(const DWORD hash_mask[2]);
|
||||
|
||||
/* Flag: Can we even use TFE, or is the hardware not available? */
|
||||
extern int tfe_cannot_use;
|
||||
|
||||
struct pcap;
|
||||
typedef struct pcap pcap_t;
|
||||
|
||||
pcap_t * TfePcapOpenAdapter(const std::string & interface_name);
|
||||
void TfePcapCloseAdapter(pcap_t * TfePcapFP);
|
||||
|
||||
extern
|
||||
void tfe_arch_recv_ctl( int bBroadcast, /* broadcast */
|
||||
int bIA, /* individual address (IA) */
|
||||
|
@ -52,38 +56,16 @@ extern
|
|||
void tfe_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver);
|
||||
|
||||
extern
|
||||
void tfe_arch_transmit(int force, /* FORCE: Delete waiting frames in transmit buffer */
|
||||
int onecoll, /* ONECOLL: Terminate after just one collision */
|
||||
int inhibit_crc, /* INHIBITCRC: Do not append CRC to the transmission */
|
||||
int tx_pad_dis, /* TXPADDIS: Disable padding to 60 Bytes */
|
||||
void tfe_arch_transmit(pcap_t * TfePcapFP,
|
||||
int txlength, /* Frame length */
|
||||
BYTE *txframe /* Pointer to the frame to be transmitted */
|
||||
);
|
||||
|
||||
extern
|
||||
int tfe_arch_receive(BYTE *pbuffer , /* where to store a frame */
|
||||
int *plen, /* IN: maximum length of frame to copy;
|
||||
OUT: length of received frame
|
||||
OUT can be bigger than IN if received frame was
|
||||
longer than supplied buffer */
|
||||
int *phashed, /* set if the dest. address is accepted by the hash filter */
|
||||
int *phash_index, /* hash table index if hashed == TRUE */
|
||||
int *prx_ok, /* set if good CRC and valid length */
|
||||
int *pcorrect_mac, /* set if dest. address is exactly our IA */
|
||||
int *pbroadcast, /* set if dest. address is a broadcast address */
|
||||
int *pcrc_error /* set if received frame had a CRC error */
|
||||
);
|
||||
|
||||
/*
|
||||
This is a helper for tfe_receive() to determine if the received frame should be accepted
|
||||
according to the settings.
|
||||
|
||||
This function is even allowed to be called in tfearch.c from tfe_arch_receive() if
|
||||
necessary, which is the reason why its prototype is included here in tfearch.h.
|
||||
*/
|
||||
extern
|
||||
int tfe_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index,
|
||||
int *pcorrect_mac, int *pbroadcast, int *pmulticast);
|
||||
int tfe_arch_receive(pcap_t * TfePcapFP,
|
||||
const int size , /* Size of buffer */
|
||||
BYTE *pbuffer /* where to store a frame */
|
||||
);
|
||||
|
||||
extern int tfe_arch_enumadapter_open(void);
|
||||
extern int tfe_arch_enumadapter(char **ppname, char **ppdescription);
|
||||
|
|
1156
source/Uthernet1.cpp
Normal file
1156
source/Uthernet1.cpp
Normal file
File diff suppressed because it is too large
Load diff
212
source/Uthernet1.h
Normal file
212
source/Uthernet1.h
Normal file
|
@ -0,0 +1,212 @@
|
|||
#pragma once
|
||||
|
||||
#include "Card.h"
|
||||
|
||||
/* define this only if VICE should write each and every frame received
|
||||
and send into the VICE log
|
||||
WARNING: The log grows very fast!
|
||||
*/
|
||||
/** #define TFE_DEBUG_FRAMES **/
|
||||
/** #define TFE_DEBUG_DUMP 1 **/
|
||||
|
||||
#define TFE_DEBUG_WARN 1 /* this should not be deactivated */
|
||||
#define TFE_DEBUG_INIT 1
|
||||
/** #define TFE_DEBUG_LOAD 1 **/
|
||||
/** #define TFE_DEBUG_STORE 1 **/
|
||||
|
||||
#define TFE_COUNT_IO_REGISTER 0x10 /* we have 16 I/O register */
|
||||
#define MAX_PACKETPAGE_ARRAY 0x1000 /* 4 KB */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* reading and writing TFE register functions */
|
||||
|
||||
/*
|
||||
These registers are currently fully or partially supported:
|
||||
|
||||
TFE_PP_ADDR_CC_RXCFG 0x0102 * # RW - 4.4.6., p. 52 - 0003 *
|
||||
TFE_PP_ADDR_CC_RXCTL 0x0104 * # RW - 4.4.8., p. 54 - 0005 *
|
||||
TFE_PP_ADDR_CC_LINECTL 0x0112 * # RW - 4.4.16., p. 62 - 0013 *
|
||||
TFE_PP_ADDR_SE_RXEVENT 0x0124 * # R- - 4.4.7., p. 53 - 0004 *
|
||||
TFE_PP_ADDR_SE_BUSST 0x0138 * # R- - 4.4.21., p. 67 - 0018 *
|
||||
TFE_PP_ADDR_TXCMD 0x0144 * # -W - 4.5., p. 70 - 5.7., p. 98 *
|
||||
TFE_PP_ADDR_TXLENGTH 0x0146 * # -W - 4.5., p. 70 - 5.7., p. 98 *
|
||||
TFE_PP_ADDR_MAC_ADDR 0x0158 * # RW - 4.6., p. 71 - 5.3., p. 86 *
|
||||
0x015a
|
||||
0x015c
|
||||
*/
|
||||
|
||||
/*
|
||||
RW: RXTXDATA = DE00/DE01
|
||||
RW: RXTXDATA2 = DE02/DE03 (for 32-bit-operation)
|
||||
-W: TXCMD = DE04/DE05 (TxCMD, Transmit Command) mapped to PP + 0144 (Reg. 9, Sec. 4.4, page 46)
|
||||
-W: TXLENGTH = DE06/DE07 (TxLenght, Transmit Length) mapped to PP + 0146
|
||||
R-: INTSTQUEUE = DE08/DE09 (Interrupt Status Queue) mapped to PP + 0120 (ISQ, Sec. 5.1, page 78)
|
||||
RW: PP_PTR = DE0A/DE0B (PacketPage Pointer) (see. page 75p: Read -011.---- ----.----)
|
||||
RW: PP_DATA0 = DE0C/DE0D (PacketPage Data (Port 0))
|
||||
RW: PP_DATA1 = DE0E/DE0F (PacketPage Data (Port 1)) (for 32 bit only)
|
||||
*/
|
||||
|
||||
#define TFE_ADDR_RXTXDATA 0x00 /* RW */
|
||||
#define TFE_ADDR_RXTXDATA2 0x02 /* RW 32 bit only! */
|
||||
#define TFE_ADDR_TXCMD 0x04 /* -W Maps to PP+0144 */
|
||||
#define TFE_ADDR_TXLENGTH 0x06 /* -W Maps to PP+0146 */
|
||||
#define TFE_ADDR_INTSTQUEUE 0x08 /* R- Interrupt status queue, maps to PP + 0120 */
|
||||
#define TFE_ADDR_PP_PTR 0x0a /* RW PacketPage Pointer */
|
||||
#define TFE_ADDR_PP_DATA 0x0c /* RW PacketPage Data, Port 0 */
|
||||
#define TFE_ADDR_PP_DATA2 0x0e /* RW PacketPage Data, Port 1 - 32 bit only */
|
||||
|
||||
/* The packetpage register: see p. 39f */
|
||||
#define TFE_PP_ADDR_PRODUCTID 0x0000 /* R- - 4.3., p. 41 */
|
||||
#define TFE_PP_ADDR_IOBASE 0x0020 /* i RW - 4.3., p. 41 - 4.7., p. 72 */
|
||||
#define TFE_PP_ADDR_INTNO 0x0022 /* i RW - 3.2., p. 17 - 4.3., p. 41 */
|
||||
#define TFE_PP_ADDR_DMA_CHAN 0x0024 /* i RW - 3.2., p. 17 - 4.3., p. 41 */
|
||||
#define TFE_PP_ADDR_DMA_SOF 0x0026 /* ? R- - 4.3., p. 41 - 5.4., p. 89 */
|
||||
#define TFE_PP_ADDR_DMA_FC 0x0028 /* ? R- - 4.3., p. 41, "Receive DMA" */
|
||||
#define TFE_PP_ADDR_RXDMA_BC 0x002a /* ? R- - 4.3., p. 41 - 5.4., p. 89 */
|
||||
#define TFE_PP_ADDR_MEMBASE 0x002c /* i RW - 4.3., p. 41 - 4.9., p. 73 */
|
||||
#define TFE_PP_ADDR_BPROM_BASE 0x0030 /* i RW - 3.6., p. 24 - 4.3., p. 41 */
|
||||
#define TFE_PP_ADDR_BPROM_MASK 0x0034 /* i RW - 3.6., p. 24 - 4.3., p. 41 */
|
||||
/* 0x0038 - 0x003F: reserved */
|
||||
#define TFE_PP_ADDR_EEPROM_CMD 0x0040 /* i RW - 3.5., p. 23 - 4.3., p. 41 */
|
||||
#define TFE_PP_ADDR_EEPROM_DATA 0x0042 /* i RW - 3.5., p. 23 - 4.3., p. 41 */
|
||||
/* 0x0044 - 0x004F: reserved */
|
||||
#define TFE_PP_ADDR_REC_FRAME_BC 0x0050 /* RW - 4.3., p. 41 - 5.2.9., p. 86 */
|
||||
/* 0x0052 - 0x00FF: reserved */
|
||||
#define TFE_PP_ADDR_CONF_CTRL 0x0100 /* - RW - 4.4., p. 46; see below */
|
||||
#define TFE_PP_ADDR_STATUS_EVENT 0x0120 /* - R- - 4.4., p. 46; see below */
|
||||
/* 0x0140 - 0x0143: reserved */
|
||||
#define TFE_PP_ADDR_TXCMD 0x0144 /* # -W - 4.5., p. 70 - 5.7., p. 98 */
|
||||
#define TFE_PP_ADDR_TXLENGTH 0x0146 /* # -W - 4.5., p. 70 - 5.7., p. 98 */
|
||||
/* 0x0148 - 0x014F: reserved */
|
||||
#define TFE_PP_ADDR_LOG_ADDR_FILTER 0x0150 /* RW - 4.6., p. 71 - 5.3., p. 86 */
|
||||
#define TFE_PP_ADDR_MAC_ADDR 0x0158 /* # RW - 4.6., p. 71 - 5.3., p. 86 */
|
||||
/* 0x015E - 0x03FF: reserved */
|
||||
#define TFE_PP_ADDR_RXSTATUS 0x0400 /* R- - 4.7., p. 72 - 5.2., p. 78 */
|
||||
#define TFE_PP_ADDR_RXLENGTH 0x0402 /* R- - 4.7., p. 72 - 5.2., p. 78 */
|
||||
#define TFE_PP_ADDR_RX_FRAMELOC 0x0404 /* R- - 4.7., p. 72 - 5.2., p. 78 */
|
||||
/* here, the received frame is stored */
|
||||
#define TFE_PP_ADDR_TX_FRAMELOC 0x0A00 /* -W - 4.7., p. 72 - 5.7., p. 98 */
|
||||
/* here, the frame to transmit is stored */
|
||||
#define TFE_PP_ADDR_END 0x1000 /* memory to TFE_PP_ADDR_END-1 is used */
|
||||
|
||||
|
||||
/* TFE_PP_ADDR_CONF_CTRL is subdivided: */
|
||||
#define TFE_PP_ADDR_CC_RXCFG 0x0102 /* # RW - 4.4.6., p. 52 - 0003 */
|
||||
#define TFE_PP_ADDR_CC_RXCTL 0x0104 /* # RW - 4.4.8., p. 54 - 0005 */
|
||||
#define TFE_PP_ADDR_CC_TXCFG 0x0106 /* RW - 4.4.9., p. 55 - 0007 */
|
||||
#define TFE_PP_ADDR_CC_TXCMD 0x0108 /* R- - 4.4.11., p. 57 - 0009 */
|
||||
#define TFE_PP_ADDR_CC_BUFCFG 0x010A /* RW - 4.4.12., p. 58 - 000B */
|
||||
#define TFE_PP_ADDR_CC_LINECTL 0x0112 /* # RW - 4.4.16., p. 62 - 0013 */
|
||||
#define TFE_PP_ADDR_CC_SELFCTL 0x0114 /* RW - 4.4.18., p. 64 - 0015 */
|
||||
#define TFE_PP_ADDR_CC_BUSCTL 0x0116 /* RW - 4.4.20., p. 66 - 0017 */
|
||||
#define TFE_PP_ADDR_CC_TESTCTL 0x0118 /* RW - 4.4.22., p. 68 - 0019 */
|
||||
|
||||
/* TFE_PP_ADDR_STATUS_EVENT is subdivided: */
|
||||
#define TFE_PP_ADDR_SE_ISQ 0x0120 /* R- - 4.4.5., p. 51 - 0000 */
|
||||
#define TFE_PP_ADDR_SE_RXEVENT 0x0124 /* # R- - 4.4.7., p. 53 - 0004 */
|
||||
#define TFE_PP_ADDR_SE_TXEVENT 0x0128 /* R- - 4.4.10., p. 56 - 0008 */
|
||||
#define TFE_PP_ADDR_SE_BUFEVENT 0x012C /* R- - 4.4.13., p. 59 - 000C */
|
||||
#define TFE_PP_ADDR_SE_RXMISS 0x0130 /* R- - 4.4.14., p. 60 - 0010 */
|
||||
#define TFE_PP_ADDR_SE_TXCOL 0x0132 /* R- - 4.4.15., p. 61 - 0012 */
|
||||
#define TFE_PP_ADDR_SE_LINEST 0x0134 /* R- - 4.4.17., p. 63 - 0014 */
|
||||
#define TFE_PP_ADDR_SE_SELFST 0x0136 /* R- - 4.4.19., p. 65 - 0016 */
|
||||
#define TFE_PP_ADDR_SE_BUSST 0x0138 /* # R- - 4.4.21., p. 67 - 0018 */
|
||||
#define TFE_PP_ADDR_SE_TDR 0x013C /* R- - 4.4.23., p. 69 - 001C */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* some parameter definitions */
|
||||
|
||||
class NetworkBackend;
|
||||
|
||||
class Uthernet1 : public Card
|
||||
{
|
||||
public:
|
||||
Uthernet1(UINT slot);
|
||||
|
||||
virtual void InitializeIO(LPBYTE pCxRomPeripheral);
|
||||
virtual void Init(void);
|
||||
virtual void Reset(const bool powerCycle);
|
||||
virtual void Update(const ULONG nExecutedCycles);
|
||||
virtual void SaveSnapshot(YamlSaveHelper& yamlSaveHelper);
|
||||
virtual bool LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version);
|
||||
|
||||
void Destroy();
|
||||
|
||||
BYTE tfe_read(WORD ioaddress);
|
||||
void tfe_store(WORD ioaddress, BYTE byte);
|
||||
|
||||
static std::string GetSnapshotCardName(void);
|
||||
|
||||
private:
|
||||
|
||||
void InitialiseBackend();
|
||||
|
||||
void tfe_sideeffects_write_pp_on_txframe(WORD ppaddress);
|
||||
void tfe_sideeffects_write_pp(WORD ppaddress, int oddaddress);
|
||||
void tfe_sideeffects_read_pp(WORD ppaddress);
|
||||
void tfe_proceed_rx_buffer(int oddaddress);
|
||||
|
||||
WORD tfe_receive(void);
|
||||
int tfe_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index,
|
||||
int *pcorrect_mac, int *pbroadcast, int *pmulticast);
|
||||
|
||||
// this function is virtually useless
|
||||
// it is only here to keep a record of these unused arguments
|
||||
void tfe_transmit(
|
||||
int force, /* FORCE: Delete waiting frames in transmit buffer */
|
||||
int onecoll, /* ONECOLL: Terminate after just one collision */
|
||||
int inhibit_crc, /* INHIBITCRC: Do not append CRC to the transmission */
|
||||
int tx_pad_dis, /* TXPADDIS: Disable padding to 60 Bytes */
|
||||
int txlength, /* Frame length */
|
||||
uint8_t *txframe /* Pointer to the frame to be transmitted */
|
||||
);
|
||||
|
||||
std::shared_ptr<NetworkBackend> networkBackend;
|
||||
|
||||
#ifdef TFE_DEBUG_DUMP
|
||||
void tfe_debug_output_general( const char *what, WORD (Uthernet1::*getFunc)(int), int count );
|
||||
WORD tfe_debug_output_io_getFunc( int i );
|
||||
WORD tfe_debug_output_pp_getFunc( int i );
|
||||
void tfe_debug_output_io( void );
|
||||
void tfe_debug_output_pp( void );
|
||||
#endif
|
||||
|
||||
/* status which received packages to accept
|
||||
This is used in tfe_should_accept().
|
||||
*/
|
||||
BYTE tfe_ia_mac[6];
|
||||
|
||||
/* remember the value of the hash mask */
|
||||
DWORD tfe_hash_mask[2];
|
||||
|
||||
int tfe_recv_broadcast; /* broadcast */
|
||||
int tfe_recv_mac; /* individual address (IA) */
|
||||
int tfe_recv_multicast; /* multicast if address passes the hash filter */
|
||||
int tfe_recv_correct; /* accept correct frames */
|
||||
int tfe_recv_promiscuous; /* promiscuous mode */
|
||||
int tfe_recv_hashfilter; /* accept if IA passes the hash filter */
|
||||
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
/* remember if the TXCMD has been completed before a new one is issued */
|
||||
int tfe_started_tx;
|
||||
#endif
|
||||
|
||||
/* TFE registers */
|
||||
/* these are the 8 16-bit-ports for "I/O space configuration"
|
||||
(see 4.10 on page 75 of cs8900a-4.pdf, the cs8900a data sheet)
|
||||
|
||||
REMARK: The TFE operatoes the cs8900a in IO space configuration, as
|
||||
it generates I/OW and I/OR signals.
|
||||
*/
|
||||
|
||||
BYTE tfe[TFE_COUNT_IO_REGISTER];
|
||||
|
||||
WORD txcollect_buffer;
|
||||
WORD rx_buffer;
|
||||
|
||||
/* The PacketPage register */
|
||||
/* note: The locations 0 to MAX_PACKETPAGE_ARRAY-1 are handled in this array. */
|
||||
|
||||
BYTE tfe_packetpage[MAX_PACKETPAGE_ARRAY];
|
||||
WORD tfe_packetpage_ptr;
|
||||
};
|
1167
source/Uthernet2.cpp
Normal file
1167
source/Uthernet2.cpp
Normal file
File diff suppressed because it is too large
Load diff
115
source/Uthernet2.h
Normal file
115
source/Uthernet2.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
#pragma once
|
||||
|
||||
#include "Card.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class NetworkBackend;
|
||||
|
||||
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 registers;
|
||||
|
||||
uint16_t sn_rx_wr;
|
||||
uint16_t sn_rx_rsr;
|
||||
|
||||
uint8_t sn_sr;
|
||||
|
||||
socket_t myFD;
|
||||
int myErrno;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
class Uthernet2 : public Card
|
||||
{
|
||||
public:
|
||||
static std::string GetSnapshotCardName();
|
||||
|
||||
Uthernet2(UINT slot);
|
||||
|
||||
void Destroy();
|
||||
|
||||
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<NetworkBackend> myNetworkBackend;
|
||||
|
||||
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);
|
||||
int receiveForMacAddress(const bool acceptAll, const int size, uint8_t * data);
|
||||
|
||||
void sendDataMacRaw(const size_t i, 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);
|
||||
};
|
|
@ -49,7 +49,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "SoundCore.h"
|
||||
|
||||
#include "Configuration/IPropertySheet.h"
|
||||
#include "Tfe/tfe.h"
|
||||
#include "Tfe/PCapBackend.h"
|
||||
|
||||
#ifdef USE_SPEECH_API
|
||||
#include "Speech.h"
|
||||
|
@ -253,39 +253,31 @@ void LoadConfiguration(bool loadImages)
|
|||
|
||||
if (RegLoadValue(regSection.c_str(), REGVALUE_CARD_TYPE, TRUE, &dwTmp))
|
||||
{
|
||||
GetCardMgr().Insert(slot, (SS_CARDTYPE)dwTmp, false);
|
||||
|
||||
if (slot == SLOT3)
|
||||
{
|
||||
tfe_enabled = 0;
|
||||
|
||||
if ((SS_CARDTYPE)dwTmp == CT_Uthernet) // TODO: move this to when UthernetCard object is instantiated
|
||||
// this must happen before the card is instantitated
|
||||
// TODO move to the card
|
||||
if ((SS_CARDTYPE)dwTmp == CT_Uthernet || (SS_CARDTYPE)dwTmp == CT_Uthernet2) // TODO: move this to when UthernetCard object is instantiated
|
||||
{
|
||||
std::string regSection = RegGetConfigSlotSection(slot);
|
||||
if (RegLoadString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, TRUE, szFilename, MAX_PATH, TEXT("")))
|
||||
update_tfe_interface(szFilename);
|
||||
|
||||
tfe_init(true);
|
||||
PCapBackend::tfe_interface = szFilename;
|
||||
}
|
||||
}
|
||||
|
||||
GetCardMgr().Insert(slot, (SS_CARDTYPE)dwTmp, false);
|
||||
}
|
||||
else // legacy (AppleWin 1.30.3 or earlier)
|
||||
{
|
||||
if (slot == SLOT3)
|
||||
{
|
||||
tfe_enabled = 0;
|
||||
// TODO: move this to when UthernetCard object is instantiated
|
||||
RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_UTHERNET_INTERFACE), 1, szFilename, MAX_PATH, TEXT(""));
|
||||
PCapBackend::tfe_interface = szFilename;
|
||||
|
||||
DWORD tfeEnabled;
|
||||
REGLOAD_DEFAULT(TEXT(REGVALUE_UTHERNET_ACTIVE), &tfeEnabled, 0);
|
||||
|
||||
GetCardMgr().Insert(SLOT3, get_tfe_enabled() ? CT_Uthernet : CT_Empty);
|
||||
|
||||
// TODO: move this to when UthernetCard object is instantiated
|
||||
RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_UTHERNET_INTERFACE), 1, szFilename, MAX_PATH, TEXT(""));
|
||||
update_tfe_interface(szFilename);
|
||||
|
||||
if (tfeEnabled)
|
||||
tfe_init(true);
|
||||
GetCardMgr().Insert(SLOT3, tfeEnabled ? CT_Uthernet : CT_Empty);
|
||||
}
|
||||
else if (slot == SLOT4 && REGLOAD(TEXT(REGVALUE_SLOT4), &dwTmp))
|
||||
GetCardMgr().Insert(SLOT4, (SS_CARDTYPE)dwTmp);
|
||||
|
@ -545,6 +537,10 @@ void ResetMachineState()
|
|||
GetCardMgr().GetRef(SLOT7).Reset(true);
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_VidHD)
|
||||
GetCardMgr().GetRef(SLOT3).Reset(true);
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet)
|
||||
GetCardMgr().GetRef(SLOT3).Reset(true);
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet2)
|
||||
GetCardMgr().GetRef(SLOT3).Reset(true);
|
||||
g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted
|
||||
|
||||
MemReset(); // calls CpuInitialize(), CNoSlotClock.Reset()
|
||||
|
@ -602,6 +598,10 @@ void CtrlReset()
|
|||
GetCardMgr().GetRef(SLOT7).Reset(false);
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_VidHD)
|
||||
GetCardMgr().GetRef(SLOT3).Reset(false);
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet)
|
||||
GetCardMgr().GetRef(SLOT3).Reset(false);
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet2)
|
||||
GetCardMgr().GetRef(SLOT3).Reset(false);
|
||||
KeybReset();
|
||||
if (GetCardMgr().IsSSCInstalled())
|
||||
GetCardMgr().GetSSC()->CommReset();
|
||||
|
|
86
source/W5100.h
Normal file
86
source/W5100.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
#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_MF 0x40 // 6
|
||||
#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_DIPR1 0x0D
|
||||
#define SN_DIPR2 0x0E
|
||||
#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
|
|
@ -55,7 +55,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "Configuration/About.h"
|
||||
#include "Configuration/PropertySheet.h"
|
||||
#include "Tfe/tfe.h"
|
||||
|
||||
//=================================================
|
||||
|
||||
|
@ -932,9 +931,6 @@ static void Shutdown(void)
|
|||
CoUninitialize();
|
||||
LogFileOutput("Exit: CoUninitialize()\n");
|
||||
|
||||
tfe_shutdown();
|
||||
LogFileOutput("Exit: tfe_shutdown()\n");
|
||||
|
||||
LogDone();
|
||||
|
||||
RiffFinishWriteFile();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "Memory.h"
|
||||
#include "CardManager.h"
|
||||
#include "Debugger/Debug.h"
|
||||
#include "Tfe/PCapBackend.h"
|
||||
#include "../resource/resource.h"
|
||||
|
||||
// Win32Frame methods are implemented in AppleWin, WinFrame and WinVideo.
|
||||
|
@ -623,3 +624,9 @@ std::string Win32Frame::Video_GetScreenShotFolder() const
|
|||
// save in current folder
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::shared_ptr<NetworkBackend> Win32Frame::CreateNetworkBackend()
|
||||
{
|
||||
std::shared_ptr<NetworkBackend> backend(new PCapBackend(PCapBackend::tfe_interface));
|
||||
return backend;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
|
||||
virtual std::string Video_GetScreenShotFolder() const;
|
||||
|
||||
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend();
|
||||
|
||||
bool GetFullScreenShowSubunitStatus(void);
|
||||
int GetFullScreenOffsetX(void);
|
||||
int GetFullScreenOffsetY(void);
|
||||
|
|
|
@ -44,6 +44,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "SaveState.h"
|
||||
#include "SerialComms.h"
|
||||
#include "SoundCore.h"
|
||||
#include "Uthernet1.h"
|
||||
#include "Uthernet2.h"
|
||||
#include "Speaker.h"
|
||||
#include "Utilities.h"
|
||||
#include "../resource/resource.h"
|
||||
|
@ -966,6 +968,10 @@ LRESULT Win32Frame::WndProc(
|
|||
GetCardMgr().GetDisk2CardMgr().Destroy();
|
||||
if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD)
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(SLOT7)).Destroy();
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet)
|
||||
dynamic_cast<Uthernet1&>(GetCardMgr().GetRef(SLOT3)).Destroy();
|
||||
if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet2)
|
||||
dynamic_cast<Uthernet2&>(GetCardMgr().GetRef(SLOT3)).Destroy();
|
||||
}
|
||||
PrintDestroy();
|
||||
if (GetCardMgr().IsSSCInstalled())
|
||||
|
|
Loading…
Add table
Reference in a new issue