void CassImpTargetDialog::DoDataExchange(CDataExchange* pDX) { DDX_Radio(pDX, IDC_CASSIMPTARG_BAS, fFileTypeIndex); DDX_Text(pDX, IDC_CASSIMPTARG_FILENAME, fFileName); if (pDX->m_bSaveAndValidate) { CString appName; appName.LoadString(IDS_MB_APP_NAME); if (fFileTypeIndex == kTypeBIN) { if (GetStartAddr() < 0) { MessageBox(L"The address field must be a valid 4-digit " L" hexadecimal number.", appName, MB_OK); pDX->Fail(); return; } fStartAddr = (unsigned short) GetStartAddr(); } if (fFileName.IsEmpty()) { MessageBox(L"You must enter a filename.", appName, MB_OK); pDX->Fail(); return; } } else { CWnd* pWnd; CString tmpStr; pWnd = GetDlgItem(IDC_CASSIMPTARG_BINADDR); tmpStr.Format(L"%04X", fStartAddr); pWnd->SetWindowText(tmpStr); } }
bool RawSPUThread::Read64(const u64 addr, u64* value) { if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) { return MemoryBlock::Read64(addr, value); } u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; ConLog.Error("RawSPUThread[%d]: Read64(0x%x)", m_index, offset); Emu.Pause(); return false; }
bool RawSPUThread::Write128(const u64 addr, const u128 value) { if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) { return MemoryBlock::Write128(addr, value); } u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; ConLog.Error("RawSPUThread[%d]: Write128(0x%x, 0x%llx_%llx)", m_index, offset, value._u64[1], value._u64[0]); Emu.Pause(); return false; }
u32 VirtualMemoryBlock::Map(u32 realaddr, u32 size) { assert(size); for (u32 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) { bool is_good_addr = true; // check if address is already mapped for (u32 i = 0; i<m_mapped_memory.size(); ++i) { if ((addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) || (m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size)) { is_good_addr = false; addr = m_mapped_memory[i].addr + m_mapped_memory[i].size; break; } } if (!is_good_addr) continue; m_mapped_memory.emplace_back(addr, realaddr, size); return addr; } return 0; }
bool RawSPUThread::Read32(const u64 addr, u32* value) { if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) { return MemoryBlock::Read32(addr, value); } u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; switch(offset) { case MFC_LSA_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_LSA)", m_index); *value = MFC2.LSA.GetValue(); break; case MFC_EAH_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_EAH)", m_index); *value = MFC2.EAH.GetValue(); break; case MFC_EAL_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_EAL)", m_index); *value = MFC2.EAL.GetValue(); break; case MFC_Size_Tag_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_Size_Tag)", m_index); *value = MFC2.Size_Tag.GetValue(); break; case MFC_CMDStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_CMDStatus)", m_index); *value = MFC2.CMDStatus.GetValue(); break; case MFC_QStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_QStatus)", m_index); *value = MFC2.QStatus.GetValue(); break; case Prxy_QueryType_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_QueryType)", m_index); *value = Prxy.QueryType.GetValue(); break; case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_QueryMask)", m_index); *value = Prxy.QueryMask.GetValue(); break; case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_TagStatus)", m_index); *value = Prxy.TagStatus.GetValue(); break; case SPU_Out_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Out_MBox)", m_index); SPU.Out_MBox.PopUncond(*value); //if Out_MBox is empty yet, the result will be undefined break; case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); while(!SPU.In_MBox.Pop(*value) && !Emu.IsStopped()) Sleep(1); break; case SPU_MBox_Status_offs: //ConLog.Warning("RawSPUThread[%d]: Read32(SPU_MBox_Status)", m_index); //SPU.MBox_Status.SetValue(SPU.Out_MBox.GetCount() ? SPU.MBox_Status.GetValue() | 1 : SPU.MBox_Status.GetValue() & ~1); SPU.MBox_Status.SetValue((SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8)); *value = SPU.MBox_Status.GetValue(); break; case SPU_RunCntl_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = SPU.RunCntl.GetValue(); break; case SPU_Status_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Status)", m_index); *value = SPU.Status.GetValue(); break; case SPU_NPC_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_NPC)", m_index); *value = SPU.NPC.GetValue(); break; case SPU_RdSigNotify1_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_RdSigNotify1)", m_index); *value = SPU.SNR[0].GetValue(); break; case SPU_RdSigNotify2_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_RdSigNotify2)", m_index); *value = SPU.SNR[1].GetValue(); break; default: ConLog.Error("RawSPUThread[%d]: Read32(0x%x)", m_index, offset); Emu.Pause(); break; } return true; }
bool VirtualMemoryBlock::Reserve(u32 size) { if(size + GetReservedAmount() > GetEndAddr() - GetStartAddr()) return false; m_reserve_size += size; return true; }
RawSPUThread::~RawSPUThread() { for(int i=0; i<Memory.MemoryBlocks.size(); ++i) { if(Memory.MemoryBlocks[i]->GetStartAddr() == GetStartAddr()) { Memory.MemoryBlocks.erase(Memory.MemoryBlocks.begin() + i); break; } } //Close(); }
void CassImpTargetDialog::OnAddrChange(void) { CWnd* pWnd; CString tmpStr; long val; val = GetStartAddr(); if (val < 0) val = 0; tmpStr.Format(L".%04X", val + fFileLength-1); pWnd = GetDlgItem(IDC_CASSIMPTARG_RANGE); pWnd->SetWindowText(tmpStr); }
bool RawSPUThread::Read32(const u64 addr, u32* value) { const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; switch (offset) { case MFC_CMDStatus_offs: { *value = MFC2.CMDStatus.GetValue(); break; } case MFC_QStatus_offs: { // TagStatus is not used: mask is written directly *value = MFC2.QueryMask.GetValue(); break; } case SPU_Out_MBox_offs: { // if Out_MBox is empty, the result is undefined SPU.Out_MBox.PopUncond(*value); break; } case SPU_MBox_Status_offs: { *value = (SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8); break; } case SPU_Status_offs: { *value = SPU.Status.GetValue(); break; } default: { // TODO: read value from LS if necessary (not important) LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(0x%llx)", m_index, offset); return false; } } return true; }
u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr) { if(addr) { if(!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1))) return 0; m_mapped_memory.emplace_back(addr, realaddr, size); return addr; } else { for(u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) { bool is_good_addr = true; // check if address is already mapped for(u32 i=0; i<m_mapped_memory.size(); ++i) { if((addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) || (m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size)) { is_good_addr = false; addr = m_mapped_memory[i].addr + m_mapped_memory[i].size; break; } } if(!is_good_addr) continue; m_mapped_memory.emplace_back(addr, realaddr, size); return addr; } return 0; } }
void RawSPUThread::InitRegs() { dmac.ls_offset = m_offset = GetStartAddr() + RAW_SPU_LS_OFFSET; SPUThread::InitRegs(); }
bool RawSPUThread::Write32(const u64 addr, const u32 value) { const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; switch (offset) { case MFC_LSA_offs: { MFC2.LSA.SetValue(value); break; } case MFC_EAH_offs: { MFC2.EAH.SetValue(value); break; } case MFC_EAL_offs: { MFC2.EAL.SetValue(value); break; } case MFC_Size_Tag_offs: { MFC2.Size_Tag.SetValue(value); break; } case MFC_CMDStatus_offs: { MFC2.CMDStatus.SetValue(value); EnqMfcCmd(MFC2); break; } case Prxy_QueryType_offs: { switch(value) { case 2: break; default: { LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Unknown Prxy Query Type. (prxy_query=0x%x)", m_index, value); return false; } } MFC2.QueryType.SetValue(value); // not used break; } case Prxy_QueryMask_offs: { MFC2.QueryMask.SetValue(value); // TagStatus is not used break; } case SPU_In_MBox_offs: { // if In_MBox is already full, the last message is overwritten SPU.In_MBox.PushUncond(value); break; } case SPU_RunCntl_offs: { if (value == SPU_RUNCNTL_RUNNABLE) { SPU.Status.SetValue(SPU_STATUS_RUNNING); Exec(); } else if (value == SPU_RUNCNTL_STOP) { SPU.Status.SetValue(SPU_STATUS_STOPPED); Stop(); } else { LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RunCtrl, 0x%x): unknown value", m_index, value); return false; } break; } case SPU_NPC_offs: { if (value & 3) { // least significant bit contains some interrupt flag LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(SPU_NPC_offs, 0x%x): lowest bits set", m_index, value); return false; } SPU.NPC.SetValue(value); break; } case SPU_RdSigNotify1_offs: { WriteSNR(0, value); break; } case SPU_RdSigNotify2_offs: { WriteSNR(1, value); break; } default: { // TODO: write value to LS if necessary (not important) LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(0x%llx, 0x%x)", m_index, offset, value); return false; } } return true; }
bool VirtualMemoryBlock::IsInMyRange(const u64 addr) { return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize() - GetReservedAmount(); }
static void DoLink( char *cmdline ) /**********************************/ // cmdline is only used when we are running under watfor. { #ifndef __OSI__ #ifdef __ZDOS__ signal( SIGBREAK, &TrapBreak ); /* so we can clean up */ #else signal( SIGINT, &TrapBreak ); /* so we can clean up */ #endif #endif StartTime(); DoCmdFile( cmdline ); CheckErr(); MapInit(); SetupFakeModule(); ProcObjFiles(); /* ObjPass1 */ CheckErr(); DoDefaultSystem(); if( LinkState & LIBRARIES_ADDED ) { FindLibPaths(); LinkState |= SEARCHING_LIBRARIES; ResolveUndefined(); LinkState &= ~SEARCHING_LIBRARIES; LinkState |= GENERATE_LIB_LIST; } ProcLocalImports(); DecideFormat(); SetFormat(); ConvertLazyRefs(); SetSegments(); CheckErr(); DefBSSSyms(); LinkFakeModule(); PreAddrCalcFormatSpec(); ReportUndefined(); CheckClassOrder(); CalcSegSizes(); SetStkSize(); AutoGroup(); CalcAddresses(); GetBSSSize(); GetStkAddr(); GetStartAddr(); PostAddrCalcFormatSpec(); #ifdef _RDOS if( FmtData.type & MK_RDOS ) GetRdosSegs(); #endif CheckErr(); InitLoadFile(); ObjPass2(); FiniMap(); CheckErr(); FiniLoadFile(); WritePermData(); BuildImpLib(); EndTime(); #ifndef __OSI__ #ifdef __ZDOS__ signal( SIGBREAK, SIG_IGN ); /* we're going to clean up anyway */ #else signal( SIGINT, SIG_IGN ); /* we're going to clean up anyway */ #endif #endif }
u64 MemoryBlock::FixAddr(const u64 addr) const { return addr - GetStartAddr(); }
bool RawSPUThread::Write32(const u64 addr, const u32 value) { if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) { return MemoryBlock::Write32(addr, value); } u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; switch(offset) { case MFC_LSA_offs: MFC2.LSA.SetValue(value); break; case MFC_EAH_offs: MFC2.EAH.SetValue(value); break; case MFC_EAL_offs: MFC2.EAL.SetValue(value); break; case MFC_Size_Tag_offs: MFC2.Size_Tag.SetValue(value); break; case MFC_CMDStatus_offs: MFC2.CMDStatus.SetValue(value); EnqMfcCmd(MFC2); break; case MFC_QStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_QStatus, 0x%x)", m_index, value); MFC2.QStatus.SetValue(value); break; case Prxy_QueryType_offs: { ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryType, 0x%x)", m_index, value); Prxy.QueryType.SetValue(value); switch(value) { case 2: ConLog.Warning("RawSPUThread[%d]: Prxy Query Immediate.", m_index); break; default: ConLog.Error("RawSPUThread[%d]: Unknown Prxy Query Type. (prxy_query=0x%x)", m_index, value); break; } Prxy.QueryType.SetValue(0); MFC2.QStatus.SetValue(Prxy.QueryMask.GetValue()); } break; case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryMask, 0x%x)", m_index, value); Prxy.QueryMask.SetValue(value); break; case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_TagStatus, 0x%x)", m_index, value); Prxy.TagStatus.SetValue(value); break; case SPU_Out_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_Out_MBox, 0x%x)", m_index, value); while(!SPU.Out_MBox.Push(value) && !Emu.IsStopped()) Sleep(1); break; case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value); SPU.In_MBox.PushUncond(value); //if In_MBox is already full, the last message will be overwritten break; case SPU_MBox_Status_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); SPU.MBox_Status.SetValue(value); break; case SPU_RunCntl_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_RunCntl, 0x%x)", m_index, value); SPU.RunCntl.SetValue(value); break; case SPU_Status_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_Status, 0x%x)", m_index, value); SPU.Status.SetValue(value); break; case SPU_NPC_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_NPC, 0x%x)", m_index, value); SPU.NPC.SetValue(value); break; case SPU_RdSigNotify1_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_RdSigNotify1, 0x%x)", m_index, value); SPU.SNR[0].SetValue(value); break; case SPU_RdSigNotify2_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_RdSigNotify2, 0x%x)", m_index, value); SPU.SNR[1].SetValue(value); break; default: ConLog.Error("RawSPUThread[%d]: Write32(0x%x, 0x%x)", m_index, offset, value); Emu.Pause(); break; } return true; }
bool MemoryBlock::IsMyAddress(const u64 addr) { return mem && addr >= GetStartAddr() && addr < GetEndAddr(); }
bool VirtualMemoryBlock::IsInMyRange(const u32 addr, const u32 size) { return addr >= GetStartAddr() && addr + size - 1 <= GetEndAddr() - GetReservedAmount(); }