psx - substantially revise original 'frontio' peripheral management code to reduce mednafenisms and support future flexibility. but for now: memory card is automatically mounted on slot 1 and tied to game name, same type of sram as other platforms.

This commit is contained in:
zeromus 2014-12-11 07:27:21 +00:00
parent eebb923b93
commit 3b1ff2df66
7 changed files with 243 additions and 716 deletions

View File

@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
isPorted: true,
isReleased: false
)]
public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains
public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam
{
public string SystemId { get { return "NULL"; } }
@ -396,5 +396,43 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
#endregion
#region ISaveRam
public byte[] CloneSaveRam()
{
var buf = new byte[128 * 1024];
fixed (byte* pbuf = buf)
{
var transaction = new OctoshockDll.ShockMemcardTransaction();
transaction.buffer128k = pbuf;
transaction.transaction = OctoshockDll.eShockMemcardTransaction.Read;
OctoshockDll.shock_Peripheral_MemcardTransact(psx, 0x01, ref transaction);
}
return buf;
}
public void StoreSaveRam(byte[] data)
{
fixed (byte* pbuf = data)
{
var transaction = new OctoshockDll.ShockMemcardTransaction();
transaction.buffer128k = pbuf;
transaction.transaction = OctoshockDll.eShockMemcardTransaction.Write;
OctoshockDll.shock_Peripheral_MemcardTransact(psx, 0x01, ref transaction);
}
}
public bool SaveRamModified
{
get
{
var transaction = new OctoshockDll.ShockMemcardTransaction();
transaction.transaction = OctoshockDll.eShockMemcardTransaction.CheckDirty;
return OctoshockDll.shock_Peripheral_MemcardTransact(psx, 0x01, ref transaction) == OctoshockDll.SHOCK_TRUE;
}
}
#endregion //ISaveRam
}
}

View File

@ -31,6 +31,15 @@ public unsafe static class OctoshockDll
PIOMem = 2, //64K
GPURAM = 3, //512K
SPURAM = 4 //512K
};
public enum eShockMemcardTransaction
{
Connect = 0, //connects it to the addressed port (not supported yet)
Disconnect = 1, //disconnects it from the addressed port (not supported yet)
Write = 2, //writes from the frontend to the memcard
Read = 3, //reads from the memcard to the frontend. Also clears the dirty flag
CheckDirty = 4, //checks whether the memcard is dirty
};
@ -46,6 +55,8 @@ public unsafe static class OctoshockDll
};
public const int SHOCK_OK = 0;
public const int SHOCK_FALSE = 0;
public const int SHOCK_TRUE = 1;
public const int SHOCK_ERROR = -1;
public const int SHOCK_NOCANDO = -2;
public const int SHOCK_INVALID_ADDRESS = -3;
@ -82,6 +93,14 @@ public unsafe static class OctoshockDll
public void* ptr;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockMemcardTransaction
{
[MarshalAs(UnmanagedType.I4)]
public eShockMemcardTransaction transaction;
public void* buffer128k;
};
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockDisc_ReadTOC(IntPtr opaque, ShockTOC* read_target, ShockTOCTrack* tracks101);
@ -114,6 +133,9 @@ public unsafe static class OctoshockDll
[DllImport("octoshock.dll")]
public static extern int shock_Peripheral_SetPadInput(IntPtr psx, int address, uint buttons, byte left_x, byte left_y, byte right_x, byte right_y);
[DllImport("octoshock.dll")]
public static extern int shock_Peripheral_MemcardTransact(IntPtr psx, int address, ref ShockMemcardTransaction transaction);
[DllImport("octoshock.dll")]
public static extern int shock_PowerOn(IntPtr psx);

Binary file not shown.

View File

@ -63,61 +63,6 @@ void InputDevice::ResetTS(void)
}
void InputDevice::SetCrosshairsColor(uint32 color)
{
chair_r = (color >> 16) & 0xFF;
chair_g = (color >> 8) & 0xFF;
chair_b = (color >> 0) & 0xFF;
draw_chair = (color != (1 << 24));
}
INLINE void InputDevice::DrawCrosshairs(uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock)
{
if(draw_chair && chair_y >= -8 && chair_y <= 8)
{
int32 ic;
int32 x_start, x_bound;
if(chair_y == 0)
ic = pix_clock / 762925;
else
ic = 0;
x_start = std::max<int32>(0, chair_x - ic);
x_bound = std::min<int32>(width, chair_x + ic + 1);
for(int32 x = x_start; x < x_bound; x++)
{
int r, g, b, a;
int nr, ng, nb;
format->DecodeColor(pixels[x], r, g, b, a);
nr = (r + chair_r * 3) >> 2;
ng = (g + chair_g * 3) >> 2;
nb = (b + chair_b * 3) >> 2;
if((int)((abs(r - nr) - 0x40) & (abs(g - ng) - 0x40) & (abs(b - nb) - 0x40)) < 0)
{
if((nr | ng | nb) & 0x80)
{
nr >>= 1;
ng >>= 1;
nb >>= 1;
}
else
{
nr ^= 0x80;
ng ^= 0x80;
nb ^= 0x80;
}
}
pixels[x] = format->MakeColor(nr, ng, nb, a);
}
}
}
bool InputDevice::RequireNoFrameskip(void)
{
@ -177,146 +122,38 @@ void InputDevice::ResetNVDirtyCount(void)
}
static unsigned EP_to_MP(bool emulate_multitap[2], unsigned ep)
//an old snippet tha showshow to set up a multitap device
//if(emulate_multitap[mp])
// DevicesTap[mp]->SetSubDevice(EP_to_SP(emulate_multitap, i), Devices[i], emulate_memcards[i] ? DevicesMC[i] : DummyDevice);
//else
// DevicesTap[mp]->SetSubDevice(EP_to_SP(emulate_multitap, i), DummyDevice, DummyDevice);
FrontIO::FrontIO()
{
if(!emulate_multitap[0] && emulate_multitap[1])
{
if(ep == 0 || ep >= 5)
return(0);
else
return(1);
}
else
return(ep >= 4);
//a dummy device used for memcards (please rename me)
DummyDevice = new InputDevice();
for(int i=0;i<2;i++)
{
Ports[i] = new InputDevice();
PortData[i] = NULL;
MCPorts[i] = new InputDevice();
}
//always add one memory device for now
MCPorts[0] = Device_Memcard_Create();
}
static INLINE unsigned EP_to_SP(bool emulate_multitap[2], unsigned ep)
{
if(!emulate_multitap[0] && emulate_multitap[1])
{
if(ep == 0)
return(0);
else if(ep < 5)
return(ep - 1);
else
return(ep - 4);
}
else
return(ep & 0x3);
}
void FrontIO::MapDevicesToPorts(void)
{
if(emulate_multitap[0] && emulate_multitap[1])
{
for(unsigned i = 0; i < 2; i++)
{
Ports[i] = DevicesTap[i];
MCPorts[i] = DummyDevice;
}
}
else if(!emulate_multitap[0] && emulate_multitap[1])
{
Ports[0] = Devices[0];
MCPorts[0] = emulate_memcards[0] ? DevicesMC[0] : DummyDevice;
Ports[1] = DevicesTap[1];
MCPorts[1] = DummyDevice;
}
else if(emulate_multitap[0] && !emulate_multitap[1])
{
Ports[0] = DevicesTap[0];
MCPorts[0] = DummyDevice;
Ports[1] = Devices[4];
MCPorts[1] = emulate_memcards[4] ? DevicesMC[4] : DummyDevice;
}
else
{
for(unsigned i = 0; i < 2; i++)
{
Ports[i] = Devices[i];
MCPorts[i] = emulate_memcards[i] ? DevicesMC[i] : DummyDevice;
}
}
//printf("\n");
for(unsigned i = 0; i < 8; i++)
{
unsigned mp = EP_to_MP(emulate_multitap, i);
if(emulate_multitap[mp])
DevicesTap[mp]->SetSubDevice(EP_to_SP(emulate_multitap, i), Devices[i], emulate_memcards[i] ? DevicesMC[i] : DummyDevice);
else
DevicesTap[mp]->SetSubDevice(EP_to_SP(emulate_multitap, i), DummyDevice, DummyDevice);
//printf("%d-> multitap: %d, sub-port: %d\n", i, mp, EP_to_SP(emulate_multitap, i));
}
}
FrontIO::FrontIO(bool emulate_memcards_[8], bool emulate_multitap_[2])
{
memcpy(emulate_memcards, emulate_memcards_, sizeof(emulate_memcards));
memcpy(emulate_multitap, emulate_multitap_, sizeof(emulate_multitap));
DummyDevice = new InputDevice();
for(unsigned i = 0; i < 8; i++)
{
DeviceData[i] = NULL;
Devices[i] = new InputDevice();
DevicesMC[i] = Device_Memcard_Create();
chair_colors[i] = 1 << 24;
Devices[i]->SetCrosshairsColor(chair_colors[i]);
}
for(unsigned i = 0; i < 2; i++)
{
DevicesTap[i] = new InputDevice_Multitap();
}
MapDevicesToPorts();
}
void FrontIO::SetCrosshairsColor(unsigned port, uint32 color)
{
assert(port >= 0 && port < 8);
chair_colors[port] = color;
Devices[port]->SetCrosshairsColor(color);
}
FrontIO::~FrontIO()
{
for(int i = 0; i < 8; i++)
{
if(Devices[i])
{
delete Devices[i];
Devices[i] = NULL;
}
if(DevicesMC[i])
{
delete DevicesMC[i];
DevicesMC[i] = NULL;
}
}
for(unsigned i = 0; i < 2; i++)
{
if(DevicesTap[i])
{
delete DevicesTap[i];
DevicesTap[i] = NULL;
}
}
if(DummyDevice)
{
delete DummyDevice;
DummyDevice = NULL;
}
for(int i=0;i<2;i++)
{
delete Ports[i];
delete MCPorts[i];
}
delete DummyDevice;
}
pscpu_timestamp_t FrontIO::CalcNextEventTS(pscpu_timestamp_t timestamp, int32 next_event)
@ -655,20 +492,20 @@ pscpu_timestamp_t FrontIO::Update(pscpu_timestamp_t timestamp)
void FrontIO::ResetTS(void)
{
for(int i = 0; i < 8; i++)
{
Devices[i]->Update(lastts); // Maybe eventually call Update() from FrontIO::Update() and remove this(but would hurt speed)?
Devices[i]->ResetTS();
for(int i=0;i<2;i++)
{
if(Ports[i] != NULL)
{
Ports[i]->Update(lastts); // Maybe eventually call Update() from FrontIO::Update() and remove this(but would hurt speed)?
Ports[i]->ResetTS();
}
DevicesMC[i]->Update(lastts); // Maybe eventually call Update() from FrontIO::Update() and remove this(but would hurt speed)?
DevicesMC[i]->ResetTS();
}
for(int i = 0; i < 2; i++)
{
DevicesTap[i]->Update(lastts);
DevicesTap[i]->ResetTS();
}
if(MCPorts[i] != NULL)
{
MCPorts[i]->Update(lastts); // Maybe eventually call Update() from FrontIO::Update() and remove this(but would hurt speed)?
MCPorts[i]->ResetTS();
}
}
for(int i = 0; i < 2; i++)
{
@ -726,10 +563,11 @@ void FrontIO::Power(void)
Control = 0;
Baudrate = 0;
for(int i = 0; i < 8; i++)
//power on all plugged devices (are we doing this when attaching them?)
for(int i=0;i<2;i++)
{
Devices[i]->Power();
DevicesMC[i]->Power();
if(Ports[i] != NULL) Ports[i]->Power();
if(MCPorts[i] != NULL) MCPorts[i]->Power();
}
istatus = false;
@ -737,102 +575,54 @@ void FrontIO::Power(void)
void FrontIO::UpdateInput(void)
{
for(int i = 0; i < 8; i++)
Devices[i]->UpdateInput(DeviceData[i]);
for(int i=0;i<2;i++)
{
if(Ports[i] != NULL) Ports[i]->UpdateInput(PortData[i]);
}
}
void FrontIO::SetInput(unsigned int port, const char *type, void *ptr)
{
delete Devices[port];
Devices[port] = NULL;
//clean up the old device
delete Ports[port];
Ports[port] = NULL;
//OCTOSHOCK TODO - not sure I understand this
if(port < 2)
irq10_pulse_ts[port] = PSX_EVENT_MAXTS;
//DAW
if(!strcmp(type, "gamepad") || !strcmp(type, "dancepad"))
Devices[port] = Device_Gamepad_Create();
Ports[port] = Device_Gamepad_Create();
else if(!strcmp(type, "dualanalog"))
Devices[port] = Device_DualAnalog_Create(false);
Ports[port] = Device_DualAnalog_Create(false);
else if(!strcmp(type, "analogjoy"))
Devices[port] = Device_DualAnalog_Create(true);
Ports[port] = Device_DualAnalog_Create(true);
else if(!strcmp(type, "dualshock"))
{
char name[256];
snprintf(name, 256, "DualShock on port %u", port + 1);
Devices[port] = Device_DualShock_Create(std::string(name));
Ports[port] = Device_DualShock_Create(std::string(name));
}
else if(!strcmp(type, "mouse"))
Devices[port] = Device_Mouse_Create();
Ports[port] = Device_Mouse_Create();
else if(!strcmp(type, "negcon"))
Devices[port] = Device_neGcon_Create();
Ports[port] = Device_neGcon_Create();
else if(!strcmp(type, "guncon"))
Devices[port] = Device_GunCon_Create();
Ports[port] = Device_GunCon_Create();
else if(!strcmp(type, "justifier"))
Devices[port] = Device_Justifier_Create();
Ports[port] = Device_Justifier_Create();
else
Devices[port] = new InputDevice();
Ports[port] = new InputDevice();
//Devices[port]->SetCrosshairsColor(chair_colors[port]);
DeviceData[port] = ptr;
MapDevicesToPorts();
PortData[port] = ptr;
}
uint64 FrontIO::GetMemcardDirtyCount(unsigned int which)
{
assert(which < 8);
return(DevicesMC[which]->GetNVDirtyCount());
}
void FrontIO::LoadMemcard(unsigned int which, const char *path)
{
//assert(which < 8);
//try
//{
// if(DevicesMC[which]->GetNVSize())
// {
// FileStream mf(path, FileStream::MODE_READ);
// std::vector<uint8> tmpbuf;
// tmpbuf.resize(DevicesMC[which]->GetNVSize());
// if(mf.size() != (int64)tmpbuf.size())
// throw(MDFN_Error(0, _("Memory card file \"%s\" is an incorrect size(%d bytes). The correct size is %d bytes."), path, (int)mf.size(), (int)tmpbuf.size()));
// mf.read(&tmpbuf[0], tmpbuf.size());
// DevicesMC[which]->WriteNV(&tmpbuf[0], 0, tmpbuf.size());
// DevicesMC[which]->ResetNVDirtyCount(); // There's no need to rewrite the file if it's the same data.
// }
//}
//catch(MDFN_Error &e)
//{
// if(e.GetErrno() != ENOENT)
// throw(e);
//}
}
void FrontIO::SaveMemcard(unsigned int which, const char *path)
{
//assert(which < 8);
//if(DevicesMC[which]->GetNVSize() && DevicesMC[which]->GetNVDirtyCount())
//{
// FileStream mf(path, FileStream::MODE_WRITE); // TODO: MODE_WRITE_ATOMIC_OVERWRITE
// std::vector<uint8> tmpbuf;
// tmpbuf.resize(DevicesMC[which]->GetNVSize());
// DevicesMC[which]->ReadNV(&tmpbuf[0], 0, tmpbuf.size());
// mf.write(&tmpbuf[0], tmpbuf.size());
// mf.close(); // Call before resetting the NV dirty count!
// DevicesMC[which]->ResetNVDirtyCount();
//}
assert(which < 2);
return(MCPorts[which]->GetNVDirtyCount());
}
int FrontIO::StateAction(StateMem* sm, int load, int data_only)
@ -871,33 +661,35 @@ int FrontIO::StateAction(StateMem* sm, int load, int data_only)
int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "FIO");
for(unsigned i = 0; i < 8; i++)
{
static const char* labels[] = {
"FIODEV0","FIODEV1","FIODEV2","FIODEV3","FIODEV4","FIODEV5","FIODEV6","FIODEV7"
};
//TODO - SAVESTATES
ret &= Devices[i]->StateAction(sm, load, data_only, labels[i]);
}
//for(unsigned i = 0; i < 8; i++)
//{
//static const char* labels[] = {
// "FIODEV0","FIODEV1","FIODEV2","FIODEV3","FIODEV4","FIODEV5","FIODEV6","FIODEV7"
//};
for(unsigned i = 0; i < 8; i++)
{
static const char* labels[] = {
"FIOMC0","FIOMC1","FIOMC2","FIOMC3","FIOMC4","FIOMC5","FIOMC6","FIOMC7"
};
// ret &= Devices[i]->StateAction(sm, load, data_only, labels[i]);
//}
//for(unsigned i = 0; i < 8; i++)
//{
//static const char* labels[] = {
// "FIOMC0","FIOMC1","FIOMC2","FIOMC3","FIOMC4","FIOMC5","FIOMC6","FIOMC7"
//};
ret &= DevicesMC[i]->StateAction(sm, load, data_only, labels[i]);
}
// ret &= DevicesMC[i]->StateAction(sm, load, data_only, labels[i]);
//}
for(unsigned i = 0; i < 2; i++)
{
static const char* labels[] = {
"FIOTAP0","FIOTAP1",
};
//for(unsigned i = 0; i < 2; i++)
//{
//static const char* labels[] = {
// "FIOTAP0","FIOTAP1",
//};
ret &= DevicesTap[i]->StateAction(sm, load, data_only, labels[i]);
}
// ret &= DevicesTap[i]->StateAction(sm, load, data_only, labels[i]);
//}
if(load)
{
@ -909,10 +701,7 @@ int FrontIO::StateAction(StateMem* sm, int load, int data_only)
bool FrontIO::RequireNoFrameskip(void)
{
for(unsigned i = 0; i < 8; i++)
if(Devices[i]->RequireNoFrameskip())
return(true);
//this whole function is nonsense. frontend should know what it has attached
return(false);
}
@ -920,9 +709,13 @@ void FrontIO::GPULineHook(const pscpu_timestamp_t timestamp, const pscpu_timesta
{
Update(timestamp);
for(unsigned i = 0; i < 8; i++)
for(int i = 0; i < 2; i++)
{
pscpu_timestamp_t plts = Devices[i]->GPULineHook(line_timestamp, vsync, pixels, format, width, pix_clock_offset, pix_clock, pix_clock_divider);
//octoshock edits.. not sure how safe it is
if(Ports[i] == NULL)
continue;
pscpu_timestamp_t plts = Ports[i]->GPULineHook(line_timestamp, vsync, pixels, format, width, pix_clock_offset, pix_clock, pix_clock_divider);
if(i < 2)
{
@ -937,17 +730,6 @@ void FrontIO::GPULineHook(const pscpu_timestamp_t timestamp, const pscpu_timesta
}
}
//
// Draw crosshairs in a separate pass so the crosshairs won't mess up the color evaluation of later lightun GPULineHook()s.
//
if(pixels && pix_clock)
{
for(unsigned i = 0; i < 8; i++)
{
Devices[i]->DrawCrosshairs(pixels, format, width, pix_clock);
}
}
PSX_SetEventNT(PSX_EVENT_FIO, CalcNextEventTS(timestamp, 0x10000000));
}

View File

@ -25,12 +25,7 @@ class InputDevice
virtual void Update(const pscpu_timestamp_t timestamp); // Partially-implemented, don't rely on for timing any more fine-grained than a video frame for now.
virtual void ResetTS(void);
void DrawCrosshairs(uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock);
//
//
//
virtual void SetCrosshairsColor(uint32 color);
//
//
//
@ -63,7 +58,7 @@ class FrontIO
{
public:
FrontIO(bool emulate_memcards_[8], bool emulate_multitap_[2]);
FrontIO();
~FrontIO();
void Power(void);
@ -81,31 +76,31 @@ class FrontIO
void SetCrosshairsColor(unsigned port, uint32 color);
uint64 GetMemcardDirtyCount(unsigned int which);
void LoadMemcard(unsigned int which, const char *path);
void SaveMemcard(unsigned int which, const char *path); //, bool force_save = false);
int StateAction(StateMem* sm, int load, int data_only);
InputDevice *Ports[2];
void *PortData[2];
InputDevice *MCPorts[2];
InputDevice *DummyDevice;
private:
void DoDSRIRQ(void);
void CheckStartStopPending(pscpu_timestamp_t timestamp, bool skip_event_set = false);
void MapDevicesToPorts(void);
bool emulate_memcards[8];
bool emulate_multitap[2];
InputDevice *Ports[2];
InputDevice *MCPorts[2];
InputDevice *DummyDevice;
InputDevice_Multitap *DevicesTap[2];
InputDevice *Devices[8];
void *DeviceData[8];
InputDevice *DevicesMC[8];
//OLD
//bool emulate_memcards[8];
//void MapDevicesToPorts(void);
//bool emulate_multitap[2];
//InputDevice_Multitap *DevicesTap[2];
//InputDevice *Devices[8];
//void *DeviceData[8];
//InputDevice *DevicesMC[8];
//
//

View File

@ -1051,231 +1051,7 @@ static void Emulate(EmulateSpecStruct *espec)
}
}
//DAW!!
// Save memcards if dirty.
//for(int i = 0; i < 8; i++)
//{
// uint64 new_dc = FIO->GetMemcardDirtyCount(i);
// if(new_dc > Memcard_PrevDC[i])
// {
// Memcard_PrevDC[i] = new_dc;
// Memcard_SaveDelay[i] = 0;
// }
// if(Memcard_SaveDelay[i] >= 0)
// {
// Memcard_SaveDelay[i] += timestamp;
// if(Memcard_SaveDelay[i] >= (33868800 * 2)) // Wait until about 2 seconds of no new writes.
// {
// PSX_DBG(PSX_DBG_SPARSE, "Saving memcard %d...\n", i);
// try
// {
// char ext[64];
// trio_snprintf(ext, sizeof(ext), "%d.mcr", i);
// FIO->SaveMemcard(i, MDFN_MakeFName(MDFNMKF_SAV, 0, ext).c_str());
// Memcard_SaveDelay[i] = -1;
// Memcard_PrevDC[i] = 0;
// }
// catch(std::exception &e)
// {
// MDFN_PrintError("Memcard %d save error: %s", i, e.what());
// MDFN_DispMessage("Memcard %d save error: %s", i, e.what());
// }
// //MDFN_DispMessage("Memcard %d saved.", i);
// }
// }
//}
}
//
//static bool TestMagic(MDFNFILE *fp)
//{
//#ifdef WANT_PSF
// if(PSFLoader::TestMagic(0x01, fp))
// return(true);
//#endif
//
// if(fp->size < 0x800)
// return(false);
//
// if(memcmp(fp->data, "PS-X EXE", 8))
// return(false);
//
// return(true);
//}
//
//static bool TestMagicCD(std::vector<CDIF *> *CDInterfaces)
//{
// uint8 buf[2048];
// CDUtility::TOC toc;
// int dt;
//
// (*CDInterfaces)[0]->ReadTOC(&toc);
//
// dt = toc.FindTrackByLBA(4);
// if(dt > 0 && !(toc.tracks[dt].control & 0x4))
// return(false);
//
// if((*CDInterfaces)[0]->ReadSector(buf, 4, 1) != 0x2)
// return(false);
//
// if(strncmp((char *)buf + 10, "Licensed by", strlen("Licensed by")))
// return(false);
//
// //if(strncmp((char *)buf + 32, "Sony", 4))
// // return(false);
//
// //for(int i = 0; i < 2048; i++)
// // printf("%d, %02x %c\n", i, buf[i], buf[i]);
// //exit(1);
//
//#if 0
// {
// uint8 buf[2048 * 7];
//
// if((*cdifs)[0]->ReadSector(buf, 5, 7) == 0x2)
// {
// printf("CRC32: 0x%08x\n", (uint32)crc32(0, &buf[0], 0x3278));
// }
// }
//#endif
//
// return(true);
//}
//
//
//static const char *CalcDiscSCEx_BySYSTEMCNF(CDIF *c, unsigned *rr)
//{
// const char *ret = NULL;
// Stream *fp = NULL;
// CDUtility::TOC toc;
//
// //(*CDInterfaces)[disc]->ReadTOC(&toc);
//
// //if(toc.first_track > 1 || toc.
//
// try
// {
// uint8 pvd[2048];
// unsigned pvd_search_count = 0;
//
// fp = c->MakeStream(0, ~0U);
// fp->seek(0x8000, SEEK_SET);
//
// do
// {
// if((pvd_search_count++) == 32)
// throw MDFN_Error(0, "PVD search count limit met.");
//
// fp->read(pvd, 2048);
//
// if(memcmp(&pvd[1], "CD001", 5))
// throw MDFN_Error(0, "Not ISO-9660");
//
// if(pvd[0] == 0xFF)
// throw MDFN_Error(0, "Missing Primary Volume Descriptor");
// } while(pvd[0] != 0x01);
// //[156 ... 189], 34 bytes
// uint32 rdel = MDFN_de32lsb(&pvd[0x9E]);
// uint32 rdel_len = MDFN_de32lsb(&pvd[0xA6]);
//
// if(rdel_len >= (1024 * 1024 * 10)) // Arbitrary sanity check.
// throw MDFN_Error(0, "Root directory table too large");
//
// fp->seek((int64)rdel * 2048, SEEK_SET);
// //printf("%08x, %08x\n", rdel * 2048, rdel_len);
// while(fp->tell() < (((int64)rdel * 2048) + rdel_len))
// {
// uint8 len_dr = fp->get_u8();
// uint8 dr[256 + 1];
//
// memset(dr, 0xFF, sizeof(dr));
//
// if(!len_dr)
// break;
//
// memset(dr, 0, sizeof(dr));
// dr[0] = len_dr;
// fp->read(dr + 1, len_dr - 1);
//
// uint8 len_fi = dr[0x20];
//
// if(len_fi == 12 && !memcmp(&dr[0x21], "SYSTEM.CNF;1", 12))
// {
// uint32 file_lba = MDFN_de32lsb(&dr[0x02]);
// //uint32 file_len = MDFN_de32lsb(&dr[0x0A]);
// uint8 fb[2048 + 1];
// char *bootpos;
//
// memset(fb, 0, sizeof(fb));
// fp->seek(file_lba * 2048, SEEK_SET);
// fp->read(fb, 2048);
//
// bootpos = strstr((char*)fb, "BOOT") + 4;
// while(*bootpos == ' ' || *bootpos == '\t') bootpos++;
// if(*bootpos == '=')
// {
// bootpos++;
// while(*bootpos == ' ' || *bootpos == '\t') bootpos++;
// if(!strncasecmp(bootpos, "cdrom:\\", 7))
// {
// bootpos += 7;
// char *tmp;
//
// if((tmp = strchr(bootpos, '_'))) *tmp = 0;
// if((tmp = strchr(bootpos, '.'))) *tmp = 0;
// if((tmp = strchr(bootpos, ';'))) *tmp = 0;
// //puts(bootpos);
//
// if(strlen(bootpos) == 4 && bootpos[0] == 'S' && (bootpos[1] == 'C' || bootpos[1] == 'L' || bootpos[1] == 'I'))
// {
// switch(bootpos[2])
// {
// case 'E': if(rr)
// *rr = REGION_EU;
// ret = "SCEE";
// goto Breakout;
//
// case 'U': if(rr)
// *rr = REGION_NA;
// ret = "SCEA";
// goto Breakout;
//
// case 'K': // Korea?
// case 'B':
// case 'P': if(rr)
// *rr = REGION_JP;
// ret = "SCEI";
// goto Breakout;
// }
// }
// }
// }
//
// //puts((char*)fb);
// //puts("ASOFKOASDFKO");
// }
// }
// }
// catch(std::exception &e)
// {
// //puts(e.what());
// }
// catch(...)
// {
//
// }
//
// Breakout:
// if(fp != NULL)
// {
// delete fp;
// fp = NULL;
// }
//
// return(ret);
//}
struct ShockConfig
{
@ -1311,6 +1087,8 @@ struct ShockPeripheral
struct {
//This is kind of redundant with the frontIO code, and should be merged with it eventually, when the configurability gets more advanced
ShockPeripheral ports[2];
void Initialize()
@ -1378,7 +1156,43 @@ struct {
buf[4] = right_y;
buf[5] = left_x;
buf[6] = left_y;
break;
return SHOCK_OK;
default:
return SHOCK_ERROR;
}
}
s32 MemcardTransact(s32 address, ShockMemcardTransaction* transaction)
{
//check the port address
int portnum = address&1;
if(portnum != 1 && portnum != 2)
return SHOCK_INVALID_ADDRESS;
portnum--;
//TODO - once we get flexible here, do some extra condition checks.. whether memcards exist, etc. much like devices.
switch(transaction->transaction)
{
case eShockMemcardTransaction_Connect: return SHOCK_ERROR; //not supported yet
case eShockMemcardTransaction_Disconnect: return SHOCK_ERROR; //not supported yet
case eShockMemcardTransaction_Write:
FIO->MCPorts[portnum]->WriteNV((uint8*)transaction->buffer128k,0,128*1024);
return SHOCK_OK;
case eShockMemcardTransaction_Read:
FIO->MCPorts[portnum]->ReadNV((uint8*)transaction->buffer128k,0,128*1024);
FIO->MCPorts[portnum]->ResetNVDirtyCount();
return SHOCK_OK;
case eShockMemcardTransaction_CheckDirty:
if(FIO->GetMemcardDirtyCount(portnum))
return SHOCK_TRUE;
else return SHOCK_FALSE;
default:
return SHOCK_ERROR;
}
}
@ -1394,6 +1208,11 @@ EW_EXPORT s32 shock_Peripheral_SetPadInput(void* psx, s32 address, u32 buttons,
return s_ShockPeripheralState.SetPadInput(address, buttons, left_x, left_y, right_x, right_y);
}
EW_EXPORT s32 shock_Peripheral_MemcardTransact(void* psx, s32 address, ShockMemcardTransaction* transaction)
{
return s_ShockPeripheralState.MemcardTransact(address, transaction);
}
static void MountCPUAddressSpace()
{
for(uint32 ma = 0x00000000; ma < 0x00800000; ma += 2048 * 1024)
@ -1423,7 +1242,10 @@ static int s_FramebufferCurrentWidth;
EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k)
{
//NEW
//TODO
//psx_dbg_level = MDFN_GetSettingUI("psx.dbg_level");
//DBG_Init();
*psx = NULL;
//PIO Mem: why wouldn't we want this?
@ -1480,11 +1302,7 @@ EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k)
VTLineWidths[i] = (int *)calloc(s_ShockConfig.fb_height, sizeof(int));
}
//TODO - configuration
static bool emulate_memcard[8] = {0};
static bool emulate_multitap[2] = {0};
FIO = new FrontIO(emulate_memcard, emulate_multitap);
FIO = new FrontIO();
s_ShockPeripheralState.Initialize();
MountCPUAddressSpace();
@ -1793,155 +1611,6 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
return SHOCK_OK;
}
static void InitCommon(std::vector<CDIF *> *CDInterfaces, const bool EmulateMemcards = true, const bool WantPIOMem = false)
{
//OLD
unsigned region;
bool emulate_memcard[8];
bool emulate_multitap[2];
int sls, sle;
#if PSX_DBGPRINT_ENABLE
psx_dbg_level = MDFN_GetSettingUI("psx.dbg_level");
#endif
//DAW
/*for(unsigned i = 0; i < 8; i++)
{
char buf[64];
trio_snprintf(buf, sizeof(buf), "psx.input.port%u.memcard", i + 1);
emulate_memcard[i] = EmulateMemcards && MDFN_GetSettingB(buf);
}
for(unsigned i = 0; i < 2; i++)
{
char buf[64];
trio_snprintf(buf, sizeof(buf), "psx.input.pport%u.multitap", i + 1);
emulate_multitap[i] = MDFN_GetSettingB(buf);
}*/
//cdifs = CDInterfaces;
//region = CalcDiscSCEx();
if(shock_GetSetting(REGION_AUTODETECT)==0)
region = shock_GetSetting(REGION_DEFAULT);
sls = shock_GetSetting((region == REGION_EU) ? SLSTARTP : SLSTART);
sle = shock_GetSetting((region == REGION_EU) ? SLENDP : SLEND);
if(sls > sle)
{
int tmp = sls;
sls = sle;
sle = tmp;
}
CPU = new PS_CPU();
SPU = new PS_SPU();
GPU = new PS_GPU(region == REGION_EU, sls, sle);
CDC = new PS_CDC();
FIO = new FrontIO(emulate_memcard, emulate_multitap);
//dont think we want the crosshair drawing to be done here
//FIO->SetCrosshairsColor(i, MDFN_GetSettingUI(buf));
DMA_Init();
//DAW
//GPU->FillVideoParams(&EmulatedPSX);
if(cdifs)
{
CD_TrayOpen = false;
CD_SelectedDisc = 0;
}
else
{
CD_TrayOpen = true;
CD_SelectedDisc = -1;
}
//CDC->SetDisc(true, NULL, NULL);
//CDC->SetDisc(CD_TrayOpen, (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? (*cdifs)[CD_SelectedDisc] : NULL,
//(CD_SelectedDisc >= 0 && !CD_TrayOpen) ? cdifs_scex_ids[CD_SelectedDisc] : NULL);
BIOSROM = new MultiAccessSizeMem<512 * 1024, uint32, false>();
if(WantPIOMem)
PIOMem = new MultiAccessSizeMem<65536, uint32, false>();
else
PIOMem = NULL;
for(uint32 ma = 0x00000000; ma < 0x00800000; ma += 2048 * 1024)
{
CPU->SetFastMap(MainRAM.data32, 0x00000000 + ma, 2048 * 1024);
CPU->SetFastMap(MainRAM.data32, 0x80000000 + ma, 2048 * 1024);
CPU->SetFastMap(MainRAM.data32, 0xA0000000 + ma, 2048 * 1024);
}
CPU->SetFastMap(BIOSROM->data32, 0x1FC00000, 512 * 1024);
CPU->SetFastMap(BIOSROM->data32, 0x9FC00000, 512 * 1024);
CPU->SetFastMap(BIOSROM->data32, 0xBFC00000, 512 * 1024);
if(PIOMem)
{
CPU->SetFastMap(PIOMem->data32, 0x1F000000, 65536);
CPU->SetFastMap(PIOMem->data32, 0x9F000000, 65536);
CPU->SetFastMap(PIOMem->data32, 0xBF000000, 65536);
}
//MDFNMP_Init(1024, ((uint64)1 << 29) / 1024);
//MDFNMP_AddRAM(2048 * 1024, 0x00000000, MainRAM.data8);
//DAW-
//TODO - load bios
//
//
//
//const char *biospath_sname;
//if(region == REGION_JP)
// biospath_sname = "psx.bios_jp";
//else if(region == REGION_EU)
// biospath_sname = "psx.bios_eu";
//else if(region == REGION_NA)
// biospath_sname = "psx.bios_na";
//else
// abort();
//{
// std::string biospath = MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, MDFN_GetSettingS(biospath_sname).c_str());
// FileStream BIOSFile(biospath.c_str(), FileStream::MODE_READ);
// BIOSFile.read(BIOSROM->data8, 512 * 1024);
//}
//todo - load memcard
//DAW
//for(int i = 0; i < 8; i++)
//{
// char ext[64];
// trio_snprintf(ext, sizeof(ext), "%d.mcr", i);
// FIO->LoadMemcard(i, MDFN_MakeFName(MDFNMKF_SAV, 0, ext).c_str());
//}
for(int i = 0; i < 8; i++)
{
Memcard_PrevDC[i] = FIO->GetMemcardDirtyCount(i);
Memcard_SaveDelay[i] = -1;
}
#ifdef WANT_DEBUGGER
DBG_Init();
#endif
PSX_Power();
}
static void LoadEXE(const uint8 *data, const uint32 size, bool ignore_pcsp = false)
{
// uint32 PC;

View File

@ -147,10 +147,19 @@ enum ePeripheralType
ePeripheralType_Pad = 1, //SCPH-1080
ePeripheralType_DualShock = 2, //SCPH-1200
ePeripheralType_DualAnalog = 3, //SCPH-1180
ePeripheralType_Multitap = 10,
};
enum eShockMemcardTransaction
{
eShockMemcardTransaction_Connect = 0, //connects it to the addressed port (not supported yet)
eShockMemcardTransaction_Disconnect = 1, //disconnects it from the addressed port (not supported yet)
eShockMemcardTransaction_Write = 2, //writes from the frontend to the memcard
eShockMemcardTransaction_Read = 3, //reads from the memcard to the frontend. Also clears the dirty flag
eShockMemcardTransaction_CheckDirty = 4, //checks whether the memcard is dirty
};
enum eShockSetting
{
REGION_AUTODETECT = 0,
@ -170,6 +179,8 @@ int shock_GetSetting(eShockSetting setting);
#define MDFN_MSC_EJECT_DISK 4
#define SHOCK_OK 0
#define SHOCK_FALSE 0
#define SHOCK_TRUE 1
#define SHOCK_ERROR -1
#define SHOCK_NOCANDO -2
#define SHOCK_INVALID_ADDRESS -3
@ -234,7 +245,14 @@ struct ShockFramebufferInfo
s32 width, height;
s32 flags;
void* ptr;
};
};
struct ShockMemcardTransaction
{
eShockMemcardTransaction transaction;
void* buffer128k;
};
//Creates a ShockDiscRef (representing a disc) with the given properties. Returns it in the specified output pointer.
//The ReadLBA2048 function should return 0x01 or 0x02 depending on which mode was there.
@ -268,6 +286,9 @@ EW_EXPORT s32 shock_Peripheral_Connect(void* psx, s32 address, s32 type);
//Read more about the input format (buttons, analog range) here: TBD
EW_EXPORT s32 shock_Peripheral_SetPadInput(void* psx, s32 address, u32 buttons, u8 left_x, u8 left_y, u8 right_x, u8 right_y);
//Performs one of several transactions on an attached memory card.
EW_EXPORT s32 shock_Peripheral_MemcardTransact(void* psx, s32 address, ShockMemcardTransaction* transaction);
//Sets the power to ON. Returns SHOCK_NOCANDO if already on.
EW_EXPORT s32 shock_PowerOn(void* psx);