From c89f4236ac68d33da253fa7a54ba5d92f008c357 Mon Sep 17 00:00:00 2001 From: "SND\\shalma_cp" Date: Thu, 9 Sep 2010 16:23:16 +0000 Subject: SIO - GameShark CDX dongle now supports memory card I/O (fixes CDX 3.3 BG and code list errors) git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@56987 e17a0e51-4ae3-4d35-97c3-1a29b211df97 --- libpcsxcore/sio.c | 257 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 181 insertions(+), 76 deletions(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/sio.c b/libpcsxcore/sio.c index 60d918fc..e7177333 100644 --- a/libpcsxcore/sio.c +++ b/libpcsxcore/sio.c @@ -46,8 +46,16 @@ #define SIO_RESET 0x0040 // *** FOR WORKS ON PADS AND MEMORY CARDS ***** + + +void LoadDongle( char *str ); +void SaveDongle( char *str ); + -static unsigned char buf[256]; +#define BUFFER_SIZE 0x1010 + +static unsigned char buf[ BUFFER_SIZE ]; + unsigned char cardh[4] = { 0x00, 0x00, 0x5a, 0x5d }; // Transfer Ready and the Buffer is Empty @@ -66,6 +74,14 @@ static unsigned int gsdonglest; char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE]; + +#define DONGLE_SIZE 0x40 * 0x1000 + +unsigned int DongleBank; +unsigned char DongleData[ DONGLE_SIZE ]; +static int DongleInit; + + #define SIO_INT(eCycle) { \ if (!Config.Sio) { \ psxRegs.interrupt |= (1 << PSXINT_SIO); \ @@ -234,7 +250,7 @@ void sioWrite8(unsigned char value) { /* - GameShark CDX 3.3 + GameShark CDX ae - be - ef - 04 + [00] ae - be - ef - 01 + 00 + [00] * $1000 @@ -246,7 +262,7 @@ void sioWrite8(unsigned char value) { case 1: SIO_INT( SIO_CYCLES ); - // GS CDX 3.3 + // GS CDX // - unknown output // reset device when fail? @@ -259,7 +275,7 @@ void sioWrite8(unsigned char value) { } - // GS CDX 3.3 + // GS CDX else if( value == 0xbe ) { StatReg |= RX_RDY; @@ -272,7 +288,7 @@ void sioWrite8(unsigned char value) { } - // GS CDX 3.3 + // GS CDX else if( value == 0xef ) { StatReg |= RX_RDY; @@ -285,7 +301,7 @@ void sioWrite8(unsigned char value) { } - // GS CDX 3.3 [1 in + $1000 out] + // GS CDX [1 in + $1000 out + $1 out] else if( value == 0x01 ) { StatReg |= RX_RDY; @@ -296,17 +312,12 @@ void sioWrite8(unsigned char value) { // $00 = 0000 0000 // - (reverse) 0000 0000 - //buf[0] = 0x00; - //gsdonglest = 4; - - // Free dongle - feature not supported - buf[0] = 0xff; - - gsdonglest = 0; + buf[0] = 0x00; + gsdonglest = 2; } - // GS CDX 3.3 [1 in + $1000 in] + // GS CDX [1 in + $1000 in + $1 out] else if( value == 0x02 ) { StatReg |= RX_RDY; @@ -317,17 +328,12 @@ void sioWrite8(unsigned char value) { // $00 = 0000 0000 // - (reverse) 0000 0000 - //buf[0] = 0x00; - //gsdonglest = 3; - - // Free dongle - feature not supported - buf[0] = 0xff; - - gsdonglest = 0; + buf[0] = 0x00; + gsdonglest = 3; } - // GS CDX 3.3 [8 in, 4 out] + // GS CDX [8 in, 4 out] else if( value == 0x03 ) { StatReg |= RX_RDY; @@ -339,11 +345,11 @@ void sioWrite8(unsigned char value) { // - (reverse) 0000 0000 buf[0] = 0x00; - gsdonglest = 2; + gsdonglest = 4; } - // GS CDX 3.3 [out 1] + // GS CDX [out 1] else if( value == 0x04 ) { StatReg |= RX_RDY; @@ -354,16 +360,12 @@ void sioWrite8(unsigned char value) { // $00 = 0000 0000 // - (reverse) 0000 0000 - //buf[0] = 0x00; - //gsdonglest = 5; - - // Free dongle - feature not supported - buf[0] = 0xff; + buf[0] = 0x00; + gsdonglest = 5; } else { // ERROR!! - StatReg |= RX_RDY; parp = 0; @@ -376,8 +378,87 @@ void sioWrite8(unsigned char value) { return; + // be - ef - 01 + case 2: { + unsigned char checksum; + unsigned int lcv; + + SIO_INT( SIO_CYCLES ); + StatReg |= RX_RDY; + + + // read 1 byte + DongleBank = buf[ 0 ]; + + + // write data + checksum + checksum = 0; + for( lcv = 0; lcv < 0x1000; lcv++ ) + { + unsigned char data; + + data = DongleData[ DongleBank * 0x1000 + lcv ]; + + buf[ lcv+1 ] = reverse_8( data ); + checksum += data; + } + + + parp = 0; + bufcount = 0x1001; + buf[ 0x1001 ] = reverse_8( checksum ); + + + gsdonglest = 255; + return; + } + + + // be - ef - 02 + case 3: + SIO_INT( SIO_CYCLES ); + StatReg |= RX_RDY; + + // command start + if( parp < 0x1000+1 ) + { + // read 1 byte + buf[ parp ] = value; + parp++; + } + + if( parp == 0x1001 ) + { + unsigned char checksum; + unsigned int lcv; + + DongleBank = buf[0]; + memcpy( DongleData + DongleBank * 0x1000, buf+1, 0x1000 ); + + // save to file + SaveDongle( "memcards/CDX_Dongle.bin" ); + + + // write 8-bit checksum + checksum = 0; + for( lcv = 1; lcv < 0x1001; lcv++ ) + { + checksum += buf[ lcv ]; + } + + parp = 0; + bufcount = 1; + buf[1] = reverse_8( checksum ); + + + // flush result + gsdonglest = 255; + } + return; + + // be - ef - 03 - case 2: + case 4: SIO_INT( SIO_CYCLES ); StatReg |= RX_RDY; @@ -399,7 +480,7 @@ void sioWrite8(unsigned char value) { // TODO: Solve CDX algorithm - // GS CDX 3.3 [magic key] + // GS CDX [magic key] if( buf[2] == 0x12 && buf[3] == 0x34 && buf[4] == 0x56 && buf[5] == 0x78 ) { @@ -409,7 +490,7 @@ void sioWrite8(unsigned char value) { buf[12] = reverse_8( 0x29 ); } - // GS CDX 3.3 [address key #2 = 6ec] + // GS CDX [address key #2 = 6ec] else if( buf[2] == 0x1f && buf[3] == 0xe3 && buf[4] == 0x45 && buf[5] == 0x60 ) { @@ -419,7 +500,7 @@ void sioWrite8(unsigned char value) { buf[12] = reverse_8( 0xa8 ); } - // GS CDX 3.3 [address key #3 = ???] + // GS CDX [address key #3 = ???] else if( buf[2] == 0x1f && buf[3] == 0xe3 && buf[4] == 0x72 && buf[5] == 0xe3 ) { @@ -434,7 +515,7 @@ void sioWrite8(unsigned char value) { buf[12] = reverse_8( 0x97 ); } - // GS CDX 3.3 [address key #4 = a00] + // GS CDX [address key #4 = a00] else if( buf[2] == 0x1f && buf[3] == 0xe3 && buf[4] == 0x85 && buf[5] == 0xae ) { @@ -444,7 +525,7 @@ void sioWrite8(unsigned char value) { buf[12] = reverse_8( 0x44 ); } - // GS CDX 3.3 [address key #5 = 9ec] + // GS CDX [address key #5 = 9ec] else if( buf[2] == 0x17 && buf[3] == 0xe3 && buf[4] == 0xb5 && buf[5] == 0x60 ) { @@ -469,44 +550,6 @@ void sioWrite8(unsigned char value) { return; - // be - ef - 02 - case 3: - SIO_INT( SIO_CYCLES ); - StatReg |= RX_RDY; - - // command start - if( parp < 0x1000+1 ) - { - // read 1 byte - buf[ parp % 256 ] = value; - parp++; - } - - if( parp == 0x1001 ) - { - // done - gsdonglest = 0; - } - return; - - - // be - ef - 01 - case 4: - SIO_INT( SIO_CYCLES ); - StatReg |= RX_RDY; - - - // read 1 byte - buf[ parp ] = value; - - - // write 0x1000 bytes - bufcount = 0x1000; - - gsdonglest = 255; - return; - - // be - ef - 04 case 5: if( value == 0x00 ) @@ -519,7 +562,8 @@ void sioWrite8(unsigned char value) { parp = 0; bufcount = parp; - buf[ 0 ] = 10; + // size of dongle card? + buf[ 0 ] = reverse_8( DONGLE_SIZE / 0x1000 ); // done already @@ -540,6 +584,10 @@ void sioWrite8(unsigned char value) { if( parp == bufcount ) { gsdonglest = 0; + +#ifdef GSDONGLE_LOG + PAD_LOG("(gameshark dongle) DONE!!\n" ); +#endif } } else @@ -556,6 +604,7 @@ void sioWrite8(unsigned char value) { return; } + switch (value) { case 0x01: // start pad StatReg |= RX_RDY; // Transfer is Ready @@ -610,7 +659,8 @@ void sioWrite8(unsigned char value) { mcdst = 1; rdwr = 0; SIO_INT(SIO_CYCLES); - return; + return; + case 0xae: // GameShark CDX - start dongle StatReg |= RX_RDY; gsdonglest = 1; @@ -618,6 +668,13 @@ void sioWrite8(unsigned char value) { parp = 0; bufcount = parp; + if( !DongleInit ) + { + LoadDongle( "memcards/CDX_Dongle.bin" ); + + DongleInit = 1; + } + SIO_INT( SIO_CYCLES ); return; @@ -1134,3 +1191,51 @@ int sioFreeze(gzFile f, int Mode) { return 0; } + + +void LoadDongle( char *str ) +{ + FILE *f; + + f = fopen(str, "r+b"); + if (f != NULL) { + fread( DongleData, 1, DONGLE_SIZE, f ); + fclose( f ); + } + else { + u32 *ptr, lcv; + + ptr = (unsigned int *) DongleData; + + // create temp data + ptr[0] = (u32) 0x02015447; + ptr[1] = (u32) 0; + ptr[2] = (u32) 1; + ptr[3] = (u32) 0; + + for( lcv=4; lcv<0x6c / 4; lcv++ ) + { + ptr[ lcv ] = 0; + } + + ptr[ lcv ] = (u32) 0x02000100; + lcv++; + + while( lcv < 0x1000/4 ) + { + ptr[ lcv ] = (u32) 0xffffffff; + lcv++; + } + } +} + +void SaveDongle( char *str ) +{ + FILE *f; + + f = fopen(str, "wb"); + if (f != NULL) { + fwrite( DongleData, 1, DONGLE_SIZE, f ); + fclose( f ); + } +} -- cgit v1.2.3