mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 23:25:40 +00:00
Shared RAM on simulated netboard is now double-buffered; Spikeout Final Edition no longer requires a hack to work.
Preparing to enable simulated netboard to run in its own thread
This commit is contained in:
parent
b62110617b
commit
50465f9a5a
|
@ -1011,8 +1011,7 @@ UINT8 CModel3::Read8(UINT32 addr)
|
|||
switch ((addr & 0x3ffff) >> 16)
|
||||
{
|
||||
case 0:
|
||||
//printf("R8 netbuffer @%x=%x\n", (addr & 0xFFFF), netBuffer[(addr & 0xFFFF)]);
|
||||
return netBuffer[(addr & 0xFFFF) ^ 2];
|
||||
return NetBoard->ReadCommRAM8((addr & 0xFFFF) ^ 2);
|
||||
|
||||
case 1: // ioreg 32bits access in 16bits environment
|
||||
if (addr > 0xc00101ff)
|
||||
|
@ -1020,22 +1019,11 @@ UINT8 CModel3::Read8(UINT32 addr)
|
|||
printf("R8 ATTENTION OUT OF RANGE\n");
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Info", "Out of Range", NULL);
|
||||
}
|
||||
//printf("R8 ioreg @%x=%x\n", (addr & 0x1FF), netBuffer[0x10000 + ((addr & 0x1FF) / 2)]);
|
||||
//return netBuffer[0x10000 + ((addr & 0x1FF) / 2)];
|
||||
return (UINT8)NetBoard->ReadIORegister((addr & 0x1FF) / 2);
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
if (addr > 0xc002ffff)
|
||||
{
|
||||
printf("R8 ATTENTION OUT OF RANGE\n");
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Info", "Out of Range", NULL);
|
||||
}
|
||||
//printf("R8 netram @%x=%x\n", (addr & 0x1FFFF), netRAM[addr & 0x1ffff]);
|
||||
return netRAM[((addr & 0x1FFFF) / 2)];
|
||||
/*case 3:
|
||||
//printf("R8 netram @%x=%x\n", (addr & 0x1FFFF), netRAM[addr & 0x1ffff]);
|
||||
return netRAM[((addr & 0x1FFFF) / 2)];*/
|
||||
|
||||
default:
|
||||
printf("R8 ATTENTION OUT OF RANGE\n");
|
||||
|
@ -1152,8 +1140,7 @@ UINT16 CModel3::Read16(UINT32 addr)
|
|||
switch ((addr & 0x3ffff) >> 16)
|
||||
{
|
||||
case 0:
|
||||
//printf("R16 netbuffer @%x=%x\n", (addr & 0xFFFF), FLIPENDIAN16(*(UINT16 *)&netBuffer[(addr & 0xFFFF)]));
|
||||
result = *(UINT16 *)&netBuffer[(addr & 0xFFFF) ^ 2];
|
||||
result = NetBoard->ReadCommRAM16((addr & 0xFFFF) ^ 2);
|
||||
return FLIPENDIAN16(result); // result
|
||||
default:
|
||||
printf("CMODEL3 : unknown R16 : %x (C0)\n", addr);
|
||||
|
@ -1317,7 +1304,7 @@ UINT32 CModel3::Read32(UINT32 addr)
|
|||
switch ((addr & 0x3ffff) >> 16)
|
||||
{
|
||||
case 0:
|
||||
result = *(UINT32 *)&netBuffer[(addr & 0xFFFF)];
|
||||
result = NetBoard->ReadCommRAM32(addr & 0xFFFF);
|
||||
result = FLIPENDIAN32(result);
|
||||
return ((result << 16) | (result >> 16));
|
||||
|
||||
|
@ -1332,11 +1319,6 @@ UINT32 CModel3::Read32(UINT32 addr)
|
|||
|
||||
case 2:
|
||||
case 3:
|
||||
if (addr > 0xc003ffff)
|
||||
{
|
||||
printf("R32 ATTENTION OUT OF RANGE\n");
|
||||
}
|
||||
|
||||
result = (*(UINT32 *)&netRAM[((addr & 0x1FFFF) / 2)]) & 0x0000ffff;
|
||||
return FLIPENDIAN32(result); // result
|
||||
|
||||
|
@ -1479,7 +1461,7 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
|
|||
switch ((addr & 0x3ffff) >> 16)
|
||||
{
|
||||
case 0:
|
||||
*(UINT8 *)&netBuffer[(addr & 0xFFFF) ^ 2] = data;
|
||||
NetBoard->WriteCommRAM8((addr & 0xFFFF) ^ 2, data);
|
||||
break;
|
||||
|
||||
case 1: // ioreg 32bits access to 16bits range
|
||||
|
@ -1493,11 +1475,6 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
|
|||
|
||||
case 2:
|
||||
case 3:
|
||||
if (addr > 0xc002ffff)
|
||||
{
|
||||
printf("W8 ATTENTION OUT OF RANGE\n");
|
||||
}
|
||||
|
||||
*(UINT8 *)&netRAM[(addr & 0x1FFFF)/2] = data;
|
||||
break;
|
||||
|
||||
|
@ -1600,7 +1577,7 @@ void CModel3::Write16(UINT32 addr, UINT16 data)
|
|||
switch ((addr & 0x3ffff) >> 16)
|
||||
{
|
||||
case 0:
|
||||
*(UINT16 *)&netBuffer[(addr & 0xFFFF) ^ 2] = FLIPENDIAN16(data);
|
||||
NetBoard->WriteCommRAM16((addr & 0xFFFF) ^ 2, FLIPENDIAN16(data));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1806,7 +1783,7 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
|
|||
{
|
||||
case 0:
|
||||
temp = FLIPENDIAN32(data);
|
||||
*(UINT32 *)&netBuffer[(addr & 0xFFFF)] = (temp << 16) | (temp >> 16);
|
||||
NetBoard->WriteCommRAM32(addr & 0xFFFF, (temp << 16) | (temp >> 16));
|
||||
break;
|
||||
|
||||
case 1: // ioreg 32bits access to 16bits range
|
||||
|
@ -1820,11 +1797,6 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
|
|||
|
||||
case 2:
|
||||
case 3:
|
||||
if (addr > 0xc003ffff)
|
||||
{
|
||||
printf("W32 ATTENTION OUT OF RANGE\n");
|
||||
}
|
||||
|
||||
*(UINT16 *)&netRAM[((addr & 0x1FFFF) / 2)] = FLIPENDIAN16(data >> 16);
|
||||
break;
|
||||
|
||||
|
|
|
@ -43,6 +43,14 @@ public:
|
|||
|
||||
virtual void GetGame(Game) = 0;
|
||||
|
||||
virtual UINT8 ReadCommRAM8(unsigned addr) = 0;
|
||||
virtual UINT16 ReadCommRAM16(unsigned addr) = 0;
|
||||
virtual UINT32 ReadCommRAM32(unsigned addr) = 0;
|
||||
|
||||
virtual void WriteCommRAM8(unsigned addr, UINT8 data) = 0;
|
||||
virtual void WriteCommRAM16(unsigned addr, UINT16 data) = 0;
|
||||
virtual void WriteCommRAM32(unsigned addr, UINT32 data) = 0;
|
||||
|
||||
virtual UINT16 ReadIORegister(unsigned reg) = 0;
|
||||
virtual void WriteIORegister(unsigned reg, UINT16 data) = 0;
|
||||
};
|
||||
|
|
|
@ -1314,6 +1314,36 @@ void CNetBoard::GetGame(Game gameinfo)
|
|||
Gameinfo = gameinfo;
|
||||
}
|
||||
|
||||
UINT8 CNetBoard::ReadCommRAM8(unsigned addr)
|
||||
{
|
||||
return CommRAM[addr];
|
||||
}
|
||||
|
||||
UINT16 CNetBoard::ReadCommRAM16(unsigned addr)
|
||||
{
|
||||
return *(UINT16*)&CommRAM[addr];
|
||||
}
|
||||
|
||||
UINT32 CNetBoard::ReadCommRAM32(unsigned addr)
|
||||
{
|
||||
return *(UINT32*)&CommRAM[addr];
|
||||
}
|
||||
|
||||
void CNetBoard::WriteCommRAM8(unsigned addr, UINT8 data)
|
||||
{
|
||||
CommRAM[addr] = data;
|
||||
}
|
||||
|
||||
void CNetBoard::WriteCommRAM16(unsigned addr, UINT16 data)
|
||||
{
|
||||
*(UINT16*)&CommRAM[addr] = data;
|
||||
}
|
||||
|
||||
void CNetBoard::WriteCommRAM32(unsigned addr, UINT32 data)
|
||||
{
|
||||
*(UINT32*)&CommRAM[addr] = data;
|
||||
}
|
||||
|
||||
UINT16 CNetBoard::ReadIORegister(unsigned reg)
|
||||
{
|
||||
if (!IsRunning())
|
||||
|
|
|
@ -61,6 +61,14 @@ public:
|
|||
|
||||
void GetGame(Game);
|
||||
|
||||
UINT8 ReadCommRAM8(unsigned addr);
|
||||
UINT16 ReadCommRAM16(unsigned addr);
|
||||
UINT32 ReadCommRAM32(unsigned addr);
|
||||
|
||||
void WriteCommRAM8(unsigned addr, UINT8 data);
|
||||
void WriteCommRAM16(unsigned addr, UINT16 data);
|
||||
void WriteCommRAM32(unsigned addr, UINT32 data);
|
||||
|
||||
UINT16 ReadIORegister(unsigned reg);
|
||||
void WriteIORegister(unsigned reg, UINT16 data);
|
||||
|
||||
|
|
|
@ -61,7 +61,10 @@ void CSimNetBoard::LoadState(CBlockFile* SaveState)
|
|||
bool CSimNetBoard::Init(uint8_t* netRAMPtr, uint8_t* netBufferPtr)
|
||||
{
|
||||
RAM = netRAMPtr;
|
||||
CommRAM = netBufferPtr;
|
||||
Buffer = netBufferPtr;
|
||||
|
||||
CommRAM = Buffer;
|
||||
externalCommRAM = Buffer + 0x10000;
|
||||
|
||||
m_attached = m_gameInfo.netboard_present && m_config["Network"].ValueAs<bool>();
|
||||
|
||||
|
@ -105,7 +108,7 @@ void CSimNetBoard::RunFrame(void)
|
|||
break;
|
||||
|
||||
case State::init:
|
||||
memset(CommRAM, 0, 0x10000);
|
||||
memset(CommRAM, 0, 0x20000);
|
||||
if (m_gameType == GameType::one)
|
||||
{
|
||||
if (m_status0 & 0x8000) // has main board changed this register?
|
||||
|
@ -454,39 +457,36 @@ void CSimNetBoard::RunFrame(void)
|
|||
m_counter++;
|
||||
CommRAM16[0x6] = FLIPENDIAN16(m_counter);
|
||||
|
||||
if (IsGame("spikeofe")) // temporary hack for spikeout final edition (avoids comm error)
|
||||
// we only send what we need to; helps cut down on bandwidth
|
||||
// each machine has to receive back its own data (TODO: copy this data manually?)
|
||||
for (int i = 0; i < m_numMachines; i++)
|
||||
{
|
||||
nets->Send(CommRAM + 0x100, m_segmentSize * m_numMachines);
|
||||
nets->Send(CommRAM + 0x100 + i * m_segmentSize, m_segmentSize);
|
||||
auto& recv_data = netr->Receive();
|
||||
if (recv_data.size() == 0)
|
||||
{
|
||||
// link broken - send an "empty" packet to alert other machines
|
||||
nets->Send(nullptr, 0);
|
||||
m_state = State::error;
|
||||
m_status1 = 0x40; // send "link broken" message to mainboard
|
||||
if (m_gameType == GameType::one)
|
||||
m_status1 = 0x40; // send "link broken" message to mainboard
|
||||
break;
|
||||
}
|
||||
memcpy(CommRAM + 0x100 + m_segmentSize, recv_data.data(), recv_data.size());
|
||||
memcpy(CommRAM + 0x100 + (i + 1) * m_segmentSize, recv_data.data(), recv_data.size());
|
||||
}
|
||||
|
||||
// swap CommRAM banks
|
||||
if (m_commbank)
|
||||
{
|
||||
m_commbank = false;
|
||||
CommRAM = Buffer;
|
||||
externalCommRAM = Buffer + 0x10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we only send what we need to; helps cut down on bandwidth
|
||||
// each machine has to receive back its own data (TODO: copy this data manually?)
|
||||
for (int i = 0; i < m_numMachines; i++)
|
||||
{
|
||||
nets->Send(CommRAM + 0x100 + i * m_segmentSize, m_segmentSize);
|
||||
auto& recv_data = netr->Receive();
|
||||
if (recv_data.size() == 0)
|
||||
{
|
||||
// link broken - send an "empty" packet to alert other machines
|
||||
nets->Send(nullptr, 0);
|
||||
m_state = State::error;
|
||||
if (m_gameType == GameType::one)
|
||||
m_status1 = 0x40; // send "link broken" message to mainboard
|
||||
break;
|
||||
}
|
||||
memcpy(CommRAM + 0x100 + (i + 1) * m_segmentSize, recv_data.data(), recv_data.size());
|
||||
}
|
||||
m_commbank = true;
|
||||
CommRAM = Buffer + 0x10000;
|
||||
externalCommRAM = Buffer;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -554,6 +554,36 @@ void CSimNetBoard::ConnectProc(void)
|
|||
m_connected = true;
|
||||
}
|
||||
|
||||
uint8_t CSimNetBoard::ReadCommRAM8(unsigned addr)
|
||||
{
|
||||
return externalCommRAM[addr];
|
||||
}
|
||||
|
||||
uint16_t CSimNetBoard::ReadCommRAM16(unsigned addr)
|
||||
{
|
||||
return *(uint16_t*)&externalCommRAM[addr];
|
||||
}
|
||||
|
||||
uint32_t CSimNetBoard::ReadCommRAM32(unsigned addr)
|
||||
{
|
||||
return *(uint32_t*)&externalCommRAM[addr];
|
||||
}
|
||||
|
||||
void CSimNetBoard::WriteCommRAM8(unsigned addr, uint8_t data)
|
||||
{
|
||||
externalCommRAM[addr] = data;
|
||||
}
|
||||
|
||||
void CSimNetBoard::WriteCommRAM16(unsigned addr, uint16_t data)
|
||||
{
|
||||
*(uint16_t*)&externalCommRAM[addr] = data;
|
||||
}
|
||||
|
||||
void CSimNetBoard::WriteCommRAM32(unsigned addr, uint32_t data)
|
||||
{
|
||||
*(uint32_t*)&externalCommRAM[addr] = data;
|
||||
}
|
||||
|
||||
uint16_t CSimNetBoard::ReadIORegister(unsigned reg)
|
||||
{
|
||||
if (!IsRunning())
|
||||
|
|
|
@ -62,6 +62,14 @@ public:
|
|||
|
||||
void GetGame(Game gameInfo);
|
||||
|
||||
uint8_t ReadCommRAM8(unsigned addr);
|
||||
uint16_t ReadCommRAM16(unsigned addr);
|
||||
uint32_t ReadCommRAM32(unsigned addr);
|
||||
|
||||
void WriteCommRAM8(unsigned addr, uint8_t data);
|
||||
void WriteCommRAM16(unsigned addr, uint16_t data);
|
||||
void WriteCommRAM32(unsigned addr, uint32_t data);
|
||||
|
||||
uint16_t ReadIORegister(unsigned reg);
|
||||
void WriteIORegister(unsigned reg, uint16_t data);
|
||||
|
||||
|
@ -70,7 +78,9 @@ private:
|
|||
const Util::Config::Node& m_config;
|
||||
|
||||
uint8_t* RAM = nullptr;
|
||||
uint8_t* Buffer = nullptr;
|
||||
uint8_t* CommRAM = nullptr;
|
||||
uint8_t* externalCommRAM = nullptr;
|
||||
|
||||
// netsock
|
||||
uint16_t port_in = 0;
|
||||
|
@ -98,6 +108,7 @@ private:
|
|||
uint16_t m_IRQ2ack = 0;
|
||||
uint16_t m_status0 = 0; // ioreg 0x88
|
||||
uint16_t m_status1 = 0; // ioreg 0x8a
|
||||
bool m_commbank = false;
|
||||
|
||||
inline bool IsGame(const char* gameName);
|
||||
void ConnectProc(void);
|
||||
|
|
Loading…
Reference in a new issue