add the rest of the network board code (Spindizzi)

This commit is contained in:
Ian Curtis 2018-01-07 14:07:59 +00:00
parent dc3048df24
commit 0b6da91cc0
9 changed files with 500 additions and 87 deletions

View file

@ -19,8 +19,8 @@
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/
/*
* SupermodelDebugger.cpp
/*
* SupermodelDebugger.cpp
*/
#ifdef SUPERMODEL_DEBUGGER
@ -66,7 +66,13 @@ namespace Debugger
cpu->AddRegion(0x90000000, 0x9000000B, false, false, "Real3D VROM Texture Port");
cpu->AddRegion(0x94000000, 0x940FFFFF, false, false, "Real3D Texture FIFO");
cpu->AddRegion(0x98000000, 0x980FFFFF, false, false, "Real3D Polygon RAM");
#ifndef NET_BOARD
cpu->AddRegion(0xC0000000, 0xC00000FF, false, false, "SCSI (Step 1.x)");
#endif
#ifdef NET_BOARD
cpu->AddRegion(0xC0000000, 0xC001FFFF, false, false, "Network Buffer");
cpu->AddRegion(0xC0020000, 0xC003FFFF, false, false, "Network RAM");
#endif
cpu->AddRegion(0xC1000000, 0xC10000FF, false, false, "SCSI (Step 1.x) (Lost World expects it here)");
cpu->AddRegion(0xC2000000, 0xC20000FF, false, false, "Real3D DMA (Step 2.x)");
cpu->AddRegion(0xF0040000, 0xF004003F, false, false, "Input (Controls) Registers");
@ -293,6 +299,30 @@ namespace Debugger
return cpu;
}
#ifdef NET_BOARD
CCPUDebug *CSupermodelDebugger::CreateNetBoardCPUDebug(::CModel3 * model3)
{
CNetBoard *netBrd = model3->GetNetBoard();
if (!netBrd->IsAttached())
return NULL;
CMusashi68KDebug *cpu = new CMusashi68KDebug("NET68K", netBrd->GetM68K());
// Regions
cpu->AddRegion(0x000000, 0x01ffff, false, false, "Net buffer");
cpu->AddRegion(0x020000, 0x03ffff, true, false, "Net RAM");
cpu->AddRegion(0x040000, 0x0401ff, false, false, "Net 1"); // ??? size unknown
cpu->AddRegion(0x080000, 0x0bffff, false, false, "Net 2"); // commram ???
cpu->AddRegion(0x0c0000, 0x0c01ff, false, false, "Net 3"); // ??? size unknown
const char *NetReg = "NetBoard Control Registers";
cpu->AddMappedIO(0x010110, 4, "Reg 1", NetReg);
cpu->AddMappedIO(0x010114, 4, "Reg 2", NetReg);
cpu->AddMappedIO(0x010180, 4, "Reg 3", NetReg);
return cpu;
}
#endif
CSupermodelDebugger::CSupermodelDebugger(::CModel3 *model3, ::CInputs *inputs, ::CLogger *logger) :
CConsoleDebugger(), m_model3(model3), m_inputs(inputs), m_logger(logger),
m_loadEmuState(false), m_saveEmuState(false), m_resetEmu(false)
@ -319,6 +349,13 @@ namespace Debugger
// Add drive board CPU (if attached)
cpu = CreateDriveBoardCPUDebug(m_model3);
if (cpu) AddCPU(cpu);
#ifdef NET_BOARD
// Add net board CPU (if attached)
cpu = CreateNetBoardCPUDebug(m_model3);
if (cpu) AddCPU(cpu);
#endif
}
void CSupermodelDebugger::WaitCommand(CCPUDebug *cpu)

View file

@ -79,6 +79,9 @@ namespace Debugger
static CCPUDebug *CreateDSBCPUDebug(::CModel3 *model3);
static CCPUDebug *CreateDriveBoardCPUDebug(::CModel3 *model3);
#ifdef NET_BOARD
static CCPUDebug *CreateNetBoardCPUDebug(::CModel3 *model3);
#endif
CSupermodelDebugger(::CModel3 *model3, ::CInputs *inputs, ::CLogger *logger);

View file

@ -881,75 +881,120 @@ UINT8 CModel3::Read8(UINT32 addr)
return ram[addr^3];
// Other
switch ((addr>>24))
switch ((addr >> 24))
{
// CROM
// CROM
case 0xFF:
if (addr < 0xFF800000)
return cromBank[(addr&0x7FFFFF)^3];
else
return crom[(addr&0x7FFFFF)^3];
if (addr < 0xFF800000)
return cromBank[(addr & 0x7FFFFF) ^ 3];
else
return crom[(addr & 0x7FFFFF) ^ 3];
// Real3D DMA
// Real3D DMA
case 0xC2:
return GPU.ReadDMARegister8(addr&0xFF);
return GPU.ReadDMARegister8(addr & 0xFF);
// Various
// Various
case 0xF0:
case 0xFE: // mirror
switch ((addr>>16)&0xFF)
{
// Inputs
case 0x04:
return ReadInputs(addr&0x3F);
// Sound Board
case 0x08:
if ((addr & 0xF) == 4) // MIDI control port
return 0x83; // magtruck country check
else
return 0;
break;
// System registers
case 0x10:
return ReadSystemRegister(addr&0x3F);
switch ((addr >> 16) & 0xFF)
{
// Inputs
case 0x04:
return ReadInputs(addr & 0x3F);
// RTC
case 0x14:
if ((addr&3)==1) // battery voltage test
return 0x03;
else if ((addr&3)==0)
return RTC.ReadRegister((addr>>2)&0xF);
return 0;
// Sound Board
case 0x08:
if ((addr & 0xF) == 4) // MIDI control port
return 0x83; // magtruck country check
else
return 0;
break;
// Unknown
default:
break;
}
// System registers
case 0x10:
return ReadSystemRegister(addr & 0x3F);
break;
// RTC
case 0x14:
if ((addr & 3) == 1) // battery voltage test
return 0x03;
else if ((addr & 3) == 0)
return RTC.ReadRegister((addr >> 2) & 0xF);
return 0;
// Tile generator
// Unknown
default:
//printf("CMODEL3 : unknown R8 mirror : %x\n", addr >> 16);
break;
}
break;
// Tile generator
case 0xF1:
if (addr < 0xF1120000)
{
// Tile generator accesses its RAM as little endian, no adjustment needed here
return TileGen.ReadRAM8(addr&0x1FFFFF);
}
break;
if (addr < 0xF1120000)
{
// Tile generator accesses its RAM as little endian, no adjustment needed here
return TileGen.ReadRAM8(addr & 0x1FFFFF);
}
break;
// 53C810 SCSI
// 53C810 SCSI
case 0xC0: // only on Step 1.0
if (m_game.stepping != "1.0")
break;
#ifndef NET_BOARD
if (m_game.stepping != "1.0")
{
//printf("Model3 : Read8 %x\n", addr);
break;
}
#endif
#ifdef NET_BOARD
switch ((addr & 0x3ffff) >> 16)
{
case 0:
//printf("R8 netbuffer @%x=%x\n", (addr & 0xFFFF), netBuffer[(addr & 0xFFFF)]);
return netBuffer[(addr & 0xFFFF)];
case 1: // ioreg 32bits access in 16bits environment
if (addr > 0xc00101ff)
{
printf("R8 ATTENTION OUT OF RANGE\n");
MessageBox(NULL, "Out of Range", NULL, MB_OK);
}
printf("R8 ioreg @%x=%x\n", (addr & 0x1FF), netBuffer[0x10000 + ((addr & 0x1FF) / 2)]);
return netBuffer[0x10000 + ((addr & 0x1FF) / 2)];
case 2:
case 3:
if (addr > 0xc002ffff)
{
printf("R8 ATTENTION OUT OF RANGE\n");
MessageBox(NULL, "Out of Range", NULL, MB_OK);
}
//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");
MessageBox(NULL, "Out of Range", NULL, MB_OK);
break;
}
#endif
case 0xF9:
case 0xC1:
return SCSI.ReadRegister(addr&0xFF);
// Unknown
default:
#ifdef NET_BOARD
printf("CMODEL3 : unknown R8 : %x\n", addr >> 24);
#endif
break;
}
@ -1023,6 +1068,7 @@ UINT16 CModel3::Read16(UINT32 addr)
// Unknown
default:
//printf("CMODEL3 : unknown R16 mirror : %x\n", addr >> 16);
break;
}
@ -1038,8 +1084,28 @@ UINT16 CModel3::Read16(UINT32 addr)
}
break;
#ifdef NET_BOARD
case 0xc0: // spikeout call this
{
UINT16 result;
switch ((addr & 0x3ffff) >> 16)
{
case 0:
printf("R16 netbuffer @%x=%x\n", (addr & 0xFFFF), FLIPENDIAN16(*(UINT16 *)&netBuffer[(addr & 0xFFFF)]));
result = *(UINT16 *)&netBuffer[(addr & 0xFFFF)];
return FLIPENDIAN16(result); // result
default:
printf("CMODEL3 : unknown R16 : %x (C0)\n", addr);
break;
}
}
#endif
// Unknown
default:
#ifdef NET_BOARD
printf("CMODEL3 : unknown R16 : %x (%x)\n", addr, addr >> 24);
MessageBox(NULL, "CMODEL3 : Unknown R16", NULL, MB_OK);
#endif
break;
}
@ -1154,6 +1220,7 @@ UINT32 CModel3::Read32(UINT32 addr)
// Unknown
default:
//printf("CModel 3 unknown R32 mirror %x", (addr >> 16) & 0xFF);
break;
}
@ -1177,8 +1244,61 @@ UINT32 CModel3::Read32(UINT32 addr)
// 53C810 SCSI
case 0xC0: // only on Step 1.0
#ifndef NET_BOARD
if (m_game.stepping != "1.0") // check for Step 1.0
break;
#endif
#ifdef NET_BOARD
if (m_game.stepping != "1.0") // check for Step 1.0
{
UINT32 result;
switch ((addr & 0x3ffff) >> 16)
{
case 0:
//printf("R32 netbuffer @%x=%x\n", (addr & 0xFFFF), FLIPENDIAN32(*(UINT32 *)&netBuffer[(addr & 0xFFFF)]));
result = *(UINT32 *)&netBuffer[(addr & 0xFFFF)];
return FLIPENDIAN32(result); // result
case 1: // ioreg 32bits access to 16bits range
//printf("R32 ioreg @%x=%x\n", (addr & 0x1FF), FLIPENDIAN32(*(UINT32 *)&netBuffer[0x10000 + ((addr & 0x1FF) / 2)]));
if (addr > 0xc00101ff)
{
printf("R32 ATTENTION OUT OF RANGE\n");
}
UINT32 test;
test = (*(UINT32 *)&netBuffer[0x10000 + ((addr & 0x1FF) / 2)]);
if (((FLIPENDIAN32(test) & 0x00ff0000) != 0x00900000) && ((FLIPENDIAN32(test) & 0x00ff0000) != 0x00a00000) && ((FLIPENDIAN32(test) & 0x00ff0000) != 0x00b00000) && ((FLIPENDIAN32(test) & 0x00ff0000) != 0x00800000) && ((FLIPENDIAN32(test) & 0x00ff0000) != 0x00f00000))
{
printf("R32 ioreg @%x=%04x\n", (addr /*& 0x1FF*/), FLIPENDIAN32(test) >> 16);
}
result = (*(UINT32 *)&netBuffer[0x10000 + ((addr & 0x1FF) / 2)]) & 0x0000ffff;
return FLIPENDIAN32(result);
case 2:
case 3:
//printf("R32 netram @%x=%x\n", (addr & 0x1FFFF), FLIPENDIAN32(*(UINT32 *)&netBuffer[(addr & 0x1FFFF)]));
if (addr > 0xc002ffff)
{
printf("R32 ATTENTION OUT OF RANGE\n");
}
result = (*(UINT32 *)&netRAM[((addr & 0x1FFFF) / 2)]) & 0x0000ffff;
return FLIPENDIAN32(result); // result
/*case 3:
//printf("R32 netram @%x=%x\n", (addr & 0x1FFFF), FLIPENDIAN32(*(UINT32 *)&netBuffer[(addr & 0x1FFFF)]));
result = (*(UINT32 *)&netRAM[((addr & 0x1FFFF) / 2)]) & 0x0000ffff;
return FLIPENDIAN32(result); // result*/
default:
printf("R32 ATTENTION OUT OF RANGE\n");
break;
}
}
#endif
case 0xF9:
case 0xC1:
data = (SCSI.ReadRegister((addr+0)&0xFF) << 24);
@ -1189,6 +1309,9 @@ UINT32 CModel3::Read32(UINT32 addr)
// Unknown
default:
#ifdef NET_BOARD
printf("CMODEL3 : unknown R32 : %x\n", addr >> 24);
#endif
break;
}
@ -1203,7 +1326,7 @@ UINT64 CModel3::Read64(UINT32 addr)
data = Read32(addr+0);
data <<= 32;
data |= Read32(addr+4);
//printf("read64 %x = %x\n",addr,data);
return data;
}
@ -1271,6 +1394,7 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
// Unknown
default:
//printf("CMODEL3 : unknown W8 mirror : %x\n", addr >> 16);
break;
}
@ -1285,7 +1409,7 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
TileGen.WriteRAM8(addr&0x1FFFFF, data);
break;
}
goto Unknown8;
goto Unknown8;
// MPC105/106
case 0xF8:
@ -1294,8 +1418,62 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
// 53C810 SCSI
case 0xC0: // only on Step 1.0
#ifndef NET_BOARD
if (m_game.stepping != "1.0")
goto Unknown8;
#endif
#ifdef NET_BOARD
if (m_game.stepping != "1.0")
{
printf("CModel 3 : write8 %x<-%x\n", addr, data);
switch ((addr & 0x3ffff) >> 16)
{
case 0:
//printf("W8 netbuffer @%x<-%x\n", (addr & 0xFFFF), data);
*(UINT8 *)&netBuffer[(addr & 0xFFFF)] = data;
break;
case 1: // ioreg 32bits access to 16bits range
if (addr > 0xc00101ff)
{
printf("W8 ATTENTION OUT OF RANGE\n");
}
printf("W8 ioreg @%x<-%x\n", (addr & 0x1FF), data);
*(UINT8 *)&netBuffer[0x10000 + ((addr & 0x1FF) / 2)] = data;
break;
case 2:
case 3:
if (addr > 0xc002ffff)
{
printf("W8 ATTENTION OUT OF RANGE\n");
}
//printf("W8 netram @%x<-%x\n", (addr & 0x1FFFF), data);
*(UINT8 *)&netRAM[(addr & 0x1FFFF)/2] = data;
break;
/*case 3:
//printf("W8 netram @%x<-%x\n", (addr & 0x1FFFF), data);
*(UINT8 *)&netRAM[(addr & 0x1FFFF) / 2] = data;
break;*/
default:
printf("W8 ATTENTION OUT OF RANGE\n");
break;
}
if ((*(UINT8 *)&netBuffer[(0xc00100c0 & 0x3FFFF)] == 0xff) && NetBoard.CodeReady == false) // c0=180/2
{
printf("Network code copy ending\n");
NetBoard.CodeReady = true;
NetBoard.Reset();
}
break;
}
#endif
case 0xF9:
case 0xC1:
SCSI.WriteRegister(addr&0xFF,data);
@ -1304,6 +1482,9 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
// Unknown:
default:
Unknown8:
#ifdef NET_BOARD
//printf("CMODEL3 : unknown W8 : %x\n", addr >> 24); // harleyb unknown 0xF1
#endif
DebugLog("PC=%08X\twrite8 : %08X=%02X\n", ppc_get_pc(), addr, data);
break;
}
@ -1352,6 +1533,7 @@ void CModel3::Write16(UINT32 addr, UINT16 data)
// Unknown
default:
//printf("CMODEL3 : unknown W16 mirror : %x\n", addr >> 16);
break;
}
@ -1377,6 +1559,9 @@ void CModel3::Write16(UINT32 addr, UINT16 data)
// Unknown
default:
Unknown16:
#ifdef NET_BOARD
printf("CMODEL3 : unknown W16 : %x\n", addr >> 24);
#endif
DebugLog("PC=%08X\twrite16: %08X=%04X\n", ppc_get_pc(), addr, data);
break;
}
@ -1472,7 +1657,7 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
break;
// MPC105/106
case 0xC0: case 0xD0: case 0xE0:
case 0xC0: case 0xD0: case 0xE0:
case 0xC1: case 0xD1: case 0xE1:
case 0xC2: case 0xD2: case 0xE2:
case 0xC3: case 0xD3: case 0xE3:
@ -1519,9 +1704,10 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
case 0x1A:
WriteSecurity(addr&0x3F,data);
break;
// Unknown
default:
//printf("CMODEL3 : unknown W32 mirror : %x\n", addr >> 16);
break;
}
@ -1556,8 +1742,60 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
// 53C810 SCSI
case 0xC0: // step 1.0 only
#ifndef NET_BOARD
if (m_game.stepping != "1.0")
goto Unknown32;
goto Unknown32;
#endif
#ifdef NET_BOARD
if (m_game.stepping != "1.0") // assuming there is no scsi card for step>1.0 because same address for network card (right or wrong ??)
{
switch ((addr & 0x3ffff) >> 16)
{
case 0:
//printf("W32 netbuffer @%x<-%x\n", (addr & 0xFFFF), data);
*(UINT32 *)&netBuffer[(addr & 0xFFFF)] = FLIPENDIAN32(data);
break;
case 1: // ioreg 32bits access to 16bits range
if (addr > 0xc00101ff)
{
printf("W32 ATTENTION OUT OF RANGE\n");
}
printf("W32 ioreg @%x<-%04x\n", (addr /*& 0x1FF*/), data>>16);
*(UINT16 *)&netBuffer[0x10000 + ((addr & 0x1FF) / 2)] = FLIPENDIAN16(data >> 16);
break;
case 2:
case 3:
if (addr > 0xc002ffff)
{
printf("W32 ATTENTION OUT OF RANGE\n");
}
//printf("W32 netram @%x<-%x\n", (addr & 0x1FFFF), data);
*(UINT16 *)&netRAM[((addr & 0x1FFFF) / 2)] = FLIPENDIAN16(data >> 16);
break;
/*case 3:
//printf("W32 netram @%x<-%x\n", (addr & 0x1FFFF), data);
*(UINT16 *)&netRAM[((addr & 0x1FFFF) / 2)] = FLIPENDIAN16(data >> 16);
break;*/
default:
printf("W32 ATTENTION OUT OF RANGE\n");
break;
}
if ((*(UINT16 *)&netBuffer[(0xc0010088 & 0x3FFFF)] == FLIPENDIAN16(0x0080)) && NetBoard.CodeReady == false) // 88=110/2
{
printf("Network code copy ending\n");
NetBoard.CodeReady = true;
NetBoard.Reset();
}
break;
}
break;
#endif
case 0xF9:
case 0xC1:
SCSI.WriteRegister((addr&0xFF)+0,(data>>24)&0xFF);
@ -1569,6 +1807,9 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
// Unknown
default:
Unknown32:
#ifdef NET_BOARD
printf("CMODEL3 : unknown W32 : %x (%x) data=%d\n", addr,addr >> 24,data);
#endif
//printf("PC=%08X\twrite32: %08X=%08X\n", ppc_get_pc(), addr, data);
DebugLog("PC=%08X\twrite32: %08X=%08X\n", ppc_get_pc(), addr, data);
break;
@ -1577,7 +1818,8 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
void CModel3::Write64(UINT32 addr, UINT64 data)
{
Write32(addr+0, (UINT32) (data>>32));
//printf("write64 %x <- %x\n", addr, data);
Write32(addr+0, (UINT32) (data>>32));
Write32(addr+4, (UINT32) data);
}
@ -1729,7 +1971,7 @@ void CModel3::RunFrame(void)
ppcBrdThreadDone = false;
sndBrdThreadDone = false;
drvBrdThreadDone = false;
// Leave notify wait critical section
if (!notifyLock->Unlock())
goto ThreadError;
@ -1737,6 +1979,9 @@ void CModel3::RunFrame(void)
// If multi-threading GPU, then sync GPUs last while PPC main board thread is waiting
if (m_gpuMultiThreaded)
SyncGPUs();
/*if (NetBoard.IsAttached())
RunNetBoardFrame();*/
}
else
{
@ -1747,6 +1992,20 @@ void CModel3::RunFrame(void)
RunSoundBoardFrame();
if (DriveBoard.IsAttached())
RunDriveBoardFrame();
#ifdef NET_BOARD
if (NetBoard.IsAttached() && (m_config["EmulateNet"].ValueAs<bool>()) && ((*(UINT16 *)&netBuffer[(0xc00100C0 & 0x3FFFF)] == 0xFFFF) || (netBuffer[(0xc00100C0 & 0x3FFFF)] == 0xFF) || (*(UINT16 *)&netBuffer[(0xc00100C0 & 0x3FFFF)] == 0x0001)) && (NetBoard.CodeReady == true))
{
// ppc irq network needed ? no effect, is it really active ?
RunNetBoardFrame();
IRQ.Assert(0x10);
ppc_execute(200); // give PowerPC time to acknowledge IRQ
//RunNetBoardFrame();
IRQ.Deassert(0x10);
ppc_execute(200); // acknowledge that IRQ was deasserted (TODO: is this really needed?)
//RunNetBoardFrame();
}
#endif
}
timings.frameTicks = CThread::GetTicks() - start;
@ -2035,6 +2294,13 @@ void CModel3::RunDriveBoardFrame(void)
timings.drvTicks = CThread::GetTicks() - start;
}
#ifdef NET_BOARD
void CModel3::RunNetBoardFrame(void)
{
NetBoard.RunFrame();
}
#endif
bool CModel3::StartThreads(void)
{
if (startedThreads)
@ -2099,7 +2365,9 @@ bool CModel3::StartThreads(void)
// Set audio callback if sound board thread is unsync'd
if (!syncSndBrdThread)
SetAudioCallback(AudioCallback, this);
{
SetAudioCallback(AudioCallback, this);
}
startedThreads = true;
return true;
@ -2245,6 +2513,7 @@ void CModel3::DeleteThreadObjects(void)
drvBrdThread = NULL;
}
// Delete synchronization objects
if (ppcBrdThreadSync != NULL)
{
@ -2261,6 +2530,8 @@ void CModel3::DeleteThreadObjects(void)
delete drvBrdThreadSync;
drvBrdThreadSync = NULL;
}
if (sndBrdNotifyLock != NULL)
{
delete sndBrdNotifyLock;
@ -2292,6 +2563,9 @@ void CModel3::DumpTimings(void)
timings.syncTicks, (timings.syncTicks > 1 ? '!' : ','),
timings.sndTicks, (timings.sndTicks > 10 ? '!' : ','),
timings.drvTicks, (timings.drvTicks > 10 ? '!' : ','),
#ifdef NET_BOARD
timings.netTicks, (timings.netTicks > 10 ? '!' : ','),
#endif
timings.frameTicks, (timings.frameTicks > 16 ? '!' : ' '));
}
@ -2328,6 +2602,7 @@ int CModel3::StartDriveBoardThread(void *data)
return model3->RunDriveBoardThread();
}
int CModel3::RunMainBoardThread(void)
{
for (;;)
@ -2625,6 +2900,8 @@ ThreadError:
return 1;
}
void CModel3::Reset(void)
{
// Clear memory (but do not modify backup RAM!)
@ -2661,7 +2938,7 @@ void CModel3::Reset(void)
if (DriveBoard.IsAttached())
DriveBoard.Reset();
m_cryptoDevice.Reset();
gpusReady = false;
@ -2672,6 +2949,10 @@ void CModel3::Reset(void)
timings.renderTicks = 0;
timings.sndTicks = 0;
timings.drvTicks = 0;
#ifdef NET_BOARD
timings.netTicks = 0;
NetBoard.CodeReady = false;
#endif
timings.frameTicks = 0;
DebugLog("Model 3 reset\n");
@ -2694,8 +2975,15 @@ void CModel3::Reset(void)
#define OFFSET_DSBPROGROM 0xE0C0000 // 128 KB (DSB program)
#define OFFSET_DSBMPEGROM 0xE0E0000 // 16 MB (DSB MPEG data -- Z80 version only uses 8MB)
#define OFFSET_DRIVEROM 0xF0E0000 // 64 KB
#ifndef NET_BOARD
#define MEMORY_POOL_SIZE (0x800000 + 0x800000 + 0x8000000 + 0x4000000 + 0x20000 + 0x20000 + 0x80000 + 0x1000000 + 0x20000 + 0x1000000 + 0x10000)
#endif
#ifdef NET_BOARD
#define OFFSET_NETBUFFER 0xC000000 // not really 128kb (64kb buffer 0000-ffff + i/o 10000-101ff)
#define OFFSET_NETRAM 0xC020000 // 128 KB (c0020000-c003ffff)
#define MEMORY_POOL_SIZE (0x800000 + 0x800000 + 0x8000000 + 0x4000000 + 0x20000 + 0x20000 + 0x80000 + 0x1000000 + 0x20000 + 0x1000000 + 0x10000 + 0x40000)
//8MB 8MB 128MB 64MB 128KB 128KB 512KB 16MB 128KB 16MB 64KB 256KB
#endif
// 64-bit magic number used to detect loading of optional ROMs
#define MAGIC_NUMBER 0x4C444D5245505553ULL
@ -2828,7 +3116,7 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
return FAIL;
}
SoundBoard.AttachDSB(DSB);
// Drive board (if present)
if (rom_set.get_rom("driveboard_program").size)
{
@ -2846,16 +3134,16 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
if (DSB)
extra_hw.insert(Util::Format() << "Digital Sound Board (Type " << game.mpeg_board << ")");
if (rom_set.get_rom("driveboard_program").size)
extra_hw.insert("Drive Board");
if (game.encryption_key)
extra_hw.insert("Security Board");
if (!game.version.empty())
std::cout << " Title: " << game.title << " (" << game.version << ")" << std::endl;
else
std::cout << " Title: " << game.title << std::endl;
std::cout << " ROM Set: " << game.name << std::endl;
std::cout << " Developer: " << game.manufacturer << std::endl;
std::cout << " Year: " << game.year << std::endl;
extra_hw.insert("Drive Board");
if (game.encryption_key)
extra_hw.insert("Security Board");
if (!game.version.empty())
std::cout << " Title: " << game.title << " (" << game.version << ")" << std::endl;
else
std::cout << " Title: " << game.title << std::endl;
std::cout << " ROM Set: " << game.name << std::endl;
std::cout << " Developer: " << game.manufacturer << std::endl;
std::cout << " Year: " << game.year << std::endl;
std::cout << " Stepping: " << game.stepping << std::endl;
if (!extra_hw.empty())
std::cout << " Extra Hardware: " << Util::Format(", ").Join(extra_hw) << std::endl;
@ -2915,6 +3203,10 @@ bool CModel3::Init(void)
backupRAM = &memoryPool[OFFSET_BACKUPRAM];
securityRAM = &memoryPool[OFFSET_SECURITYRAM];
driveROM = &memoryPool[OFFSET_DRIVEROM];
#ifdef NET_BOARD
netRAM = &memoryPool[OFFSET_NETRAM];
netBuffer = &memoryPool[OFFSET_NETBUFFER];
#endif
SetCROMBank(0xFF);
// Initialize other devices (PowerPC, DSB, and security board initialized after ROMs loaded)
@ -2930,7 +3222,11 @@ bool CModel3::Init(void)
return FAIL;
if (OKAY != SoundBoard.Init(soundROM,sampleROM))
return FAIL;
#ifdef NET_BOARD
if (OKAY != NetBoard.Init(netRAM, netBuffer))
return FAIL;
#endif
PCIBridge.AttachPCIBus(&PCIBus);
PCIBus.AttachDevice(13,&GPU);
PCIBus.AttachDevice(14,&SCSI);
@ -2943,7 +3239,7 @@ bool CModel3::Init(void)
CSoundBoard *CModel3::GetSoundBoard(void)
{
return &SoundBoard;
return &SoundBoard;
}
CDriveBoard *CModel3::GetDriveBoard(void)
@ -2951,6 +3247,13 @@ CDriveBoard *CModel3::GetDriveBoard(void)
return &DriveBoard;
}
#ifdef NET_BOARD
CNetBoard *CModel3::GetNetBoard(void)
{
return &NetBoard;
}
#endif
CModel3::CModel3(const Util::Config::Node &config)
: m_config(config),
m_multiThreaded(config["MultiThreaded"].ValueAs<bool>()),
@ -2959,7 +3262,11 @@ CModel3::CModel3(const Util::Config::Node &config)
GPU(config),
SoundBoard(config),
DriveBoard(config),
m_jtag(GPU)
m_jtag(GPU),
#ifdef NET_BOARD
NetBoard(config)
#endif
{
// Initialize pointers so dtor can know whether to free them
memoryPool = NULL;
@ -2977,7 +3284,11 @@ CModel3::CModel3(const Util::Config::Node &config)
cromBank = NULL;
backupRAM = NULL;
securityRAM = NULL;
#ifdef NET_BOARD
netRAM = NULL;
netBuffer = NULL;
#endif
DSB = NULL;
securityPtr = 0;
@ -2988,16 +3299,19 @@ CModel3::CModel3(const Util::Config::Node &config)
ppcBrdThread = NULL;
sndBrdThread = NULL;
drvBrdThread = NULL;
ppcBrdThreadRunning = false;
ppcBrdThreadDone = false;
sndBrdThreadRunning = false;
sndBrdThreadDone = false;
drvBrdThreadRunning = false;
drvBrdThreadDone = false;
syncSndBrdThread = false;
ppcBrdThreadSync = NULL;
sndBrdThreadSync = NULL;
drvBrdThreadSync = NULL;
notifyLock = NULL;
notifySync = NULL;
@ -3049,7 +3363,8 @@ CModel3::~CModel3(void)
delete DSB;
DSB = NULL;
}
Inputs = NULL;
Outputs = NULL;
ram = NULL;
@ -3062,6 +3377,10 @@ CModel3::~CModel3(void)
cromBank = NULL;
backupRAM = NULL;
securityRAM = NULL;
#ifdef NET_BOARD
netRAM = NULL;
netBuffer = NULL;
#endif
DebugLog("Destroyed Model 3\n");
}

View file

@ -46,6 +46,9 @@ struct FrameTimings
UINT32 renderTicks;
UINT32 sndTicks;
UINT32 drvTicks;
#ifdef NET_BOARD
UINT32 netTicks;
#endif
UINT32 frameTicks;
};
@ -108,7 +111,7 @@ public:
* OKAY if successful, FAIL otherwise. Prints errors.
*/
bool LoadGame(const Game &game, const ROMSet &rom_set);
/*
* GetSoundBoard(void):
*
@ -129,6 +132,18 @@ public:
*/
CDriveBoard *GetDriveBoard(void);
#ifdef NET_BOARD
/*
* GetNetBoard(void):
*
* Returns a reference to the net board.
* Returns:
* Pointer to CNetBoard object.
*/
CNetBoard * GetNetBoard(void);
#endif
/*
* DumpTimings(void):
*
@ -178,6 +193,9 @@ private:
void SyncGPUs(void); // Sync's up GPUs in preparation for rendering - must be called when PPC is not running
bool RunSoundBoardFrame(void); // Runs sound board for a frame
void RunDriveBoardFrame(void); // Runs drive board for a frame
#ifdef NET_BOARD
void RunNetBoardFrame(void); // Runs net board for a frame
#endif
bool StartThreads(void); // Starts all threads
bool StopThreads(void); // Stops all threads
@ -195,7 +213,7 @@ private:
int RunSoundBoardThread(void); // Runs sound board thread (not sync'd in step with render thread, ie running at full speed)
int RunSoundBoardThreadSyncd(void); // Runs sound board thread (sync'd in step with render thread)
int RunDriveBoardThread(void); // Runs drive board thread (sync'd in step with render thread)
// Runtime configuration
const Util::Config::Node &m_config;
bool m_multiThreaded;
@ -229,7 +247,12 @@ private:
UINT8 *backupRAM; // 128 KB Backup RAM (battery backed)
UINT8 *securityRAM; // 128 KB Security Board RAM
UINT8 *driveROM; // 32 KB drive board ROM (Z80 program) (optional)
#ifdef NET_BOARD
UINT8 *netRAM; // 128KB RAM
UINT8 *netBuffer; // 128KB buffer
UINT8 *commRAM; // 64 kB or more ??
#endif
// Banked CROM
UINT8 *cromBank; // currently mapped in CROM bank
unsigned cromBankReg; // the CROM bank register
@ -284,6 +307,10 @@ private:
CDriveBoard DriveBoard; // Drive board
CCrypto m_cryptoDevice; // Encryption device
CJTAG m_jtag; // JTAG interface
#ifdef NET_BOARD
CNetBoard NetBoard; // Net board
#endif
};

View file

@ -348,8 +348,8 @@ static const unsigned decode8x1[8] =
void CReal3D::StoreTexture(unsigned level, unsigned xPos, unsigned yPos, unsigned width, unsigned height, const uint16_t *texData, bool sixteenBit, bool writeLSB, bool writeMSB, uint32_t &texDataOffset)
{
uint32_t tileX = std::min(8u, width);
uint32_t tileY = std::min(8u, height);
uint32_t tileX = (std::min)(8u, width);
uint32_t tileY = (std::min)(8u, height);
texDataOffset = 0;
@ -435,7 +435,7 @@ void CReal3D::StoreTexture(unsigned level, unsigned xPos, unsigned yPos, unsigne
}
destOffset += 2048 - tileX; // next line
}
uint32_t offset = std::max(1u, (tileY * tileX) / 2);
uint32_t offset = (std::max)(1u, (tileY * tileX) / 2);
texData += offset; // next tile
texDataOffset += offset; // next tile
}

View file

@ -48,7 +48,7 @@
* - SUPERMODEL_DEBUGGER: Enable the debugger.
* - DEBUG: Debug mode (use with caution, produces large logs of game behavior)
*/
#include <new>
#include <cmath>
#include <cstdio>
@ -1319,6 +1319,10 @@ static Util::Config::Node DefaultConfig()
config.Set("XInputConstForceThreshold", "30");
config.Set("XInputConstForceMax", "100");
config.Set("XInputVibrateMax", "100");
#ifdef NET_BOARD
// NetBoard
config.Set("EmulateNet", false);
#endif
#else
config.Set("InputSystem", "sdl");
#endif
@ -1381,6 +1385,12 @@ static void Help(void)
puts(" -no-sound Disable sound board emulation (sound effects)");
puts(" -no-dsb Disable Digital Sound Board (MPEG music)");
puts("");
#ifdef NET_BOARD
puts("Net Options:");
puts(" -no-net Disable net board emulation (default)");
puts(" -net Enable net board emulation (not working ATM - need -no-threads)");
puts("");
#endif
puts("Input Options:");
#ifdef SUPERMODEL_WIN32
puts(" -force-feedback Enable force feedback (DirectInput, XInput)");
@ -1462,6 +1472,10 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
{ "-no-sound", { "EmulateSound", false } },
{ "-dsb", { "EmulateDSB", true } },
{ "-no-dsb", { "EmulateDSB", false } },
#ifdef NET_BOARD
{ "-net", { "EmulateNet", true } },
{ "-no-net", { "EmulateNet", false } },
#endif
#ifdef SUPERMODEL_WIN32
{ "-no-force-feedback", { "ForceFeedback", false } },
{ "-force-feedback", { "ForceFeedback", true } },

View file

@ -27,7 +27,9 @@
#ifndef INCLUDED_SUPERMODEL_H
#define INCLUDED_SUPERMODEL_H
#ifdef NET_BOARD
#include "Winsock2.h" // force include winsock2 before windows.h because conflict with winsock1
#endif
// Used throughout Supermodel
#include <cstdio>
#include <cstdlib>
@ -147,6 +149,9 @@
#include "Model3/SoundBoard.h"
#include "Model3/DSB.h"
#include "Model3/DriveBoard.h"
#ifdef NET_BOARD
#include "Network/NetBoard.h"
#endif
#include "Model3/Model3.h"

View file

@ -93,7 +93,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Src;..\Src\OSD;..\Src\OSD\SDL;..\Src\OSD\Windows;..\Libraries\zlib-1.2.4;..\Libraries\SDL-1.2.14\include;$(DXSDK_DIR)\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC</PreprocessorDefinitions>
<PreprocessorDefinitions>SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC;NET_BOARD</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -157,7 +157,7 @@ xcopy /D /Y "$(ProjectDir)\SDL\$(Platform)\$(Configuration)\SDL.dll" "$(TargetDi
<Optimization>Full</Optimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\Src;..\Src\OSD;..\Src\OSD\SDL;..\Src\OSD\Windows;..\Libraries\zlib-1.2.4;..\Libraries\SDL-1.2.14\include;$(DXSDK_DIR)\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC</PreprocessorDefinitions>
<PreprocessorDefinitions>SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC;NET_BOARD</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
@ -345,6 +345,7 @@ xcopy /D /Y "$(ProjectDir)\SDL\$(Platform)\$(Configuration)\SDL.dll" "$(TargetDi
<ClCompile Include="..\Src\Model3\RTC72421.cpp" />
<ClCompile Include="..\Src\Model3\SoundBoard.cpp" />
<ClCompile Include="..\Src\Model3\TileGen.cpp" />
<ClCompile Include="..\Src\Network\NetBoard.cpp" />
<ClCompile Include="..\Src\Network\UDPReceive.cpp" />
<ClCompile Include="..\Src\Network\UDPSend.cpp" />
<ClCompile Include="..\Src\Network\WinSockWrap.cpp" />
@ -572,6 +573,7 @@ xcopy /D /Y "$(ProjectDir)\SDL\$(Platform)\$(Configuration)\SDL.dll" "$(TargetDi
<ClInclude Include="..\Src\Model3\RTC72421.h" />
<ClInclude Include="..\Src\Model3\SoundBoard.h" />
<ClInclude Include="..\Src\Model3\TileGen.h" />
<ClInclude Include="..\Src\Network\NetBoard.h" />
<ClInclude Include="..\Src\Network\UDPPacket.h" />
<ClInclude Include="..\Src\Network\UDPReceive.h" />
<ClInclude Include="..\Src\Network\UDPSend.h" />

View file

@ -461,6 +461,9 @@
<ClCompile Include="..\Src\Network\WinSockWrap.cpp">
<Filter>Source Files\Network</Filter>
</ClCompile>
<ClCompile Include="..\Src\Network\NetBoard.cpp">
<Filter>Source Files\Network</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="..\Src\CPU\68K\Turbo68K\Turbo68K.asm">
@ -856,6 +859,9 @@
<ClInclude Include="..\Src\Network\WinSockWrap.h">
<Filter>Header Files\Network</Filter>
</ClInclude>
<ClInclude Include="..\Src\Network\NetBoard.h">
<Filter>Header Files\Network</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\Src\Debugger\ReadMe.txt">