Parse the AX command list in the AX thread
This commit is contained in:
parent
9e813502ac
commit
7535c6d903
|
@ -20,7 +20,7 @@
|
|||
|
||||
CUCode_NewAX::CUCode_NewAX(DSPHLE* dsp_hle, u32 crc)
|
||||
: IUCode(dsp_hle, crc)
|
||||
, m_cmdlist_addr(0)
|
||||
, m_cmdlist_size(0)
|
||||
, m_axthread(&CUCode_NewAX::AXThread, this)
|
||||
{
|
||||
m_rMailHandler.PushMail(DSP_INIT);
|
||||
|
@ -29,7 +29,7 @@ CUCode_NewAX::CUCode_NewAX(DSPHLE* dsp_hle, u32 crc)
|
|||
|
||||
CUCode_NewAX::~CUCode_NewAX()
|
||||
{
|
||||
m_cmdlist_addr = (u32)-1; // Special value to signal end
|
||||
m_cmdlist_size = (u16)-1; // Special value to signal end
|
||||
NotifyAXThread();
|
||||
m_axthread.join();
|
||||
|
||||
|
@ -42,16 +42,16 @@ void CUCode_NewAX::AXThread()
|
|||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_cmdlist_mutex);
|
||||
while (m_cmdlist_addr == 0)
|
||||
while (m_cmdlist_size == 0)
|
||||
m_cmdlist_cv.wait(lk);
|
||||
}
|
||||
|
||||
if (m_cmdlist_addr == (u32)-1) // End of thread signal
|
||||
if (m_cmdlist_size == (u16)-1) // End of thread signal
|
||||
break;
|
||||
|
||||
m_processing.lock();
|
||||
HandleCommandList(m_cmdlist_addr);
|
||||
m_cmdlist_addr = 0;
|
||||
HandleCommandList();
|
||||
m_cmdlist_size = 0;
|
||||
|
||||
// Signal end of processing
|
||||
m_rMailHandler.PushMail(DSP_YIELD);
|
||||
|
@ -66,15 +66,78 @@ void CUCode_NewAX::NotifyAXThread()
|
|||
m_cmdlist_cv.notify_one();
|
||||
}
|
||||
|
||||
void CUCode_NewAX::HandleCommandList(u32 addr)
|
||||
void CUCode_NewAX::HandleCommandList()
|
||||
{
|
||||
WARN_LOG(DSPHLE, "TODO: HandleCommandList(%08x)", addr);
|
||||
u16 pb_addr_hi, pb_addr_lo;
|
||||
u32 pb_addr = 0;
|
||||
|
||||
u32 curr_idx = 0;
|
||||
bool end = false;
|
||||
while (!end)
|
||||
{
|
||||
u16 cmd = m_cmdlist[curr_idx++];
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
|
||||
// A lot of these commands are unknown, or unused in this AX HLE.
|
||||
// We still need to skip their arguments using "curr_idx += N".
|
||||
|
||||
case CMD_STUDIO_ADDR: curr_idx += 2; break;
|
||||
case CMD_UNK_01: curr_idx += 5; break;
|
||||
|
||||
case CMD_PB_ADDR:
|
||||
pb_addr_hi = m_cmdlist[curr_idx++];
|
||||
pb_addr_lo = m_cmdlist[curr_idx++];
|
||||
pb_addr = (pb_addr_hi << 16) | pb_addr_lo;
|
||||
|
||||
WARN_LOG(DSPHLE, "PB addr: %08x", pb_addr);
|
||||
break;
|
||||
|
||||
case CMD_PROCESS:
|
||||
ProcessPB(pb_addr);
|
||||
break;
|
||||
|
||||
case CMD_UNK_04: curr_idx += 4; break;
|
||||
case CMD_UNK_05: curr_idx += 4; break;
|
||||
case CMD_UNK_06: curr_idx += 2; break;
|
||||
case CMD_SBUFFER_ADDR: curr_idx += 2; break;
|
||||
case CMD_UNK_08: curr_idx += 10; break; // TODO: check
|
||||
case CMD_UNK_09: curr_idx += 2; break;
|
||||
case CMD_COMPRESSOR_TABLE_ADDR: curr_idx += 2; break;
|
||||
case CMD_UNK_0B: break; // TODO: check other versions
|
||||
case CMD_UNK_0C: break; // TODO: check other versions
|
||||
case CMD_UNK_0D: curr_idx += 2; break;
|
||||
case CMD_UNK_0E: curr_idx += 4; break;
|
||||
|
||||
case CMD_END:
|
||||
end = true;
|
||||
break;
|
||||
|
||||
case CMD_UNK_10: curr_idx += 4; break;
|
||||
case CMD_UNK_11: curr_idx += 2; break;
|
||||
case CMD_UNK_12: curr_idx += 1; break;
|
||||
case CMD_UNK_13: curr_idx += 12; break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(DSPHLE, "Unknown command in AX cmdlist: %04x", cmd);
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CUCode_NewAX::ProcessPB(u32 pb_addr)
|
||||
{
|
||||
NOTICE_LOG(DSPHLE, "TODO: process pb %08x", pb_addr);
|
||||
}
|
||||
|
||||
void CUCode_NewAX::HandleMail(u32 mail)
|
||||
{
|
||||
// Indicates if the next message is a command list address.
|
||||
static bool next_is_cmdlist = false;
|
||||
static u16 cmdlist_size = 0;
|
||||
|
||||
bool set_next_is_cmdlist = false;
|
||||
|
||||
// Wait for DSP processing to be done before answering any mail. This is
|
||||
|
@ -84,7 +147,7 @@ void CUCode_NewAX::HandleMail(u32 mail)
|
|||
|
||||
if (next_is_cmdlist)
|
||||
{
|
||||
m_cmdlist_addr = mail;
|
||||
CopyCmdList(mail, cmdlist_size);
|
||||
NotifyAXThread();
|
||||
}
|
||||
else if (m_UploadSetupInProgress)
|
||||
|
@ -97,7 +160,7 @@ void CUCode_NewAX::HandleMail(u32 mail)
|
|||
m_rMailHandler.PushMail(DSP_RESUME);
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
}
|
||||
else if (mail == MAIL_NEWUCODE)
|
||||
else if (mail == MAIL_NEW_UCODE)
|
||||
{
|
||||
soundStream->GetMixer()->SetHLEReady(false);
|
||||
m_UploadSetupInProgress = true;
|
||||
|
@ -115,6 +178,7 @@ void CUCode_NewAX::HandleMail(u32 mail)
|
|||
{
|
||||
// A command list address is going to be sent next.
|
||||
set_next_is_cmdlist = true;
|
||||
cmdlist_size = (u16)(mail & ~MAIL_CMDLIST_MASK);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -125,6 +189,19 @@ void CUCode_NewAX::HandleMail(u32 mail)
|
|||
next_is_cmdlist = set_next_is_cmdlist;
|
||||
}
|
||||
|
||||
void CUCode_NewAX::CopyCmdList(u32 addr, u16 size)
|
||||
{
|
||||
if (size >= (sizeof (m_cmdlist) / sizeof (u16)))
|
||||
{
|
||||
ERROR_LOG(DSPHLE, "Command list at %08x is too large: size=%d", addr, size);
|
||||
return;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < size; ++i, addr += 2)
|
||||
m_cmdlist[i] = HLEMemory_Read_U16(addr);
|
||||
m_cmdlist_size = size;
|
||||
}
|
||||
|
||||
void CUCode_NewAX::MixAdd(short* out_buffer, int nsamples)
|
||||
{
|
||||
// nsamples * 2 for left and right audio channel
|
||||
|
|
|
@ -36,7 +36,7 @@ private:
|
|||
enum MailType
|
||||
{
|
||||
MAIL_RESUME = 0xCDD10000,
|
||||
MAIL_NEWUCODE = 0xCDD10001,
|
||||
MAIL_NEW_UCODE = 0xCDD10001,
|
||||
MAIL_RESET = 0xCDD10002,
|
||||
MAIL_CONTINUE = 0xCDD10003,
|
||||
|
||||
|
@ -45,9 +45,34 @@ private:
|
|||
MAIL_CMDLIST_MASK = 0xFFFF0000
|
||||
};
|
||||
|
||||
enum CmdType
|
||||
{
|
||||
CMD_STUDIO_ADDR = 0x00,
|
||||
CMD_UNK_01 = 0x01,
|
||||
CMD_PB_ADDR = 0x02,
|
||||
CMD_PROCESS = 0x03,
|
||||
CMD_UNK_04 = 0x04,
|
||||
CMD_UNK_05 = 0x05,
|
||||
CMD_UNK_06 = 0x06,
|
||||
CMD_SBUFFER_ADDR = 0x07,
|
||||
CMD_UNK_08 = 0x08,
|
||||
CMD_UNK_09 = 0x09,
|
||||
CMD_COMPRESSOR_TABLE_ADDR = 0x0A,
|
||||
CMD_UNK_0B = 0x0B,
|
||||
CMD_UNK_0C = 0x0C,
|
||||
CMD_UNK_0D = 0x0D,
|
||||
CMD_UNK_0E = 0x0E,
|
||||
CMD_END = 0x0F,
|
||||
CMD_UNK_10 = 0x10,
|
||||
CMD_UNK_11 = 0x11,
|
||||
CMD_UNK_12 = 0x12,
|
||||
CMD_UNK_13 = 0x13,
|
||||
};
|
||||
|
||||
// Volatile because it's set by HandleMail and accessed in
|
||||
// HandleCommandList, which are running in two different threads.
|
||||
volatile u32 m_cmdlist_addr;
|
||||
volatile u16 m_cmdlist[512];
|
||||
volatile u32 m_cmdlist_size;
|
||||
|
||||
std::thread m_axthread;
|
||||
|
||||
|
@ -56,12 +81,16 @@ private:
|
|||
std::condition_variable m_cmdlist_cv;
|
||||
std::mutex m_cmdlist_mutex;
|
||||
|
||||
// Copy a command list from memory to our temp buffer
|
||||
void CopyCmdList(u32 addr, u16 size);
|
||||
|
||||
// Send a notification to the AX thread to tell him a new cmdlist addr is
|
||||
// available for processing.
|
||||
void NotifyAXThread();
|
||||
|
||||
void AXThread();
|
||||
void HandleCommandList(u32 addr);
|
||||
void HandleCommandList();
|
||||
void ProcessPB(u32 pb_addr);
|
||||
};
|
||||
|
||||
#endif // !_UCODE_NEWAX_H
|
||||
|
|
Loading…
Reference in New Issue