From 56545f0b7db9cee0aed2de6f0543c58fdded9326 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Sat, 2 May 2009 10:48:41 +0000 Subject: [PATCH] *Experimental* Made new IopHwRead and IopHwWrite from scratch, in pre-preparation for a new lookup-based IOP memory manager. Could be some lingering bugs or typos. :/ Win32/vcproj: Re-structured the folder layout of the project. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1116 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/EEregs.h | 40 - pcsx2/IopCounters.cpp | 240 +- pcsx2/IopCounters.h | 38 +- pcsx2/IopHw.cpp | 40 +- pcsx2/IopHw.h | 77 +- pcsx2/IopMem.cpp | 152 +- pcsx2/IopMem.h | 46 +- pcsx2/ps2/Iop/IopHwRead.cpp | 445 ++++ pcsx2/ps2/Iop/IopHwWrite.cpp | 529 ++++ pcsx2/ps2/Iop/IopHw_Internal.h | 204 ++ pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 2524 ++++++++++---------- 11 files changed, 2808 insertions(+), 1527 deletions(-) delete mode 100644 pcsx2/EEregs.h create mode 100644 pcsx2/ps2/Iop/IopHwRead.cpp create mode 100644 pcsx2/ps2/Iop/IopHwWrite.cpp create mode 100644 pcsx2/ps2/Iop/IopHw_Internal.h diff --git a/pcsx2/EEregs.h b/pcsx2/EEregs.h deleted file mode 100644 index 1445350185..0000000000 --- a/pcsx2/EEregs.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __EEREGS_H__ -#define __EEREGS_H__ - -#define at cpuRegs.GPR.n.at -#define k0 cpuRegs.GPR.n.k0 -#define k1 cpuRegs.GPR.n.k1 -#define v0 cpuRegs.GPR.n.v0 -#define v1 cpuRegs.GPR.n.v1 -#define a0 cpuRegs.GPR.n.a0 -#define a1 cpuRegs.GPR.n.a1 -#define a2 cpuRegs.GPR.n.a2 -#define a3 cpuRegs.GPR.n.a3 -#define t0 cpuRegs.GPR.n.t0 -#define s0 cpuRegs.GPR.n.s0 -#define gp cpuRegs.GPR.n.gp -#define fp cpuRegs.GPR.n.s8 -#define sp cpuRegs.GPR.n.sp -#define ra cpuRegs.GPR.n.ra - -#define pc0 cpuRegs.pc - -#endif /* __EEREGS_H__ */ diff --git a/pcsx2/IopCounters.cpp b/pcsx2/IopCounters.cpp index 664dceb228..9e169100f7 100644 --- a/pcsx2/IopCounters.cpp +++ b/pcsx2/IopCounters.cpp @@ -479,7 +479,9 @@ void psxRcntUpdate() for (i=0; i<6; i++) _rcntSet( i ); } -void psxRcntWcount16(int index, u32 value) +////////////////////////////////////////////////////////////////////////////////////////// +// +void psxRcntWcount16(int index, u16 value) { u32 change; @@ -500,6 +502,8 @@ void psxRcntWcount16(int index, u32 value) _rcntSet( index ); } +////////////////////////////////////////////////////////////////////////////////////////// +// void psxRcntWcount32(int index, u32 value) { u32 change; @@ -521,159 +525,119 @@ void psxRcntWcount32(int index, u32 value) _rcntSet( index ); } -void psxRcnt0Wmode(u32 value) +////////////////////////////////////////////////////////////////////////////////////////// +// +__forceinline void psxRcntWmode16( int index, u32 value ) { - PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value); + PSXCNT_LOG( "IOP Counter[%d] writeMode = 0x%04X", index, value ); - psxCounters[0].mode = value; - psxCounters[0].mode|= 0x0400; - psxCounters[0].rate = 1; + jASSUME( index >= 0 && index < 3 ); + psxCounter& counter = psxCounters[index]; - if(value & IOPCNT_ALT_SOURCE) - psxCounters[0].rate = PSXPIXEL; - - if(psxCounters[0].mode & IOPCNT_ENABLE_GATE) + counter.mode = value; + counter.mode |= 0x0400; + + if( index == 2 ) { - // gated counters are added up as per the h/vblank timers. - PSXCNT_LOG("IOP Counter[0] Gate Check set, value = %x", value); - psxhblankgate |= 1; - } - else psxhblankgate &= ~1; - - psxCounters[0].count = 0; - psxCounters[0].sCycleT = psxRegs.cycle; - psxCounters[0].target &= 0xffff; - - _rcntSet( 0 ); -} - -void psxRcnt1Wmode(u32 value) -{ - PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value); - - psxCounters[1].mode = value; - psxCounters[1].mode|= 0x0400; - psxCounters[1].rate = 1; - - if(value & IOPCNT_ALT_SOURCE) - psxCounters[1].rate = PSXHBLANK; - - if(psxCounters[1].mode & IOPCNT_ENABLE_GATE) - { - PSXCNT_LOG("IOP Counter[1] Gate Check set, value = %x", value); - psxvblankgate |= 1<<1; - } - else psxvblankgate &= ~(1<<1); - - psxCounters[1].count = 0; - psxCounters[1].sCycleT = psxRegs.cycle; - psxCounters[1].target &= 0xffff; - _rcntSet( 1 ); -} - -void psxRcnt2Wmode(u32 value) -{ - PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value); - - psxCounters[2].mode = value; - psxCounters[2].mode|= 0x0400; - - switch(value & 0x200) - { - case 0x200: psxCounters[2].rate = 8; break; + switch(value & 0x200) + { case 0x000: psxCounters[2].rate = 1; break; + case 0x200: psxCounters[2].rate = 8; break; + jNO_DEFAULT; + } + + if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1) + { + counter.mode |= IOPCNT_STOPPED; + } + } + else + { + // Counters 0 and 1 can select PIXEL or HSYNC as an alternate source: + counter.rate = 1; + + if(value & IOPCNT_ALT_SOURCE) + counter.rate = (index==0) ? PSXPIXEL : PSXHBLANK; + + if(counter.mode & IOPCNT_ENABLE_GATE) + { + // gated counters are added up as per the h/vblank timers. + // (the PIXEL alt source becomes a vsync gate) + + PSXCNT_LOG( "IOP Counter[%d] Gate Check set, value = 0x%04X", index, value ); + if( index == 0 ) + psxhblankgate |= 1; // fixme: these gate flags should be one var >_< + else + psxvblankgate |= 1<<1; + } + else + { + if( index == 0 ) + psxhblankgate &= ~1; + else + psxvblankgate &= ~(1<<1); + } } - if((psxCounters[2].mode & 0x7) == 0x7 || (psxCounters[2].mode & 0x7) == 0x1) - { - //Console::WriteLn("Gate set on IOP C2, disabling"); - psxCounters[2].mode |= IOPCNT_STOPPED; - } - - psxCounters[2].count = 0; - psxCounters[2].sCycleT = psxRegs.cycle; - psxCounters[2].target &= 0xffff; - _rcntSet( 2 ); + counter.count = 0; + counter.sCycleT = psxRegs.cycle; + counter.target &= 0xffff; + + _rcntSet( index ); } -void psxRcnt3Wmode(u32 value) +////////////////////////////////////////////////////////////////////////////////////////// +// +__forceinline void psxRcntWmode32( int index, u32 value ) { - PSXCNT_LOG("IOP Counter[3] writeMode = %lx", value); + PSXCNT_LOG( "IOP Counter[%d] writeMode = 0x%04x", index, value ); - psxCounters[3].mode = value; - psxCounters[3].rate = 1; - psxCounters[3].mode|= 0x0400; + jASSUME( index >= 3 && index < 6 ); + psxCounter& counter = psxCounters[index]; - if(value & IOPCNT_ALT_SOURCE) - psxCounters[3].rate = PSXHBLANK; - - if(psxCounters[3].mode & IOPCNT_ENABLE_GATE) + counter.mode = value; + counter.mode |= 0x0400; + + if( index == 3 ) { - PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value); - psxvblankgate |= 1<<3; - } - else psxvblankgate &= ~(1<<3); + // Counter 3 has the HBlank as an alternate source. + counter.rate = 1; + if(value & IOPCNT_ALT_SOURCE) + counter.rate = PSXHBLANK; - psxCounters[3].count = 0; - psxCounters[3].sCycleT = psxRegs.cycle; - psxCounters[3].target &= 0xffffffff; - _rcntSet( 3 ); -} - -void psxRcnt4Wmode(u32 value) -{ - PSXCNT_LOG("IOP Counter[4] writeMode = %lx", value); - - psxCounters[4].mode = value; - psxCounters[4].mode|= 0x0400; - - switch(value & 0x6000) - { - case 0x0000: psxCounters[4].rate = 1; break; - case 0x2000: psxCounters[4].rate = 8; break; - case 0x4000: psxCounters[4].rate = 16; break; - case 0x6000: psxCounters[4].rate = 256; break; - } - // Need to set a rate and target - if((psxCounters[4].mode & 0x7) == 0x7 || (psxCounters[4].mode & 0x7) == 0x1) - { - Console::WriteLn("Gate set on IOP C4, disabling"); - psxCounters[4].mode |= IOPCNT_STOPPED; - } - - psxCounters[4].count = 0; - psxCounters[4].sCycleT = psxRegs.cycle; - psxCounters[4].target &= 0xffffffff; - _rcntSet( 4 ); -} - -void psxRcnt5Wmode(u32 value) -{ - PSXCNT_LOG("IOP Counter[5] writeMode = %lx", value); - - psxCounters[5].mode = value; - psxCounters[5].mode|= 0x0400; - - switch(value & 0x6000) - { - case 0x0000: psxCounters[5].rate = 1; break; - case 0x2000: psxCounters[5].rate = 8; break; - case 0x4000: psxCounters[5].rate = 16; break; - case 0x6000: psxCounters[5].rate = 256; break; - } - // Need to set a rate and target - if((psxCounters[5].mode & 0x7) == 0x7 || (psxCounters[5].mode & 0x7) == 0x1) - { - Console::WriteLn("Gate set on IOP C5, disabling"); - psxCounters[5].mode |= IOPCNT_STOPPED; - } - - psxCounters[5].count = 0; - psxCounters[5].sCycleT = psxRegs.cycle; - psxCounters[5].target &= 0xffffffff; - _rcntSet( 5 ); + if(counter.mode & IOPCNT_ENABLE_GATE) + { + PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value); + psxvblankgate |= 1<<3; + } + else psxvblankgate &= ~(1<<3); + } + else + { + switch(value & 0x6000) + { + case 0x0000: counter.rate = 1; break; + case 0x2000: counter.rate = 8; break; + case 0x4000: counter.rate = 16; break; + case 0x6000: counter.rate = 256; break; + } + + // Need to set a rate and target + if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1) + { + Console::WriteLn( "Gate set on IOP Counter %d, disabling", params index ); + counter.mode |= IOPCNT_STOPPED; + } + } + + counter.count = 0; + counter.sCycleT = psxRegs.cycle; + counter.target &= 0xffffffff; + _rcntSet( index ); } +////////////////////////////////////////////////////////////////////////////////////////// +// void psxRcntWtarget16(int index, u32 value) { assert( index < 3 ); diff --git a/pcsx2/IopCounters.h b/pcsx2/IopCounters.h index 8a743408f0..c31fbe36fd 100644 --- a/pcsx2/IopCounters.h +++ b/pcsx2/IopCounters.h @@ -34,30 +34,24 @@ struct psxCounter { #endif extern psxCounter psxCounters[NUM_COUNTERS]; -extern s32 psxNextCounter; -extern u32 psxNextsCounter; -void psxRcntInit(); -void psxRcntUpdate(); -void cntspu2async(); -void psxRcntWcount16(int index, u32 value); -void psxRcntWcount32(int index, u32 value); -void psxRcnt0Wmode(u32 value); -void psxRcnt1Wmode(u32 value); -void psxRcnt2Wmode(u32 value); -void psxRcnt3Wmode(u32 value); -void psxRcnt4Wmode(u32 value); -void psxRcnt5Wmode(u32 value); -void psxRcntWtarget16(int index, u32 value); -void psxRcntWtarget32(int index, u32 value); -u16 psxRcntRcount16(int index); -u32 psxRcntRcount32(int index); -u64 psxRcntCycles(int index); +extern void psxRcntInit(); +extern void psxRcntUpdate(); +extern void cntspu2async(); +extern void psxRcntWcount16(int index, u16 value); +extern void psxRcntWcount32(int index, u32 value); +extern void psxRcntWmode16(int index, u32 value); +extern void psxRcntWmode32(int index, u32 value); +extern void psxRcntWtarget16(int index, u32 value); +extern void psxRcntWtarget32(int index, u32 value); +extern u16 psxRcntRcount16(int index); +extern u32 psxRcntRcount32(int index); +extern u64 psxRcntCycles(int index); -void psxVBlankStart(); -void psxVBlankEnd(); -void psxCheckStartGate16(int i); -void psxCheckEndGate16(int i); +extern void psxVBlankStart(); +extern void psxVBlankEnd(); +extern void psxCheckStartGate16(int i); +extern void psxCheckEndGate16(int i); //static void psxCheckStartGate32(int i); //static void psxCheckEndGate32(int i); diff --git a/pcsx2/IopHw.cpp b/pcsx2/IopHw.cpp index de7eafadd6..80c5108f9e 100644 --- a/pcsx2/IopHw.cpp +++ b/pcsx2/IopHw.cpp @@ -618,8 +618,8 @@ u32 psxHwRead32(u32 add) { } // A buffer that stores messages until it gets a /n or the number of chars (g_pbufi) is more then 1023. -s8 g_pbuf[1024]; -int g_pbufi; +static s8 g_pbuf[1024]; +static int g_pbufi; void psxHwWrite8(u32 add, u8 value) { if (add >= HW_USB_START && add < HW_USB_END) { USBwrite8(add, value); return; @@ -768,7 +768,7 @@ void psxHwWrite16(u32 add, u16 value) { psxRcntWcount16(0, value); return; case IOP_T0_MODE: PSXCNT_LOG("COUNTER 0 MODE 16bit write %x", value); - psxRcnt0Wmode(value); return; + psxRcntWmode16(0, value); return; case IOP_T0_TARGET: PSXCNT_LOG("COUNTER 0 TARGET 16bit write %x", value); psxRcntWtarget16(0, value); return; @@ -778,7 +778,7 @@ void psxHwWrite16(u32 add, u16 value) { psxRcntWcount16(1, value); return; case IOP_T1_MODE: PSXCNT_LOG("COUNTER 1 MODE 16bit write %x", value); - psxRcnt1Wmode(value); return; + psxRcntWmode16(1, value); return; case IOP_T1_TARGET: PSXCNT_LOG("COUNTER 1 TARGET 16bit write %x", value); psxRcntWtarget16(1, value); return; @@ -788,7 +788,7 @@ void psxHwWrite16(u32 add, u16 value) { psxRcntWcount16(2, value); return; case IOP_T2_MODE: PSXCNT_LOG("COUNTER 2 MODE 16bit write %x", value); - psxRcnt2Wmode(value); return; + psxRcntWmode16(2, value); return; case IOP_T2_TARGET: PSXCNT_LOG("COUNTER 2 TARGET 16bit write %x", value); psxRcntWtarget16(2, value); return; @@ -803,7 +803,7 @@ void psxHwWrite16(u32 add, u16 value) { psxRcntWcount32(3, value); return; case IOP_T3_MODE: PSXCNT_LOG("COUNTER 3 MODE 16bit write %lx", value); - psxRcnt3Wmode(value); return; + psxRcntWmode32(3, value); return; case IOP_T3_TARGET: PSXCNT_LOG("COUNTER 3 TARGET 16bit write %lx", value); psxRcntWtarget32(3, value); return; @@ -813,7 +813,7 @@ void psxHwWrite16(u32 add, u16 value) { psxRcntWcount32(4, value); return; case IOP_T4_MODE: PSXCNT_LOG("COUNTER 4 MODE 16bit write %lx", value); - psxRcnt4Wmode(value); return; + psxRcntWmode32(4, value); return; case IOP_T4_TARGET: PSXCNT_LOG("COUNTER 4 TARGET 16bit write %lx", value); psxRcntWtarget32(4, value); return; @@ -823,7 +823,7 @@ void psxHwWrite16(u32 add, u16 value) { psxRcntWcount32(5, value); return; case IOP_T5_MODE: PSXCNT_LOG("COUNTER 5 MODE 16bit write %lx", value); - psxRcnt5Wmode(value); return; + psxRcntWmode32(5, value); return; case IOP_T5_TARGET: PSXCNT_LOG("COUNTER 5 TARGET 16bit write %lx", value); psxRcntWtarget32(5, value); return; @@ -1180,7 +1180,7 @@ void psxHwWrite32(u32 add, u32 value) { psxRcntWcount16(0, value ); return; case IOP_T0_MODE: PSXCNT_LOG("COUNTER 0 MODE 32bit write %lx", value); - psxRcnt0Wmode(value); return; + psxRcntWmode16(0, value); return; case IOP_T0_TARGET: PSXCNT_LOG("COUNTER 0 TARGET 32bit write %lx", value); psxRcntWtarget16(0, value ); return; @@ -1190,7 +1190,7 @@ void psxHwWrite32(u32 add, u32 value) { psxRcntWcount16(1, value ); return; case IOP_T1_MODE: PSXCNT_LOG("COUNTER 1 MODE 32bit write %lx", value); - psxRcnt1Wmode(value); return; + psxRcntWmode16(1, value); return; case IOP_T1_TARGET: PSXCNT_LOG("COUNTER 1 TARGET 32bit write %lx", value); psxRcntWtarget16(1, value ); return; @@ -1200,7 +1200,7 @@ void psxHwWrite32(u32 add, u32 value) { psxRcntWcount16(2, value ); return; case IOP_T2_MODE: PSXCNT_LOG("COUNTER 2 MODE 32bit write %lx", value); - psxRcnt2Wmode(value); return; + psxRcntWmode16(0, value); return; case IOP_T2_TARGET: PSXCNT_LOG("COUNTER 2 TARGET 32bit write %lx", value); psxRcntWtarget16(2, value); return; @@ -1210,7 +1210,7 @@ void psxHwWrite32(u32 add, u32 value) { psxRcntWcount32(3, value); return; case IOP_T3_MODE: PSXCNT_LOG("COUNTER 3 MODE 32bit write %lx", value); - psxRcnt3Wmode(value); return; + psxRcntWmode32(3, value); return; case IOP_T3_TARGET: PSXCNT_LOG("COUNTER 3 TARGET 32bit write %lx", value); psxRcntWtarget32(3, value); return; @@ -1220,7 +1220,7 @@ void psxHwWrite32(u32 add, u32 value) { psxRcntWcount32(4, value); return; case IOP_T4_MODE: PSXCNT_LOG("COUNTER 4 MODE 32bit write %lx", value); - psxRcnt4Wmode(value); return; + psxRcntWmode32(4, value); return; case IOP_T4_TARGET: PSXCNT_LOG("COUNTER 4 TARGET 32bit write %lx", value); psxRcntWtarget32(4, value); return; @@ -1230,7 +1230,7 @@ void psxHwWrite32(u32 add, u32 value) { psxRcntWcount32(5, value); return; case IOP_T5_MODE: PSXCNT_LOG("COUNTER 5 MODE 32bit write %lx", value); - psxRcnt5Wmode(value); return; + psxRcntWmode32(5, value); return; case IOP_T5_TARGET: PSXCNT_LOG("COUNTER 5 TARGET 32bit write %lx", value); psxRcntWtarget32(5, value); return; @@ -1335,16 +1335,20 @@ void psxHw4Write8(u32 add, u8 value) PSXHW_LOG("Known 8bit write to addr 0x%x = 0x%x", add, value); } -void psxDmaInterrupt(int n) { - if (HW_DMA_ICR & (1 << (16 + n))) { +void psxDmaInterrupt(int n) +{ + if (HW_DMA_ICR & (1 << (16 + n))) + { HW_DMA_ICR|= (1 << (24 + n)); psxRegs.CP0.n.Cause |= 1 << (9 + n); iopIntcIrq( 3 ); } } -void psxDmaInterrupt2(int n) { - if (HW_DMA_ICR2 & (1 << (16 + n))) { +void psxDmaInterrupt2(int n) +{ + if (HW_DMA_ICR2 & (1 << (16 + n))) + { /* if (HW_DMA_ICR2 & (1 << (24 + n))) { Console::WriteLn("*PCSX2*: HW_DMA_ICR2 n=%d already set", params n); } diff --git a/pcsx2/IopHw.h b/pcsx2/IopHw.h index 5579161b9c..4b31f5f2c0 100644 --- a/pcsx2/IopHw.h +++ b/pcsx2/IopHw.h @@ -16,18 +16,69 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __PSXHW_H__ -#define __PSXHW_H__ +#pragma once -#include "R3000A.h" #include "IopMem.h" -#define HW_USB_START 0x1f801600 -#define HW_USB_END 0x1f801700 -#define HW_FW_START 0x1f808400 -#define HW_FW_END 0x1f808550 -#define HW_SPU2_START 0x1f801c00 -#define HW_SPU2_END 0x1f801e00 +static const u32 + HW_USB_START = 0x1f801600, + HW_USB_END = 0x1f801700, + HW_FW_START = 0x1f808400, + HW_FW_END = 0x1f808550, // end addr for FW is a guess... + HW_SPU2_START = 0x1f801c00, + HW_SPU2_END = 0x1f801e00; + +static const u32 + HW_SSBUS_SPD_ADDR = 0x1f801000, + HW_SSBUS_PIO_ADDR = 0x1f801004, + HW_SSBUS_SPD_DELAY = 0x1f801008, + HW_SSBUS_DEV1_DELAY = 0x1f80100C, + HW_SSBUS_ROM_DELAY = 0x1f801010, + HW_SSBUS_SPU_DELAY = 0x1f801014, + HW_SSBUS_DEV5_DELAY = 0x1f801018, + HW_SSBUS_PIO_DELAY = 0x1f80101c, + HW_SSBUS_COM_DELAY = 0x1f801020, + + HW_SIO_DATA = 0x1f801040, // SIO read/write register + HW_SIO_STAT = 0x1f801044, + HW_SIO_MODE = 0x1f801048, + HW_SIO_CTRL = 0x1f80104a, + HW_SIO_BAUD = 0x1f80104e, + + HW_IREG = 0x1f801070, + HW_IMASK = 0x1f801074, + HW_ICTRL = 0x1f801078, + + HW_SSBUS_DEV1_ADDR = 0x1f801400, + HW_SSBUS_SPU_ADDR = 0x1f801404, + HW_SSBUS_DEV5_ADDR = 0x1f801408, + HW_SSBUS_SPU1_ADDR = 0x1f80140c, + HW_SSBUS_DEV9_ADDR3 = 0x1f801410, + HW_SSBUS_SPU1_DELAY = 0x1f801414, + HW_SSBUS_DEV9_DELAY2= 0x1f801418, + HW_SSBUS_DEV9_DELAY3= 0x1f80141c, + HW_SSBUS_DEV9_DELAY1= 0x1f801420, + + HW_ICFG = 0x1f801450, + HW_DEV9_DATA = 0x1f80146e, // DEV9 read/write register + + // CDRom registers are used for various command, status, and data stuff. + + HW_CDR_DATA0 = 0x1f801800, // CDROM multipurpose data register 1 + HW_CDR_DATA1 = 0x1f801801, // CDROM multipurpose data register 2 + HW_CDR_DATA2 = 0x1f801802, // CDROM multipurpose data register 3 + HW_CDR_DATA3 = 0x1f801803, // CDROM multipurpose data register 4 + + // SIO2 is a DMA interface for the SIO. + + HW_SIO2_DATAIN = 0x1F808260, + HW_SIO2_FIFO = 0x1f808264, + HW_SIO2_CTRL = 0x1f808268, + HW_SIO2_RECV1 = 0x1f80826c, + HW_SIO2_RECV2 = 0x1f808270, + HW_SIO2_RECV3 = 0x1f808274, + HW_SIO2_INTR = 0x1f808280; + /* Registers for the IOP Counters */ enum IOPCountRegs @@ -37,7 +88,7 @@ enum IOPCountRegs IOP_T2_COUNT = 0x1f801120, IOP_T3_COUNT = 0x1f801480, IOP_T4_COUNT = 0x1f801490, - IOP_T5_COUNT = 0x1f8014a0, + IOP_T5_COUNT = 0x1f8014a0, IOP_T0_MODE = 0x1f801104, IOP_T1_MODE = 0x1f801114, @@ -46,7 +97,7 @@ enum IOPCountRegs IOP_T4_MODE = 0x1f801494, IOP_T5_MODE = 0x1f8014a4, - IOP_T0_TARGET= 0x1f801108, + IOP_T0_TARGET = 0x1f801108, IOP_T1_TARGET = 0x1f801118, IOP_T2_TARGET = 0x1f801128, IOP_T3_TARGET = 0x1f801488, @@ -166,6 +217,8 @@ extern void PSX_INT( IopEventId n, s32 ecycle); extern void psxSetNextBranch( u32 startCycle, s32 delta ); extern void psxSetNextBranchDelta( s32 delta ); +extern int iopTestCycle( u32 startCycle, s32 delta ); +extern void _iopTestInterrupts(); void psxHwReset(); u8 psxHwRead8 (u32 add); @@ -192,5 +245,3 @@ void psxHwConstWrite16(u32 add, int mmreg); void psxHwConstWrite32(u32 add, int mmreg); int psxHw4ConstRead8 (u32 x86reg, u32 add, u32 sign); void psxHw4ConstWrite8(u32 add, int mmreg); - -#endif /* __PSXHW_H__ */ diff --git a/pcsx2/IopMem.cpp b/pcsx2/IopMem.cpp index f44df6ac9f..a9580a1cdb 100644 --- a/pcsx2/IopMem.cpp +++ b/pcsx2/IopMem.cpp @@ -72,13 +72,9 @@ void psxMemReset() for (int i=0; i<0x0080; i++) { psxMemWLUT[i + 0x0000] = (uptr)&psxM[(i & 0x1f) << 16]; - //psxMemWLUT[i + 0x8000] = (uptr)&psxM[(i & 0x1f) << 16]; - //psxMemWLUT[i + 0xa000] = (uptr)&psxM[(i & 0x1f) << 16]; // RLUTs, accessed through WLUT. psxMemWLUT[i + 0x2000] = (uptr)&psxM[(i & 0x1f) << 16]; - //psxMemWLUT[i + 0x18000] = (uptr)&psxM[(i & 0x1f) << 16]; - //psxMemWLUT[i + 0x1a000] = (uptr)&psxM[(i & 0x1f) << 16]; } // A few single-page allocations for things we store in special locations. @@ -94,25 +90,17 @@ void psxMemReset() for (int i=0; i<0x0040; i++) { psxMemWLUT[i + 0x2000 + 0x1fc0] = (uptr)&PS2MEM_ROM[i << 16]; - //psxMemWLUT[i + 0x19fc0] = (uptr)&PS2MEM_ROM[i << 16]; - //psxMemWLUT[i + 0x1bfc0] = (uptr)&PS2MEM_ROM[i << 16]; } for (int i=0; i<0x0004; i++) { psxMemWLUT[i + 0x2000 + 0x1e00] = (uptr)&PS2MEM_ROM1[i << 16]; - //psxMemWLUT[i + 0x19e00] = (uptr)&PS2MEM_ROM1[i << 16]; - //psxMemWLUT[i + 0x1be00] = (uptr)&PS2MEM_ROM1[i << 16]; } // sif!! (which is read only? (air)) psxMemWLUT[0x2000 + 0x1d00] = (uptr)psxS; //psxMemWLUT[0x1bd00] = (uptr)psxS; - // why isn't scratchpad read/write? (air) - //for (i=0; i<0x0001; i++) psxMemWLUT[i + 0x1d00] = (uptr)&psxS[i << 16]; - //for (i=0; i<0x0001; i++) psxMemWLUT[i + 0xbd00] = (uptr)&psxS[i << 16]; - // this one looks like an old hack for some special write-only memory area, // but leaving it in for reference (air) //for (i=0; i<0x0008; i++) psxMemWLUT[i + 0xbfc0] = (uptr)&psR[i << 16]; @@ -136,10 +124,21 @@ u8 iopMemRead8(u32 mem) if (t == 0x1f80) { - if (mem < 0x1f801000) - return psxHu8(mem); - else - return psxHwRead8(mem); + switch( mem & 0xf000 ) + { + case 0x1000: return IopMemory::iopHwRead8_Page1(mem); + case 0x3000: return IopMemory::iopHwRead8_Page3(mem); + case 0x8000: return IopMemory::iopHwRead8_Page8(mem); + + // code for regression testing -- selectively enable these to help narrow out + // which register became buggy with the new Hw handlers. + //case 0x1000: return psxHwRead8(mem); + //case 0x3000: return psxHwRead8(mem); + //case 0x8000: return psxHwRead8(mem); + + default: + return psxHu8(mem); + } } else if (t == 0x1f40) { @@ -169,10 +168,21 @@ u16 iopMemRead16(u32 mem) if (t == 0x1f80) { - if (mem < 0x1f801000) - return psxHu16(mem); - else - return psxHwRead16(mem); + switch( mem & 0xf000 ) + { + case 0x1000: return IopMemory::iopHwRead16_Page1(mem); + case 0x3000: return IopMemory::iopHwRead16_Page3(mem); + case 0x8000: return IopMemory::iopHwRead16_Page8(mem); + + // code for regression testing -- selectively enable these to help narrow out + // which register became buggy with the new Hw handlers. + //case 0x1000: return psxHwRead16(mem); + //case 0x3000: return psxHwRead16(mem); + //case 0x8000: return psxHwRead16(mem); + + default: + return psxHu16(mem); + } } else { @@ -224,10 +234,21 @@ u32 iopMemRead32(u32 mem) if (t == 0x1f80) { - if (mem < 0x1f801000) - return psxHu32(mem); - else - return psxHwRead32(mem); + switch( mem & 0xf000 ) + { + case 0x1000: return IopMemory::iopHwRead32_Page1(mem); + case 0x3000: return IopMemory::iopHwRead32_Page3(mem); + case 0x8000: return IopMemory::iopHwRead32_Page8(mem); + + // code for regression testing -- selectively enable these to help narrow out + // which register became buggy with the new Hw handlers. + //case 0x1000: return psxHwRead32(mem); + //case 0x3000: return psxHwRead32(mem); + //case 0x8000: return psxHwRead32(mem); + + default: + return psxHu32(mem); + } } else { //see also Hw.c @@ -282,10 +303,31 @@ void iopMemWrite8(u32 mem, u8 value) if (t == 0x1f80) { - if (mem < 0x1f801000) - psxHu8(mem) = value; - else - psxHwWrite8(mem, value); + switch( mem & 0xf000 ) + { + // Regression testing: selectively pass ranges of registers to new or old + // handlers. Helps narrow out which area of registers is erroring out. + /*case 0x1000: + if( mem >= 0x1f801000 ) + psxHwWrite8( mem, value ); + else + IopMemory::iopHwWrite8_Page1(mem,value); + break;*/ + + case 0x1000: IopMemory::iopHwWrite8_Page1(mem,value); break; + case 0x3000: IopMemory::iopHwWrite8_Page3(mem,value); break; + case 0x8000: IopMemory::iopHwWrite8_Page8(mem,value); break; + + // code for regression testing -- selectively enable these to help narrow out + // which register became buggy with the new Hw handlers. + //case 0x1000: psxHwWrite8(mem,value); break; + //case 0x3000: psxHwWrite8(mem,value); break; + //case 0x8000: psxHwWrite8(mem,value); break; + + default: + psxHu8(mem) = value; + break; + } } else if (t == 0x1f40) { @@ -323,10 +365,29 @@ void iopMemWrite16(u32 mem, u16 value) if (t == 0x1f80) { - if (mem < 0x1f801000) - psxHu16(mem) = value; - else - psxHwWrite16(mem, value); + switch( mem & 0xf000 ) + { + // Regression testing: selectively pass ranges of registers to new or old + // handlers. Helps narrow out which area of registers is erroring out. + /*case 0x1000: + if( mem >= 0x1f801000 ) + psxHwWrite16( mem, value ); + else + IopMemory::iopHwWrite16_Page1(mem,value); + break;*/ + + case 0x1000: IopMemory::iopHwWrite16_Page1(mem,value); break; + case 0x3000: IopMemory::iopHwWrite16_Page3(mem,value); break; + case 0x8000: IopMemory::iopHwWrite16_Page8(mem,value); break; + + //case 0x1000: psxHwWrite16(mem,value); break; + //case 0x3000: psxHwWrite16(mem,value); break; + //case 0x8000: psxHwWrite16(mem,value); break; + + default: + psxHu16(mem) = value; + break; + } } else { u8* p = (u8 *)(psxMemWLUT[mem >> 16]); @@ -386,10 +447,29 @@ void iopMemWrite32(u32 mem, u32 value) if (t == 0x1f80) { - if (mem < 0x1f801000) - psxHu32(mem) = value; - else - psxHwWrite32(mem, value); + switch( mem & 0xf000 ) + { + // Regression testing: selectively pass ranges of registers to new or old + // handlers. Helps narrow out which area of registers is erroring out. + /*case 0x1000: + if( mem >= 0x1f801528 ) + psxHwWrite32( mem, value ); + else + IopMemory::iopHwWrite32_Page1(mem,value); + break;*/ + + case 0x1000: IopMemory::iopHwWrite32_Page1(mem,value); break; + case 0x3000: IopMemory::iopHwWrite32_Page3(mem,value); break; + case 0x8000: IopMemory::iopHwWrite32_Page8(mem,value); break; + + //case 0x1000: psxHwWrite32(mem,value); break; + //case 0x3000: psxHwWrite32(mem,value); break; + //case 0x8000: psxHwWrite32(mem,value); break; + + default: + psxHu32(mem) = value; + break; + } } else { //see also Hw.c diff --git a/pcsx2/IopMem.h b/pcsx2/IopMem.h index 21581df609..dc62657c45 100644 --- a/pcsx2/IopMem.h +++ b/pcsx2/IopMem.h @@ -16,8 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __PSXMEMORY_H__ -#define __PSXMEMORY_H__ +#pragma once extern u8 *psxM; extern u8 *psxP; @@ -90,21 +89,40 @@ void iopMemWrite32(u32 mem, u32 value); // x86reg and mmreg are always x86 regs void psxRecMemRead8(); -int psxRecMemConstRead8(u32 x86reg, u32 mem, u32 sign); - void psxRecMemRead16(); -int psxRecMemConstRead16(u32 x86reg, u32 mem, u32 sign); - void psxRecMemRead32(); -int psxRecMemConstRead32(u32 x86reg, u32 mem); - void psxRecMemWrite8(); -int psxRecMemConstWrite8(u32 mem, int mmreg); - void psxRecMemWrite16(); -int psxRecMemConstWrite16(u32 mem, int mmreg); - void psxRecMemWrite32(); -int psxRecMemConstWrite32(u32 mem, int mmreg); -#endif /* __PSXMEMORY_H__ */ +namespace IopMemory +{ + // Sif functions not made yet (will for future Iop improvements): + extern u8 __fastcall SifRead8( u32 iopaddr ); + extern u16 __fastcall SifRead16( u32 iopaddr ); + extern u32 __fastcall SifRead32( u32 iopaddr ); + + extern void __fastcall SifWrite8( u32 iopaddr, u8 data ); + extern void __fastcall SifWrite16( u32 iopaddr, u16 data ); + extern void __fastcall SifWrite32( u32 iopaddr, u32 data ); + + extern u8 __fastcall iopHwRead8_Page1( u32 iopaddr ); + extern u8 __fastcall iopHwRead8_Page3( u32 iopaddr ); + extern u8 __fastcall iopHwRead8_Page8( u32 iopaddr ); + extern u16 __fastcall iopHwRead16_Page1( u32 iopaddr ); + extern u16 __fastcall iopHwRead16_Page3( u32 iopaddr ); + extern u16 __fastcall iopHwRead16_Page8( u32 iopaddr ); + extern u32 __fastcall iopHwRead32_Page1( u32 iopaddr ); + extern u32 __fastcall iopHwRead32_Page3( u32 iopaddr ); + extern u32 __fastcall iopHwRead32_Page8( u32 iopaddr ); + + extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, u8 data ); + extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, u8 data ); + extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, u8 data ); + extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, u16 data ); + extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, u16 data ); + extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, u16 data ); + extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, u32 data ); + extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, u32 data ); + extern void __fastcall iopHwWrite32_Page8( u32 iopaddr, u32 data ); +} \ No newline at end of file diff --git a/pcsx2/ps2/Iop/IopHwRead.cpp b/pcsx2/ps2/Iop/IopHwRead.cpp new file mode 100644 index 0000000000..85202e74c3 --- /dev/null +++ b/pcsx2/ps2/Iop/IopHwRead.cpp @@ -0,0 +1,445 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "IopHw_Internal.h" + +namespace IopMemory +{ +using namespace Internal; + +////////////////////////////////////////////////////////////////////////////////////////// +// +u8 __fastcall iopHwRead8_Page1( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f801xxx: + jASSUME( (addr >> 12) == 0x1f801 ); + + u32 masked_addr = addr & 0x0fff; + + u8 ret; // using a return var can be helpful in debugging. + switch( masked_addr ) + { + mcase(HW_SIO_DATA): ret = sioRead8(); break; + + // for use of serial port ignore for now + //case 0x50: ret = serial_read8(); break; + + mcase(HW_DEV9_DATA): ret = DEV9read8( addr ); break; + + mcase(HW_CDR_DATA0): ret = cdrRead0(); break; + mcase(HW_CDR_DATA1): ret = cdrRead1(); break; + mcase(HW_CDR_DATA2): ret = cdrRead2(); break; + mcase(HW_CDR_DATA3): ret = cdrRead3(); break; + + default: + if( masked_addr >= 0x100 && masked_addr < 0x130 ) + { + DevCon::Notice( "*Hardware Read8 from Counter16 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + ret = psxHu8( addr ); + } + else if( masked_addr >= 0x480 && masked_addr < 0x4a0 ) + { + DevCon::Notice( "*Hardware Read8 from Counter32 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + ret = psxHu8( addr ); + } + else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) ) + { + ret = USBread8( addr ); + PSXHW_LOG( "Hardware Read8 from USB: addr 0x%08x = 0x%02x", addr, ret ); + } + else + { + ret = psxHu8(addr); + PSXHW_LOG( "*Unknown Hardware Read8 from addr 0x%08x = 0x%02x", addr, ret ); + } + return ret; + } + + PSXHW_LOG( "*Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, ret ); + return ret; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +u8 __fastcall iopHwRead8_Page3( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f803xxx: + jASSUME( (addr >> 12) == 0x1f803 ); + + u8 ret; + if( addr == 0x1f803100 ) // PS/EE/IOP conf related + ret = 0x10; // Dram 2M + else + ret = psxHu8( addr ); + + PSXHW_LOG( "Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, psxHu8(addr) ); + return ret; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +u8 __fastcall iopHwRead8_Page8( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f808xxx: + jASSUME( (addr >> 12) == 0x1f808 ); + + u8 ret; + + if( addr == HW_SIO2_FIFO ) + ret = sio2_fifoOut();//sio2 serial data feed/fifo_out + else + ret = psxHu8( addr ); + + PSXHW_LOG( "Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, psxHu8(addr) ); + return ret; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +template< typename T > +static __forceinline T _HwRead_16or32_Page1( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f801xxx: + jASSUME( (addr >> 12) == 0x1f801 ); + + // all addresses should be aligned to the data operand size: + jASSUME( + ( sizeof(T) == 2 && (addr & 1) == 0 ) || + ( sizeof(T) == 4 && (addr & 3) == 0 ) + ); + + u32 masked_addr = pgmsk( addr ); + T ret; + + // ------------------------------------------------------------------------ + // Counters, 16-bit varieties! + // + if( masked_addr >= 0x100 && masked_addr < 0x130 ) + { + int cntidx = ( masked_addr >> 4 ) & 0xf; + switch( masked_addr & 0xf ) + { + case 0x0: + ret = (T)psxRcntRcount16( cntidx ); + break; + + case 0x4: + ret = psxCounters[cntidx].mode; + + // hmm! The old code only did this bitwise math for 16 bit reads. + // Logic indicates it should do the math consistently. Question is, + // should it do the logic for both 16 and 32, or not do logic at all? + + psxCounters[cntidx].mode &= ~0x1800; + psxCounters[cntidx].mode |= 0x400; + break; + + case 0x8: + ret = psxCounters[cntidx].target; + break; + + default: + ret = psxHu32(addr); + break; + } + } + // ------------------------------------------------------------------------ + // Counters, 32-bit varieties! + // + else if( masked_addr >= 0x480 && masked_addr < 0x4b0 ) + { + int cntidx = (( masked_addr >> 4 ) & 0xf) - 5; + switch( masked_addr & 0xf ) + { + case 0x0: + ret = (T)psxRcntRcount32( cntidx ); + break; + + case 0x2: + ret = (T)(psxRcntRcount32( cntidx ) >> 16); + break; + + case 0x4: + ret = psxCounters[cntidx].mode; + + // hmm! The old code only did the following bitwise math for 16 bit reads. + // Logic indicates it should do the math consistently. Question is, + // should it do the logic for both 16 and 32, or not do logic at all? + + psxCounters[cntidx].mode &= ~0x1800; + psxCounters[cntidx].mode |= 0x400; + break; + + case 0x8: + ret = psxCounters[cntidx].target; + break; + + case 0xa: + ret = psxCounters[cntidx].target >> 16; + break; + + default: + ret = psxHu32(addr); + break; + } + } + // ------------------------------------------------------------------------ + // USB, with both 16 and 32 bit interfaces + // + else if( masked_addr >= pgmsk(HW_USB_START) && masked_addr < pgmsk(HW_USB_END) ) + { + ret = (sizeof(T) == 2) ? USBread16( addr ) : USBread32( addr ); + } + // ------------------------------------------------------------------------ + // SPU2, accessible in 16 bit mode only! + // + else if( masked_addr >= pgmsk(HW_SPU2_START) && masked_addr < pgmsk(HW_SPU2_END) ) + { + if( sizeof(T) == 2 ) + ret = SPU2read( addr ); + else + { + DevCon::Notice( "*PCSX2* SPU2 Hardware Read32 (addr=0x%08X)? What manner of trickery is this?!", params addr ); + ret = psxHu32(addr); + } + } + else + { + switch( masked_addr ) + { + // ------------------------------------------------------------------------ + mcase(HW_SIO_DATA): + ret = sioRead8(); + ret |= sioRead8() << 8; + if( sizeof(T) == 4 ) + { + ret |= sioRead8() << 16; + ret |= sioRead8() << 24; + } + break; + + mcase(HW_SIO_STAT): + ret = sio.StatReg; + break; + + mcase(HW_SIO_MODE): + ret = sio.ModeReg; + if( sizeof(T) == 4 ) + { + // My guess on 32-bit accesses. Dunno yet what the real hardware does. --air + ret |= sio.CtrlReg << 16; + } + break; + + mcase(HW_SIO_CTRL): + ret = sio.CtrlReg; + break; + + mcase(HW_SIO_BAUD): + ret = sio.BaudReg; + break; + + // ------------------------------------------------------------------------ + //Serial port stuff not support now ;P + // case 0x050: hard = serial_read32(); break; + // case 0x054: hard = serial_status_read(); break; + // case 0x05a: hard = serial_control_read(); break; + // case 0x05e: hard = serial_baud_read(); break; + + mcase(HW_ICTRL): + ret = psxHu32(0x1078); + psxHu32(0x1078) = 0; + break; + + mcase(HW_ICTRL+2): + ret = psxHu16(0x107a); + psxHu32(0x1078) = 0; // most likely should clear all 32 bits here. + break; + + // ------------------------------------------------------------------------ + // Soon-to-be outdated SPU2 DMA hack (spu2 manages its own DMA MADR). + // + mcase(0x1f8010C0): + ret = SPU2ReadMemAddr(0); + break; + + mcase(0x1f801500): + ret = SPU2ReadMemAddr(1); + break; + + // ------------------------------------------------------------------------ + // Legacy GPU emulation (not needed). + // The IOP emulates the GPU itself through the EE's hardware. + + /*case 0x810: + PSXHW_LOG("GPU DATA 32bit write %lx", value); + GPU_writeData(value); return; + case 0x814: + PSXHW_LOG("GPU STATUS 32bit write %lx", value); + GPU_writeStatus(value); return; + + case 0x820: + mdecWrite0(value); break; + case 0x824: + mdecWrite1(value); break;*/ + + // ------------------------------------------------------------------------ + + mcase(0x1f80146e): + ret = DEV9read16( addr ); + break; + + default: + ret = psxHu32(addr); + break; + } + } + + PSXHW_LOG( "Hardware Read%s from %s, addr 0x%08x = 0x%04x", + (sizeof(T) == 2) ? "16" : "32", _log_GetIopHwName( addr ), addr, ret + ); + return ret; +} + +// Some Page 2 mess? I love random question marks for comments! +//case 0x1f802030: hard = //int_2000???? +//case 0x1f802040: hard =//dip switches...?? + +////////////////////////////////////////////////////////////////////////////////////////// +// +u16 __fastcall iopHwRead16_Page1( u32 addr ) +{ + return _HwRead_16or32_Page1( addr ); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +u16 __fastcall iopHwRead16_Page3( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f803xxx: + jASSUME( (addr >> 12) == 0x1f803 ); + + u16 ret = psxHu16(addr); + PSXHW_LOG( "Hardware Read16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, ret ); + return ret; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +u16 __fastcall iopHwRead16_Page8( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f808xxx: + jASSUME( (addr >> 12) == 0x1f808 ); + + u16 ret = psxHu16(addr); + PSXHW_LOG( "Hardware Read16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, ret ); + return ret; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +u32 __fastcall iopHwRead32_Page1( u32 addr ) +{ + return _HwRead_16or32_Page1( addr ); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +u32 __fastcall iopHwRead32_Page3( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f803xxx: + jASSUME( (addr >> 12) == 0x1f803 ); + const u32 ret = psxHu32(addr); + PSXHW_LOG( "Hardware Read32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName( addr ), addr, ret ); + return ret; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +u32 __fastcall iopHwRead32_Page8( u32 addr ) +{ + // all addresses are assumed to be prefixed with 0x1f808xxx: + jASSUME( (addr >> 12) == 0x1f808 ); + + u32 masked_addr = addr & 0x0fff; + u32 ret; + + if( masked_addr >= 0x200 ) + { + if( masked_addr < 0x240 ) + { + const int parm = (masked_addr-0x200) / 4; + ret = sio2_getSend3( parm ); + } + else if( masked_addr < 0x260 ) + { + // SIO2 Send commands alternate registers. First reg maps to Send1, second + // to Send2, third to Send1, etc. And the following clever code does this: + + const int parm = (masked_addr-0x240) / 8; + ret = (masked_addr & 4) ? sio2_getSend2( parm ) : sio2_getSend1( parm ); + } + else + { + switch( masked_addr ) + { + mcase(0x1f801264): // unknown / reserved. + ret = psxHu32(addr); + break; + + mcase(HW_SIO2_CTRL): + ret = sio2_getCtrl(); + break; + + mcase(HW_SIO2_RECV1): + ret = sio2_getRecv1(); + break; + + mcase(HW_SIO2_RECV2): + ret = sio2_getRecv2(); + break; + + mcase(HW_SIO2_RECV3): + ret = sio2_getRecv3(); + break; + + mcase(0x1f808278): + ret = sio2_get8278(); + break; + + mcase(0x1f80827C): + ret = sio2_get827C(); + break; + + mcase(HW_SIO2_INTR): + ret = sio2_getIntr(); + break; + + jNO_DEFAULT; + } + } + } + else ret = psxHu32(addr); + + PSXHW_LOG( "Hardware Read32 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, ret ); + return ret; +} + +} + diff --git a/pcsx2/ps2/Iop/IopHwWrite.cpp b/pcsx2/ps2/Iop/IopHwWrite.cpp new file mode 100644 index 0000000000..04c5e61ce0 --- /dev/null +++ b/pcsx2/ps2/Iop/IopHwWrite.cpp @@ -0,0 +1,529 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "IopHw_Internal.h" + +namespace IopMemory { + +using namespace Internal; + +////////////////////////////////////////////////////////////////////////////////////////// +// +void __fastcall iopHwWrite8_Page1( u32 addr, u8 val ) +{ + // all addresses are assumed to be prefixed with 0x1f801xxx: + jASSUME( (addr >> 12) == 0x1f801 ); + + u32 masked_addr = pgmsk( addr ); + + switch( masked_addr ) + { + mcase(HW_SIO_DATA): sioWrite8( val ); break; + + // for use of serial port ignore for now + //case 0x50: serial_write8( val ); break; + + mcase(HW_DEV9_DATA): DEV9write8( addr, val ); break; + + mcase(HW_CDR_DATA0): cdrWrite0( val ); break; + mcase(HW_CDR_DATA1): cdrWrite1( val ); break; + mcase(HW_CDR_DATA2): cdrWrite2( val ); break; + mcase(HW_CDR_DATA3): cdrWrite3( val ); break; + + default: + if( masked_addr >= 0x100 && masked_addr < 0x130 ) + { + DevCon::Notice( "*Hardware Write8 to Counter16 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + psxHu8( addr ) = val; + } + else if( masked_addr >= 0x480 && masked_addr < 0x4a0 ) + { + DevCon::Notice( "*Hardware Write8 to Counter32 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + psxHu8( addr ) = val; + } + else if( masked_addr >= pgmsk(HW_USB_START) && masked_addr < pgmsk(HW_USB_END) ) + { + USBwrite8( addr, val ); + } + else + { + psxHu8(addr) = val; + } + break; + } + + PSXHW_LOG( "*Hardware Write8 to %s, addr 0x%08x = 0x%02x\n", _log_GetIopHwName(addr), addr, val ); +} + +static char g_pbuf[1024]; +static int g_pbufi; + +void __fastcall iopHwWrite8_Page3( u32 addr, u8 val ) +{ + // all addresses are assumed to be prefixed with 0x1f803xxx: + jASSUME( (addr >> 12) == 0x1f803 ); + + if( addr == 0x1f80380c ) // STDOUT + { + bool flush = false; + + // Terminate lines on CR or full buffers, and ignore \n's if the string contents + // are empty (otherwise terminate on \n too!) + if( ( val == '\r' ) || ( g_pbufi == 1023 ) || + ( val == '\n' && g_pbufi != 0 ) ) + { + g_pbuf[g_pbufi] = 0; + DevCon::WriteLn( Color_Cyan, g_pbuf ); + g_pbufi = 0; + } + else if( val != '\n' ) + { + g_pbuf[g_pbufi++] = val; + } + } + + PSXHW_LOG( "Hardware Write8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(addr), addr, psxHu8(addr) ); + psxHu8( addr ) = val; +} + +void __fastcall iopHwWrite8_Page8( u32 addr, u8 val ) +{ + // all addresses are assumed to be prefixed with 0x1f808xxx: + jASSUME( (addr >> 12) == 0x1f808 ); + + if( addr == HW_SIO2_DATAIN ) // sio2 serial data feed input + sio2_serialIn( val ); + else + psxHu8( addr ) = val; + + PSXHW_LOG( "Hardware Write8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(addr), addr, psxHu8(addr) ); + +} + +// Template-compatible version of the psxHu macro. Used for writing. +#define psxHu(mem) (*(u32*)&psxH[(mem) & 0xffff]) + +////////////////////////////////////////////////////////////////////////////////////////// +// Templated handler for both 32 and 16 bit write operations, to Page 1 registers. +// +template< typename T > +static __forceinline void _HwWrite_16or32_Page1( u32 addr, T val ) +{ + // all addresses are assumed to be prefixed with 0x1f801xxx: + jASSUME( (addr >> 12) == 0x1f801 ); + + // all addresses should be aligned to the data operand size: + jASSUME( + ( sizeof(T) == 2 && (addr & 1) == 0 ) || + ( sizeof(T) == 4 && (addr & 3) == 0 ) + ); + + u32 masked_addr = addr & 0x0fff; + + // ------------------------------------------------------------------------ + // Counters, 16-bit varieties! + // + if( masked_addr >= 0x100 && masked_addr < 0x130 ) + { + int cntidx = ( masked_addr >> 4 ) & 0xf; + switch( masked_addr & 0xf ) + { + case 0x0: + psxRcntWcount16( cntidx, val ); + break; + + case 0x4: + psxRcntWmode16( cntidx, val ); + break; + + case 0x8: + psxRcntWtarget16( cntidx, val ); + break; + + default: + psxHu(addr) = val; + break; + } + } + // ------------------------------------------------------------------------ + // Counters, 32-bit varieties! + // + else if( masked_addr >= 0x480 && masked_addr < 0x4b0 ) + { + int cntidx = (( masked_addr >> 4 ) & 0xf) - 5; + switch( masked_addr & 0xf ) + { + case 0x0: + psxRcntWcount32( cntidx, val ); + break; + + case 0x2: // Count HiWord + psxRcntWcount32( cntidx, (u32)val << 16 ); + break; + + case 0x4: + psxRcntWmode32( cntidx, val ); + break; + + case 0x8: + psxRcntWtarget32( cntidx, val ); + break; + + case 0xa: // Target HiWord + psxRcntWtarget32( cntidx, (u32)val << 16); + break; + + default: + psxHu(addr) = val; + break; + } + } + // ------------------------------------------------------------------------ + // USB, with both 16 and 32 bit interfaces + // + else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) ) + { + if( sizeof(T) == 2 ) USBwrite16( addr, val ); else USBwrite32( addr, val ); + } + // ------------------------------------------------------------------------ + // SPU2, accessible in 16 bit mode only! + // + else if( (masked_addr >= pgmsk(HW_SPU2_START)) && (masked_addr < pgmsk(HW_SPU2_END)) ) + { + if( sizeof(T) == 2 ) + SPU2write( addr, val ); + else + { + DevCon::Notice( "*PCSX2* SPU2 Hardware Write32 (addr=0x%08X)? What manner of trickery is this?!", params addr ); + //psxHu(addr) = val; + } + } + else + { + switch( masked_addr ) + { + // ------------------------------------------------------------------------ + mcase(HW_SIO_DATA): + sioWrite8( (u8)val ); + sioWrite8( (u8)(val >> 8) ); + if( sizeof(T) == 4 ) + { + // u32 gets rid of compiler warnings when using the u16 version of this template + sioWrite8( (u8)((u32)val >> 16) ); + sioWrite8( (u8)((u32)val >> 24) ); + } + break; + + mcase(HW_SIO_STAT): // read-only? + //regname = "SIO_STAT (read-only?)"; + //sio.StatReg; + break; + + mcase(HW_SIO_MODE): + sio.ModeReg = (u16)val; + if( sizeof(T) == 4 ) + { + // My guess on 32-bit accesses. Dunno yet what the real hardware does. --air + sio.CtrlReg = (u16)((u32)val >> 16); + } + break; + + mcase(HW_SIO_CTRL): + sio.CtrlReg = (u16)val; + break; + + mcase(HW_SIO_BAUD): + sio.BaudReg = (u16)val; + break; + + // ------------------------------------------------------------------------ + //Serial port stuff not support now ;P + // case 0x050: serial_write16( val ); break; + // case 0x054: serial_status_write( val ); break; + // case 0x05a: serial_control_write( val ); break; + // case 0x05e: serial_baud_write( val ); break; + + mcase(HW_IREG): + psxHu(addr) &= val; + break; + + mcase(HW_IREG+2): + psxHu(addr) &= val; + break; + + mcase(HW_IMASK): + psxHu(addr) = val; + iopTestIntc(); + break; + + mcase(HW_IMASK+2): + psxHu(addr) = val; + iopTestIntc(); + break; + + mcase(HW_ICTRL): + psxHu(addr) = val; + iopTestIntc(); + break; + + mcase(HW_ICTRL+2): + psxHu(addr) = val; + iopTestIntc(); + break; + + // ------------------------------------------------------------------------ + // Soon-to-be outdated SPU2 DMA hack (spu2 manages its own DMA MADR currently, + // as asinine as that may seem). + // + mcase(0x1f8010C0): + SPU2WriteMemAddr( 0, val ); + HW_DMA4_MADR = val; + break; + + mcase(0x1f801500): + SPU2WriteMemAddr( 1, val ); + HW_DMA7_MADR = val; + break; + + // ------------------------------------------------------------------------ + // + /* + mcase(0x1f801088): // DMA0 CHCR -- MDEC IN [ignored] + DmaExec(0); + break; + + mcase(0x1f801098): // DMA1 CHCR -- MDEC OUT [ignored] + DmaExec(1); + break; + + mcase(0x1f8010a8): // DMA2 CHCR -- GPU [ignored] + DmaExec(2); + break;*/ + + mcase(0x1f8010b8): // DMA3 CHCR -- CDROM + psxHu(addr) = val; + DmaExec(3); + break; + + mcase(0x1f8010c8): // DMA4 CHCR -- SPU2 Core 1 + psxHu(addr) = val; + DmaExecNew(4); + break; + + mcase(0x1f8010e8): // DMA6 CHCR -- OT clear + psxHu(addr) = val; + DmaExec(6); + break; + + mcase(0x1f801508): // DMA7 CHCR -- SPU2 core 2 + psxHu(addr) = val; + DmaExecNew2(7); + break; + + mcase(0x1f801518): // DMA8 CHCR -- DEV9 + psxHu(addr) = val; + DmaExec2(8); + break; + + mcase(0x1f801528): // DMA9 CHCR -- SIF0 + psxHu(addr) = val; + DmaExec2(9); + break; + + mcase(0x1f801538): // DMA10 CHCR -- SIF1 + psxHu(addr) = val; + DmaExec2(10); + break; + + mcase(0x1f801548): // DMA11 CHCR -- SIO2 IN + psxHu(addr) = val; + DmaExec2(11); + break; + + mcase(0x1f801558): // DMA12 CHCR -- SIO2 OUT + psxHu(addr) = val; + DmaExec2(12); + break; + + // ------------------------------------------------------------------------ + // DMA ICR handlers -- General XOR behavior! + + mcase(0x1f8010f4): + { + u32 tmp = (~val) & HW_DMA_ICR; + psxHu(addr) = ((tmp ^ val) & 0xffffff) ^ tmp; + } + break; + + mcase(0x1f8010f6): // ICR_hi (16 bit?) [dunno if it ever happens] + { + const u32 val2 = (u32)val << 16; + const u32 tmp = (~val2) & HW_DMA_ICR; + psxHu(addr) = (((tmp ^ val2) & 0xffffff) ^ tmp) >> 16; + } + break; + + mcase(0x1f801574): + { + u32 tmp = (~val) & HW_DMA_ICR2; + psxHu(addr) = ((tmp ^ val) & 0xffffff) ^ tmp; + } + break; + + mcase(0x1f801576): // ICR2_hi (16 bit?) [dunno if it ever happens] + { + const u32 val2 = (u32)val << 16; + const u32 tmp = (~val2) & HW_DMA_ICR2; + psxHu(addr) = (((tmp ^ val2) & 0xffffff) ^ tmp) >> 16; + } + break; + + // ------------------------------------------------------------------------ + // Legacy GPU emulation (not needed). + // The IOP emulates the GPU itself through the EE's hardware. + + /*case 0x810: + PSXHW_LOG("GPU DATA 32bit write %lx", value); + GPU_writeData(value); return; + case 0x814: + PSXHW_LOG("GPU STATUS 32bit write %lx", value); + GPU_writeStatus(value); return; + + case 0x820: + mdecWrite0(value); break; + case 0x824: + mdecWrite1(value); break;*/ + + // ------------------------------------------------------------------------ + + mcase(HW_DEV9_DATA): + DEV9write16( addr, val ); + psxHu(addr) = val; + break; + + default: + psxHu(addr) = val; + break; + } + } + + PSXHW_LOG( "Hardware Write%s to %s, addr 0x%08x = 0x%04x", + sizeof(T) == 2 ? "16" : "32", _log_GetIopHwName( addr ), addr, val + ); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +void __fastcall iopHwWrite16_Page1( u32 addr, u16 val ) +{ + _HwWrite_16or32_Page1( addr, val ); +} + +void __fastcall iopHwWrite16_Page3( u32 addr, u16 val ) +{ + // all addresses are assumed to be prefixed with 0x1f803xxx: + jASSUME( (addr >> 12) == 0x1f803 ); + psxHu16(addr) = val; + PSXHW_LOG( "Hardware Write16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); +} + +void __fastcall iopHwWrite16_Page8( u32 addr, u16 val ) +{ + // all addresses are assumed to be prefixed with 0x1f808xxx: + jASSUME( (addr >> 12) == 0x1f808 ); + psxHu16(addr) = val; + PSXHW_LOG( "Hardware Write16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +void __fastcall iopHwWrite32_Page1( u32 addr, u32 val ) +{ + _HwWrite_16or32_Page1( addr, val ); +} + +void __fastcall iopHwWrite32_Page3( u32 addr, u32 val ) +{ + // all addresses are assumed to be prefixed with 0x1f803xxx: + jASSUME( (addr >> 12) == 0x1f803 ); + psxHu16(addr) = val; + PSXHW_LOG( "Hardware Write32 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); +} + +void __fastcall iopHwWrite32_Page8( u32 addr, u32 val ) +{ + // all addresses are assumed to be prefixed with 0x1f808xxx: + jASSUME( (addr >> 12) == 0x1f808 ); + + u32 masked_addr = addr & 0x0fff; + + if( masked_addr >= 0x200 ) + { + if( masked_addr < 0x240 ) + { + const int parm = (masked_addr-0x200) / 4; + sio2_setSend3( parm, val ); + } + else if( masked_addr < 0x260 ) + { + // SIO2 Send commands alternate registers. First reg maps to Send1, second + // to Send2, third to Send1, etc. And the following clever code does this: + + const int parm = (masked_addr-0x240) / 8; + if(masked_addr & 4) sio2_setSend2( parm, val ); else sio2_setSend1( parm, val ); + } + else + { + switch( masked_addr ) + { + case 0x264: // unknown / reserved. + case 0x26C: // recv1 [read-only] + case 0x270: // recv2 [read-only] + case 0x274: // recv3 [read-only] + psxHu32(addr) = val; + break; + + case 0x268: + sio2_setCtrl( val ); + break; + + case 0x278: + sio2_set8278( val ); + break; + + case 0x27C: + sio2_set827C( val ); + break; + + case 0x280: + sio2_setIntr( val ); + break; + + jNO_DEFAULT; + } + } + } + else psxHu32(addr) = val; + + PSXHW_LOG( "Hardware Write32 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, val ); + +} + +} diff --git a/pcsx2/ps2/Iop/IopHw_Internal.h b/pcsx2/ps2/Iop/IopHw_Internal.h new file mode 100644 index 0000000000..1a78d64bec --- /dev/null +++ b/pcsx2/ps2/Iop/IopHw_Internal.h @@ -0,0 +1,204 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +#include "IopCommon.h" + +namespace IopMemory { +namespace Internal { + +////////////////////////////////////////////////////////////////////////////////////////// +// Masking helper so that I can use the fully qualified address for case statements. +// Switches are based on the bottom 12 bits only, since MSVC tends to optimize switches +// better when it has a limited width operand to work with. :) +// +#define pgmsk( src ) ( (src) & 0x0fff ) +#define mcase( src ) case pgmsk(src) + + +////////////////////////////////////////////////////////////////////////////////////////// +// Helper for debug logging of IOP Registers. Takes an input address and retuns a +// register name. +// +// This list is not yet exhaustive. If you spot something that's missing, feel free to +// fill it in any time. :) +// +template< typename T> +static __forceinline const char* _log_GetIopHwName( u32 addr ) +{ + switch( addr ) + { + // ------------------------------------------------------------------------ + // SSBUS -- Two Ess'es? + + case HW_SSBUS_SPD_ADDR: return "SSBUS spd_addr"; + case HW_SSBUS_PIO_ADDR: return "SSBUS pio_addr"; + case HW_SSBUS_SPD_DELAY: return "SSBUS spd_delay"; + case HW_SSBUS_DEV1_DELAY: return "SSBUS dev1_delay"; + case HW_SSBUS_ROM_DELAY: return "SSBUS rom_delay"; + case HW_SSBUS_SPU_DELAY: return "SSBUS spu_delay"; + case HW_SSBUS_DEV5_DELAY: return "SSBUS dev5_delay"; + case HW_SSBUS_PIO_DELAY: return "SSBUS pio_delay"; + case HW_SSBUS_COM_DELAY: return "SSBUS com_delay"; + case HW_SSBUS_DEV1_ADDR: return "SSBUS dev1_addr"; + case HW_SSBUS_SPU_ADDR: return "SSBUS spu_addr"; + case HW_SSBUS_DEV5_ADDR: return "SSBUS dev5_addr"; + case HW_SSBUS_SPU1_ADDR: return "SSBUS spu1_addr"; + case HW_SSBUS_DEV9_ADDR3: return "SSBUS dev9_addr3"; + case HW_SSBUS_SPU1_DELAY: return "SSBUS spu1_delay"; + case HW_SSBUS_DEV9_DELAY2: return "SSBUS dev9_delay2"; + case HW_SSBUS_DEV9_DELAY3: return "SSBUS dev9_delay3"; + case HW_SSBUS_DEV9_DELAY1: return "SSBUS dev9_delay1"; + + // ------------------------------------------------------------------------ + case 0x1f801060:return "RAM_SIZE"; + + case HW_IREG: return "IREG"; + case HW_IREG+2: return "IREG_hi"; + case HW_IMASK: return "IMASK"; + case HW_IMASK+2:return "IMASK_hi"; + case HW_ICTRL: return "ICTRL"; + case HW_ICTRL+2:return "ICTRL_hi"; + case HW_ICFG: return "ICFG"; + + case HW_SIO_DATA: return "SIO"; + case HW_SIO_STAT: return "SIO STAT"; + case HW_SIO_MODE: return ( sizeof(T) == 4 ) ? "SIO_MODE+CTRL" : "SIO MODE"; + case HW_SIO_CTRL: return "SIO CTRL"; + case HW_SIO_BAUD: return "SIO BAUD"; + + case 0x1f8014c0: return "RTC_HOLDMODE"; + case HW_DEV9_DATA: return "DEV9_R_REV/DATA"; + + // ------------------------------------------------------------------------ + // BCR_LABEL -- Selects label for BCR depending on operand size (BCR has hi + // and low values of count and size, respectively) + #define BCR_LABEL( dma ) (sizeof(T)==4) ? dma" BCR" : dma" BCR_size"; + + case 0x1f8010a0: return "DMA2 MADR"; + case 0x1f8010a4: return BCR_LABEL( "DMA2" ); + case 0x1f8010a6: return "DMA2 BCR_count"; + case 0x1f8010a8: return "DMA2 CHCR"; + case 0x1f8010ac: return "DMA2 TADR"; + + case 0x1f8010b0: return "DMA3 MADR"; + case 0x1f8010b4: return BCR_LABEL( "DMA3" ); + case 0x1f8010b6: return "DMA3 BCR_count"; + case 0x1f8010b8: return "DMA3 CHCR"; + case 0x1f8010bc: return "DMA3 TADR"; + + case 0x1f8010c0: return "[SPU]DMA4 MADR"; + case 0x1f8010c4: return BCR_LABEL( "DMA4" ); + case 0x1f8010c6: return "[SPU]DMA4 BCR_count"; + case 0x1f8010c8: return "[SPU]DMA4 CHCR"; + case 0x1f8010cc: return "[SPU]DMA4 TADR"; + + case 0x1f8010f0: return "DMA PCR"; + case 0x1f8010f4: return "DMA ICR"; + case 0x1f8010f6: return "DMA ICR_hi"; + + case 0x1f801500: return "[SPU2]DMA7 MADR"; + case 0x1f801504: return BCR_LABEL( "DMA7" ); + case 0x1f801506: return "[SPU2]DMA7 BCR_count"; + case 0x1f801508: return "[SPU2]DMA7 CHCR"; + case 0x1f80150C: return "[SPU2]DMA7 TADR"; + + case 0x1f801520: return "DMA9 MADR"; + case 0x1f801524: return BCR_LABEL( "DMA9" ); + case 0x1f801526: return "DMA9 BCR_count"; + case 0x1f801528: return "DMA9 CHCR"; + case 0x1f80152C: return "DMA9 TADR"; + + case 0x1f801530: return "DMA10 MADR"; + case 0x1f801534: return BCR_LABEL( "DMA10" ); + case 0x1f801536: return "DMA10 BCR_count"; + case 0x1f801538: return "DMA10 CHCR"; + case 0x1f80153c: return "DMA10 TADR"; + + case 0x1f801570: return "DMA PCR2"; + case 0x1f801574: return "DMA ICR2"; + case 0x1f801576: return "DMA ICR2_hi"; + + case HW_CDR_DATA0: return "CDROM DATA0"; + case HW_CDR_DATA1: return "CDROM DATA1"; + case HW_CDR_DATA2: return "CDROM DATA2"; + case HW_CDR_DATA3: return "CDROM DATA3"; + + case 0x1f80380c: return "STDOUT"; + + // ------------------------------------------------------------------------ + + case HW_SIO2_FIFO: return "SIO2 FIFO"; + case HW_SIO2_CTRL: return "SIO2 CTRL"; + case HW_SIO2_RECV1: return "SIO2 RECV1"; + case HW_SIO2_RECV2: return "SIO2 RECV2"; + case HW_SIO2_RECV3: return "SIO2 RECV3"; + case HW_SIO2_INTR: return "SIO2 INTR"; + case 0x1f808278: return "SIO2 8278"; + case 0x1f80827C: return "SIO2 827C"; + + // ------------------------------------------------------------------------ + // Check for "zoned" registers in the default case. + // And if all that fails, return "unknown"! :) + + default: + if( addr >= 0x1f801100 && addr < 0x1f801130 ) + { + switch( addr & 0xf ) + { + case 0x0: return "CNT16_COUNT"; + case 0x4: return "CNT16_MODE"; + case 0x8: return "CNT16_TARGET"; + + default: return "Invalid Counter"; + } + } + else if( addr >= 0x1f801480 && addr < 0x1f8014b0 ) + { + switch( addr & 0xf ) + { + case 0x0: return "CNT32_COUNT"; + case 0x2: return "CNT32_COUNT_hi"; + case 0x4: return "CNT32_MODE"; + case 0x8: return "CNT32_TARGET"; + case 0xa: return "CNT32_TARGET_hi"; + + default: return "Invalid Counter"; + } + } + else if( (addr >= HW_USB_START) && (addr < HW_USB_END) ) + { + return "USB"; + } + else if( (addr >= HW_SPU2_START) && (addr < HW_SPU2_END) ) + { + return "SPU2"; + } + else if( addr >= 0x1f808200 ) + { + if( addr < 0x1f808240 ) + return "SIO2 param"; + else if( addr < 0x260 ) + return "SIO2 send"; + } + return "Unknown"; + } +} + +} }; \ No newline at end of file diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index f11c2294aa..16743d3655 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -270,7 +270,7 @@ - - - - - - @@ -1017,28 +1005,6 @@ RelativePath="..\..\vssprintf.cpp" > - - - - - - - - @@ -1363,6 +1329,1075 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1755,529 +2790,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2286,12 +2804,135 @@ UsePrecompiledHeader="0" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -