/** ** Supermodel ** A Sega Model 3 Arcade Emulator. ** Copyright 2011 Bart Trzynadlowski, Nik Henson ** ** This file is part of Supermodel. ** ** Supermodel 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 3 of the License, or (at your option) ** any later version. ** ** Supermodel 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 Supermodel. If not, see . **/ /* * IO.cpp */ #ifdef SUPERMODEL_DEBUGGER #include "CPUDebug.h" #include "IO.h" #include "Watch.h" namespace Debugger { CIO::CIO(CCPUDebug *ioCPU, const char *ioName, const char *ioGroup, unsigned ioDataSize) : cpu(ioCPU), name(ioName), group(ioGroup), dataSize(ioDataSize), watch(NULL), inCount(0), outCount(0), lastIn(0), lastOut(0), last(&lastIn) { // } bool CIO::CheckInput(UINT64 data) { inCount++; RecordInput(data); // Check watch, if any return watch != NULL && watch->CheckInput(this, data); } bool CIO::CheckOutput(UINT64 data) { outCount++; RecordOutput(data); // Check watch, if any return watch != NULL && watch->CheckOutput(this, data); } CSimpleWatch *CIO::AddSimpleWatch(bool trigInput, bool trigOutput) { CSimpleWatch *sWatch = new CSimpleWatch(cpu, this, trigInput, trigOutput); cpu->AddWatch(sWatch); return sWatch; } CCountWatch *CIO::AddCountWatch(bool trigInput, bool trigOutput, unsigned count) { CCountWatch *cWatch = new CCountWatch(cpu, this, trigInput, trigOutput, count); cpu->AddWatch(cWatch); return cWatch; } CMatchWatch *CIO::AddMatchWatch(bool trigInput, bool trigOutput, std::vector &dataSeq) { CMatchWatch *mWatch = new CMatchWatch(cpu, this, trigInput, trigOutput, dataSeq); cpu->AddWatch(mWatch); return mWatch; } CPrintWatch *CIO::AddPrintWatch(bool trigInput, bool trigOutput) { CPrintWatch *pWatch = new CPrintWatch(cpu, this, trigInput, trigOutput); cpu->AddWatch(pWatch); return pWatch; } CCaptureWatch *CIO::AddCaptureWatch(bool trigInput, bool trigOutput, unsigned maxLen) { CCaptureWatch *cWatch = new CCaptureWatch(cpu, this, trigInput, trigOutput, maxLen); cpu->AddWatch(cWatch); return cWatch; } bool CIO::RemoveWatch() { return watch != NULL && cpu->RemoveWatch(watch); } CPortIO::CPortIO(CCPUDebug *ioCPU, const char *ioName, const char *ioGroup, unsigned ioDataSize, UINT16 ioPortNum) : CIO(ioCPU, ioName, ioGroup, ioDataSize), portNum(ioPortNum), label(NULL) { // } void CPortIO::AddLabel(const char *pLabel) { strncpy(labelStr, pLabel, MAX_LABEL_LENGTH); labelStr[MAX_LABEL_LENGTH] = '\0'; label = labelStr; } void CPortIO::RemoveLabel() { label = NULL; } void CPortIO::GetLocation(char *str) { if (name != NULL) strcpy(str, name); else sprintf(str, "port %u", portNum); } UINT64 CPortIO::Read() { UINT64 data = cpu->ReadPort(portNum); RecordInput(data); return data; } bool CPortIO::Write(UINT64 data) { if (!cpu->WritePort(portNum, data)) return false; RecordOutput(data); return true; } CMappedIO::CMappedIO(CCPUDebug *ioCPU, const char *ioName, const char *ioGroup, unsigned ioDataSize, UINT32 ioAddr) : CIO(ioCPU, ioName, ioGroup, ioDataSize), CAddressRef(ioCPU, ioAddr, ioDataSize) { // } bool CMappedIO::CheckInput(UINT32 cAddr, unsigned cDataSize, UINT64 data) { // Take care with input that was not aligned with mapped I/O address and size UINT64 sData = CDebugger::GetSlottedData(cAddr, cDataSize, data, addr, dataSize); return CIO::CheckInput(sData); } bool CMappedIO::CheckOutput(UINT32 cAddr, unsigned cDataSize, UINT64 data) { // Take care with output that was not aligned with mapped I/O address and size UINT64 sData = CDebugger::GetSlottedData(cAddr, cDataSize, data, addr, dataSize); return CIO::CheckOutput(sData); } void CMappedIO::AddLabel(const char *label) { CIO::cpu->AddLabel(addr, label); } void CMappedIO::RemoveLabel() { CIO::cpu->RemoveLabel(addr); } void CMappedIO::GetLocation(char *str) { CIO::cpu->FormatAddress(str, addr); } UINT64 CMappedIO::Read() { UINT64 data = CIO::cpu->ReadMem(addr, dataSize); RecordInput(data); return data; } bool CMappedIO::Write(UINT64 data) { if (!CIO::cpu->WriteMem(addr, dataSize, data)) return false; RecordOutput(data); return true; } } #endif // SUPERMODEL_DEBUGGER