1
// Copyright 2013 Dolphin Emulator Project
2
// Licensed under GPLv2
3
// Refer to the license.txt file included.
5
#include "Common.h" // Common
7
#include "../ConfigManager.h"
8
#include "../CoreTiming.h"
9
#include "../HW/SystemTimers.h"
11
#include "DVDInterface.h"
13
#include "AMBaseboard.h"
18
static File::IOFile *m_netcfg;
19
static File::IOFile *m_netctrl;
20
static File::IOFile *m_dimm;
22
static u32 m_controllertype;
24
static unsigned char media_buffer[0x60];
25
static unsigned char network_command_buffer[0x200];
27
static inline void PrintMBBuffer( u32 Address )
29
NOTICE_LOG(DVDINTERFACE, "GC-AM: %08x %08x %08x %08x", Memory::Read_U32(Address),
30
Memory::Read_U32(Address+4),
31
Memory::Read_U32(Address+8),
32
Memory::Read_U32(Address+12) );
33
NOTICE_LOG(DVDINTERFACE, "GC-AM: %08x %08x %08x %08x", Memory::Read_U32(Address+16),
34
Memory::Read_U32(Address+20),
35
Memory::Read_U32(Address+24),
36
Memory::Read_U32(Address+28) );
42
memset( media_buffer, 0, sizeof(media_buffer) );
44
//Convert game ID into hex
45
sscanf( SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), "%s", &gameid );
47
// This is checking for the real game IDs (not those people made up) (See boot.id within the game)
48
switch(Common::swap32(gameid))
54
// SBLJ - VIRTUA STRIKER 4 Ver.2006
56
// SBHJ - VIRTUA STRIKER 4 VER.A
58
// SBJJ - VIRTUA STRIKER 4
60
// SBEJ - Virtua Striker 2002
64
// SBKJ - MARIOKART ARCADE GP
66
// SBNJ - MARIOKART ARCADE GP2
71
// PanicAlertT("Unknown game ID, using default controls.");
76
std::string netcfg_Filename( File::GetUserPath(D_TRIUSER_IDX) + "trinetcfg.bin" );
77
if( File::Exists( netcfg_Filename ) )
79
m_netcfg = new File::IOFile( netcfg_Filename, "rb+" );
83
m_netcfg = new File::IOFile( netcfg_Filename, "wb+" );
86
std::string netctrl_Filename( File::GetUserPath(D_TRIUSER_IDX) + "trinetctrl.bin" );
87
if( File::Exists( netctrl_Filename ) )
89
m_netctrl = new File::IOFile( netctrl_Filename, "rb+" );
93
m_netctrl = new File::IOFile( netctrl_Filename, "wb+" );
96
std::string dimm_Filename( File::GetUserPath(D_TRIUSER_IDX) + "tridimm_" + SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() + ".bin" );
97
if( File::Exists( dimm_Filename ) )
99
m_dimm = new File::IOFile( dimm_Filename, "rb+" );
103
m_dimm = new File::IOFile( dimm_Filename, "wb+" );
106
u32 ExecuteCommand( u32 Command, u32 Length, u32 Address, u32 Offset )
108
NOTICE_LOG(DVDINTERFACE, "GCAM: %08x %08x DMA=addr:%08x,len:%08x",
109
Command, Offset, Address, Length);
119
if( (Offset & 0x8FFF0000) == 0x80000000 )
123
// Media board status (1)
125
Memory::Write_U16( Common::swap16( 0x0100 ), Address );
127
// Media board status (2)
129
memset( Memory::GetPointer(Address), 0, Length );
131
// Media board status (3)
133
memset( Memory::GetPointer(Address), 0xFFFFFFFF, Length );
135
Memory::Write_U32( Common::swap32( 0x20000000 ), Address );
137
Memory::Write_U32( 0x4743414D, Address+4 );
139
// Firmware status (1)
141
Memory::Write_U32( Common::swap32( (u32)0x00000001 ), Address );
143
// Firmware status (2)
145
Memory::Write_U32( Common::swap32( (u32)0x00000001 ), Address );
148
PrintMBBuffer(Address);
149
PanicAlertT("Unhandled Media Board Read");
154
// Network configuration
155
if( (Offset == 0x00000000) && (Length == 0x80) )
157
m_netcfg->Seek( 0, SEEK_SET );
158
m_netcfg->ReadBytes( Memory::GetPointer(Address), Length );
162
if( (Offset >= 0x1F000000) && (Offset <= 0x1F300000) )
164
u32 dimmoffset = Offset - 0x1F000000;
165
m_dimm->Seek( dimmoffset, SEEK_SET );
166
m_dimm->ReadBytes( Memory::GetPointer(Address), Length );
170
if( (Offset >= 0x1F900000) && (Offset <= 0x1F90003F) )
172
u32 dimmoffset = Offset - 0x1F900000;
173
memcpy( Memory::GetPointer(Address), media_buffer + dimmoffset, Length );
175
NOTICE_LOG(DVDINTERFACE, "GC-AM: Read MEDIA BOARD COMM AREA (%08x)", dimmoffset );
176
PrintMBBuffer(Address);
180
if( (Offset >= 0x1F800200) && (Offset <= 0x1F8003FF) )
182
memcpy( Memory::GetPointer(Address), network_command_buffer, Length );
186
if( (Offset >= 0x84000000) && (Offset <= 0x8400005F) )
188
u32 dimmoffset = Offset - 0x84000000;
189
memcpy( Memory::GetPointer(Address), media_buffer + dimmoffset, Length );
191
NOTICE_LOG(DVDINTERFACE, "GC-AM: Read MEDIA BOARD COMM AREA (%08x)", dimmoffset );
192
PrintMBBuffer(Address);
196
if( (Offset >= 0xFF000000) && (Offset <= 0xFF800000) )
198
u32 dimmoffset = Offset - 0xFF000000;
199
m_dimm->Seek( dimmoffset, SEEK_SET );
200
m_dimm->ReadBytes( Memory::GetPointer(Address), Length );
204
if( (Offset == 0xFFFF0000) && (Length == 0x20) )
206
m_netctrl->Seek( 0, SEEK_SET );
207
m_netctrl->ReadBytes( Memory::GetPointer(Address), Length );
210
// Max GC disc offset
211
if( Offset >= 0x57058000 )
213
PanicAlertT("Unhandled Media Board Read");
215
if( !DVDInterface::DVDRead( Offset, Address, Length) )
217
PanicAlertT("Can't read from DVD_Plugin - DVD-Interface: Fatal Error");
222
// Network configuration
223
if( (Offset == 0x00000000) && (Length == 0x80) )
225
m_netcfg->Seek( 0, SEEK_SET );
226
m_netcfg->WriteBytes( Memory::GetPointer(Address), Length );
229
// Backup memory (8MB)
230
if( (Offset >= 0x000006A0) && (Offset <= 0x00800000) )
232
m_dimm->Seek( Offset, SEEK_SET );
233
m_dimm->WriteBytes( Memory::GetPointer(Address), Length );
237
if( (Offset >= 0x1F000000) && (Offset <= 0x1F300000) )
239
u32 dimmoffset = Offset - 0x1F000000;
240
m_dimm->Seek( dimmoffset, SEEK_SET );
241
m_dimm->WriteBytes( Memory::GetPointer(Address), Length );
245
if( (Offset >= 0x1F800200) && (Offset <= 0x1F8003FF) )
247
memcpy( network_command_buffer, Memory::GetPointer(Address), Length );
251
if( (Offset >= 0x1F900000) && (Offset <= 0x1F90003F) )
253
u32 dimmoffset = Offset - 0x1F900000;
254
memcpy( media_buffer + dimmoffset, Memory::GetPointer(Address), Length );
256
ERROR_LOG(DVDINTERFACE, "GC-AM: Write MEDIA BOARD COMM AREA (%08x)", dimmoffset );
257
PrintMBBuffer(Address);
261
if( (Offset >= 0x84000000) && (Offset <= 0x8400005F) )
263
u32 dimmoffset = Offset - 0x84000000;
264
memcpy( media_buffer + dimmoffset, Memory::GetPointer(Address), Length );
266
if( dimmoffset == 0x40 )
268
ERROR_LOG(DVDINTERFACE, "GC-AM: EXECUTE (%03x)", *(u16*)(media_buffer+0x22) );
271
ERROR_LOG(DVDINTERFACE, "GC-AM: Write MEDIA BOARD COMM AREA (%08x)", dimmoffset );
272
PrintMBBuffer(Address);
276
if( (Offset >= 0xFF000000) && (Offset <= 0xFF800000) )
278
u32 dimmoffset = Offset - 0xFF000000;
279
m_dimm->Seek( dimmoffset, SEEK_SET );
280
m_dimm->WriteBytes( Memory::GetPointer(Address), Length );
284
if( (Offset == 0xFFFF0000) && (Length == 0x20) )
286
m_netctrl->Seek( 0, SEEK_SET );
287
m_netctrl->WriteBytes( Memory::GetPointer(Address), Length );
290
// Max GC disc offset
291
if( Offset >= 0x57058000 )
293
PrintMBBuffer(Address);
294
PanicAlertT("Unhandled Media Board Write");
300
if( (Offset == 0) && (Length == 0) )
302
memset( media_buffer, 0, 0x20 );
304
media_buffer[0] = media_buffer[0x20];
307
*(u16*)(media_buffer+2) = *(u16*)(media_buffer+0x22) | 0x8000;
309
NOTICE_LOG(DVDINTERFACE, "GCAM: Execute command:%03X", *(u16*)(media_buffer+0x22) );
311
switch(*(u16*)(media_buffer+0x22))
315
*(u32*)(media_buffer+4) = 1;
319
*(u32*)(media_buffer+4) = 0x20000000;
321
// Media board status
323
0x00: "Initializing media board. Please wait.."
324
0x01: "Checking network. Please wait..."
325
0x02: "Found a system disc. Insert a game disc"
326
0x03: "Testing a game program. %d%%"
327
0x04: "Loading a game program. %d%%"
333
*(u32*)(media_buffer+4) = 5;
335
*(u32*)(media_buffer+8) = 100;
337
// Media board version: 3.03
340
*(u16*)(media_buffer+4) = Common::swap16(0x0303);
342
*(u16*)(media_buffer+6) = Common::swap16(0x0100);
343
*(u32*)(media_buffer+8)= 1;
344
*(u32*)(media_buffer+16)= 0xFFFFFFFF;
351
// enable development mode (Sega Boot)
353
// Only used when inquiry 0x29
355
0: NAND/MASK BOARD(HDD)
356
1: NAND/MASK BOARD(MASK)
357
2: NAND/MASK BOARD(NAND)
358
3: NAND/MASK BOARD(NAND)
359
4: DIMM BOARD (TYPE 3)
360
5: DIMM BOARD (TYPE 3)
361
6: DIMM BOARD (TYPE 3)
365
//media_buffer[7] = 0;
367
// Media board serial
369
memcpy(media_buffer + 4, "A89E27A50364511", 15);
381
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x301: (%08X)", *(u32*)(media_buffer+0x24) );
383
//Pointer to a memory address that is directly displayed on screen as a string
384
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
386
// On real system it shows the status about the DIMM/GD-ROM here
387
// We just show "TEST OK"
388
Memory::Write_U32( 0x54534554, *(u32*)(media_buffer+0x28) );
389
Memory::Write_U32( 0x004B4F20, *(u32*)(media_buffer+0x28)+4 );
391
*(u32*)(media_buffer+0x04) = *(u32*)(media_buffer+0x24);
394
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x401: (%08X)", *(u32*)(media_buffer+0x24) );
395
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
396
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
397
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
400
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x403: (%08X)", *(u32*)(media_buffer+0x24) );
401
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
405
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x404: (%08X)", *(u32*)(media_buffer+0x2C) );
406
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
409
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x408: (%08X)", *(u32*)(media_buffer+0x24) );
410
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
411
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
414
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x40B: (%08X)", *(u32*)(media_buffer+0x24) );
415
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
416
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
417
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
420
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x40C: (%08X)", *(u32*)(media_buffer+0x24) );
421
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
422
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
423
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
424
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) );
425
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x38) );
428
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x40E: (%08X)", *(u32*)(media_buffer+0x28) );
429
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
430
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
431
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) );
432
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x38) );
435
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x410: (%08X)", *(u32*)(media_buffer+0x28) );
436
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
437
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
438
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) );
441
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x411: (%08X)", *(u32*)(media_buffer+0x24) );
442
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
444
*(u32*)(media_buffer+4) = 0x46;
449
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x415: (%08X)", *(u32*)(media_buffer+0x24) );
451
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
453
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
454
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
456
u32 offset = *(u32*)(media_buffer+0x28) - 0x1F800200;
457
NOTICE_LOG(DVDINTERFACE, "GC-AM: Set IP:%s", (char*)(network_command_buffer+offset) );
461
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x601");
464
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x606: (%04X)", *(u16*)(media_buffer+0x24) );
465
ERROR_LOG(DVDINTERFACE, "GC-AM: (%04X)", *(u16*)(media_buffer+0x26) );
466
ERROR_LOG(DVDINTERFACE, "GC-AM: (%02X)", *( u8*)(media_buffer+0x28) );
467
ERROR_LOG(DVDINTERFACE, "GC-AM: (%02X)", *( u8*)(media_buffer+0x29) );
468
ERROR_LOG(DVDINTERFACE, "GC-AM: (%04X)", *(u16*)(media_buffer+0x2A) );
469
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) );
470
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) );
471
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) );
472
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x38) );
473
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x3C) );
476
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x607: (%04X)", *(u16*)(media_buffer+0x24) );
477
ERROR_LOG(DVDINTERFACE, "GC-AM: (%04X)", *(u16*)(media_buffer+0x26) );
478
ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) );
481
ERROR_LOG(DVDINTERFACE, "GC-AM: 0x601");
484
ERROR_LOG(DVDINTERFACE, "GC-AM: execute buffer UNKNOWN:%03X", *(u16*)(media_buffer+0x22) );
488
memset( media_buffer + 0x20, 0, 0x20 );
492
PanicAlertT("Unhandled Media Board Execute");
498
u32 GetControllerType( void )
500
return m_controllertype;
502
void Shutdown( void )