mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #1583 from PCSX2/ramapcsx2-psx-mode
PCSX2 rudimentary supports PlayStation 1 games now. Many thanks to user Wisi on the assemblergames.com forums. He researched and wrote the essential missing piece; The PGIF device! Note: To use this in any form, SPU2-X needs to be fixed. ZeroSPU2 can be used to boot games for now, but without sound.
This commit is contained in:
commit
fdf5e7ab2a
|
@ -402,6 +402,14 @@ void cdvdReloadElfInfo(wxString elfoverride)
|
|||
)
|
||||
);
|
||||
//Console.Error( "Playstation1 game discs are not supported by PCSX2." );
|
||||
|
||||
// PCSX2 currently only recognizes *.elf executables in proper PS2 format.
|
||||
// To support different PSX titles in the console title and for savestates, this code bypasses all the detection,
|
||||
// simply using the exe name, stripped of problematic characters.
|
||||
wxString fname = elfpath.AfterLast('\\');
|
||||
wxString fname2 = fname.BeforeFirst(';');
|
||||
DiscSerial = fname2;
|
||||
Console.SetTitle(DiscSerial);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,8 @@ static void ReadTrack() {
|
|||
cdr.Prev[2] = itob(cdr.SetSector[2]);
|
||||
|
||||
CDVD_LOG("KEY *** %x:%x:%x", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]);
|
||||
if (EmuConfig.CdvdVerboseReads)
|
||||
DevCon.WriteLn("CD Read Sector %x", msf_to_lsn(cdr.SetSector));
|
||||
cdr.RErr = DoCDVDreadTrack(msf_to_lsn(cdr.SetSector), CDVD_MODE_2340);
|
||||
}
|
||||
|
||||
|
@ -912,7 +914,9 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
|
|||
case 0x11000000:
|
||||
case 0x11400100:
|
||||
if (cdr.Readed == 0) {
|
||||
CDVD_LOG("*** DMA 3 *** NOT READY");
|
||||
DevCon.Warning("*** DMA 3 *** NOT READY");
|
||||
HW_DMA3_CHCR &= ~0x01000000; //hack
|
||||
psxDmaInterrupt(3); //hack
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ set(pcsx2Sources
|
|||
IopIrq.cpp
|
||||
IopMem.cpp
|
||||
IopSio2.cpp
|
||||
# Mdec.cpp
|
||||
Mdec.cpp
|
||||
Memory.cpp
|
||||
MMI.cpp
|
||||
MTGS.cpp
|
||||
|
@ -137,7 +137,7 @@ set(pcsx2Headers
|
|||
IopHw.h
|
||||
IopMem.h
|
||||
IopSio2.h
|
||||
# Mdec.h
|
||||
Mdec.h
|
||||
MTVU.h
|
||||
Memory.h
|
||||
MemoryTypes.h
|
||||
|
@ -408,6 +408,7 @@ set(pcsx2LinuxHeaders
|
|||
# ps2 sources
|
||||
set(pcsx2ps2Sources
|
||||
ps2/BiosTools.cpp
|
||||
ps2/pgif.cpp
|
||||
ps2/LegacyDmac.cpp
|
||||
ps2/Iop/IopHwRead.cpp
|
||||
ps2/Iop/IopHwWrite.cpp)
|
||||
|
@ -416,6 +417,7 @@ set(pcsx2ps2Sources
|
|||
set(pcsx2ps2Headers
|
||||
ps2/BiosTools.h
|
||||
ps2/eeHwTraceLog.inl
|
||||
ps2/pgif.h
|
||||
ps2/HwInternal.h
|
||||
ps2/Iop/IopHw_Internal.h)
|
||||
|
||||
|
|
|
@ -80,7 +80,9 @@ namespace EEMemoryMap
|
|||
static const uint SIO_Start = 0x1000F100;
|
||||
static const uint SIO_End = 0x1000F200;
|
||||
static const uint SBUS_Start = 0x1000F200;
|
||||
static const uint SBUS_End = 0x1000F400;
|
||||
static const uint SBUS_End = 0x1000F300;
|
||||
static const uint SBUS_PS1_Start = 0x1000F300;
|
||||
static const uint SBUS_PS1_End = 0x1000F400;
|
||||
|
||||
// MCH area -- Really not sure what this area is. Information is lacking.
|
||||
static const uint MCH_Start = 0x1000F400;
|
||||
|
@ -330,7 +332,7 @@ enum EERegisterAddresses
|
|||
SBUS_F250 = 0x1000F250,
|
||||
SBUS_F260 = 0x1000F260,
|
||||
SBUS_F300 = 0x1000F300,
|
||||
SBUS_F380 = 0x1000F380,
|
||||
SBUS_F380 = 0x1000F380,
|
||||
|
||||
MCH_RICM = 0x1000F430,
|
||||
MCH_DRD = 0x1000F440,
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "ps2/HwInternal.h"
|
||||
#include "ps2/eeHwTraceLog.inl"
|
||||
|
||||
#include "ps2/pgif.h"
|
||||
|
||||
using namespace R5900;
|
||||
|
||||
static __fi void IntCHackCheck()
|
||||
|
@ -92,8 +94,13 @@ mem32_t __fastcall _hwRead32(u32 mem)
|
|||
return psHu32(INTC_STAT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// todo: psx mode: this is new
|
||||
if (((mem & 0x1FFFFFFF) >= EEMemoryMap::SBUS_PS1_Start) && ((mem & 0x1FFFFFFF) < EEMemoryMap::SBUS_PS1_End)) {
|
||||
return PGIFr((mem & 0x1FFFFFFF));
|
||||
}
|
||||
|
||||
// WARNING: this code is never executed anymore due to previous condition.
|
||||
// It requires investigation of what to do.
|
||||
if ((mem & 0x1000ff00) == 0x1000f300)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -139,14 +146,21 @@ mem32_t __fastcall _hwRead32(u32 mem)
|
|||
switch( mem )
|
||||
{
|
||||
case SIO_ISR:
|
||||
case SBUS_F260:
|
||||
|
||||
case 0x1000f410:
|
||||
case MCH_RICM:
|
||||
return 0;
|
||||
|
||||
case SBUS_F240:
|
||||
#if PSX_EXTRALOGS
|
||||
DevCon.Warning("Read SBUS_F240 %x ", psHu32(SBUS_F240));
|
||||
#endif
|
||||
return psHu32(SBUS_F240) | 0xF0000102;
|
||||
|
||||
case SBUS_F260:
|
||||
#if PSX_EXTRALOGS
|
||||
DevCon.Warning("Read SBUS_F260 %x ", psHu32(SBUS_F260));
|
||||
#endif
|
||||
return psHu32(SBUS_F260);
|
||||
case MCH_DRD:
|
||||
if( !((psHu32(MCH_RICM) >> 6) & 0xF) )
|
||||
{
|
||||
|
@ -347,6 +361,14 @@ void __fastcall _hwRead128(u32 mem, mem128_t* result )
|
|||
ZeroQWC( result );
|
||||
break;
|
||||
case 0x0F:
|
||||
// todo: psx mode: this is new
|
||||
if (((mem & 0x1FFFFFFF) >= EEMemoryMap::SBUS_PS1_Start) && ((mem & 0x1FFFFFFF) < EEMemoryMap::SBUS_PS1_End)) {
|
||||
PGIFrQword((mem & 0x1FFFFFFF), result);
|
||||
return;
|
||||
}
|
||||
|
||||
// WARNING: this code is never executed anymore due to previous condition.
|
||||
// It requires investigation of what to do.
|
||||
if ((mem & 0xffffff00) == 0x1000f300)
|
||||
{
|
||||
DevCon.Warning("128bit read from %x wibble", mem);
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "ps2/HwInternal.h"
|
||||
#include "ps2/eeHwTraceLog.inl"
|
||||
|
||||
#include "ps2/pgif.h"
|
||||
|
||||
using namespace R5900;
|
||||
|
||||
// Shift the middle 8 bits (bits 4-12) into the lower 8 bits.
|
||||
|
@ -47,7 +49,11 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
|
|||
#if PSX_EXTRALOGS
|
||||
if ((mem & 0x1000ff00) == 0x1000f300) DevCon.Warning("32bit Write to SIF Register %x value %x", mem, value);
|
||||
//if ((mem & 0x1000ff00) == 0x1000f200) DevCon.Warning("Write to SIF Register %x value %x", mem, value);
|
||||
|
||||
// todo: psx mode: this is new
|
||||
if (((mem & 0x1FFFFFF0) == 0x1000f010) || ((mem & 0x1FFFFFF0) == 0x1000f010)) Console.WriteLn("EE ###INTC hwWR 0x%08X = 0x%08X PC=%08X ", mem, value, cpuRegs.pc);
|
||||
#endif
|
||||
|
||||
switch (page)
|
||||
{
|
||||
case 0x00: if (!rcntWrite32<0x00>(mem, value)) return; break;
|
||||
|
@ -172,7 +178,10 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
|
|||
psHu32(mem) &= ~value;
|
||||
return;
|
||||
|
||||
mcase(SBUS_F240):
|
||||
mcase(SBUS_F240) :
|
||||
#if PSX_EXTRALOGS
|
||||
DevCon.Warning("Write SBUS_F240 %x ", value);
|
||||
#endif
|
||||
if(!(value & 0x100))
|
||||
psHu32(mem) &= ~0x100;
|
||||
else
|
||||
|
@ -180,9 +189,14 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
|
|||
return;
|
||||
|
||||
mcase(SBUS_F260):
|
||||
psHu32(mem) = 0;
|
||||
#if PSX_EXTRALOGS
|
||||
DevCon.Warning("Write SBUS_F260 %x ", psHu32(SBUS_F260));
|
||||
#endif
|
||||
psHu32(mem) = value;
|
||||
return;
|
||||
|
||||
// TODO: psx handling is done in the default case. Keep the code until we decide if we decide which interface to use (sif2/Pgif dma)
|
||||
#if 0
|
||||
mcase(SBUS_F300) :
|
||||
psxHu32(0x1f801814) = value;
|
||||
/*
|
||||
|
@ -211,6 +225,8 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
|
|||
mcase(SBUS_F380) :
|
||||
psHu32(mem) = value;
|
||||
return;
|
||||
#endif
|
||||
|
||||
mcase(MCH_RICM)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
|
||||
if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0
|
||||
rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid
|
||||
|
@ -225,6 +241,13 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
|
|||
mcase(DMAC_ENABLEW):
|
||||
if (!dmacWrite32<0x0f>(DMAC_ENABLEW, value)) return;
|
||||
|
||||
default:
|
||||
// TODO: psx add the real address in a sbus mcase
|
||||
if (((mem & 0x1FFFFFFF) >= EEMemoryMap::SBUS_PS1_Start) && ((mem & 0x1FFFFFFF) < EEMemoryMap::SBUS_PS1_End)) {
|
||||
PGIFw((mem & 0x1FFFFFFF), value);
|
||||
return;
|
||||
}
|
||||
|
||||
//mcase(SIO_ISR):
|
||||
//mcase(0x1000f410):
|
||||
// Mystery Regs! No one knows!?
|
||||
|
@ -423,9 +446,16 @@ void __fastcall _hwWrite128(u32 mem, const mem128_t* srcval)
|
|||
|
||||
//WriteFIFO_IPUout(srcval);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
case 0x0F:
|
||||
// todo: psx mode: this is new
|
||||
if (((mem & 0x1FFFFFFF) >= EEMemoryMap::SBUS_PS1_Start) && ((mem & 0x1FFFFFFF) < EEMemoryMap::SBUS_PS1_End)) {
|
||||
PGIFwQword((mem & 0x1FFFFFFF), (void*)srcval);
|
||||
return;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,11 +134,13 @@ void spu2DMA7Irq()
|
|||
#ifndef DISABLE_PSX_GPU_DMAS
|
||||
void psxDma2(u32 madr, u32 bcr, u32 chcr) // GPU
|
||||
{
|
||||
DevCon.Warning("SIF2 IOP CHCR = %x MADR = %x BCR = %x first 16bits %x", chcr, madr, bcr, iopMemRead16(madr));
|
||||
//DevCon.Warning("SIF2 IOP CHCR = %x MADR = %x BCR = %x first 16bits %x", chcr, madr, bcr, iopMemRead16(madr));
|
||||
sif2.iop.busy = true;
|
||||
sif2.iop.end = false;
|
||||
//SIF2Dma();
|
||||
dmaSIF2();
|
||||
// todo: psxmode: dmaSIF2 appears to interface with PGPU but everything is already handled without it.
|
||||
// it slows down psxmode if it's run.
|
||||
//dmaSIF2();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "iR5900.h"
|
||||
#include "Sio.h"
|
||||
#include "Mdec.h"
|
||||
#include "ps2/pgif.h" // for pgpu reset
|
||||
|
||||
// NOTE: Any modifications to read/write fns should also go into their const counterparts
|
||||
// found in iPsxHw.cpp.
|
||||
|
@ -29,7 +31,10 @@ void psxHwReset() {
|
|||
|
||||
memset(iopHw, 0, 0x10000);
|
||||
|
||||
// mdecInit(); //initialize mdec decoder
|
||||
// todo: psxmode: this should be in an EE reset routine, since PGIF is on that IC
|
||||
pgifInit();
|
||||
|
||||
mdecInit(); //initialize mdec decoder
|
||||
cdrReset();
|
||||
cdvdReset();
|
||||
psxRcntInit();
|
||||
|
|
|
@ -18,12 +18,14 @@
|
|||
#include "IopMem.h"
|
||||
|
||||
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;
|
||||
HW_PS1_GPU_START = 0x1F8010A0,
|
||||
HW_PS1_GPU_END = 0x1F8010B0,
|
||||
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,
|
||||
|
|
118
pcsx2/Mdec.cpp
118
pcsx2/Mdec.cpp
|
@ -18,7 +18,7 @@
|
|||
|
||||
/* This code was based on the FPSE v0.08 Mdec decoder*/
|
||||
|
||||
#if 0
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -26,6 +26,25 @@
|
|||
#include "IopCommon.h"
|
||||
#include "Mdec.h"
|
||||
|
||||
struct {
|
||||
u32 command;
|
||||
u32 status;
|
||||
u16 *rl;
|
||||
int rlsize;
|
||||
} mdec;
|
||||
|
||||
struct config_mdec {
|
||||
u32 Mdec;
|
||||
};
|
||||
struct config_mdec Config;
|
||||
|
||||
u32 mdecArr2[0x100000] = { 0 };
|
||||
|
||||
u32 mdecMem[0x100000]; //watherver large size. //Memory only used to get DMA data and not really for anything else.
|
||||
//Sould be optimized(the funcs. that use it) to read IOP RAM direcly.
|
||||
#define PSXM(x) ((uptr)mdecMem + x)
|
||||
|
||||
|
||||
int iq_y[DCTSIZE2],iq_uv[DCTSIZE2];
|
||||
|
||||
static void idct1(int *block)
|
||||
|
@ -150,7 +169,11 @@ void idct(int *block,int k)
|
|||
}
|
||||
|
||||
void mdecInit(void) {
|
||||
mdec.rl = (u16*)&psxM[0x100000];
|
||||
|
||||
Config.Mdec = 1; //XXXXXXXXXXXXXXXXX 0 or 1
|
||||
|
||||
mdec.rl = (u16*)PSXM(0);
|
||||
//mdec.rl = (u16*)&psxM[0x100000];
|
||||
mdec.command = 0;
|
||||
mdec.status = 0;
|
||||
round_init();
|
||||
|
@ -158,7 +181,7 @@ void mdecInit(void) {
|
|||
|
||||
|
||||
void mdecWrite0(u32 data) {
|
||||
CDR_LOG("mdec0 write %lx", data);
|
||||
MDEC_LOG("mdec0 write %lx", data);
|
||||
|
||||
mdec.command = data;
|
||||
if ((data&0xf5ff0000)==0x30000000) {
|
||||
|
@ -167,7 +190,7 @@ void mdecWrite0(u32 data) {
|
|||
}
|
||||
|
||||
void mdecWrite1(u32 data) {
|
||||
CDR_LOG("mdec1 write %lx", data);
|
||||
MDEC_LOG("mdec1 write %lx", data);
|
||||
|
||||
if (data&0x80000000) { // mdec reset
|
||||
round_init();
|
||||
|
@ -176,35 +199,47 @@ void mdecWrite1(u32 data) {
|
|||
}
|
||||
|
||||
u32 mdecRead0(void) {
|
||||
CDR_LOG("mdec0 read %lx", mdec.command);
|
||||
MDEC_LOG("mdec0 read %lx", mdec.command);
|
||||
|
||||
return mdec.command;
|
||||
}
|
||||
|
||||
u32 mdecRead1(void) {
|
||||
#ifdef CDR_LOG
|
||||
CDR_LOG("mdec1 read %lx", mdec.status);
|
||||
#endif
|
||||
MDEC_LOG("mdec1 read %lx", mdec.status);
|
||||
|
||||
return mdec.status;
|
||||
}
|
||||
|
||||
void psxDma0(u32 adr, u32 bcr, u32 chcr) {
|
||||
int cmd = mdec.command;
|
||||
int size;
|
||||
|
||||
CDR_LOG("DMA0 %lx %lx %lx", adr, bcr, chcr);
|
||||
MDEC_LOG("DMA0 %lx %lx %lx", adr, bcr, chcr);
|
||||
|
||||
if (chcr!=0x01000201) return;
|
||||
if (chcr != 0x01000201) return;
|
||||
|
||||
size = (bcr>>16)*(bcr&0xffff);
|
||||
|
||||
if (cmd==0x40000001) {
|
||||
u8 *p = (u8*)PSXM(adr);
|
||||
iqtab_init(iq_y,p);
|
||||
iqtab_init(iq_uv,p+64);
|
||||
// bcr LSBs are the blocksize in words
|
||||
// bcr MSBs are the number of block
|
||||
int size = (bcr >> 16)*(bcr & 0xffff);
|
||||
if (size < 0) {
|
||||
// Need to investigate what happen if the transfer is huge
|
||||
Console.Error("psxDma0 DMA transfer overflow !");
|
||||
return;
|
||||
}
|
||||
else if ((cmd&0xf5ff0000)==0x30000000) {
|
||||
mdec.rl = (u16*)PSXM(adr);
|
||||
|
||||
for (int i = 0; i<(size); i++) {
|
||||
*(u32*)PSXM(((i + 0) * 4)) = iopMemRead32(adr + ((i + 0) * 4));
|
||||
if (i <20)
|
||||
MDEC_LOG(" data %08X %08X ", iopMemRead32((adr & 0x00FFFFFF) + (i * 4)), *(u32*)PSXM((i * 4)));
|
||||
}
|
||||
|
||||
|
||||
if (cmd == 0x40000001) {
|
||||
u8 *p = (u8*)PSXM(0); //u8 *p = (u8*)PSXM(adr);
|
||||
iqtab_init(iq_y, p);
|
||||
iqtab_init(iq_uv, p + 64);
|
||||
}
|
||||
else if ((cmd & 0xf5ff0000) == 0x30000000) {
|
||||
mdec.rl = (u16*)PSXM(0); //mdec.rl = (u16*)PSXM(adr);
|
||||
}
|
||||
|
||||
HW_DMA0_CHCR &= ~0x01000000;
|
||||
|
@ -214,14 +249,22 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) {
|
|||
void psxDma1(u32 adr, u32 bcr, u32 chcr) {
|
||||
int blk[DCTSIZE2*6];
|
||||
unsigned short *image;
|
||||
int size;
|
||||
|
||||
CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)", adr, bcr, chcr, mdec.command);
|
||||
MDEC_LOG("DMA1 %lx %lx %lx (cmd = %lx)", adr, bcr, chcr, mdec.command);
|
||||
|
||||
if (chcr!=0x01000200) return;
|
||||
if (chcr != 0x01000200) return;
|
||||
// bcr LSBs are the blocksize in words
|
||||
// bcr MSBs are the number of block
|
||||
int size = (bcr >> 16)*(bcr & 0xffff);
|
||||
int size2 = (bcr >> 16)*(bcr & 0xffff);
|
||||
if (size < 0) {
|
||||
// Need to investigate what happen if the transfer is huge
|
||||
Console.Error("psxDma1 DMA transfer overflow !");
|
||||
return;
|
||||
}
|
||||
|
||||
image = (u16*)mdecArr2;//(u16*)PSXM(0); //image = (u16*)PSXM(adr);
|
||||
|
||||
size = (bcr>>16)*(bcr&0xffff);
|
||||
image = (u16*)PSXM(adr);
|
||||
if (mdec.command&0x08000000) {
|
||||
for (;size>0;size-=(16*16)/2,image+=(16*16)) {
|
||||
mdec.rl = rl2blk(blk,mdec.rl);
|
||||
|
@ -234,6 +277,12 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i<(size2); i++) {
|
||||
iopMemWrite32(((adr & 0x00FFFFFF) + (i * 4) + 0), mdecArr2[i]);
|
||||
if (i <20)
|
||||
MDEC_LOG(" data %08X %08X ", iopMemRead32((adr & 0x00FFFFFF) + (i * 4)), mdecArr2[i]);
|
||||
}
|
||||
|
||||
HW_DMA1_CHCR &= ~0x01000000;
|
||||
psxDmaInterrupt(1);
|
||||
}
|
||||
|
@ -407,15 +456,12 @@ void yuv2rgb24(int *blk,unsigned char *image) {
|
|||
}
|
||||
}
|
||||
|
||||
int SaveState::mdecFreeze() {
|
||||
Freeze(mdec);
|
||||
Freeze(iq_y);
|
||||
Freeze(iq_uv);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//todo: psxmode: add mdec savestate support
|
||||
//int SaveState::mdecFreeze() {
|
||||
// Freeze(mdec);
|
||||
// Freeze(iq_y);
|
||||
// Freeze(iq_uv);
|
||||
//
|
||||
// return 0;
|
||||
//
|
||||
//}
|
||||
|
|
24
pcsx2/Mdec.h
24
pcsx2/Mdec.h
|
@ -85,14 +85,15 @@
|
|||
image[n+1] = ROUND(Y); \
|
||||
image[n+0] = ROUND(Y);
|
||||
|
||||
void mdecInit();
|
||||
void mdecWrite0(u32 data);
|
||||
void mdecWrite1(u32 data);
|
||||
u32 mdecRead0();
|
||||
u32 mdecRead1();
|
||||
void psxDma0(u32 madr, u32 bcr, u32 chcr);
|
||||
void psxDma1(u32 madr, u32 bcr, u32 chcr);
|
||||
int mdecFreeze(gzFile f, int Mode);
|
||||
extern void mdecInit();
|
||||
extern void mdecWrite0(u32 data);
|
||||
extern void mdecWrite1(u32 data);
|
||||
extern u32 mdecRead0();
|
||||
extern u32 mdecRead1();
|
||||
extern void psxDma0(u32 madr, u32 bcr, u32 chcr);
|
||||
extern void psxDma1(u32 madr, u32 bcr, u32 chcr);
|
||||
//int mdecFreeze(gzFile f, int Mode);
|
||||
|
||||
|
||||
u16* rl2blk(int *blk,u16 *mdec_rl);
|
||||
void iqtab_init(int *iqtab,unsigned char *iq_y);
|
||||
|
@ -100,11 +101,4 @@ void round_init(void);
|
|||
void yuv2rgb24(int *blk,unsigned char *image);
|
||||
void yuv2rgb15(int *blk,u16 *image);
|
||||
|
||||
struct {
|
||||
u32 command;
|
||||
u32 status;
|
||||
u16 *rl;
|
||||
int rlsize;
|
||||
} mdec;
|
||||
|
||||
#endif /* __MDEC_H__ */
|
||||
|
|
|
@ -601,7 +601,7 @@ void __fastcall eeloadHook()
|
|||
}
|
||||
}
|
||||
|
||||
if (!g_GameStarted && disctype == 2 && elfname == discelf)
|
||||
if (!g_GameStarted && (disctype == 2 || disctype == 1) && elfname == discelf)
|
||||
g_GameLoading = true;
|
||||
}
|
||||
|
||||
|
|
119
pcsx2/Sio.cpp
119
pcsx2/Sio.cpp
|
@ -136,7 +136,8 @@ void SIO_FORCEINLINE sioInterrupt()
|
|||
{
|
||||
PAD_LOG("Sio Interrupt");
|
||||
sio.StatReg|= IRQ;
|
||||
psxHu32(0x1070)|=0x80;
|
||||
iopIntcIrq(7); //Should this be used instead of the one below?
|
||||
//psxHu32(0x1070)|=0x80;
|
||||
}
|
||||
|
||||
SIO_WRITE sioWriteStart(u8 data)
|
||||
|
@ -173,22 +174,35 @@ SIO_WRITE sioWriteStart(u8 data)
|
|||
sioWrite8inl(data);
|
||||
}
|
||||
|
||||
int byteCnt = 0;
|
||||
|
||||
//This is only for digital pad! .... a fast hacky fix for testing
|
||||
//#define IS_LAST_BYTE_IN_PACKET ((byteCnt >= 3) ? 1 : 0)
|
||||
//this should be done on the last byte, but it works like this fine for now... How does one know which number is the last byte anyway (or are there any more following it).
|
||||
//maybe in the end a small LUT will be necessary that has the number of bytes for each command...
|
||||
//On the real PS1, if the controller doesn't supply an /ACK signal after each byte but the last, the transmission falls through... but it seems it is actually the interrupt
|
||||
//what 'continues' a transfer.
|
||||
//On the real PS1, asserting /ACK after the last byte would cause the transfer to fail.
|
||||
#define IS_LAST_BYTE_IN_PACKET ((sio.bufCount >= 3) ? 1 : 0)
|
||||
|
||||
SIO_WRITE sioWriteController(u8 data)
|
||||
{
|
||||
//if (data == 0x01) byteCnt = 0;
|
||||
switch(sio.bufCount)
|
||||
{
|
||||
case 0:
|
||||
byteCnt = 0; //hope this gets only cleared on the first byte...
|
||||
SIO_STAT_READY();
|
||||
DEVICE_PLUGGED();
|
||||
sio.buf[0] = PADstartPoll(sio.port + 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
sio.buf[sio.bufCount] = PADpoll(data);
|
||||
break;
|
||||
}
|
||||
|
||||
SIO_INT();
|
||||
//Console.WriteLn( "SIO: sent = %02X From pad data = %02X bufCnt %08X ", data, sio.buf[sio.bufCount], sio.bufCount);
|
||||
SIO_INT(); //Don't all commands(transfers) cause an interrupt?
|
||||
}
|
||||
|
||||
SIO_WRITE sioWriteMultitap(u8 data)
|
||||
|
@ -456,7 +470,8 @@ SIO_WRITE memcardWrite(u8 data)
|
|||
|
||||
SIO_WRITE memcardRead(u8 data)
|
||||
{
|
||||
//static u8 checksum_pos = 0;
|
||||
/*static u8 checksum_pos = 0;*/
|
||||
// psxmode: check if memcard reads need checksum_pos as well as writes (function above!)
|
||||
static u8 transfer_size = 0;
|
||||
static bool once = false;
|
||||
|
||||
|
@ -712,8 +727,8 @@ SIO_WRITE sioWriteMemcardPSX(u8 data)
|
|||
break;
|
||||
|
||||
case 1:
|
||||
sio.cmd = data;
|
||||
switch(data)
|
||||
sio.cmd = data;
|
||||
switch(data)
|
||||
{
|
||||
case 0x53: // PSX 'S'tate // haven't seen it happen yet
|
||||
sio.buf[1] = mcd->FLAG;
|
||||
|
@ -729,7 +744,7 @@ SIO_WRITE sioWriteMemcardPSX(u8 data)
|
|||
sio.buf[4] = 0x00;
|
||||
break;
|
||||
|
||||
case 0x58: // POCKETSTATION!! Grrrr // Lots of love to the PS2DEV/ps2sdk
|
||||
case 0x58: // POCKETSTATION!! Grrrr // Lots of love to the PS2DEV/ps2sdk
|
||||
DEVICE_UNPLUGGED(); // Check is for 0x01000 on stat
|
||||
siomode = SIO_DUMMY;
|
||||
break;
|
||||
|
@ -754,7 +769,7 @@ SIO_WRITE sioWriteMemcardPSX(u8 data)
|
|||
sio.buf[6] = data;
|
||||
mcd->sectorAddr |= data;
|
||||
mcd->goodSector = !(mcd->sectorAddr > 0x3FF);
|
||||
mcd->transferAddr = 128 * mcd->sectorAddr;
|
||||
mcd->transferAddr = 128 * mcd->sectorAddr;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
|
@ -800,7 +815,7 @@ SIO_WRITE sioWriteMemcardPSX(u8 data)
|
|||
sio.buf[136] = 0x5D;
|
||||
|
||||
// (47h=Good, 4Eh=BadChecksum, FFh=BadSector)
|
||||
sio.buf[137] = data == xorcheck ? 0x47 : 0x4E;
|
||||
sio.buf[137] = data == xorcheck ? 0x47 : 0x4E;
|
||||
if(!mcd->goodSector) sio.buf[137] = 0xFF;
|
||||
else mcd->Write(&sio.buf[7], 0x80);
|
||||
siomode = SIO_DUMMY;
|
||||
|
@ -817,8 +832,41 @@ SIO_WRITE sioWriteInfraRed(u8 data)
|
|||
SIO_INT();
|
||||
}
|
||||
|
||||
//This bit-field in the STATUS register contains the (inveted) state of the /ACK linre from the Controller / MC.
|
||||
//1 = /ACK_line_active_low
|
||||
//Should go into Sio.h
|
||||
#define ACK_INP 0x80
|
||||
|
||||
//This is named RESET_ERR in sio_internal.h.
|
||||
#define CLR_INTR 0x0010
|
||||
//Set the ammount of received bytes that triggers an interrupt.
|
||||
//0=1, 1=2, 2=4, 3=8 receivedBytesIntTriger = 1<< ((ctrl & RX_BYTES_INT) >>8)
|
||||
#define RX_BYTES_INT 0x0300
|
||||
//Enable interrupt on TX ready and TX empty
|
||||
#define TX_INT_EN 0x0400
|
||||
//Trigger interrupt after receiving several (see above) bytes.
|
||||
#define RX_INT_EN 0x0800
|
||||
//Controll register: Enable the /ACK line trigerring the interrupt.
|
||||
#define ACK_INT_EN 0x1000
|
||||
//Selects slot 1 or 2
|
||||
#define SLOT_NR 0x2000
|
||||
|
||||
void chkTriggerInt() {
|
||||
//Conditions for triggerring an interrupt.
|
||||
//this is not correct, but ... it can be fixed later
|
||||
SIO_INT(); return;
|
||||
if ((sio.StatReg & IRQ)) { SIO_INT(); return; } //The interrupt flag in the main INTR_STAT reg should go active on multiple occasions. Set it here for now (hack), until the correct mechanism is made.
|
||||
if ((sio.CtrlReg & ACK_INT_EN) && ((sio.StatReg & TX_RDY) || (sio.StatReg & TX_EMPTY))) { SIO_INT(); return; }
|
||||
if ((sio.CtrlReg & ACK_INT_EN) && (sio.StatReg & ACK_INP)) { SIO_INT(); return; }
|
||||
//The following one may be incorrect.
|
||||
//if ((sio.CtrlReg & RX_INT_EN) && ((byteCnt >= (1<< ((sio.CtrlReg & RX_BYTES_INT) >>8))) ? 1:0) ) { SIO_INT(); return; }
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void sioWrite8inl(u8 data)
|
||||
{
|
||||
// Console.WriteLn( "SIO DATA write %02X mode %08X " , data, siomode);
|
||||
switch(siomode)
|
||||
{
|
||||
case SIO_START: sioWriteStart(data); break;
|
||||
|
@ -834,12 +882,44 @@ static void sioWrite8inl(u8 data)
|
|||
case SIO_MEMCARD_PSX: sioWriteMemcardPSX(data); break;
|
||||
case SIO_DUMMY: break;
|
||||
};
|
||||
sio.StatReg |= RX_RDY; //Why not set the byte-received flag, when for EVERY sent byte, one is received... it's just how SPI is...
|
||||
sio.StatReg |= TX_EMPTY; //The current byte *has* been sent, so it is empty.
|
||||
if (IS_LAST_BYTE_IN_PACKET != 1) //The following should be set after each byte transfer but the last one.
|
||||
sio.StatReg |= ACK_INP; //Signal that Controller (or MC) has brought the /ACK (Acknowledge) line active low.
|
||||
|
||||
SIO_INT();
|
||||
//chkTriggerInt();
|
||||
//Console.WriteLn( "SIO0 WR DATA COMMON %02X INT_STAT= %08X IOPpc= %08X " , data, psxHu32(0x1070), psxRegs.pc);
|
||||
byteCnt++;
|
||||
}
|
||||
|
||||
void sioWriteCtrl16(u16 value)
|
||||
int clrAckCnt =0;
|
||||
|
||||
void sioStatRead() {
|
||||
|
||||
if (clrAckCnt > 1) { //This check can probably be removed...
|
||||
sio.StatReg &= ~ACK_INP; //clear (goes inactive) /ACK line.
|
||||
//sio.StatReg &= ~TX_RDY;
|
||||
// sio.StatReg &= ~0x200; //irq
|
||||
//if (byteCnt == 1)
|
||||
// sio.StatReg &= ~RX_RDY;
|
||||
clrAckCnt = 0;
|
||||
}
|
||||
//The /ACK line should go active for >2us, in a time window between 12us and 100us after each byte is sent (received by the controller).
|
||||
//If that doesn't happen, the controller is considered missing.
|
||||
//The /ACK line must NOT go active after the last byte in the transmission! (Otherwise some err. may happen - tested.)
|
||||
if ((sio.StatReg & ACK_INP)) clrAckCnt++;
|
||||
|
||||
chkTriggerInt();
|
||||
return;
|
||||
}
|
||||
|
||||
void sioWriteCtrl16(u16 value)
|
||||
{
|
||||
static u8 tcount[2];
|
||||
|
||||
// Console.WriteLn( "SIO0 WR CTRL %02X IOPpc= %08X " , value, psxRegs.pc);
|
||||
|
||||
tcount[sio.port] = sio.bufCount;
|
||||
sio.port = (value >> 13) & 1;
|
||||
|
||||
|
@ -859,24 +939,29 @@ void sioWriteCtrl16(u16 value)
|
|||
psxRegs.interrupt &= ~(1<<IopEvt_SIO);
|
||||
}
|
||||
|
||||
if (sio.CtrlReg & CLR_INTR) sio.StatReg &= ~(IRQ | PARITY_ERR); //clear internal interrupt
|
||||
sio.bufCount = tcount[sio.port];
|
||||
//chkTriggerInt(); //necessary? - causes transfer to stup after the third byte
|
||||
}
|
||||
|
||||
u8 sioRead8()
|
||||
u8 sioRead8()
|
||||
{
|
||||
u8 ret;
|
||||
|
||||
if(sio.StatReg & RX_RDY)
|
||||
if(sio.StatReg & RX_RDY)
|
||||
{
|
||||
ret = sio.buf[sio.bufCount];
|
||||
if(sio.bufCount == sio.bufSize) SIO_STAT_EMPTY();
|
||||
sio.bufCount++;
|
||||
SIO_STAT_EMPTY(); //this should depend on the counter above... but it seems wrong (buffer never empties).
|
||||
sio.StatReg &= ~TX_RDY; //all clear (transfer of byte ended)
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = sio.ret;
|
||||
}
|
||||
|
||||
// sio.StatReg &= ~TX_RDY; //all clear (transfer of byte ended)
|
||||
// Console.WriteLn( "SIO DATA read %02X stat= %08X " , ret, sio.StatReg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -885,8 +970,8 @@ void sioWrite8(u8 value)
|
|||
sioWrite8inl(value);
|
||||
}
|
||||
|
||||
void SIODMAWrite(u8 value)
|
||||
{
|
||||
void SIODMAWrite(u8 value) //Why does the SIO2 FIFO handler call this function...??
|
||||
{ //PS1 and PS2 modes are separate and the SIO0 and SIO2 aren't active at the sam time...
|
||||
sioWrite8inl(value);
|
||||
}
|
||||
|
||||
|
@ -944,7 +1029,7 @@ void SaveStateBase::sioFreeze()
|
|||
// it has a "rule" that the memcard should never be ejected during a song. So by
|
||||
// ejecting it, the game freezes (which is actually good emulation, but annoying!)
|
||||
|
||||
for( u8 port=0; port<2; ++port )
|
||||
for( u8 port=0; port<2; ++port )
|
||||
for( u8 slot=0; slot<4; ++slot )
|
||||
{
|
||||
u64 checksum = mcds[port][slot].GetChecksum();
|
||||
|
|
|
@ -128,5 +128,6 @@ extern void sioInterrupt();
|
|||
extern void InitializeSIO(u8 value);
|
||||
extern void SetForceMcdEjectTimeoutNow();
|
||||
extern void ClearMcdEjectTimeoutNow();
|
||||
extern void sioNextFrame();
|
||||
extern void sioStatRead();
|
||||
extern void sioSetGameSerial(const wxString& serial);
|
||||
extern void sioNextFrame();
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include "Sio.h"
|
||||
#include "CDVD/CdRom.h"
|
||||
|
||||
#include "ps2/pgif.h"
|
||||
#include "Mdec.h"
|
||||
|
||||
namespace IopMemory
|
||||
{
|
||||
using namespace Internal;
|
||||
|
@ -36,7 +39,12 @@ mem8_t __fastcall iopHwRead8_Page1( u32 addr )
|
|||
mem8_t ret; // using a return var can be helpful in debugging.
|
||||
switch( masked_addr )
|
||||
{
|
||||
mcase(HW_SIO_DATA): ret = sioRead8(); break;
|
||||
mcase(HW_SIO_DATA) :
|
||||
// 1F801040h 1/4 JOY_DATA Joypad/Memory Card Data (R/W)
|
||||
// psxmode: documentation suggests a valid 8 bit read and the rest of the 32 bit register is unclear.
|
||||
// todo: check this and compare with the HW_SIO_DATA read around line 245 as well.
|
||||
ret = sioRead8();
|
||||
break;
|
||||
|
||||
// for use of serial port ignore for now
|
||||
//case 0x50: ret = serial_read8(); break;
|
||||
|
@ -85,7 +93,8 @@ mem8_t __fastcall iopHwRead8_Page3( u32 addr )
|
|||
|
||||
mem8_t ret;
|
||||
if( addr == 0x1f803100 ) // PS/EE/IOP conf related
|
||||
ret = 0x10; // Dram 2M
|
||||
//ret = 0x10; // Dram 2M
|
||||
ret = 0xFF; //all high bus is the corect default state for CEX PS2!
|
||||
else
|
||||
ret = psxHu8( addr );
|
||||
|
||||
|
@ -110,7 +119,6 @@ mem8_t __fastcall iopHwRead8_Page8( u32 addr )
|
|||
IopHwTraceLog<mem8_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template< typename T >
|
||||
|
@ -126,7 +134,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
|
|||
);
|
||||
|
||||
u32 masked_addr = pgmsk( addr );
|
||||
T ret;
|
||||
T ret = 0;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Counters, 16-bit varieties!
|
||||
|
@ -216,10 +224,23 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
|
|||
ret = SPU2read( addr );
|
||||
else
|
||||
{
|
||||
DbgCon.Warning( "HwRead32 from SPU2? @ 0x%08X .. What manner of trickery is this?!", addr );
|
||||
DevCon.Warning( "HwRead32 from SPU2? @ 0x%08X .. What manner of trickery is this?!", addr );
|
||||
ret = psxHu32(addr);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
// PS1 GPU access
|
||||
//
|
||||
else if( (masked_addr >= pgmsk(HW_PS1_GPU_START)) && (masked_addr < pgmsk(HW_PS1_GPU_END)) )
|
||||
{
|
||||
// todo: psx mode: this is new
|
||||
if( sizeof(T) == 2 )
|
||||
DevCon.Warning( "HwRead16 from PS1 GPU? @ 0x%08X .. What manner of trickery is this?!", addr );
|
||||
|
||||
pxAssert(sizeof(T) == 4);
|
||||
|
||||
ret = psxDma2GpuR(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( masked_addr )
|
||||
|
@ -237,6 +258,8 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
|
|||
|
||||
mcase(HW_SIO_STAT):
|
||||
ret = sio.StatReg;
|
||||
sioStatRead();
|
||||
// Console.WriteLn( "SIO0 Read STAT %02X INT_STAT= %08X IOPpc= %08X " , ret, psxHu32(0x1070), psxRegs.pc);
|
||||
break;
|
||||
|
||||
mcase(HW_SIO_MODE):
|
||||
|
@ -301,51 +324,26 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
|
|||
break;
|
||||
|
||||
mcase(HW_PS1_GPU_DATA) :
|
||||
ret = psxHu32(addr);
|
||||
ret = psxGPUr(addr);
|
||||
//ret = psxHu32(addr); // old
|
||||
DevCon.Warning("GPU Data Read %x", ret);
|
||||
break;
|
||||
|
||||
mcase(HW_PS1_GPU_STATUS) :
|
||||
//ret = psxHu32(addr);
|
||||
/*if (sif2.fifo.size == 0x8) psxHu32(0x1f801814) &= ~(3 << 25);
|
||||
else psxHu32(0x1f801814) |= (3 << 25);*/
|
||||
/*switch ((psxHu32(HW_PS1_GPU_STATUS) >> 29) & 0x3)
|
||||
{
|
||||
case 0x0:
|
||||
//DevCon.Warning("Set DMA Mode OFF");
|
||||
psxHu32(HW_PS1_GPU_STATUS) &= ~0x2000000;
|
||||
break;
|
||||
case 0x1:
|
||||
//DevCon.Warning("Set DMA Mode FIFO");
|
||||
psxHu32(HW_PS1_GPU_STATUS) |= 0x2000000;
|
||||
break;
|
||||
case 0x2:
|
||||
//DevCon.Warning("Set DMA Mode CPU->GPU");
|
||||
psxHu32(HW_PS1_GPU_STATUS) = (psxHu32(HW_PS1_GPU_STATUS) & ~0x2000000) | ((psxHu32(HW_PS1_GPU_STATUS) & 0x10000000) >> 3);
|
||||
break;
|
||||
case 0x3:
|
||||
//DevCon.Warning("Set DMA Mode GPUREAD->CPU");
|
||||
psxHu32(HW_PS1_GPU_STATUS) = (psxHu32(HW_PS1_GPU_STATUS) & ~0x2000000) | ((psxHu32(HW_PS1_GPU_STATUS) & 0x8000000) >> 2);
|
||||
break;
|
||||
}*/
|
||||
ret = psxHu32(addr); //Idle & Ready to recieve command.
|
||||
//psxHu32(addr) = psHu32(0x1000f300);
|
||||
#if PSX_EXTRALOGS
|
||||
DevCon.Warning("GPU Status Read %x Sif fifo size %x", ret, sif2.fifo.size);
|
||||
#endif
|
||||
//ret = -1; // fake alive GPU :p
|
||||
ret = psxGPUr(addr);
|
||||
break;
|
||||
|
||||
mcase (0x1f801820): // MDEC
|
||||
ret = psxHu32(addr);
|
||||
// ret = psxHu32(addr); // old
|
||||
ret = mdecRead0();
|
||||
#if PSX_EXTRALOGS
|
||||
DevCon.Warning("MDEC 1820 Read %x", ret);
|
||||
#endif
|
||||
break;
|
||||
|
||||
mcase (0x1f801824): // MDEC
|
||||
|
||||
ret = psxHu32(addr);
|
||||
//ret = psxHu32(addr); // old
|
||||
ret = mdecRead1();
|
||||
#if PSX_EXTRALOGS
|
||||
DevCon.Warning("MDEC 1824 Read %x", ret);
|
||||
#endif
|
||||
|
@ -461,12 +459,15 @@ mem32_t __fastcall iopHwRead32_Page8( u32 addr )
|
|||
// 4-byte FIFO input?
|
||||
// The old IOP system just ignored it, so that's what we do here. I've included commented code
|
||||
// for treating it as a 16/32 bit write though [which is what the SIO does, for example).
|
||||
mcase(HW_SIO2_FIFO):
|
||||
mcase(HW_SIO2_FIFO) :
|
||||
//ret = sio2_fifoOut();
|
||||
//ret |= sio2_fifoOut() << 8;
|
||||
//ret |= sio2_fifoOut() << 16;
|
||||
//ret |= sio2_fifoOut() << 24;
|
||||
//break;
|
||||
DevCon.Warning("HW_SIO2_FIFO read");
|
||||
ret = psxHu32(addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = psxHu32(addr);
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include "Sio.h"
|
||||
#include "CDVD/CdRom.h"
|
||||
|
||||
#include "ps2/pgif.h"
|
||||
#include "Mdec.h"
|
||||
|
||||
namespace IopMemory {
|
||||
|
||||
using namespace Internal;
|
||||
|
@ -248,6 +251,19 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
//psxHu(addr) = val;
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
// PS1 GPU access
|
||||
//
|
||||
else if( (masked_addr >= pgmsk(HW_PS1_GPU_START)) && (masked_addr < pgmsk(HW_PS1_GPU_END)) )
|
||||
{
|
||||
// todo: psx mode: this is new
|
||||
if( sizeof(T) == 2 )
|
||||
DevCon.Warning( "HwWrite16 to PS1 GPU? @ 0x%08X .. What manner of trickery is this?!", addr );
|
||||
|
||||
pxAssert(sizeof(T) == 4);
|
||||
|
||||
psxDma2GpuW(addr, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( masked_addr )
|
||||
|
@ -279,7 +295,8 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
break;
|
||||
|
||||
mcase(HW_SIO_CTRL):
|
||||
sio.CtrlReg = (u16)val;
|
||||
//sio.CtrlReg = (u16)val;
|
||||
sioWriteCtrl16((u16)val);
|
||||
break;
|
||||
|
||||
mcase(HW_SIO_BAUD):
|
||||
|
@ -295,6 +312,10 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
|
||||
mcase(HW_IREG):
|
||||
psxHu(addr) &= val;
|
||||
if ((val == 0xffffffff) ) {
|
||||
psxHu32(addr) |= 1 << 2;
|
||||
psxHu32(addr) |= 1 << 3;
|
||||
}
|
||||
break;
|
||||
|
||||
mcase(HW_IREG+2):
|
||||
|
@ -342,16 +363,18 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
// ------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
mcase(0x1f801088) : // DMA0 CHCR -- MDEC IN [ignored]
|
||||
//DmaExec(0);
|
||||
DevCon.Warning("MDEC IN (DMA0) Started"); //Can be disabled later, need to see when this is used.
|
||||
HW_DMA0_CHCR &= ~0x01000000;
|
||||
mcase(0x1f801088) : // DMA0 CHCR -- MDEC IN
|
||||
// psx mode
|
||||
HW_DMA0_CHCR = val;
|
||||
//Console.WriteLn("MDEC WR DMA0 %08X = %08X", addr, val);
|
||||
psxDma0(HW_DMA0_MADR, HW_DMA0_BCR, HW_DMA0_CHCR);
|
||||
break;
|
||||
|
||||
mcase(0x1f801098): // DMA1 CHCR -- MDEC OUT [ignored]
|
||||
//DmaExec(1);
|
||||
DevCon.Warning("MDEC IN (DMA1) Started"); //Can be disabled later, need to see when this is used.
|
||||
HW_DMA1_CHCR &= ~0x01000000;
|
||||
mcase(0x1f801098): // DMA1 CHCR -- MDEC OUT
|
||||
// psx mode
|
||||
HW_DMA1_CHCR = val;
|
||||
//Console.WriteLn("MDEC WR DMA1 %08X = %08X", addr, val);
|
||||
psxDma1(HW_DMA1_MADR, HW_DMA1_BCR, HW_DMA1_CHCR);
|
||||
break;
|
||||
mcase(0x1f8010ac):
|
||||
DevCon.Warning("SIF2 IOP TADR?? write");
|
||||
|
@ -359,6 +382,7 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
break;
|
||||
|
||||
mcase(0x1f8010a8) : // DMA2 CHCR -- GPU [ignored]
|
||||
// todo: psx mode: Original mod doesn't do "psxHu(addr) = val;"
|
||||
psxHu(addr) = val;
|
||||
DmaExec(2);
|
||||
break;
|
||||
|
@ -511,103 +535,20 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
//
|
||||
|
||||
mcase(HW_PS1_GPU_DATA) :
|
||||
DevCon.Warning("GPUDATA Write %x", val);
|
||||
/*if (val == 0x00000000)
|
||||
{
|
||||
psxHu32(HW_PS1_GPU_STATUS) = 0x14802000;
|
||||
}
|
||||
else if (val == 0x01000000)
|
||||
{
|
||||
DevCon.Warning("GP0 FIFO Clear");
|
||||
sif2.fifo.clear();
|
||||
}
|
||||
else
|
||||
{*/
|
||||
psxHu(HW_PS1_GPU_DATA) = val; // guess
|
||||
WriteFifoSingleWord();
|
||||
|
||||
//}
|
||||
//GPU_writeData(value); // really old code from PCSX? (rama)
|
||||
break;
|
||||
psxGPUw(addr, val);
|
||||
break;
|
||||
mcase (HW_PS1_GPU_STATUS):
|
||||
DevCon.Warning("GPUSTATUS Write Command %x Param %x", (u32)val >> 24, val & 0xffffff);
|
||||
//psxHu(addr) = val; // guess
|
||||
//psxHu(HW_PS1_GPU_STATUS) = val;
|
||||
//WriteFifoSingleWord();
|
||||
// psxHu(HW_PS1_GPU_DATA) = val; // guess
|
||||
// WriteFifoSingleWord();
|
||||
/*if (val == 0) //Reset
|
||||
{
|
||||
psxHu32(HW_PS1_GPU_STATUS) = 0x14802000;
|
||||
}
|
||||
else if (val == 0x10000007) //Get GPU version
|
||||
{
|
||||
//DevCon.Warning("Get Version");
|
||||
psxHu(HW_PS1_GPU_DATA) = 2;
|
||||
}
|
||||
else if ((val & 0xff000000) == 0x04000000)
|
||||
{
|
||||
//psxHu32(HW_PS1_GPU_STATUS) = psxHu32(HW_PS1_GPU_STATUS) &= ~0x60000000;
|
||||
psxHu32(HW_PS1_GPU_STATUS) |= (val & 0x3) << 29;
|
||||
switch (val & 0x3)
|
||||
{
|
||||
case 0x0:
|
||||
//DevCon.Warning("Set DMA Mode OFF");
|
||||
psxHu32(HW_PS1_GPU_STATUS) &= ~0x2000000;
|
||||
break;
|
||||
case 0x1:
|
||||
//DevCon.Warning("Set DMA Mode FIFO");
|
||||
psxHu32(HW_PS1_GPU_STATUS) |= 0x2000000;
|
||||
break;
|
||||
case 0x2:
|
||||
//DevCon.Warning("Set DMA Mode CPU->GPU");
|
||||
psxHu32(HW_PS1_GPU_STATUS) = (psxHu32(HW_PS1_GPU_STATUS) & ~0x2000000) | ((psxHu32(HW_PS1_GPU_STATUS) & 0x10000000) >> 3);
|
||||
break;
|
||||
case 0x3:
|
||||
//DevCon.Warning("Set DMA Mode GPUREAD->CPU");
|
||||
psxHu32(HW_PS1_GPU_STATUS) = (psxHu32(HW_PS1_GPU_STATUS) & ~0x2000000) | ((psxHu32(HW_PS1_GPU_STATUS) & 0x8000000) >> 2);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if (val == 0x03000000)
|
||||
{
|
||||
// DevCon.Warning("Turn Display on");
|
||||
psxHu32(HW_PS1_GPU_STATUS) &= ~(1 << 23);
|
||||
}
|
||||
else if ((val & 0xff000000) == 0x05000000)
|
||||
{
|
||||
DevCon.Warning("Start display area");
|
||||
|
||||
//psxHu32(HW_PS1_GPU_STATUS) |= 0x80000000;
|
||||
//psxHu32(HW_PS1_GPU_STATUS) &= ~(1 << 26);
|
||||
}
|
||||
else if ((val & 0xff000000) == 0x08000000)
|
||||
{
|
||||
//DevCon.Warning("Display Mode");
|
||||
psxHu32(HW_PS1_GPU_STATUS) &= ~0x7F4000;
|
||||
psxHu32(HW_PS1_GPU_STATUS) |= (u32)(val & 0x3f) << 17;
|
||||
psxHu32(HW_PS1_GPU_STATUS) |= (u32)(val & 0x40) << 10;
|
||||
psxHu32(HW_PS1_GPU_STATUS) |= (u32)(val & 0x80) << 7;
|
||||
//psxHu32(HW_PS1_GPU_STATUS) |= 0x80000000;
|
||||
//psxHu32(HW_PS1_GPU_STATUS) &= ~(1 << 26);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DevCon.Warning("Unknown GP1 Command");
|
||||
}*/
|
||||
//GPU_writeStatus(value); // really old code from PCSX? (rama)
|
||||
break;
|
||||
psxGPUw(addr, val);
|
||||
psxHu(addr) = val; // guess
|
||||
break;
|
||||
mcase (0x1f801820): // MDEC
|
||||
DevCon.Warning("MDEX 1820 Write %x", val);
|
||||
psxHu(addr) = val; // guess
|
||||
//mdecWrite0(value); // really old code from PCSX? (rama)
|
||||
break;
|
||||
mdecWrite0(val);
|
||||
break;
|
||||
mcase (0x1f801824): // MDEC
|
||||
DevCon.Warning("MDEX 1824 Write %x", val);
|
||||
psxHu(addr) = val; // guess
|
||||
//mdecWrite1(value); // really old code from PCSX? (rama)
|
||||
break;
|
||||
mdecWrite1(val);
|
||||
break;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,40 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2016-2016 PCSX2 Dev Team
|
||||
* Copyright (C) 2016 Wisi
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 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 PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void pgifInit(void);
|
||||
|
||||
extern void psxGPUw(int, u32);
|
||||
extern u32 psxGPUr(int);
|
||||
|
||||
extern void PGIFw(int, u32);
|
||||
extern u32 PGIFr(int);
|
||||
|
||||
extern void PGIFwQword(u32 addr, void *);
|
||||
extern void PGIFrQword(u32 addr, void *);
|
||||
|
||||
extern u32 psxDma2GpuR(u32 addr);
|
||||
extern void psxDma2GpuW(u32 addr, u32 data);
|
||||
|
||||
|
||||
extern void ps12PostOut(u32 mem, u8 value);
|
||||
extern void psDuartW(u32 mem, u8 value);
|
||||
extern u8 psExp2R8(u32 mem);
|
||||
extern void kernelTTYFileDescrWrite(u32 mem, u32 data);
|
||||
extern u32 getIntTmrKReg(u32 mem, u32 data);
|
||||
extern void testInt(void);
|
||||
extern void HPCoS_print(u32 mem, u32 data);
|
||||
extern void anyIopLS(u32 addr, u32 data, int Wr);
|
||||
extern void dma6_OTClear(void);
|
|
@ -188,6 +188,7 @@
|
|||
<ClCompile Include="..\..\Linux\LnxConsolePipe.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Mdec.cpp" />
|
||||
<ClCompile Include="..\..\MultipartFileReader.cpp" />
|
||||
<ClCompile Include="..\..\Patch.cpp" />
|
||||
<ClCompile Include="..\..\Patch_Memory.cpp" />
|
||||
|
@ -195,6 +196,7 @@
|
|||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ps2\LegacyDmac.cpp" />
|
||||
<ClCompile Include="..\..\ps2\pgif.cpp" />
|
||||
<ClCompile Include="..\..\ShiftJisToUnicode.cpp" />
|
||||
<ClCompile Include="..\..\sif2.cpp" />
|
||||
<ClCompile Include="..\..\Utilities\FileUtils.cpp" />
|
||||
|
@ -443,8 +445,10 @@
|
|||
<ClInclude Include="..\..\gui\Panels\MemoryCardPanels.h" />
|
||||
<ClInclude Include="..\..\IopGte.h" />
|
||||
<ClInclude Include="..\..\IPU\IPUdma.h" />
|
||||
<ClInclude Include="..\..\Mdec.h" />
|
||||
<ClInclude Include="..\..\Patch.h" />
|
||||
<ClInclude Include="..\..\PrecompiledHeader.h" />
|
||||
<ClInclude Include="..\..\ps2\pgif.h" />
|
||||
<ClInclude Include="..\..\Utilities\AsciiFile.h" />
|
||||
<ClInclude Include="..\..\Elfheader.h" />
|
||||
<ClInclude Include="..\..\CDVD\IsoFileFormats.h" />
|
||||
|
@ -625,4 +629,4 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -874,6 +874,12 @@
|
|||
<ClCompile Include="..\..\IopGte.cpp">
|
||||
<Filter>System\Ps2\Iop</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ps2\pgif.cpp">
|
||||
<Filter>System\Ps2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Mdec.cpp">
|
||||
<Filter>System\Ps2\Iop</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Patch.h">
|
||||
|
@ -1308,6 +1314,12 @@
|
|||
<ClInclude Include="..\..\IopGte.h">
|
||||
<Filter>System\Ps2\Iop</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ps2\pgif.h">
|
||||
<Filter>System\Ps2</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Mdec.h">
|
||||
<Filter>System\Ps2\Iop</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\wxResources.rc">
|
||||
|
|
Loading…
Reference in New Issue