From c704b89cd1ad0b5a406c2f6d20cdb0b4ee2ede34 Mon Sep 17 00:00:00 2001 From: refraction Date: Thu, 17 Mar 2011 18:39:57 +0000 Subject: [PATCH] FireWire: Improved Null emulation to help games like Silent Scope 2 and Unreal Tournament (possibly Time Splitters 2) etc boot. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4446 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/FWnull/FW.cpp | 116 ++++++++++++++++++++++++++++++++++++++++-- plugins/FWnull/FW.h | 3 ++ 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/plugins/FWnull/FW.cpp b/plugins/FWnull/FW.cpp index 9e9c294ee0..30b532c982 100644 --- a/plugins/FWnull/FW.cpp +++ b/plugins/FWnull/FW.cpp @@ -30,7 +30,8 @@ static char *libraryName = "FWnull Driver"; string s_strIniPath="inis/"; string s_strLogPath = "logs/"; - + +u8 phyregs[16]; s8 *fwregs; Config conf; PluginLog FWLog; @@ -76,6 +77,7 @@ EXPORT_C_(s32) FWinit() FWLog.WriteLn("FWnull plugin version %d,%d", revision, build); FWLog.WriteLn("Initializing FWnull"); + memset(phyregs, 0, sizeof(phyregs)); // Initializing our registers. fwregs = (s8*)calloc(0x10000,1); if (fwregs == NULL) @@ -108,15 +110,54 @@ EXPORT_C_(void) FWclose() FWLog.WriteLn("Closing FWnull."); } +void PHYWrite() +{ + u8 reg = (PHYACC >> 8) & 0xf; + u8 data = PHYACC & 0xff; + + phyregs[reg] = data; + + PHYACC &= ~0x4000ffff; +} + +void PHYRead() +{ + u8 reg = (PHYACC >> 24) & 0xf; + u8 data = (PHYACC >> 16) & 0xff; + + PHYACC &= ~0x80000000; + + PHYACC |= phyregs[reg] | (reg << 8); + + if(fwRu32(0x8424) & 0x40000000) //RRx interrupt mask + { + fwRu32(0x8420) |= 0x40000000; + FWirq(); + } +} EXPORT_C_(u32) FWread32(u32 addr) { u32 ret = 0; switch (addr) { - // We should document what this location is. + //Node ID Register the top part is default, bottom part i got from my ps2 + case 0x1f808400: + ret = /*(0x3ff << 22) | 1;*/ 0xffc00001; + break; + // Control Register 2 case 0x1f808410: - ret = 0x8; + ret = fwRu32(addr); //SCLK OK (Needs to be set when FW is "Ready" + break; + //Interrupt 0 Register + case 0x1f808420: + ret = fwRu32(addr); + break; + + //Dunno what this is, but my home console always returns this value 0x10000001 + //Seems to be related to the Node ID however (does some sort of compare/check) + case 0x1f80847c: + ret = 0x10000001; break; // Include other relevant 32 bit addresses we need to catch here. @@ -144,8 +185,73 @@ EXPORT_C_(void) FWwrite32(u32 addr, u32 value) // case 0x1f808428: // case 0x1f808430: // -// Are addresses to look at. - case 0x1f808410: fwRu32(addr) = value; break; + + //PHY access + case 0x1f808414: + //If in read mode (top bit set) we read the PHY register requested then set the RRx interrupt if it's enabled + //Im presuming we send that back to pcsx2 then. This register stores the result, plus whatever was written (minus the read/write flag + fwRu32(addr) = value; //R/W Bit cleaned in underneath function + if(value & 0x40000000) //Writing to PHY + { + PHYWrite(); + } + else if(value & 0x80000000) //Reading from PHY + { + PHYRead(); + } + break; + + //Control Register 0 + case 0x1f808408: + //This enables different functions of the link interface + //Just straight writes, should brobably struct these later. + //Default written settings (on unreal tournament) are + //Urcv M = 1 + //RSP 0 = 1 + //Retlim = 0xF + //Cyc Tmr En = 1 + //Bus ID Rst = 1 + //Rcv Self ID = 1 + fwRu32(addr) = value; + // if((value & 0x800000) && (fwRu32(0x842C) & 0x2)) + // { + // fwRu32(0x8428) |= 0x2; + // FWirq(); + // } + fwRu32(addr) &= ~0x800000; + break; + //Control Register 2 + case 0x1f808410:// fwRu32(addr) = value; break; + //Ignore writes to this for now, apart from 0x2 which is Link Power Enable + //0x8 is SCLK OK (Ready) which should be set for emulation + fwRu32(addr) = 0x8 /*| value & 0x2*/; + break; + //Interrupt 0 Register + case 0x1f808420: + //Interrupt 1 Register + case 0x1f808428: + //Interrupt 2 Register + case 0x1f808430: + //Writes of 1 clear the corresponding bits + fwRu32(addr) &= ~value; + break; + //Interrupt 0 Register Mask + case 0x1f808424: + //Interrupt 1 Register Mask + case 0x1f80842C: + //Interrupt 2 Register Mask + case 0x1f808434: + //These are direct writes (as it's a mask!) + fwRu32(addr) = value; + break; + //DMA Control and Status Register 0 + case 0x1f8084B8: + fwRu32(addr) = value; + break; + //DMA Control and Status Register 1 + case 0x1f808538: + fwRu32(addr) = value; + break; default: // By default, just write it to fwregs. fwRu32(addr) = value; diff --git a/plugins/FWnull/FW.h b/plugins/FWnull/FW.h index b321075d75..b9e238a358 100644 --- a/plugins/FWnull/FW.h +++ b/plugins/FWnull/FW.h @@ -27,6 +27,9 @@ extern s8 *fwregs; #define fwRs32(mem) (*(s32*)&fwregs[(mem) & 0xffff]) #define fwRu32(mem) (*(u32*)&fwregs[(mem) & 0xffff]) +//PHY Access Address for ease of use :P +#define PHYACC fwRu32(0x8414) + typedef struct { s32 Log;