work harder to update mednafen PSX.cpp from 1.24.0-UNSTABLE more exactly

This commit is contained in:
zeromus 2020-04-09 16:00:39 -04:00
parent f6a165752e
commit b8accdfd75
2 changed files with 1037 additions and 1044 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,22 @@
/******************************************************************************/
/* Mednafen Sony PS1 Emulation Module */
/******************************************************************************/
/* psx.h:
** Copyright (C) 2011-2016 Mednafen 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.
/******************************************************************************/
/* Mednafen Sony PS1 Emulation Module */
/******************************************************************************/
/* psx.h:
** Copyright (C) 2011-2016 Mednafen 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
@ -54,7 +54,7 @@ namespace MDFN_IEN_PSX
#define PSX_DBG_FLOOD 4 // Heavy informational debug messages(GPU commands; TODO).
#if PSX_DBGPRINT_ENABLE
void PSX_DBG(unsigned level, const char *format, ...) noexcept MDFN_COLD MDFN_FORMATSTR(gnu_printf, 2, 3);
void PSX_DBG(unsigned level, const char *format, ...) noexcept MDFN_COLD MDFN_FORMATSTR(gnu_printf, 2, 3);
void PSX_DBG_BIOS_PUTC(uint8 c) noexcept;
#define PSX_WARNING(format, ...) { PSX_DBG(PSX_DBG_WARNING, format "\n", ## __VA_ARGS__); }
@ -68,17 +68,17 @@ namespace MDFN_IEN_PSX
typedef int32 pscpu_timestamp_t;
bool PSX_EventHandler(const pscpu_timestamp_t timestamp);
bool MDFN_FASTCALL PSX_EventHandler(const pscpu_timestamp_t timestamp);
void PSX_MemWrite8(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
void PSX_MemWrite16(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
void PSX_MemWrite24(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
void PSX_MemWrite32(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
void MDFN_FASTCALL PSX_MemWrite8(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
void MDFN_FASTCALL PSX_MemWrite16(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
void MDFN_FASTCALL PSX_MemWrite24(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
void MDFN_FASTCALL PSX_MemWrite32(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
uint8 PSX_MemRead8(pscpu_timestamp_t &timestamp, uint32 A);
uint16 PSX_MemRead16(pscpu_timestamp_t &timestamp, uint32 A);
uint32 PSX_MemRead24(pscpu_timestamp_t &timestamp, uint32 A);
uint32 PSX_MemRead32(pscpu_timestamp_t &timestamp, uint32 A);
uint8 MDFN_FASTCALL PSX_MemRead8(pscpu_timestamp_t &timestamp, uint32 A);
uint16 MDFN_FASTCALL PSX_MemRead16(pscpu_timestamp_t &timestamp, uint32 A);
uint32 MDFN_FASTCALL PSX_MemRead24(pscpu_timestamp_t &timestamp, uint32 A);
uint32 MDFN_FASTCALL PSX_MemRead32(pscpu_timestamp_t &timestamp, uint32 A);
uint8 PSX_MemPeek8(uint32 A);
uint16 PSX_MemPeek16(uint32 A);
@ -129,10 +129,10 @@ namespace MDFN_IEN_PSX
class PS_CDC;
class PS_SPU;
extern PS_CPU *CPU;
extern PS_CDC *CDC;
extern PS_SPU *SPU;
extern MultiAccessSizeMem<2048 * 1024, false> MainRAM;
MDFN_HIDE extern PS_CPU *CPU;
MDFN_HIDE extern PS_CDC *CDC;
MDFN_HIDE extern PS_SPU *SPU;
MDFN_HIDE extern MultiAccessSizeMem<2048 * 1024, false> MainRAM;
}
enum eRegion
@ -143,11 +143,11 @@ enum eRegion
REGION_NONE = 3
};
enum eShockDeinterlaceMode
{
eShockDeinterlaceMode_Weave,
eShockDeinterlaceMode_Bob,
eShockDeinterlaceMode_BobOffset
enum eShockDeinterlaceMode
{
eShockDeinterlaceMode_Weave,
eShockDeinterlaceMode_Bob,
eShockDeinterlaceMode_BobOffset
};
enum eShockStep
@ -195,31 +195,31 @@ enum ePeripheralType
ePeripheralType_Multitap = 10,
};
enum eShockStateTransaction : s32
{
eShockStateTransaction_BinarySize = 0,
eShockStateTransaction_BinaryLoad = 1,
eShockStateTransaction_BinarySave = 2,
eShockStateTransaction_TextLoad = 3,
eShockStateTransaction_TextSave = 4
enum eShockStateTransaction : s32
{
eShockStateTransaction_BinarySize = 0,
eShockStateTransaction_BinaryLoad = 1,
eShockStateTransaction_BinarySave = 2,
eShockStateTransaction_TextLoad = 3,
eShockStateTransaction_TextSave = 4
};
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 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 eShockMemCb
{
eShockMemCb_None = 0,
eShockMemCb_Read = 1,
eShockMemCb_Write = 2,
eShockMemCb_Execute = 4
};
enum eShockMemCb
{
eShockMemCb_None = 0,
eShockMemCb_Read = 1,
eShockMemCb_Write = 2,
eShockMemCb_Execute = 4
};
#define MDFN_MSC_RESET 0
#define MDFN_MSC_POWER 1
@ -249,67 +249,67 @@ struct ShockTOC
u8 disc_type;
};
struct ShockRegisters_CPU
{
u32 GPR[32];
u32 PC, PC_NEXT;
u32 IN_BD_SLOT;
u32 LO, HI;
u32 SR, CAUSE, EPC;
struct ShockRegisters_CPU
{
u32 GPR[32];
u32 PC, PC_NEXT;
u32 IN_BD_SLOT;
u32 LO, HI;
u32 SR, CAUSE, EPC;
};
// [0] is unused, [100] is for the leadout track.
// Also, for convenience, tracks[last_track + 1] will always refer
// to the leadout track(even if last_track < 99, IE the leadout track details are duplicated).
typedef s32 (*ShockDisc_ReadTOC)(void* opaque, ShockTOC *read_target, ShockTOCTrack tracks[100 + 1]);
typedef s32 (*ShockDisc_ReadLBA)(void* opaque, s32 lba, void* dst);
//The callback to be issued for traces
typedef void (*ShockCallback_Trace)(void* opaque, u32 PC, u32 inst, const char* msg);
//the callback to be issued for memory hook events
//note: only one callback can be set. the type is sent to mask that one callback, not indicate which event type the callback is fore.
//there isnt one callback per type.
typedef void (*ShockCallback_Mem)(u32 address, eShockMemCb type, u32 size, u32 value);
class ShockDiscRef
{
public:
ShockDiscRef(void *opaque, s32 lbaCount, ShockDisc_ReadTOC cbReadTOC, ShockDisc_ReadLBA cbReadLBA2448, bool suppliesDeinterleavedSubcode)
: mOpaque(opaque)
, mLbaCount(lbaCount)
, mcbReadTOC(cbReadTOC)
, mcbReadLBA2448(cbReadLBA2448)
, mSuppliesDeinterleavedSubcode(suppliesDeinterleavedSubcode)
{
}
s32 ReadTOC( ShockTOC *read_target, ShockTOCTrack tracks[100 + 1])
{
return mcbReadTOC(mOpaque, read_target, tracks);
}
//formerly ReadRawSector
//Reads 2352 + 96
s32 ReadLBA2448(s32 lba, void* dst2448);
//formerly ReadRawSectorPWOnly
//Reads 96 bytes (of raw subchannel PW data) into pwbuf.
//Probably the same format as what's at the end of ReadLBA2448
//TODO - reorder args
bool ReadLBA_PW(uint8* pwbuf96, int32 lba, bool hint_fullread);
//only used by disc analysis stuff which should be refactored anyway. should eventually be removed
s32 ReadLBA2048(s32 lba, void* dst2048);
private:
s32 InternalReadLBA2448(s32 lba, void* dst2448, bool needSubcode);
void *mOpaque;
s32 mLbaCount;
ShockDisc_ReadTOC mcbReadTOC;
ShockDisc_ReadLBA mcbReadLBA2448;
bool mSuppliesDeinterleavedSubcode;
};
typedef s32 (*ShockDisc_ReadTOC)(void* opaque, ShockTOC *read_target, ShockTOCTrack tracks[100 + 1]);
typedef s32 (*ShockDisc_ReadLBA)(void* opaque, s32 lba, void* dst);
//The callback to be issued for traces
typedef void (*ShockCallback_Trace)(void* opaque, u32 PC, u32 inst, const char* msg);
//the callback to be issued for memory hook events
//note: only one callback can be set. the type is sent to mask that one callback, not indicate which event type the callback is fore.
//there isnt one callback per type.
typedef void (*ShockCallback_Mem)(u32 address, eShockMemCb type, u32 size, u32 value);
class ShockDiscRef
{
public:
ShockDiscRef(void *opaque, s32 lbaCount, ShockDisc_ReadTOC cbReadTOC, ShockDisc_ReadLBA cbReadLBA2448, bool suppliesDeinterleavedSubcode)
: mOpaque(opaque)
, mLbaCount(lbaCount)
, mcbReadTOC(cbReadTOC)
, mcbReadLBA2448(cbReadLBA2448)
, mSuppliesDeinterleavedSubcode(suppliesDeinterleavedSubcode)
{
}
s32 ReadTOC( ShockTOC *read_target, ShockTOCTrack tracks[100 + 1])
{
return mcbReadTOC(mOpaque, read_target, tracks);
}
//formerly ReadRawSector
//Reads 2352 + 96
s32 ReadLBA2448(s32 lba, void* dst2448);
//formerly ReadRawSectorPWOnly
//Reads 96 bytes (of raw subchannel PW data) into pwbuf.
//Probably the same format as what's at the end of ReadLBA2448
//TODO - reorder args
bool ReadLBA_PW(uint8* pwbuf96, int32 lba, bool hint_fullread);
//only used by disc analysis stuff which should be refactored anyway. should eventually be removed
s32 ReadLBA2048(s32 lba, void* dst2048);
private:
s32 InternalReadLBA2448(s32 lba, void* dst2448, bool needSubcode);
void *mOpaque;
s32 mLbaCount;
ShockDisc_ReadTOC mcbReadTOC;
ShockDisc_ReadLBA mcbReadLBA2448;
bool mSuppliesDeinterleavedSubcode;
};
struct ShockDiscInfo
{
@ -322,87 +322,87 @@ struct ShockFramebufferInfo
s32 width, height;
s32 flags;
void* ptr;
};
struct ShockRenderOptions
{
s32 scanline_start, scanline_end;
eShockRenderType renderType;
eShockDeinterlaceMode deinterlaceMode;
bool skip;
};
struct ShockMemcardTransaction
{
eShockMemcardTransaction transaction;
void* buffer128k;
};
};
struct ShockRenderOptions
{
s32 scanline_start, scanline_end;
eShockRenderType renderType;
eShockDeinterlaceMode deinterlaceMode;
bool skip;
};
struct ShockMemcardTransaction
{
eShockMemcardTransaction transaction;
void* buffer128k;
};
struct ShockStateTransaction
{
eShockStateTransaction transaction;
void *buffer;
s32 bufferLength;
//originally this was a pointer, however, we had problems getting it to marshal correctly
EW::FPtrs ff;
void *buffer;
s32 bufferLength;
//originally this was a pointer, however, we had problems getting it to marshal correctly
EW::FPtrs ff;
};
//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.
//Others should return SHOCK_OK
EW_EXPORT s32 shock_CreateDisc(ShockDiscRef** outDisc, void *Opaque, s32 lbaCount, ShockDisc_ReadTOC ReadTOC, ShockDisc_ReadLBA ReadLBA2448, bool suppliesDeinterleavedSubcode);
//Destroys a ShockDiscRef created with shock_CreateDisc. Make sure you havent left it in the playstation before destroying it!
EW_EXPORT s32 shock_DestroyDisc(ShockDiscRef* disc);
//Inspects a disc by looking for the system.cnf and retrieves some necessary information about it.
//Useful for determining the region of a disc
EW_EXPORT s32 shock_AnalyzeDisc(ShockDiscRef* disc, ShockDiscInfo* info);
//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.
//Others should return SHOCK_OK
EW_EXPORT s32 shock_CreateDisc(ShockDiscRef** outDisc, void *Opaque, s32 lbaCount, ShockDisc_ReadTOC ReadTOC, ShockDisc_ReadLBA ReadLBA2448, bool suppliesDeinterleavedSubcode);
//Destroys a ShockDiscRef created with shock_CreateDisc. Make sure you havent left it in the playstation before destroying it!
EW_EXPORT s32 shock_DestroyDisc(ShockDiscRef* disc);
//Inspects a disc by looking for the system.cnf and retrieves some necessary information about it.
//Useful for determining the region of a disc
EW_EXPORT s32 shock_AnalyzeDisc(ShockDiscRef* disc, ShockDiscInfo* info);
//Creates the psx instance as a console of the specified region.
//Additionally mounts the firmware from the provided buffer (the contents are copied)
//TODO - receive a model number parameter instead
EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k);
//Frees the psx instance created with shock_Create
EW_EXPORT s32 shock_Destroy(void* psx);
//Attaches (or detaches) a peripheral at the given address.
//Send ePeripheralType_None to detach.
//Do not attach when something is already attached.
//You can detach when nothing is attached.
//Returns SHOCK_NOCANDO if something inappropriate is done.
//Presently this has only been validated as functioning correctly before the initial PowerOn, but we would like to use it other times.
EW_EXPORT s32 shock_Peripheral_Connect(void* psx, s32 address, s32 type);
//Sets pad-type input (pad,dualshock,dualanalog) on the specified address;
//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);
//Polls the given peripheral address for it's active flag status (inverse of lag flag)
//If you want, the lag flag can be cleared
//Returns SHOCK_TRUE if the input has been read this frame
//Returns SHOCK_FALSE if the input hasnt been read this frame (is lagging)
//Returns SHOCK_NOCANDO if there is no peripheral there
//Returns SHOCK_INVALID_ADDRESS if address is invalid
//Returns SHOCK_ERROR for other errors.
EW_EXPORT s32 shock_Peripheral_PollActive(void* psx, s32 address, s32 clear);
//Mounts a PS-EXE executable
EW_EXPORT s32 shock_MountEXE(void* psx, void* exebuf, s32 size, s32 ignore_pcsp);
//Sets the power to ON. Returns SHOCK_NOCANDO if already on.
EW_EXPORT s32 shock_PowerOn(void* psx);
//Triggers a soft reset immediately. Returns SHOCK_NOCANDO if console is powered off.
EW_EXPORT s32 shock_SoftReset(void* psx);
//Sets the power to OFF. Returns SHOCK_NOCANDO if already off.
EW_EXPORT s32 shock_PowerOff(void* psx);
EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k);
//Frees the psx instance created with shock_Create
EW_EXPORT s32 shock_Destroy(void* psx);
//Attaches (or detaches) a peripheral at the given address.
//Send ePeripheralType_None to detach.
//Do not attach when something is already attached.
//You can detach when nothing is attached.
//Returns SHOCK_NOCANDO if something inappropriate is done.
//Presently this has only been validated as functioning correctly before the initial PowerOn, but we would like to use it other times.
EW_EXPORT s32 shock_Peripheral_Connect(void* psx, s32 address, s32 type);
//Sets pad-type input (pad,dualshock,dualanalog) on the specified address;
//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);
//Polls the given peripheral address for it's active flag status (inverse of lag flag)
//If you want, the lag flag can be cleared
//Returns SHOCK_TRUE if the input has been read this frame
//Returns SHOCK_FALSE if the input hasnt been read this frame (is lagging)
//Returns SHOCK_NOCANDO if there is no peripheral there
//Returns SHOCK_INVALID_ADDRESS if address is invalid
//Returns SHOCK_ERROR for other errors.
EW_EXPORT s32 shock_Peripheral_PollActive(void* psx, s32 address, s32 clear);
//Mounts a PS-EXE executable
EW_EXPORT s32 shock_MountEXE(void* psx, void* exebuf, s32 size, s32 ignore_pcsp);
//Sets the power to ON. Returns SHOCK_NOCANDO if already on.
EW_EXPORT s32 shock_PowerOn(void* psx);
//Triggers a soft reset immediately. Returns SHOCK_NOCANDO if console is powered off.
EW_EXPORT s32 shock_SoftReset(void* psx);
//Sets the power to OFF. Returns SHOCK_NOCANDO if already off.
EW_EXPORT s32 shock_PowerOff(void* psx);
//Opens the disc tray. Returns SHOCK_NOCANDO if already open.
EW_EXPORT s32 shock_OpenTray(void* psx);
@ -437,20 +437,20 @@ EW_EXPORT s32 shock_GetSamples(void* psx, void* buffer);
EW_EXPORT s32 shock_GetMemData(void* psx, void** ptr, s32* size, s32 memType);
//Savestate work. Returns the size if that's what was requested, otherwise error codes
EW_EXPORT s32 shock_StateTransaction(void *psx, ShockStateTransaction* transaction);
//Retrieves the CPU registers in a compact struct
EW_EXPORT s32 shock_GetRegisters_CPU(void* psx, ShockRegisters_CPU* buffer);
//Sets a CPU register. Rather than have an enum for the registers, lets just use the index (not offset) within the struct
EW_EXPORT s32 shock_SetRegister_CPU(void* psx, s32 index, u32 value);
//Sets the callback to be used for CPU tracing
EW_EXPORT s32 shock_SetTraceCallback(void* psx, void* opaque, ShockCallback_Trace callback);
//Sets whether LEC is enabled (sector level error correction). Defaults to FALSE (disabled)
EW_EXPORT s32 shock_SetLEC(void* psx, bool enabled);
//whether "determine lag from GPU frames" signal is set (GPU did something considered non-lag)
//returns SHOCK_TRUE or SHOCK_FALSE
EW_EXPORT s32 shock_GetGPUUnlagged(void* psx);
EW_EXPORT s32 shock_StateTransaction(void *psx, ShockStateTransaction* transaction);
//Retrieves the CPU registers in a compact struct
EW_EXPORT s32 shock_GetRegisters_CPU(void* psx, ShockRegisters_CPU* buffer);
//Sets a CPU register. Rather than have an enum for the registers, lets just use the index (not offset) within the struct
EW_EXPORT s32 shock_SetRegister_CPU(void* psx, s32 index, u32 value);
//Sets the callback to be used for CPU tracing
EW_EXPORT s32 shock_SetTraceCallback(void* psx, void* opaque, ShockCallback_Trace callback);
//Sets whether LEC is enabled (sector level error correction). Defaults to FALSE (disabled)
EW_EXPORT s32 shock_SetLEC(void* psx, bool enabled);
//whether "determine lag from GPU frames" signal is set (GPU did something considered non-lag)
//returns SHOCK_TRUE or SHOCK_FALSE
EW_EXPORT s32 shock_GetGPUUnlagged(void* psx);