mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
Merge pull request #47 from Nekotekina/master
cellSync, cellPamf and other
This commit is contained in:
commit
40f2e679ec
@ -293,7 +293,7 @@ public:
|
||||
};
|
||||
volatile u64 m_indval;
|
||||
};
|
||||
volatile long m_lock;
|
||||
wxCriticalSection m_lock;
|
||||
|
||||
public:
|
||||
|
||||
@ -305,24 +305,19 @@ public:
|
||||
void Init()
|
||||
{
|
||||
m_index = 0;
|
||||
m_lock = 0; //simple lock
|
||||
}
|
||||
|
||||
__forceinline bool Pop(u32& res)
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
if(!m_index)
|
||||
{
|
||||
m_lock = 0; //release lock
|
||||
return false;
|
||||
}
|
||||
res = m_value[--m_index];
|
||||
m_value[m_index] = 0;
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -342,16 +337,12 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
if(m_index >= max_count)
|
||||
{
|
||||
m_lock = 0; //release lock
|
||||
return false;
|
||||
}
|
||||
m_value[m_index++] = value;
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -370,14 +361,11 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
if(m_index >= max_count)
|
||||
m_value[max_count-1] = value; //last message is overwritten
|
||||
else
|
||||
m_value[m_index++] = value;
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
}
|
||||
else
|
||||
{ //lock-free
|
||||
@ -389,14 +377,11 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
if(m_index >= max_count)
|
||||
m_value[max_count-1] |= value; //last message is logically ORed
|
||||
else
|
||||
m_value[m_index++] = value;
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -412,8 +397,7 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
if(!m_index)
|
||||
res = 0; //result is undefined
|
||||
else
|
||||
@ -421,8 +405,6 @@ public:
|
||||
res = m_value[--m_index];
|
||||
m_value[m_index] = 0;
|
||||
}
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
}
|
||||
else
|
||||
{ //lock-free
|
||||
@ -436,24 +418,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetCount() const
|
||||
__forceinline u32 GetCount()
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
while (m_lock);
|
||||
_mm_lfence();
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
return m_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
return m_index;
|
||||
}
|
||||
|
||||
u32 GetFreeCount() const
|
||||
__forceinline u32 GetFreeCount()
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
while (m_lock);
|
||||
_mm_lfence();
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
return max_count - m_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return max_count - m_index;
|
||||
}
|
||||
return max_count - m_index;
|
||||
}
|
||||
|
||||
void SetValue(u32 value)
|
||||
|
@ -196,6 +196,11 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
|
||||
res[idx].mount = "/app_home/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(GameDir)\\..\\";
|
||||
res[idx].mount = "/dev_bdvd/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "";
|
||||
res[idx].mount = "/host_root/";
|
||||
|
@ -141,10 +141,10 @@ struct Pad
|
||||
, m_device_capability(device_capability)
|
||||
, m_device_type(device_type)
|
||||
|
||||
, m_analog_left_x(0)
|
||||
, m_analog_left_y(0)
|
||||
, m_analog_right_x(0)
|
||||
, m_analog_right_y(0)
|
||||
, m_analog_left_x(128)
|
||||
, m_analog_left_y(128)
|
||||
, m_analog_right_x(128)
|
||||
, m_analog_right_y(128)
|
||||
|
||||
, m_press_right(0)
|
||||
, m_press_left(0)
|
||||
|
@ -90,6 +90,7 @@ static const g_module_list[] =
|
||||
{0x0050, "cellSpursJq"},
|
||||
{0x0052, "cellPngEnc"},
|
||||
{0x0053, "cellMusicDecode2"},
|
||||
{0x0054, "cellSync"},
|
||||
{0x0055, "cellSync2"},
|
||||
{0x0056, "cellNpUtil"},
|
||||
{0x0057, "cellRudp"},
|
||||
|
@ -17,145 +17,532 @@ enum
|
||||
CELL_PAMF_ERROR_EP_NOT_FOUND = 0x80610507,
|
||||
};
|
||||
|
||||
int cellPamfGetHeaderSize(mem8_ptr_t pAddr, u64 fileSize, mem64_t pSize)
|
||||
// PamfReaderInitialize Attribute Flags
|
||||
enum
|
||||
{
|
||||
CELL_PAMF_ATTRIBUTE_VERIFY_ON = 1,
|
||||
CELL_PAMF_ATTRIBUTE_MINIMUM_HEADER = 2,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
CELL_PAMF_STREAM_TYPE_AVC = 0,
|
||||
CELL_PAMF_STREAM_TYPE_M2V = 1,
|
||||
CELL_PAMF_STREAM_TYPE_ATRAC3PLUS = 2,
|
||||
CELL_PAMF_STREAM_TYPE_PAMF_LPCM = 3,
|
||||
CELL_PAMF_STREAM_TYPE_AC3 = 4,
|
||||
CELL_PAMF_STREAM_TYPE_USER_DATA = 5,
|
||||
CELL_PAMF_STREAM_TYPE_VIDEO = 20,
|
||||
CELL_PAMF_STREAM_TYPE_AUDIO = 21,
|
||||
} CellPamfStreamType;
|
||||
|
||||
// Timestamp information (time in increments of 90 kHz)
|
||||
struct CellCodecTimeStamp {
|
||||
be_t<u32> upper;
|
||||
be_t<u32> lower;
|
||||
};
|
||||
|
||||
// Entry point information
|
||||
struct CellPamfEp {
|
||||
be_t<u32> indexN;
|
||||
be_t<u32> nThRefPictureOffset;
|
||||
CellCodecTimeStamp pts;
|
||||
be_t<u64> rpnOffset;
|
||||
};
|
||||
|
||||
// Entry point iterator
|
||||
struct CellPamfEpIterator {
|
||||
be_t<bool> isPamf;
|
||||
be_t<u32> index;
|
||||
be_t<u32> num;
|
||||
be_t<u32> pCur_addr;
|
||||
};
|
||||
|
||||
struct CellCodecEsFilterId {
|
||||
be_t<u32> filterIdMajor;
|
||||
be_t<u32> filterIdMinor;
|
||||
be_t<u32> supplementalInfo1;
|
||||
be_t<u32> supplementalInfo2;
|
||||
};
|
||||
|
||||
// AVC (MPEG4 AVC Video) Specific Information
|
||||
struct CellPamfAvcInfo {
|
||||
u8 profileIdc;
|
||||
u8 levelIdc;
|
||||
u8 frameMbsOnlyFlag;
|
||||
u8 videoSignalInfoFlag;
|
||||
u8 frameRateInfo;
|
||||
u8 aspectRatioIdc;
|
||||
be_t<u16> sarWidth; //reserved
|
||||
be_t<u16> sarHeight; //reserved
|
||||
be_t<u16> horizontalSize; //multiple of 16
|
||||
be_t<u16> verticalSize; //multiple of 16
|
||||
be_t<u16> frameCropLeftOffset; //reserved
|
||||
be_t<u16> frameCropRightOffset; //reserved
|
||||
be_t<u16> frameCropTopOffset; //reserved
|
||||
be_t<u16> frameCropBottomOffset;
|
||||
u8 videoFormat; //reserved
|
||||
u8 videoFullRangeFlag;
|
||||
u8 colourPrimaries;
|
||||
u8 transferCharacteristics;
|
||||
u8 matrixCoefficients;
|
||||
u8 entropyCodingModeFlag; //reserved
|
||||
u8 deblockingFilterFlag;
|
||||
u8 minNumSlicePerPictureIdc; //reserved
|
||||
u8 nfwIdc; //reserved
|
||||
u8 maxMeanBitrate; //reserved
|
||||
};
|
||||
|
||||
// M2V (MPEG2 Video) Specific Information
|
||||
struct CellPamfM2vInfo {
|
||||
u8 profileAndLevelIndication;
|
||||
be_t<bool> progressiveSequence;
|
||||
u8 videoSignalInfoFlag;
|
||||
u8 frameRateInfo;
|
||||
u8 aspectRatioIdc;
|
||||
be_t<u16> sarWidth;
|
||||
be_t<u16> sarHeight;
|
||||
be_t<u16> horizontalSize;
|
||||
be_t<u16> verticalSize;
|
||||
be_t<u16> horizontalSizeValue;
|
||||
be_t<u16> verticalSizeValue;
|
||||
u8 videoFormat;
|
||||
u8 videoFullRangeFlag;
|
||||
u8 colourPrimaries;
|
||||
u8 transferCharacteristics;
|
||||
u8 matrixCoefficients;
|
||||
};
|
||||
|
||||
// LPCM Audio Specific Information
|
||||
struct CellPamfLpcmInfo {
|
||||
be_t<u32> samplingFrequency;
|
||||
u8 numberOfChannels;
|
||||
be_t<u16> bitsPerSample;
|
||||
};
|
||||
|
||||
// ATRAC3+ Audio Specific Information
|
||||
struct CellPamfAtrac3plusInfo {
|
||||
be_t<u32> samplingFrequency;
|
||||
u8 numberOfChannels;
|
||||
};
|
||||
|
||||
// AC3 Audio Specific Information
|
||||
struct CellPamfAc3Info {
|
||||
be_t<u32> samplingFrequency;
|
||||
u8 numberOfChannels;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1) //file data
|
||||
|
||||
struct PamfStreamHeader_AVC { //AVC information
|
||||
u8 profileIdc;
|
||||
u8 levelIdc;
|
||||
u8 unk0;
|
||||
u8 unk1; //1
|
||||
u32 unk2; //0
|
||||
be_t<u16> horizontalSize; //divided by 16
|
||||
be_t<u16> verticalSize; //divided by 16
|
||||
u32 unk3; //0
|
||||
u32 unk4; //0
|
||||
u8 unk5; //0xA0
|
||||
u8 unk6; //1
|
||||
u8 unk7; //1
|
||||
u8 unk8; //1
|
||||
u8 unk9; //0xB0
|
||||
u8 unk10;
|
||||
u16 unk11; //0
|
||||
u32 unk12; //0
|
||||
};
|
||||
|
||||
struct PamfStreamHeader //48 bytes
|
||||
{
|
||||
//TODO: look for correct beginning of stream header
|
||||
u8 type; //0x1B for video (AVC), 0xDC ATRAC3+, 0x80 LPCM, 0xDD userdata
|
||||
u8 unk; //0
|
||||
u16 unk0; //0
|
||||
//TODO: examine stream_ch encoding
|
||||
u8 stream_id;
|
||||
u8 private_stream_id;
|
||||
u16 unk1; //?????
|
||||
be_t<u32> ep_offset; //offset of ep section in header
|
||||
be_t<u32> ep_num; //count of ep
|
||||
//union { //32 bytes
|
||||
PamfStreamHeader_AVC AVC;
|
||||
//};
|
||||
};
|
||||
|
||||
struct PamfHeader
|
||||
{
|
||||
u32 magic; //"PAMF"
|
||||
u32 version; //"0041" (is it const?)
|
||||
be_t<u32> data_offset; //== 2048 >> 11, PAMF headers seem to be always 2048 bytes in size
|
||||
be_t<u32> data_size; //== ((fileSize - 2048) >> 11)
|
||||
u64 reserved[8];
|
||||
be_t<u32> table_size; //== size of mapping-table
|
||||
u16 reserved1;
|
||||
be_t<u16> start_pts_high;
|
||||
be_t<u32> start_pts_low; //Presentation Time Stamp (start)
|
||||
be_t<u16> end_pts_high;
|
||||
be_t<u32> end_pts_low; //Presentation Time Stamp (end)
|
||||
be_t<u32> mux_rate_max; //== 0x01D470 (400 bps per unit, == 48000000 bps)
|
||||
be_t<u32> mux_rate_min; //== 0x0107AC (?????)
|
||||
u16 reserved2; // ?????
|
||||
be_t<u16> stream_count; //total stream count
|
||||
be_t<u16> unk1; //== 1 (?????)
|
||||
be_t<u32> table_data_size; //== table_size - 0x20 == 0x14 + (0x30 * total_stream_num) (?????)
|
||||
//TODO: check relative offset of stream structs (could be from 0x0c to 0x14, currently 0x14)
|
||||
be_t<u16> start_pts_high2; //????? (probably same values)
|
||||
be_t<u32> start_pts_low2; //?????
|
||||
be_t<u16> end_pts_high2; //?????
|
||||
be_t<u32> end_pts_low2; //?????
|
||||
be_t<u32> unk2; //== 0x10000 (?????)
|
||||
be_t<u16> unk3; // ?????
|
||||
be_t<u16> unk4; // == total_stream_num
|
||||
//==========================
|
||||
PamfStreamHeader stream_headers[256];
|
||||
};
|
||||
|
||||
struct PamfEpHeader { //12 bytes
|
||||
be_t<u16> value0; //mixed indexN (probably left 2 bits) and nThRefPictureOffset
|
||||
be_t<u16> pts_high;
|
||||
be_t<u32> pts_low;
|
||||
be_t<u32> rpnOffset;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct CellPamfReader
|
||||
{
|
||||
//this struct can be used in any way, if it is not accessed directly by virtual CPU
|
||||
//be_t<u64> internalData[16];
|
||||
u32 pAddr;
|
||||
int stream;
|
||||
u64 fileSize;
|
||||
u32 internalData[28];
|
||||
};
|
||||
|
||||
int cellPamfGetHeaderSize(mem_ptr_t<PamfHeader> pAddr, u64 fileSize, mem64_t pSize)
|
||||
{
|
||||
cellPamf.Warning("cellPamfGetHeaderSize(pAddr=0x%x, fileSize=%d, pSize_addr=0x%x)",
|
||||
pAddr.GetAddr(), fileSize, pSize.GetAddr());
|
||||
|
||||
pSize = 2048; // PAMF headers seem to be always 2048 bytes in size
|
||||
const u64 size = (u64)pAddr->data_offset << 11;
|
||||
pSize = size;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfGetHeaderSize2(mem8_ptr_t pAddr, u64 fileSize, u32 attribute, mem64_t pSize)
|
||||
int cellPamfGetHeaderSize2(mem_ptr_t<PamfHeader> pAddr, u64 fileSize, u32 attribute, mem64_t pSize)
|
||||
{
|
||||
cellPamf.Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=%d, pSize_addr=0x%x)",
|
||||
cellPamf.Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=0x%x, pSize_addr=0x%x)",
|
||||
pAddr.GetAddr(), fileSize, attribute, pSize.GetAddr());
|
||||
|
||||
pSize = 2048; // PAMF headers seem to be always 2048 bytes in size
|
||||
const u64 size = (u64)pAddr->data_offset << 11;
|
||||
pSize = size;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfGetStreamOffsetAndSize()
|
||||
int cellPamfGetStreamOffsetAndSize(mem_ptr_t<PamfHeader> pAddr, u64 fileSize, mem64_t pOffset, mem64_t pSize)
|
||||
{
|
||||
cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)",
|
||||
pAddr.GetAddr(), fileSize, pOffset.GetAddr(), pSize.GetAddr());
|
||||
|
||||
pOffset = (u64)pAddr->data_offset << 11;
|
||||
pSize = (u64)pAddr->data_size << 11;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfVerify(mem_ptr_t<PamfHeader> pAddr, u64 fileSize)
|
||||
{
|
||||
cellPamf.Warning("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.GetAddr(), fileSize);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderInitialize(mem_ptr_t<CellPamfReader> pSelf, mem_ptr_t<PamfHeader> pAddr, u64 fileSize, u32 attribute)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderInitialize(pSelf=0x%x, pAddr=0x%x, fileSize=%d, attribute=0x%x)",
|
||||
pSelf.GetAddr(), pAddr.GetAddr(), fileSize, attribute);
|
||||
|
||||
if (fileSize)
|
||||
{
|
||||
pSelf->fileSize = fileSize;
|
||||
}
|
||||
else //if fileSize is unknown
|
||||
{
|
||||
pSelf->fileSize = ((u64)pAddr->data_offset << 11) + ((u64)pAddr->data_size << 11);
|
||||
}
|
||||
pSelf->pAddr = pAddr.GetAddr();
|
||||
|
||||
if (attribute & CELL_PAMF_ATTRIBUTE_VERIFY_ON)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
pSelf->stream = 0; //??? currently set stream
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetPresentationStartTime(mem_ptr_t<CellPamfReader> pSelf, mem_ptr_t<CellCodecTimeStamp> pTimeStamp)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetPresentationStartTime(pSelf=0x%x, pTimeStamp_addr=0x%x)",
|
||||
pSelf.GetAddr(), pTimeStamp.GetAddr());
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
pTimeStamp->upper = pAddr->start_pts_high;
|
||||
pTimeStamp->lower = pAddr->start_pts_low;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetPresentationEndTime(mem_ptr_t<CellPamfReader> pSelf, mem_ptr_t<CellCodecTimeStamp> pTimeStamp)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetPresentationEndTime(pSelf=0x%x, pTimeStamp_addr=0x%x)",
|
||||
pSelf.GetAddr(), pTimeStamp.GetAddr());
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
pTimeStamp->upper = pAddr->end_pts_high;
|
||||
pTimeStamp->lower = pAddr->end_pts_low;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetMuxRateBound(mem_ptr_t<CellPamfReader> pSelf)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetMuxRateBound(pSelf=0x%x)", pSelf.GetAddr());
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
return pAddr->mux_rate_max;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetNumberOfStreams(mem_ptr_t<CellPamfReader> pSelf)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetNumberOfStreams(pSelf=0x%x)", pSelf.GetAddr());
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
return pAddr->stream_count;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t<CellPamfReader> pSelf, u8 streamType)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=0x%x, streamType=%d)",
|
||||
pSelf.GetAddr(), streamType);
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
|
||||
int counts[6] = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
for (int i = 0; i < pAddr->stream_count; i++)
|
||||
{
|
||||
switch (pAddr->stream_headers[i].type)
|
||||
{
|
||||
case 0x1b: counts[CELL_PAMF_STREAM_TYPE_AVC]++; break;
|
||||
case 0xdc: counts[CELL_PAMF_STREAM_TYPE_ATRAC3PLUS]++; break;
|
||||
case 0x80: counts[CELL_PAMF_STREAM_TYPE_PAMF_LPCM]++; break;
|
||||
case 0xdd: counts[CELL_PAMF_STREAM_TYPE_USER_DATA]++; break;
|
||||
default:
|
||||
cellPamf.Error("cellPamfReaderGetNumberOfSpecificStreams: unsupported stream type found(0x%x)",
|
||||
pAddr->stream_headers[i].type);
|
||||
}
|
||||
}
|
||||
|
||||
switch (streamType)
|
||||
{
|
||||
case CELL_PAMF_STREAM_TYPE_AVC:
|
||||
case CELL_PAMF_STREAM_TYPE_M2V:
|
||||
case CELL_PAMF_STREAM_TYPE_ATRAC3PLUS:
|
||||
case CELL_PAMF_STREAM_TYPE_PAMF_LPCM:
|
||||
case CELL_PAMF_STREAM_TYPE_AC3:
|
||||
case CELL_PAMF_STREAM_TYPE_USER_DATA:
|
||||
return counts[streamType];
|
||||
case CELL_PAMF_STREAM_TYPE_VIDEO:
|
||||
return counts[CELL_PAMF_STREAM_TYPE_AVC] + counts[CELL_PAMF_STREAM_TYPE_M2V];
|
||||
case CELL_PAMF_STREAM_TYPE_AUDIO:
|
||||
return counts[CELL_PAMF_STREAM_TYPE_ATRAC3PLUS] +
|
||||
counts[CELL_PAMF_STREAM_TYPE_PAMF_LPCM] + counts[CELL_PAMF_STREAM_TYPE_AC3];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int cellPamfReaderSetStreamWithIndex(mem_ptr_t<CellPamfReader> pSelf, u8 streamIndex)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderSetStreamWithIndex(pSelf=0x%x, streamIndex=%d)",
|
||||
pSelf.GetAddr(), streamIndex);
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
if (streamIndex < pAddr->stream_count)
|
||||
{
|
||||
pSelf->stream = streamIndex;
|
||||
return CELL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_PAMF_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
int cellPamfReaderSetStreamWithTypeAndChannel(mem_ptr_t<CellPamfReader> pSelf, u8 streamType, u8 ch)
|
||||
{
|
||||
cellPamf.Error("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=0x%x, streamType=%d, ch=%d)",
|
||||
pSelf.GetAddr(), streamType, ch);
|
||||
//TODO
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderSetStreamWithTypeAndIndex(mem_ptr_t<CellPamfReader> pSelf, u8 streamType, u8 streamIndex)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=0x%x, streamType=%d, streamIndex=%d)",
|
||||
pSelf.GetAddr(), streamType, streamIndex);
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
|
||||
u32 found = 0;
|
||||
|
||||
for (int i = 0; i < pAddr->stream_count; i++)
|
||||
{
|
||||
switch (pAddr->stream_headers[i].type)
|
||||
{
|
||||
case 0x1b: if (streamType == CELL_PAMF_STREAM_TYPE_AVC ||
|
||||
streamType == CELL_PAMF_STREAM_TYPE_VIDEO) found++; break;
|
||||
case 0xdc: if (streamType == CELL_PAMF_STREAM_TYPE_ATRAC3PLUS ||
|
||||
streamType == CELL_PAMF_STREAM_TYPE_AUDIO) found++; break;
|
||||
case 0x80: if (streamType == CELL_PAMF_STREAM_TYPE_PAMF_LPCM ||
|
||||
streamType == CELL_PAMF_STREAM_TYPE_AUDIO) found++; break;
|
||||
case 0xdd: if (streamType == CELL_PAMF_STREAM_TYPE_USER_DATA) found++; break;
|
||||
default:
|
||||
cellPamf.Error("cellPamfReaderSetStreamWithTypeAndIndex: unsupported stream type found(0x%x)",
|
||||
pAddr->stream_headers[i].type);
|
||||
}
|
||||
if (found > streamIndex)
|
||||
{
|
||||
pSelf->stream = i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_PAMF_ERROR_STREAM_NOT_FOUND;
|
||||
}
|
||||
|
||||
int cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, mem_ptr_t<CellCodecEsFilterId> pEsFilterId)
|
||||
{
|
||||
cellPamf.Error("cellPamfStreamTypeToEsFilterId(type=%d, ch=%d, pEsFilterId_addr=0x%x)",
|
||||
type, ch, pEsFilterId.GetAddr());
|
||||
//TODO
|
||||
pEsFilterId->filterIdMajor = 0;
|
||||
pEsFilterId->filterIdMinor = 0;
|
||||
pEsFilterId->supplementalInfo1 = 0;
|
||||
pEsFilterId->supplementalInfo2 = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetStreamIndex(mem_ptr_t<CellPamfReader> pSelf)
|
||||
{
|
||||
return pSelf->stream;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetStreamTypeAndChannel(mem_ptr_t<CellPamfReader> pSelf, mem8_t pType, mem8_t pCh)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetStreamTypeAndChannel(pSelf=0x%x (stream=%d), pType_addr=0x%x, pCh_addr=0x%x",
|
||||
pSelf.GetAddr(), pSelf->stream, pType.GetAddr(), pCh.GetAddr());
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
|
||||
switch (pAddr->stream_headers[pSelf->stream].type)
|
||||
{
|
||||
case 0x1b: pType = CELL_PAMF_STREAM_TYPE_AVC; break;
|
||||
case 0xdc: pType = CELL_PAMF_STREAM_TYPE_ATRAC3PLUS; break;
|
||||
case 0x80: pType = CELL_PAMF_STREAM_TYPE_PAMF_LPCM; break;
|
||||
case 0xdd: pType = CELL_PAMF_STREAM_TYPE_USER_DATA; break;
|
||||
default:
|
||||
pType = 0;
|
||||
cellPamf.Error("cellPamfReaderGetStreamTypeAndChannel: unsupported stream type found(0x%x)",
|
||||
pAddr->stream_headers[pSelf->stream].type);
|
||||
}
|
||||
|
||||
//TODO: get correct channel value
|
||||
pCh = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetEsFilterId(mem_ptr_t<CellPamfReader> pSelf, mem_ptr_t<CellCodecEsFilterId> pEsFilterId)
|
||||
{
|
||||
cellPamf.Error("cellPamfReaderGetEsFilterId(pSelf=0x%x (stream=%d), pEsFilterId_addr=0x%x)",
|
||||
pSelf.GetAddr(), pSelf->stream, pEsFilterId.GetAddr());
|
||||
//TODO
|
||||
pEsFilterId->filterIdMajor = 0;
|
||||
pEsFilterId->filterIdMinor = 0;
|
||||
pEsFilterId->supplementalInfo1 = 0;
|
||||
pEsFilterId->supplementalInfo2 = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetStreamInfo(mem_ptr_t<CellPamfReader> pSelf, u32 pInfo_addr, u32 size)
|
||||
{
|
||||
cellPamf.Error("cellPamfReaderGetStreamInfo(pSelf=0x%x (stream=%d), pInfo_addr=0x%x, size=%d)",
|
||||
pSelf.GetAddr(), pSelf->stream, pInfo_addr, size);
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
|
||||
//TODO
|
||||
switch (pAddr->stream_headers[pSelf->stream].type)
|
||||
{
|
||||
case 0x1b: /*CELL_PAMF_STREAM_TYPE_AVC*/
|
||||
{
|
||||
//target structure
|
||||
mem_ptr_t<CellPamfAvcInfo> pInfo(pInfo_addr);
|
||||
//file data structure (fixed offset 0x98, fixed step 0x30)
|
||||
mem_ptr_t<PamfStreamHeader_AVC> pAVC(pSelf->pAddr + 0x98 + pSelf->stream * 0x30);
|
||||
if (size != sizeof(CellPamfAvcInfo)) {
|
||||
cellPamf.Error("cellPamfReaderGetStreamInfo: incorrect AVC data size(%d)", size);
|
||||
break;
|
||||
}
|
||||
//TODO
|
||||
pInfo->profileIdc = pAVC->profileIdc;
|
||||
pInfo->levelIdc = pAVC->levelIdc;
|
||||
|
||||
pInfo->horizontalSize = pAVC->horizontalSize;
|
||||
pInfo->verticalSize = pAVC->verticalSize;
|
||||
}
|
||||
break;
|
||||
case 0xdc: /*CELL_PAMF_STREAM_TYPE_ATRAC3PLUS*/ break;
|
||||
case 0x80: /*CELL_PAMF_STREAM_TYPE_PAMF_LPCM*/ break;
|
||||
case 0xdd: /*CELL_PAMF_STREAM_TYPE_USER_DATA*/ break;
|
||||
default:
|
||||
cellPamf.Error("cellPamfReaderGetStreamInfo: unsupported stream type found(0x%x)",
|
||||
pAddr->stream_headers[pSelf->stream].type);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetNumberOfEp(mem_ptr_t<CellPamfReader> pSelf)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetNumberOfEp(pSelf=0x%x (stream=%d))",
|
||||
pSelf.GetAddr(), pSelf->stream);
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
return pAddr->stream_headers[pSelf->stream].ep_num;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetEpIteratorWithIndex(mem_ptr_t<CellPamfReader> pSelf, u32 epIndex, mem_ptr_t<CellPamfEpIterator> pIt)
|
||||
{
|
||||
cellPamf.Warning("cellPamfReaderGetEpIteratorWithIndex(pSelf=0x%x (stream=%d), epIndex=%d, pIt_addr=0x%x)",
|
||||
pSelf.GetAddr(), pSelf->stream, epIndex, pIt.GetAddr());
|
||||
|
||||
const mem_ptr_t<PamfHeader> pAddr(pSelf->pAddr);
|
||||
//TODO:
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetEpIteratorWithTimeStamp(mem_ptr_t<CellPamfReader> pSelf, mem_ptr_t<CellCodecTimeStamp> pTimeStamp, mem_ptr_t<CellPamfEpIterator> pIt)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfVerify()
|
||||
int cellPamfEpIteratorGetEp(mem_ptr_t<CellPamfEpIterator> pIt, mem_ptr_t<CellPamfEp> pEp)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderInitialize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetPresentationStartTime()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetPresentationEndTime()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetMuxRateBound()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetNumberOfStreams()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetNumberOfSpecificStreams()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderSetStreamWithIndex()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderSetStreamWithTypeAndChannel()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderSetStreamWithTypeAndIndex()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfStreamTypeToEsFilterId()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetStreamIndex()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetStreamTypeAndChannel()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetEsFilterId()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetStreamInfo()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetNumberOfEp()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetEpIteratorWithIndex()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetEpIteratorWithTimeStamp()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfEpIteratorGetEp()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfEpIteratorMove()
|
||||
int cellPamfEpIteratorMove(mem_ptr_t<CellPamfEpIterator> pIt, int steps, mem_ptr_t<CellPamfEp> pEp)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPamf);
|
||||
return CELL_OK;
|
||||
|
100
rpcs3/Emu/SysCalls/Modules/cellSync.cpp
Normal file
100
rpcs3/Emu/SysCalls/Modules/cellSync.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
void cellSync_init();
|
||||
Module cellSync(0x0054, cellSync_init);
|
||||
|
||||
// Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_SYNC_ERROR_AGAIN = 0x80410101,
|
||||
CELL_SYNC_ERROR_INVAL = 0x80410102,
|
||||
CELL_SYNC_ERROR_NOMEM = 0x80410104,
|
||||
CELL_SYNC_ERROR_DEADLK = 0x80410108,
|
||||
CELL_SYNC_ERROR_PERM = 0x80410109,
|
||||
CELL_SYNC_ERROR_BUSY = 0x8041010A,
|
||||
CELL_SYNC_ERROR_STAT = 0x8041010F,
|
||||
CELL_SYNC_ERROR_ALIGN = 0x80410110,
|
||||
CELL_SYNC_ERROR_NULL_POINTER = 0x80410111,
|
||||
CELL_SYNC_ERROR_NOT_SUPPORTED_THREAD = 0x80410112,
|
||||
CELL_SYNC_ERROR_NO_NOTIFIER = 0x80410113,
|
||||
CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114,
|
||||
};
|
||||
|
||||
int cellSyncMutexInitialize(mem32_t mutex)
|
||||
{
|
||||
const u32 mutex_addr = mutex.GetAddr();
|
||||
if (!mutex_addr)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
mutex = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncMutexLock(mem32_t mutex)
|
||||
{
|
||||
const u32 mutex_addr = mutex.GetAddr();
|
||||
if (!mutex_addr)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
while (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24));
|
||||
//need to check how does SPU work with these mutexes, also obtainment order is not guaranteed
|
||||
_mm_lfence();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncMutexTryLock(mem32_t mutex)
|
||||
{
|
||||
const u32 mutex_addr = mutex.GetAddr();
|
||||
if (!mutex_addr)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
//check cellSyncMutexLock
|
||||
if (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24))
|
||||
{
|
||||
return CELL_SYNC_ERROR_BUSY;
|
||||
}
|
||||
_mm_lfence();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncMutexUnlock(mem32_t mutex)
|
||||
{
|
||||
const u32 mutex_addr = mutex.GetAddr();
|
||||
if (!mutex_addr)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
//check cellSyncMutexLock
|
||||
_mm_sfence();
|
||||
_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 0);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void cellSync_init()
|
||||
{
|
||||
cellSync.AddFunc(0xa9072dee, cellSyncMutexInitialize);
|
||||
cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock);
|
||||
cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock);
|
||||
cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock);
|
||||
}
|
@ -91,16 +91,22 @@ int sys_spu_image_import(mem_ptr_t<sys_spu_image> img, u32 src, u32 type)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_image_close(mem_ptr_t<sys_spu_image> img)
|
||||
{
|
||||
sysPrxForUser.Warning("sys_spu_image_close(img=0x%x)", img.GetAddr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_load(int id, u32 path_addr, mem32_t entry)
|
||||
{
|
||||
const wxString path = Memory.ReadString(path_addr).mb_str();
|
||||
sysPrxForUser.Warning("sys_raw_spu_load(id=0x%x, path=0x%x [%s], entry_addr=0x%x)",
|
||||
id, path_addr, path, entry.GetAddr());
|
||||
id, path_addr, path.c_str(), entry.GetAddr());
|
||||
|
||||
vfsFile f(path.c_str());
|
||||
if(!f.IsOpened())
|
||||
{
|
||||
sysPrxForUser.Error("sys_raw_spu_load error: '%s' not found!", path);
|
||||
sysPrxForUser.Error("sys_raw_spu_load error: '%s' not found!", path.c_str());
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
@ -166,6 +172,7 @@ void sysPrxForUser_init()
|
||||
sysPrxForUser.AddFunc(0x1ed454ce, sys_spu_elf_get_information);
|
||||
sysPrxForUser.AddFunc(0xdb6b3250, sys_spu_elf_get_segments);
|
||||
sysPrxForUser.AddFunc(0xebe5f72f, sys_spu_image_import);
|
||||
sysPrxForUser.AddFunc(0xe0da8efd, sys_spu_image_close);
|
||||
|
||||
sysPrxForUser.AddFunc(0x893305fa, sys_raw_spu_load);
|
||||
sysPrxForUser.AddFunc(0xb995662e, sys_raw_spu_image_load);
|
||||
|
@ -155,4 +155,6 @@ void sys_fs_init()
|
||||
sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate);
|
||||
sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate);
|
||||
sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize);
|
||||
|
||||
sys_fs.AddFunc(0xc1c507e7, cellFsAioRead);
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ void sys_io_init()
|
||||
sys_io.AddFunc(0x3aaad464, cellPadGetInfo);
|
||||
sys_io.AddFunc(0xa703a51d, cellPadGetInfo2);
|
||||
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);
|
||||
sys_io.AddFunc(0x0e2dfaad, cellPadInfoPressMode);
|
||||
sys_io.AddFunc(0x78200559, cellPadInfoSensorMode);
|
||||
|
||||
sys_io.AddFunc(0x433f6ec0, cellKbInit);
|
||||
sys_io.AddFunc(0xbfce3285, cellKbEnd);
|
||||
|
@ -95,8 +95,9 @@ static func_caller* sc_table[1024] =
|
||||
null_func, bind_func(sys_spu_image_open), null_func, null_func, null_func, //159
|
||||
bind_func(sys_raw_spu_create), null_func, null_func, null_func, null_func, //164
|
||||
null_func, null_func, null_func, null_func, bind_func(sys_spu_initialize), //169
|
||||
bind_func(sys_spu_thread_group_create), bind_func(sys_spu_thread_set_argument), bind_func(sys_spu_thread_initialize), bind_func(sys_spu_thread_group_start), null_func, //174
|
||||
null_func, null_func, null_func, null_func, null_func, //179
|
||||
bind_func(sys_spu_thread_group_create), bind_func(sys_spu_thread_set_argument), bind_func(sys_spu_thread_initialize), //172
|
||||
bind_func(sys_spu_thread_group_start), bind_func(sys_spu_thread_group_suspend), //174
|
||||
null_func, null_func, null_func, bind_func(sys_spu_thread_group_join), null_func, //179
|
||||
null_func, bind_func(sys_spu_thread_write_ls), bind_func(sys_spu_thread_read_ls), null_func, bind_func(sys_spu_thread_write_snr), //184
|
||||
null_func, null_func, bind_func(sys_spu_thread_set_spu_cfg), bind_func(sys_spu_thread_get_spu_cfg), null_func, //189
|
||||
bind_func(sys_spu_thread_write_spu_mb), bind_func(sys_spu_thread_connect_event), null_func, null_func, null_func, //194
|
||||
|
@ -225,6 +225,7 @@ extern int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos);
|
||||
extern int cellFsFtruncate(u32 fd, u64 size);
|
||||
extern int cellFsTruncate(u32 path_addr, u64 size);
|
||||
extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size);
|
||||
extern int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t id, u32 func_addr);
|
||||
|
||||
//cellVideo
|
||||
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
|
||||
@ -244,6 +245,8 @@ extern int cellPadSetActDirect(u32 port_no, u32 param_addr);
|
||||
extern int cellPadGetInfo(u32 info_addr);
|
||||
extern int cellPadGetInfo2(u32 info_addr);
|
||||
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);
|
||||
extern int cellPadInfoPressMode(u32 port_no);
|
||||
extern int cellPadInfoSensorMode(u32 port_no);
|
||||
|
||||
//cellKb
|
||||
extern int cellKbInit(u32 max_connect);
|
||||
@ -285,9 +288,11 @@ extern int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr);
|
||||
extern int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<sys_spu_image> img, mem_ptr_t<sys_spu_thread_attribute> attr, mem_ptr_t<sys_spu_thread_argument> arg);
|
||||
extern int sys_spu_thread_set_argument(u32 id, mem_ptr_t<sys_spu_thread_argument> arg);
|
||||
extern int sys_spu_thread_group_start(u32 id);
|
||||
extern int sys_spu_thread_group_suspend(u32 id);
|
||||
extern int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu_thread_group_attribute> attr);
|
||||
extern int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
|
||||
extern int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup);
|
||||
extern int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status);
|
||||
extern int sys_raw_spu_create(mem32_t id, u32 attr_addr);
|
||||
extern int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
|
||||
extern int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type);
|
||||
|
@ -385,3 +385,49 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
std::atomic<u32> g_FsAioReadID = 0;
|
||||
|
||||
int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, u32 func_addr)
|
||||
{
|
||||
sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x, id_addr: 0x%x, func_addr: 0x%x)", aio.GetAddr(), aio_id.GetAddr(), func_addr);
|
||||
|
||||
ID id;
|
||||
u32 fd = (u32)aio->fd;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsFileBase& orig_file = *(vfsFileBase*)id.m_data;
|
||||
//open the file again (to prevent access conflicts roughly)
|
||||
vfsStream file = *Emu.GetVFS().Open(orig_file.GetPath(), vfsRead);
|
||||
|
||||
u64 nbytes = (u64)aio->size;
|
||||
const u32 buf_addr = (u32)aio->buf_addr;
|
||||
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
||||
{
|
||||
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
|
||||
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
||||
}
|
||||
|
||||
//read data immediately (actually it should be read in special thread)
|
||||
file.Seek((u64)aio->offset);
|
||||
const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||
file.Close();
|
||||
|
||||
//get a unique id for the callback
|
||||
const u32 xid = g_FsAioReadID++;
|
||||
aio_id = xid;
|
||||
|
||||
//TODO: init the callback
|
||||
/*CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
new_thread.SetEntry(func_addr);
|
||||
new_thread.SetPrio(1001);
|
||||
new_thread.SetStackSize(0x10000);
|
||||
new_thread.SetName("FsAioReadCallback");
|
||||
new_thread.SetArg(0, aio.GetAddr()); //xaio
|
||||
new_thread.SetArg(1, CELL_OK); //error code
|
||||
new_thread.SetArg(2, xid); //xid (unique id)
|
||||
new_thread.SetArg(3, res); //size (bytes read)
|
||||
new_thread.Run();
|
||||
new_thread.Exec();*/
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -84,3 +84,12 @@ struct CellFsDirent
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
struct CellFsAio
|
||||
{
|
||||
be_t<u32> fd;
|
||||
be_t<u64> offset;
|
||||
be_t<u32> buf_addr;
|
||||
be_t<u64> size;
|
||||
be_t<u64> user_data;
|
||||
};
|
@ -221,3 +221,15 @@ int cellPadSetPortSetting(u32 port_no, u32 port_setting)
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPadInfoPressMode(u32 port_no)
|
||||
{
|
||||
sys_io.Log("cellPadInfoPressMode(port_no=%d)", port_no);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPadInfoSensorMode(u32 port_no)
|
||||
{
|
||||
sys_io.Log("cellPadInfoSensorMode(port_no=%d)", port_no);
|
||||
return CELL_OK;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
#include "Loader/ELF.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include <atomic>
|
||||
|
||||
static SysCallBase sc_spu("sys_spu");
|
||||
extern SysCallBase sys_event;
|
||||
@ -14,8 +15,9 @@ struct SpuGroupInfo
|
||||
{
|
||||
CPUThread* threads[g_spu_group_thr_count];
|
||||
sys_spu_thread_group_attribute& attr;
|
||||
volatile long lock;
|
||||
|
||||
SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(attr)
|
||||
SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(attr), lock(0)
|
||||
{
|
||||
memset(threads, 0, sizeof(CPUThread*) * g_spu_group_thr_count);
|
||||
}
|
||||
@ -38,14 +40,14 @@ u32 LoadSpuImage(vfsStream& stream)
|
||||
int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr)
|
||||
{
|
||||
const wxString path = Memory.ReadString(path_addr).mb_str();
|
||||
sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path);
|
||||
sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path.c_str());
|
||||
|
||||
if(!img.IsGood() || !Memory.IsGoodAddr(path_addr))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
vfsFile f(path.c_str());
|
||||
vfsFile f(path);
|
||||
if(!f.IsOpened())
|
||||
{
|
||||
sc_spu.Error("sys_spu_image_open error: '%s' not found!", path);
|
||||
@ -122,7 +124,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
|
||||
ConLog.Write("New SPU Thread:");
|
||||
ConLog.Write("ls_entry = 0x%x", ls_entry);
|
||||
ConLog.Write("name = %s", wxString(name));
|
||||
ConLog.Write("name = %s", name.c_str());
|
||||
ConLog.Write("a1 = 0x%x", a1);
|
||||
ConLog.Write("a2 = 0x%x", a2);
|
||||
ConLog.Write("a3 = 0x%x", a3);
|
||||
@ -182,6 +184,31 @@ int sys_spu_thread_group_start(u32 id)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//174
|
||||
int sys_spu_thread_group_suspend(u32 id)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_suspend(id=0x%x)", id);
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(id))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
ID& id_data = Emu.GetIdManager().GetIDData(id);
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
|
||||
|
||||
//Emu.Pause();
|
||||
for(int i=0; i<g_spu_group_thr_count; i++)
|
||||
{
|
||||
if(group_info.threads[i])
|
||||
{
|
||||
group_info.threads[i]->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//170
|
||||
int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu_thread_group_attribute> attr)
|
||||
{
|
||||
@ -197,13 +224,46 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu
|
||||
ConLog.Write("*** attr.option.ct=%d", attr->option.ct.ToLE());
|
||||
|
||||
const wxString name = Memory.ReadString(attr->name_addr, attr->name_len).mb_str();
|
||||
ConLog.Write("*** name='%s'", name);
|
||||
ConLog.Write("*** name='%s'", name.c_str());
|
||||
|
||||
id = Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group '%s'", name), new SpuGroupInfo(*attr));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//178
|
||||
int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_join(id=0x%x, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr());
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(id))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
ID& id_data = Emu.GetIdManager().GetIDData(id);
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
|
||||
|
||||
if (_InterlockedCompareExchange(&group_info.lock, 1, 0)) //get lock
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
cause = SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT;
|
||||
status = 0; //unspecified because of ALL_THREADS_EXIT
|
||||
|
||||
for(int i=0; i<g_spu_group_thr_count; i++)
|
||||
{
|
||||
if(group_info.threads[i])
|
||||
{
|
||||
while (!group_info.threads[i]->IsStopped()) Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
_InterlockedExchange(&group_info.lock, 0); //release lock
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sc_spu);
|
||||
|
@ -2,6 +2,13 @@
|
||||
|
||||
u32 LoadSpuImage(vfsStream& stream);
|
||||
|
||||
enum
|
||||
{
|
||||
SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT = 0x0001,
|
||||
SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT = 0x0002,
|
||||
SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004
|
||||
};
|
||||
|
||||
struct sys_spu_thread_group_attribute
|
||||
{
|
||||
be_t<u32> name_len;
|
||||
|
@ -277,6 +277,7 @@
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellPngDec.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellRtc.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSync.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSysutil.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />
|
||||
|
@ -358,6 +358,9 @@
|
||||
<ClCompile Include="Emu\Audio\AudioManager.cpp">
|
||||
<Filter>Emu\Audio</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSync.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Gui\RSXDebugger.cpp">
|
||||
<Filter>Gui</Filter>
|
||||
</ClCompile>
|
||||
|
Loading…
Reference in New Issue
Block a user