mirror of https://github.com/PCSX2/pcsx2.git
401 lines
9.8 KiB
C
401 lines
9.8 KiB
C
/* Pcsx2 - Pc Ps2 Emulator
|
|
* Copyright (C) 2002-2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#ifndef __HW_H__
|
|
#define __HW_H__
|
|
|
|
//#include "Common.h"
|
|
#include "PS2Etypes.h"
|
|
#include <assert.h>
|
|
|
|
#ifndef WIN32_VIRTUAL_MEM
|
|
u8 *psH; // hw mem
|
|
u16 *psHW;
|
|
u32 *psHL;
|
|
u64 *psHD;
|
|
#endif
|
|
|
|
#define psHs8(mem) (*(s8 *)&PS2MEM_HW[(mem) & 0xffff])
|
|
#define psHs16(mem) (*(s16*)&PS2MEM_HW[(mem) & 0xffff])
|
|
#define psHs32(mem) (*(s32*)&PS2MEM_HW[(mem) & 0xffff])
|
|
#define psHs64(mem) (*(s64*)&PS2MEM_HW[(mem) & 0xffff])
|
|
#define psHu8(mem) (*(u8 *)&PS2MEM_HW[(mem) & 0xffff])
|
|
#define psHu16(mem) (*(u16*)&PS2MEM_HW[(mem) & 0xffff])
|
|
#define psHu32(mem) (*(u32*)&PS2MEM_HW[(mem) & 0xffff])
|
|
#define psHu64(mem) (*(u64*)&PS2MEM_HW[(mem) & 0xffff])
|
|
|
|
extern u32 g_nextBranchCycle;
|
|
|
|
#define INT(n, ecycle) { \
|
|
g_nextBranchCycle = min(g_nextBranchCycle, cpuRegs.cycle+ecycle); \
|
|
cpuRegs.interrupt|= 1 << n; \
|
|
cpuRegs.sCycle[n] = cpuRegs.cycle; \
|
|
cpuRegs.eCycle[n] = ecycle; \
|
|
}
|
|
|
|
// VIF0 -- 0x10004000 -- psH[0x4000]
|
|
// VIF1 -- 0x10005000 -- psH[0x5000]
|
|
// GIF -- 0x10006000 -- psH[0x6000]
|
|
// IPUout -- 0x10007000 -- psH[0x7000]
|
|
// IPUin -- 0x10007010 -- psH[0x7010]
|
|
|
|
void ReadFIFO(u32 mem, u64 *out);
|
|
void ConstReadFIFO(u32 mem);
|
|
|
|
void WriteFIFO(u32 mem, u64 *value);
|
|
void ConstWriteFIFO(u32 mem);
|
|
|
|
|
|
//
|
|
// --- DMA ---
|
|
//
|
|
|
|
typedef struct {
|
|
u32 chcr;
|
|
u32 null0[3];
|
|
u32 madr;
|
|
u32 null1[3];
|
|
u16 qwc; u16 pad;
|
|
u32 null2[3];
|
|
u32 tadr;
|
|
u32 null3[3];
|
|
u32 asr0;
|
|
u32 null4[3];
|
|
u32 asr1;
|
|
u32 null5[11];
|
|
u32 sadr;
|
|
} DMACh;
|
|
|
|
int sifenabled[2];
|
|
|
|
// HW defines
|
|
|
|
#define RCNT0_COUNT 0x10000000
|
|
#define RCNT0_MODE 0x10000010
|
|
#define RCNT0_TARGET 0x10000020
|
|
#define RCNT0_HOLD 0x10000030
|
|
|
|
#define RCNT1_COUNT 0x10000800
|
|
#define RCNT1_MODE 0x10000810
|
|
#define RCNT1_TARGET 0x10000820
|
|
#define RCNT1_HOLD 0x10000830
|
|
|
|
#define RCNT2_COUNT 0x10001000
|
|
#define RCNT2_MODE 0x10001010
|
|
#define RCNT2_TARGET 0x10001020
|
|
|
|
#define RCNT3_COUNT 0x10001800
|
|
#define RCNT3_MODE 0x10001810
|
|
#define RCNT3_TARGET 0x10001820
|
|
|
|
#define IPU_CMD 0x10002000
|
|
#define IPU_CTRL 0x10002010
|
|
#define IPU_BP 0x10002020
|
|
#define IPU_TOP 0x10002030
|
|
|
|
#define GIF_CTRL 0x10003000
|
|
#define GIF_MODE 0x10003010
|
|
#define GIF_STAT 0x10003020
|
|
#define GIF_TAG0 0x10003040
|
|
#define GIF_TAG1 0x10003050
|
|
#define GIF_TAG2 0x10003060
|
|
#define GIF_TAG3 0x10003070
|
|
#define GIF_CNT 0x10003080
|
|
#define GIF_P3CNT 0x10003090
|
|
#define GIF_P3TAG 0x100030A0
|
|
|
|
#define GIF_FIFO 0x10006000
|
|
|
|
#define IPUout_FIFO 0x10007000
|
|
#define IPUin_FIFO 0x10007010
|
|
|
|
//VIF0
|
|
#define D0_CHCR 0x10008000
|
|
#define D0_MADR 0x10008010
|
|
#define D0_QWC 0x10008020
|
|
|
|
//VIF1
|
|
#define D1_CHCR 0x10009000
|
|
#define D1_MADR 0x10009010
|
|
#define D1_QWC 0x10009020
|
|
#define D1_TADR 0x10009030
|
|
|
|
//GS
|
|
#define D2_CHCR 0x1000A000
|
|
#define D2_MADR 0x1000A010
|
|
#define D2_QWC 0x1000A020
|
|
#define D2_TADR 0x1000A030
|
|
|
|
//fromIPU
|
|
#define D3_CHCR 0x1000B000
|
|
#define D3_MADR 0x1000B010
|
|
#define D3_QWC 0x1000B020
|
|
|
|
//toIPU
|
|
#define D4_CHCR 0x1000B400
|
|
#define D4_MADR 0x1000B410
|
|
#define D4_QWC 0x1000B420
|
|
#define D4_TADR 0x1000B430
|
|
|
|
//SIF0
|
|
#define D5_CHCR 0x1000C000
|
|
#define D5_MADR 0x1000C010
|
|
#define D5_QWC 0x1000C020
|
|
|
|
//SIF1
|
|
#define D6_CHCR 0x1000C400
|
|
#define D6_MADR 0x1000C410
|
|
#define D6_QWC 0x1000C420
|
|
|
|
//SIF2
|
|
#define D7_CHCR 0x1000C800
|
|
#define D7_MADR 0x1000C810
|
|
#define D7_QWC 0x1000C820
|
|
|
|
//fromSPR
|
|
#define D8_CHCR 0x1000D000
|
|
#define D8_MADR 0x1000D010
|
|
#define D8_QWC 0x1000D020
|
|
#define D8_SADR 0x1000D080
|
|
|
|
|
|
#define DMAC_CTRL 0x1000E000
|
|
#define DMAC_STAT 0x1000E010
|
|
#define DMAC_PCR 0x1000E020
|
|
#define DMAC_SQWC 0x1000E030
|
|
#define DMAC_RBSR 0x1000E040
|
|
#define DMAC_RBOR 0x1000E050
|
|
#define DMAC_STADR 0x1000E060
|
|
|
|
#define INTC_STAT 0x1000F000
|
|
#define INTC_MASK 0x1000F010
|
|
|
|
#define SBUS_F220 0x1000F220
|
|
#define SBUS_SMFLG 0x1000F230
|
|
#define SBUS_F240 0x1000F240
|
|
|
|
#define DMAC_ENABLER 0x1000F520
|
|
#define DMAC_ENABLEW 0x1000F590
|
|
|
|
#define SBFLG_IOPALIVE 0x10000
|
|
#define SBFLG_IOPSYNC 0x40000
|
|
|
|
#define GS_PMODE 0x12000000
|
|
#define GS_SMODE1 0x12000010
|
|
#define GS_SMODE2 0x12000020
|
|
#define GS_SRFSH 0x12000030
|
|
#define GS_SYNCH1 0x12000040
|
|
#define GS_SYNCH2 0x12000050
|
|
#define GS_SYNCV 0x12000060
|
|
#define GS_DISPFB1 0x12000070
|
|
#define GS_DISPLAY1 0x12000080
|
|
#define GS_DISPFB2 0x12000090
|
|
#define GS_DISPLAY2 0x120000A0
|
|
#define GS_EXTBUF 0x120000B0
|
|
#define GS_EXTDATA 0x120000C0
|
|
#define GS_EXTWRITE 0x120000D0
|
|
#define GS_BGCOLOR 0x120000E0
|
|
#define GS_CSR 0x12001000
|
|
#define GS_IMR 0x12001010
|
|
#define GS_BUSDIR 0x12001040
|
|
#define GS_SIGLBLID 0x12001080
|
|
|
|
#define INTC_GS 0
|
|
#define INTC_SBUS 1
|
|
#define INTC_VBLANK_S 2
|
|
#define INTC_VBLANK_E 3
|
|
#define INTC_VIF0 4
|
|
#define INTC_VIF1 5
|
|
#define INTC_VU0 6
|
|
#define INTC_VU1 7
|
|
#define INTC_IPU 8
|
|
#define INTC_TIM0 9
|
|
#define INTC_TIM1 10
|
|
#define INTC_TIM2 11
|
|
#define INTC_TIM3 12
|
|
|
|
#define DMAC_VIF0 0
|
|
#define DMAC_VIF1 1
|
|
#define DMAC_GIF 2
|
|
#define DMAC_FROM_IPU 3
|
|
#define DMAC_TO_IPU 4
|
|
#define DMAC_SIF0 5
|
|
#define DMAC_SIF1 6
|
|
#define DMAC_SIF2 7
|
|
#define DMAC_FROM_SPR 8
|
|
#define DMAC_TO_SPR 9
|
|
#define DMAC_ERROR 15
|
|
|
|
#define VIF0_STAT_VPS_W (1)
|
|
#define VIF0_STAT_VPS_D (2)
|
|
#define VIF0_STAT_VPS_T (3)
|
|
#define VIF0_STAT_VPS (3)
|
|
#define VIF0_STAT_VEW (1<<2)
|
|
#define VIF0_STAT_MRK (1<<6)
|
|
#define VIF0_STAT_DBF (1<<7)
|
|
#define VIF0_STAT_VSS (1<<8)
|
|
#define VIF0_STAT_VFS (1<<9)
|
|
#define VIF0_STAT_VIS (1<<10)
|
|
#define VIF0_STAT_INT (1<<11)
|
|
#define VIF0_STAT_ER0 (1<<12)
|
|
#define VIF0_STAT_ER1 (1<<13)
|
|
|
|
#define VIF1_STAT_VPS_W (1)
|
|
#define VIF1_STAT_VPS_D (2)
|
|
#define VIF1_STAT_VPS_T (3)
|
|
#define VIF1_STAT_VPS (3)
|
|
#define VIF1_STAT_VEW (1<<2)
|
|
#define VIF1_STAT_VGW (1<<3)
|
|
#define VIF1_STAT_MRK (1<<6)
|
|
#define VIF1_STAT_DBF (1<<7)
|
|
#define VIF1_STAT_VSS (1<<8)
|
|
#define VIF1_STAT_VFS (1<<9)
|
|
#define VIF1_STAT_VIS (1<<10)
|
|
#define VIF1_STAT_INT (1<<11)
|
|
#define VIF1_STAT_ER0 (1<<12)
|
|
#define VIF1_STAT_ER1 (1<<13)
|
|
#define VIF1_STAT_FDR (1<<23)
|
|
|
|
//DMA interrupts & masks
|
|
#define BEISintr (0x8000)
|
|
#define VIF0intr (0x10001)
|
|
#define VIF1intr (0x20002)
|
|
#define GIFintr (0x40004)
|
|
#define IPU0intr (0x80008)
|
|
#define IPU1intr (0x100010)
|
|
#define SIF0intr (0x200020)
|
|
#define SIF1intr (0x400040)
|
|
#define SIF2intr (0x800080)
|
|
#define SPR0intr (0x1000100)
|
|
#define SPR1intr (0x2000200)
|
|
#define SISintr (0x20002000)
|
|
#define MEISintr (0x40004000)
|
|
|
|
#define DMAend(dma, num) { \
|
|
dma->chcr &= ~0x100; \
|
|
psHu32(DMAC_STAT)|= 1<<num; \
|
|
return; \
|
|
}
|
|
|
|
#define DMAerror(dma, num) { \
|
|
psHu32(DMAC_STAT)|= 1<<15; /* BUS error */ \
|
|
DMAend(dma, num); \
|
|
}
|
|
|
|
#define _dmaGetAddr(dma, ptr, addr, num) \
|
|
ptr = (u32*)dmaGetAddr(addr); \
|
|
if (ptr == NULL) DMAerror(dma, num);
|
|
|
|
#ifdef WIN32_VIRTUAL_MEM
|
|
|
|
#define dmaGetAddrBase(addr) (((addr) & 0x80000000) ? (void*)&PS2MEM_SCRATCH[(addr) & 0x3ff0] : (void*)(PS2MEM_BASE+TRANSFORM_ADDR(addr)))
|
|
|
|
extern PSMEMORYMAP *memLUT;
|
|
__forceinline u8* dmaGetAddr(u32 mem)
|
|
{
|
|
u8* p, *pbase;
|
|
mem &= ~0xf;
|
|
if( mem == 0x50000000 ) // reserved scratch pad mem
|
|
return NULL;
|
|
|
|
p = (u8*)dmaGetAddrBase(mem), *pbase;
|
|
// do manual LUT since IPU/SPR seems to use addrs 0x3000xxxx quite often
|
|
#ifndef PCSX2_RELEASE
|
|
if( memLUT[ (p-PS2MEM_BASE)>>12 ].aPFNs == NULL ) {
|
|
SysPrintf("*PCSX2*: DMA error: %8.8x\n", mem);
|
|
return NULL;
|
|
}
|
|
#endif
|
|
pbase = (u8*)memLUT[ (p-PS2MEM_BASE)>>12 ].aVFNs[0];
|
|
if( pbase != NULL )
|
|
p = pbase + ((u32)p&0xfff);
|
|
return p;
|
|
}
|
|
|
|
#else
|
|
|
|
__forceinline void *dmaGetAddr(u32 addr) {
|
|
u8 *ptr;
|
|
|
|
/*#ifdef DMA_LOG
|
|
if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x\n", addr); }
|
|
#endif*/
|
|
if (addr & 0x80000000) { // teh sux why the f00k 0xE0000000
|
|
return (void*)&psS[addr & 0x3ff0];
|
|
}
|
|
|
|
ptr = (u8*)memLUTR[addr >> 12];
|
|
if (ptr == NULL) {
|
|
SysPrintf("*PCSX2*: DMA error: %8.8x\n", addr);
|
|
return NULL;
|
|
}
|
|
return (void*)(ptr + (addr & 0xff0));
|
|
}
|
|
|
|
#endif
|
|
|
|
int hwInit();
|
|
void hwReset();
|
|
void hwShutdown();
|
|
|
|
// hw read functions
|
|
u8 hwRead8 (u32 mem);
|
|
int hwConstRead8 (u32 x86reg, u32 mem, u32 sign);
|
|
|
|
u16 hwRead16(u32 mem);
|
|
int hwConstRead16(u32 x86reg, u32 mem, u32 sign);
|
|
|
|
u32 hwRead32(u32 mem);
|
|
int hwConstRead32(u32 x86reg, u32 mem);
|
|
|
|
u64 hwRead64(u32 mem);
|
|
void hwConstRead64(u32 mem, int mmreg);
|
|
|
|
void hwRead128(u32 mem, u64 *out);
|
|
void hwConstRead128(u32 mem, int xmmreg);
|
|
|
|
// hw write functions
|
|
void hwWrite8 (u32 mem, u8 value);
|
|
void hwConstWrite8 (u32 mem, int mmreg);
|
|
|
|
void hwWrite16(u32 mem, u16 value);
|
|
void hwConstWrite16(u32 mem, int mmreg);
|
|
|
|
void hwWrite32(u32 mem, u32 value);
|
|
void hwConstWrite32(u32 mem, int mmreg);
|
|
|
|
void hwWrite64(u32 mem, u64 value);
|
|
void hwConstWrite64(u32 mem, int mmreg);
|
|
|
|
void hwWrite128(u32 mem, u64 *value);
|
|
void hwConstWrite128(u32 mem, int xmmreg);
|
|
|
|
void hwIntcIrq(int n);
|
|
void hwDmacIrq(int n);
|
|
|
|
int hwMFIFORead(u32 addr, u8 *data, int size);
|
|
int hwMFIFOWrite(u32 addr, u8 *data, int size);
|
|
|
|
int hwDmacSrcChainWithStack(DMACh *dma, int id);
|
|
int hwDmacSrcChain(DMACh *dma, int id);
|
|
|
|
int intcInterrupt();
|
|
int dmacInterrupt();
|
|
|
|
#endif /* __HW_H__ */
|