diff options
Diffstat (limited to 'src/electronics/gpsimprocessor.cpp')
-rw-r--r-- | src/electronics/gpsimprocessor.cpp | 880 |
1 files changed, 880 insertions, 0 deletions
diff --git a/src/electronics/gpsimprocessor.cpp b/src/electronics/gpsimprocessor.cpp new file mode 100644 index 0000000..1a3b862 --- /dev/null +++ b/src/electronics/gpsimprocessor.cpp @@ -0,0 +1,880 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * 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. * + ***************************************************************************/ + +#include "config.h" +#ifndef NO_GPSIM + +#include "asmparser.h" +#include "debugmanager.h" +#include "flowcodedocument.h" +#include "gpsimprocessor.h" +#include "language.h" +#include "languagemanager.h" +#include "microlibrary.h" +#include "processchain.h" +#include "simulator.h" + +#include <assert.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ktempfile.h> +#include <kstandarddirs.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qtimer.h> + +#include "gpsim/cod.h" +#include "gpsim/interface.h" +#include "gpsim/gpsim_classes.h" +#include "gpsim/pic-processor.h" +#include "gpsim/registers.h" +#include "gpsim/14bit-registers.h" +#include "gpsim/symbol.h" +#include "gpsim/sim_context.h" + +bool bDoneGpsimInit = false; +bool bUseGUI = true; +// extern "C" void initialize_gpsim(); +// void initialize_gpsim(void); +extern void initialize_commands(); +void initialize_ConsoleUI(); +extern void initialize_readline(); +extern void gui_main(void); +extern void cli_main(); +void gpsim_version() {}; +void quit_gui() {}; + + +//BEGIN class GpsimProcessor +/** +Work around a bug in gpsim: the directory in a filename is recorded twice, e.g. +"/home/david/afile.asm" is recorded as "/home/david//home/david/afile.asm". This +function will remove the duplicated directory path (by searching for a "//"). +*/ +QString sanitizeGpsimFile( QString file ) +{ + int pos = file.find("//"); + if ( pos != -1 ) + { + file.remove( 0, pos + 1 ); + } + return file; +} + + +GpsimProcessor::GpsimProcessor( QString symbolFile, QObject *parent ) + : QObject(parent), + m_symbolFile(symbolFile) +{ + if (!bDoneGpsimInit) + { +#ifndef GPSIM_0_21_4 + initialize_ConsoleUI(); +#endif + initialize_gpsim_core(); + initialization_is_complete(); + + bDoneGpsimInit = true; + } + + m_bCanExecuteNextCycle = true; + m_bIsRunning = false; + m_pPicProcessor = 0l; + m_codLoadStatus = CodUnknown; + m_pRegisterMemory = 0l; + m_debugMode = GpsimDebugger::AsmDebugger; + m_pDebugger[0] = m_pDebugger[1] = 0l; + + Processor * tempProcessor = 0l; + const char * fileName = symbolFile.ascii(); + +#ifdef GPSIM_0_21_4 + switch ( (cod_errors)load_symbol_file( &tempProcessor, fileName ) ) + { + case COD_SUCCESS: + m_codLoadStatus = CodSuccess; + break; + case COD_FILE_NOT_FOUND: + m_codLoadStatus = CodFileNotFound; + break; + case COD_UNRECOGNIZED_PROCESSOR: + m_codLoadStatus = CodUnrecognizedProcessor; + break; + case COD_FILE_NAME_TOO_LONG: + m_codLoadStatus = CodFileNameTooLong; + break; + case COD_LST_NOT_FOUND: + m_codLoadStatus = CodLstNotFound; + break; + case COD_BAD_FILE: + m_codLoadStatus = CodBadFile; + break; + default: + m_codLoadStatus = CodUnknown; + } +#else // GPSIM_0_21_11+ + FILE * pFile = fopen( fileName, "r" ); + if ( !pFile ) + m_codLoadStatus = CodFileUnreadable; + else + m_codLoadStatus = ( ProgramFileTypeList::GetList().LoadProgramFile( & tempProcessor, fileName, pFile ) ) ? CodSuccess : CodFailure; +#endif + + m_pPicProcessor = dynamic_cast<pic_processor*>(tempProcessor); + + if ( codLoadStatus() == CodSuccess ) + { + m_pRegisterMemory = new RegisterSet( m_pPicProcessor ); + m_pDebugger[0] = new GpsimDebugger( GpsimDebugger::AsmDebugger, this ); + m_pDebugger[1] = new GpsimDebugger( GpsimDebugger::HLLDebugger, this ); + Simulator::self()->attachGpsimProcessor(this); + DebugManager::self()->registerGpsim(this); + } +} + + +GpsimProcessor::~GpsimProcessor() +{ + Simulator::self()->detachGpsimProcessor(this); + delete m_pRegisterMemory; + + if ( m_pDebugger[0] ) + m_pDebugger[0]->deleteLater(); + if ( m_pDebugger[1] ) + m_pDebugger[1]->deleteLater(); +} + + +void GpsimProcessor::displayCodLoadStatus( ) +{ + switch (m_codLoadStatus) + { + case CodSuccess: + break; + case CodFileNotFound: + KMessageBox::sorry( 0l, i18n("The cod file \"%1\" was not found.").arg(m_symbolFile), i18n("File Not Found") ); + break; + case CodUnrecognizedProcessor: + KMessageBox::sorry( 0l, i18n("The processor for cod file \"%1\" is unrecognized.").arg(m_symbolFile), i18n("Unrecognized Processor") ); + break; + case CodFileNameTooLong: + KMessageBox::sorry( 0l, i18n("The file name \"%1\" is too long.").arg(m_symbolFile), i18n("Filename Too Long") ); + break; + case CodLstNotFound: + KMessageBox::sorry( 0l, i18n("The lst file associated with the cod file \"%1\" was not found.").arg(m_symbolFile), i18n("LST File Not Found") ); + break; + case CodBadFile: + KMessageBox::sorry( 0l, i18n("The cod file \"%1\" is bad.").arg(m_symbolFile), i18n("Bad File") ); + break; + case CodFileUnreadable: + KMessageBox::sorry( 0l, i18n("The cod file \"%1\" could not be read from.").arg(m_symbolFile), i18n("Unreadable File") ); + break; + case CodFailure: + case CodUnknown: + KMessageBox::sorry( 0l, i18n("An error occured with the cod file \"%1\".").arg(m_symbolFile), i18n("Error") ); + break; + } +} + + +unsigned GpsimProcessor::programMemorySize() const +{ + return m_pPicProcessor->program_memory_size(); +} + + +QStringList GpsimProcessor::sourceFileList() +{ + QStringList files; + + // Work around nasty bug in gpsim 0.21.4 where nsrc_files value might be used uninitiazed + int max = m_pPicProcessor->files.nsrc_files(); +#ifdef GPSIM_0_21_4 + if ( max > 10 ) + max = 10; +#endif + + for ( int i = 0; i < max; ++i ) + { + if ( !m_pPicProcessor->files[i] ) + continue; + + files << sanitizeGpsimFile( m_pPicProcessor->files[i]->name().c_str() ); + } + + return files; +} + + +void GpsimProcessor::emitLineReached() +{ + m_pDebugger[0]->emitLineReached(); + m_pDebugger[1]->emitLineReached(); +} + + +void GpsimProcessor::setRunning( bool run ) +{ + if ( m_bIsRunning == run ) + return; + + m_bIsRunning = run; + emit runningStatusChanged(run); +} + + +void GpsimProcessor::executeNext() +{ + if ( !m_bIsRunning ) + return; + + if ( !m_bCanExecuteNextCycle ) + { + m_bCanExecuteNextCycle = true; + return; + } + + unsigned long long beforeExecuteCount = get_cycles().get(); + + m_pPicProcessor->step_one(false); // Don't know what the false is for; gpsim ignores its value anyway + + // Some instructions take more than one cycle to execute, so ignore next cycle if this was the case + if ( (get_cycles().get() - beforeExecuteCount) > 1 ) + m_bCanExecuteNextCycle = false; + + currentDebugger()->checkForBreak(); + + // Let's also update the values of RegisterInfo every 50 milliseconds + if ( (beforeExecuteCount % 20000) == 0 ) + registerMemory()->update(); +} + + +void GpsimProcessor::reset() +{ + bool wasRunning = isRunning(); + m_pPicProcessor->reset(SIM_RESET); + setRunning(false); + if (!wasRunning) + { + // If we weren't running before, then the next signal won't have been emitted + emitLineReached(); + } +} + + +MicroInfo * GpsimProcessor::microInfo( ) const +{ + if ( !m_pPicProcessor ) + return 0l; + + return MicroLibrary::self()->microInfoWithID( m_pPicProcessor->name().c_str() ); +} + + +int GpsimProcessor::operandRegister( unsigned address ) +{ + instruction * ins = m_pPicProcessor->program_memory[ address ]; + if ( Register_op * reg = dynamic_cast<Register_op*>(ins) ) + return reg->register_address; + return -1; +} + + +int GpsimProcessor::operandLiteral( unsigned address ) +{ + instruction * ins = m_pPicProcessor->program_memory[ address ]; + if ( Literal_op * lit = dynamic_cast<Literal_op*>(ins) ) + return lit->L; + return -1; +} + + +GpsimProcessor::ProgramFileValidity GpsimProcessor::isValidProgramFile( const QString & programFile ) +{ + if ( !KStandardDirs::exists(programFile) ) + return DoesntExist; + + QString extension = programFile.right( programFile.length() - programFile.findRev('.') - 1 ).lower(); + + if ( extension == "flowcode" || + extension == "asm" || + extension == "cod" || + extension == "basic" || extension == "microbe" || + extension == "c" ) + return Valid; + + if ( extension == "hex" && QFile::exists( QString(programFile).replace(".hex",".cod") ) ) + return Valid; + + return IncorrectType; +} + + +QString GpsimProcessor::generateSymbolFile( const QString &fileName, QObject *receiver, const char *successMember, const char * failMember ) +{ + if ( !isValidProgramFile(fileName) ) + return QString::null; + + QString extension = fileName.right( fileName.length() - fileName.findRev('.') - 1 ).lower(); + + if ( extension == "cod" ) + { + QTimer::singleShot( 0, receiver, successMember ); + return fileName; + } + if ( extension == "hex" ) + { + QTimer::singleShot( 0, receiver, successMember ); + // We've already checked for the existance of the ".cod" file in GpsimProcessor::isValidProgramFile + return QString(fileName).replace(".hex",".cod"); + } + + else if ( extension == "basic" || extension == "microbe" ) + { + compileMicrobe( fileName, receiver, successMember, failMember ); + return QString(fileName).replace( "."+extension, ".cod" ); + } + else if ( extension == "flowcode" ) + { + const QString hexFile = KTempFile( QString::null, ".hex" ).name(); + + ProcessOptions o; + o.b_addToProject = false; + o.setTargetFile( hexFile ); + o.setInputFiles( fileName ); + o.setMethod( ProcessOptions::Method::Forget ); + o.setProcessPath( ProcessOptions::ProcessPath::FlowCode_Program ); + + ProcessChain * pc = LanguageManager::self()->compile(o); + if (receiver) + { + if (successMember) + connect( pc, SIGNAL(successful()), receiver, successMember ); + if (failMember) + connect( pc, SIGNAL(failed()), receiver, failMember ); + } + + return QString(hexFile).replace( ".hex", ".cod" ); + } + else if ( extension == "asm" ) + { + ProcessOptions o; + o.b_addToProject = false; + o.setTargetFile( QString(fileName).replace(".asm",".hex")); + o.setInputFiles(fileName); + o.setMethod( ProcessOptions::Method::Forget ); + o.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::guessMediaType(fileName), ProcessOptions::ProcessPath::Program ) ); + + ProcessChain *pc = LanguageManager::self()->compile(o); + if (receiver) + { + if (successMember) + connect( pc, SIGNAL(successful()), receiver, successMember ); + if (failMember) + connect( pc, SIGNAL(failed()), receiver, failMember ); + } + + return QString(fileName).replace(".asm",".cod"); + } + else if ( extension == "c" ) + { + ProcessOptions o; + o.b_addToProject = false; + o.setTargetFile( QString(fileName).replace(".c",".hex")); + o.setInputFiles(fileName); + o.setMethod( ProcessOptions::Method::Forget ); + o.setProcessPath( ProcessOptions::ProcessPath::C_Program ); + + ProcessChain *pc = LanguageManager::self()->compile(o); + if (receiver) + { + if (successMember) + connect( pc, SIGNAL(successful()), receiver, successMember ); + if (failMember) + connect( pc, SIGNAL(failed()), receiver, failMember ); + } + + return QString(fileName).replace(".c",".cod"); + } + + if ( failMember ) + QTimer::singleShot( 0, receiver, failMember ); + return QString::null; +} + + +void GpsimProcessor::compileMicrobe( const QString &filename, QObject *receiver, const char * successMember, const char * failMember ) +{ + ProcessOptions o; + o.b_addToProject = false; + o.setTargetFile( QString(filename).replace(".microbe",".hex") ); + o.setInputFiles(filename); + o.setMethod( ProcessOptions::Method::Forget ); + o.setProcessPath( ProcessOptions::ProcessPath::Microbe_Program ); + ProcessChain * pc = LanguageManager::self()->compile(o); + if (receiver) + { + if (successMember) + connect( pc, SIGNAL(successful()), receiver, successMember ); + if (failMember) + connect( pc, SIGNAL(failed()), receiver, failMember ); + } +} +//END class GpsimProcessor + + + +//BEGIN class GpsimDebugger +GpsimDebugger::GpsimDebugger( Type type, GpsimProcessor * gpsim ) + : QObject() +{ + m_pGpsim = gpsim; + m_type = type; + m_pBreakFromOldLine = 0l; + m_addressToLineMap = 0l; + m_stackLevelLowerBreak = -1; + m_addressSize = 0; + + connect( m_pGpsim, SIGNAL(runningStatusChanged(bool )), this, SLOT(gpsimRunningStatusChanged(bool )) ); + + if ( type == HLLDebugger ) + { + const QStringList sourceFileList = m_pGpsim->sourceFileList(); + QStringList::const_iterator sflEnd = sourceFileList.end(); + for ( QStringList::const_iterator it = sourceFileList.begin(); it != sflEnd; ++it ) + { + AsmParser p(*it); + p.parse(this); + } + } + + initAddressToLineMap(); +} + + +GpsimDebugger::~GpsimDebugger() +{ + QValueList<DebugLine*> debugLinesToDelete; + + for ( unsigned i = 0; i < m_addressSize; ++i ) + { + DebugLine * dl = m_addressToLineMap[i]; + if ( !dl || dl->markedAsDeleted() ) + continue; + + dl->markAsDeleted(); + debugLinesToDelete += dl; + } + + const QValueList<DebugLine*>::iterator end = debugLinesToDelete.end(); + for ( QValueList<DebugLine*>::iterator it = debugLinesToDelete.begin(); it != end; ++it ) + delete *it; + + delete [] m_addressToLineMap; +} + + +void GpsimDebugger::gpsimRunningStatusChanged( bool isRunning ) +{ + if (!isRunning) + { + m_stackLevelLowerBreak = -1; + m_pBreakFromOldLine = 0l; + emitLineReached(); + } +} + + +void GpsimDebugger::associateLine( const QString & sourceFile, int sourceLine, const QString & assemblyFile, int assemblyLine ) +{ + if ( assemblyLine < 0 || sourceLine < 0 ) + { + kdWarning() << k_funcinfo << "Invalid lines: assemblyLine="<<assemblyLine<<" sourceLine="<<sourceLine<<endl; + return; + } + + SourceLine hllSource = SourceLine( sourceFile, sourceLine ); + SourceLine asmSource = SourceLine( assemblyFile, assemblyLine ); + + if ( m_sourceLineMap.contains(asmSource) ) + { + kdWarning() << k_funcinfo << "Already have an association for assembly (\""<<assemblyFile<<"\","<<assemblyLine<<")"<<endl; + return; + } + + m_sourceLineMap[asmSource] = hllSource; +} + + +void GpsimDebugger::initAddressToLineMap() +{ + m_addressSize = m_pGpsim->programMemorySize(); + + delete [] m_addressToLineMap; + m_addressToLineMap = new DebugLine*[m_addressSize]; + memset( m_addressToLineMap, 0, m_addressSize * sizeof(DebugLine*) ); + + if ( m_type == AsmDebugger ) + { + for ( unsigned i = 0; i < m_addressSize; ++i ) + { + int line = m_pGpsim->picProcessor()->pma->get_src_line(i) - 1; + int fileID = m_pGpsim->picProcessor()->pma->get_file_id(i); + FileContext * fileContext = m_pGpsim->picProcessor()->files[fileID]; + + if (fileContext) + m_addressToLineMap[i] = new DebugLine( sanitizeGpsimFile( fileContext->name().c_str() ), line ); + } + } + else + { + SourceLineMap::const_iterator slmEnd = m_sourceLineMap.end(); + for ( SourceLineMap::const_iterator it = m_sourceLineMap.begin(); it != slmEnd; ++it ) + { + SourceLineMap::const_iterator next = it; + ++next; + + int asmToLine = ((next == slmEnd) || (next.key().fileName() != it.key().fileName())) ? -1 : next.key().line() - 1; + + QString asmFile = it.key().fileName(); + int asmFromLine = it.key().line(); + SourceLine sourceLine = it.data(); + + + std::string stdAsmFile( asmFile.ascii() ); + int fileID = m_pGpsim->picProcessor()->files.Find( stdAsmFile ); + if ( fileID == -1 ) + { + kdWarning() << k_funcinfo << "Could not find FileContext (asmFile=\""<<asmFile<<"\")"<<endl; + continue; + } + + if ( asmToLine == -1 ) + asmToLine = m_pGpsim->picProcessor()->files[fileID]->max_line() - 2; + + if ( (asmFromLine < 0) || (asmToLine < asmFromLine) ) + { + kdWarning() << k_funcinfo << "Invalid lines: asmFromLine="<<asmFromLine<<" asmToLine="<<asmToLine<<endl; + continue; + } + + DebugLine * debugLine = new DebugLine( sourceLine.fileName(), sourceLine.line() ); + bool used = false; + + for ( int i = asmFromLine; i <= asmToLine; ++i ) + { +#ifdef GPSIM_0_21_4 + int address = m_pGpsim->picProcessor()->pma->find_address_from_line( fileID, i+1 ); +#else // GPSIM_0_21_11 + int address = m_pGpsim->picProcessor()->pma->find_address_from_line( m_pGpsim->picProcessor()->files[fileID], i+1 ); +#endif + if ( address != -1 ) + { + used = true; + m_addressToLineMap[address] = debugLine; + } + } + + if (!used) + delete debugLine; + } + } +} + + +void GpsimDebugger::setBreakpoints( const QString & path, const IntList & lines ) +{ + for ( unsigned i = 0; i < m_addressSize; i++ ) + { + DebugLine * dl = m_addressToLineMap[i]; + if ( !dl || dl->fileName() != path ) + continue; + + dl->setBreakpoint( lines.contains( dl->line() ) ); + } +} + + +void GpsimDebugger::setBreakpoint( const QString & path, int line, bool isBreakpoint ) +{ + for ( unsigned i = 0; i < m_addressSize; i++ ) + { + if ( !m_addressToLineMap[i] ) + continue; + + if ( (m_addressToLineMap[i]->fileName() == path) && + ( line == m_addressToLineMap[i]->line() ) ) + m_addressToLineMap[i]->setBreakpoint(isBreakpoint); + } +} + + +DebugLine * GpsimDebugger::currentDebugLine() +{ + return m_addressToLineMap[ m_pGpsim->picProcessor()->pc->get_value() ]; +} + + +SourceLine GpsimDebugger::currentLine() +{ + DebugLine * dl = currentDebugLine(); + return dl ? *dl : SourceLine(); +} + + +void GpsimDebugger::emitLineReached() +{ + SourceLine currentAt = currentLine(); + + if ( currentAt == m_previousAtLineEmit ) + return; + + m_previousAtLineEmit = currentAt; + m_pGpsim->registerMemory()->update(); + emit lineReached(currentAt); +} + + +void GpsimDebugger::checkForBreak() +{ + DebugLine * currentLine = m_addressToLineMap[ m_pGpsim->picProcessor()->pc->get_value() ]; + int currentStackLevel = int( m_pGpsim->picProcessor()->stack->pointer & m_pGpsim->picProcessor()->stack->stack_mask ); + + bool ontoNextLine = m_pBreakFromOldLine != currentLine; + bool lineBreakpoint = currentLine ? currentLine->isBreakpoint() : false; + bool stackBreakpoint = m_stackLevelLowerBreak >= currentStackLevel; + + if ( ontoNextLine && (lineBreakpoint || stackBreakpoint) ) + m_pGpsim->setRunning(false); +} + + +int GpsimDebugger::programAddress( const QString & path, int line ) +{ + for ( unsigned i = 0; i < m_addressSize; ++i ) + { + DebugLine * dl = m_addressToLineMap[i]; + if ( !dl || (dl->line() != line) || (dl->fileName() != path) ) + continue; + + return i; + } + + return -1; +} + + +void GpsimDebugger::stepInto() +{ + // I'm not aware of the stack being able to increase in size by more than + // one at a time, so "1" should suffice here...but to be on the safe side, + // make it a nice large number + stackStep( 1 << 16 ); +} +void GpsimDebugger::stepOver() +{ + stackStep(0); +} +void GpsimDebugger::stepOut() +{ + stackStep(-1); +} +void GpsimDebugger::stackStep( int dl ) +{ + if ( m_pGpsim->isRunning() ) + return; + + int initialStack = (m_pGpsim->picProcessor()->stack->pointer & m_pGpsim->picProcessor()->stack->stack_mask) + dl; + DebugLine * initialLine = currentDebugLine(); + + if ( initialStack < 0 ) + initialStack = 0; + + // Reset any previous stackStep, and step + m_pBreakFromOldLine = 0l; + m_stackLevelLowerBreak = -1; + m_pGpsim->picProcessor()->step_one(false); + + int currentStack = m_pGpsim->picProcessor()->stack->pointer & m_pGpsim->picProcessor()->stack->stack_mask; + DebugLine * currentLine = currentDebugLine(); + + if ( (initialStack >= currentStack) && (initialLine != currentLine) ) + emitLineReached(); + + else + { + // Looks like we stepped into something or haven't gone onto the next + // instruction, wait until we step back out.... + m_stackLevelLowerBreak = initialStack; + m_pBreakFromOldLine = initialLine; + m_pGpsim->setRunning(true); + } +} +//END class Debugger + + + +//BEGIN class RegisterSet +RegisterSet::RegisterSet( pic_processor * picProcessor ) +{ + unsigned numRegisters = picProcessor->rma.get_size(); + m_registers.resize( numRegisters, 0l ); + for ( unsigned i = 0; i < numRegisters; ++i ) + { + RegisterInfo * info = new RegisterInfo( & picProcessor->rma[i] ); + m_registers[i] = info; + m_nameToRegisterMap[ info->name() ] = info; + } + + RegisterInfo * info = new RegisterInfo( picProcessor->W ); + m_registers.append( info ); + m_nameToRegisterMap[ info->name() ] = info; +} + + +RegisterSet::~RegisterSet() +{ + for ( unsigned i = 0; i < m_registers.size(); ++i ) + delete m_registers[i]; +} + + +RegisterInfo * RegisterSet::fromAddress( unsigned address ) +{ + return (address < m_registers.size()) ? m_registers[address] : 0l; +} + + +RegisterInfo * RegisterSet::fromName( const QString & name ) +{ + // First try the name as case sensitive, then as case insensitive. + if ( m_nameToRegisterMap.contains( name ) ) + return m_nameToRegisterMap[ name ]; + + QString nameLower = name.lower(); + + RegisterInfoMap::iterator end = m_nameToRegisterMap.end(); + for ( RegisterInfoMap::iterator it = m_nameToRegisterMap.begin(); it != end; ++ it ) + { + if ( it.key().lower() == nameLower ) + return it.data(); + } + + return 0l; +} + + +void RegisterSet::update() +{ + for ( unsigned i = 0; i < m_registers.size(); ++i ) + m_registers[i]->update(); +} +//END class RegisterSet + + + +//BEGIN class RegisterInfo +RegisterInfo::RegisterInfo( Register * reg ) +{ + assert(reg); + m_pRegister = reg; + m_type = Invalid; + m_prevEmitValue = 0; + + switch ( m_pRegister->isa() ) + { + case Register::GENERIC_REGISTER: + m_type = Generic; + break; + case Register::FILE_REGISTER: + m_type = File; + break; + case Register::SFR_REGISTER: + m_type = SFR; + break; + case Register::BP_REGISTER: + m_type = Breakpoint; + break; + case Register::INVALID_REGISTER: + m_type = Invalid; + break; + } + + m_name = m_pRegister->baseName(); +} + + +unsigned RegisterInfo::value() const +{ + return m_pRegister->value.data; +} + + +void RegisterInfo::update() +{ + unsigned newValue = value(); + if ( newValue != m_prevEmitValue ) + { + m_prevEmitValue = newValue; + emit valueChanged(newValue); + } +} + + +QString RegisterInfo::toString( RegisterType type ) +{ + switch ( type ) + { + case Generic: + return i18n("Generic"); + + case File: + return i18n("File"); + + case SFR: + return i18n("SFR"); + + case Breakpoint: + return i18n("Breakpoint"); + + case Invalid: + return i18n("Invalid"); + } + + return i18n("Unknown"); +} +//END class RegisterInfo + + + +//BEGIN class DebugLine +DebugLine::DebugLine( const QString & fileName, int line ) + : SourceLine( fileName, line ) +{ + m_bIsBreakpoint = false; + m_bMarkedAsDeleted = false; +} + + +DebugLine::DebugLine() + : SourceLine() +{ + m_bIsBreakpoint = false; + m_bMarkedAsDeleted = false; +} +//END class DebugLine + + +#include "gpsimprocessor.moc" + +#endif |