diff --git a/Core/Cpu.cpp b/Core/Cpu.cpp index 486d2cb..bc11d28 100644 --- a/Core/Cpu.cpp +++ b/Core/Cpu.cpp @@ -57,6 +57,7 @@ Cpu::Cpu(shared_ptr memoryManager) _state.PC = ReadDataWord(Cpu::ResetVector); _state.SP = 0x1FF; _state.EmulationMode = true; + _nmiFlag = false; SetFlags(ProcFlags::MemoryMode8); SetFlags(ProcFlags::IndexMode8); } @@ -77,6 +78,16 @@ void Cpu::Exec() (this->*_opTable[opCode])(); opCount++; + + if(_nmiFlag) { + ProcessInterrupt(Cpu::NmiVector); + _nmiFlag = false; + } +} + +void Cpu::SetNmiFlag() +{ + _nmiFlag = true; } uint32_t Cpu::GetProgramAddress(uint16_t addr) @@ -220,76 +231,59 @@ uint16_t Cpu::PopWord() return lo | hi << 8; } -uint16_t Cpu::GetDirectAddress(uint8_t baseAddress, uint16_t offset, bool allowEmulationMode) +uint16_t Cpu::GetDirectAddress(uint16_t offset, bool allowEmulationMode) { if(allowEmulationMode && _state.EmulationMode && (_state.D & 0xFF) == 0) { //TODO: Check if new instruction or not (PEI) - return (uint16_t)((_state.D & 0xFF00) | ((baseAddress + offset) & 0xFF)); + return (uint16_t)((_state.D & 0xFF00) | (offset & 0xFF)); } else { - return (uint16_t)(_state.D + baseAddress + offset); + return (uint16_t)(_state.D + offset); } } +uint16_t Cpu::GetDirectAddressIndirectWord(uint16_t offset, bool allowEmulationMode) +{ + uint8_t lsb = ReadData(GetDirectAddress(offset + 0)); + uint8_t msb = ReadData(GetDirectAddress(offset + 1)); + return (msb << 8) | lsb; +} + +uint32_t Cpu::GetDirectAddressIndirectLong(uint16_t offset, bool allowEmulationMode) +{ + uint8_t b1 = ReadData(GetDirectAddress(offset + 0)); + uint8_t b2 = ReadData(GetDirectAddress(offset + 1)); + uint8_t b3 = ReadData(GetDirectAddress(offset + 2)); + return (b3 << 16) | (b2 << 8) | b1; +} + uint32_t Cpu::FetchEffectiveAddress() { switch(_instAddrMode) { case AddrMode::Abs: return GetDataAddress(ReadOperandWord()); - case AddrMode::AbsIdxX: return GetDataAddress(ReadOperandWord()) + _state.X; - case AddrMode::AbsIdxY: return GetDataAddress(ReadOperandWord()) + _state.Y; + case AddrMode::AbsIdxX: return (GetDataAddress(ReadOperandWord()) + _state.X) & 0xFFFFFF; + case AddrMode::AbsIdxY: return (GetDataAddress(ReadOperandWord()) + _state.Y) & 0xFFFFFF; case AddrMode::AbsLng: return ReadOperandLong(); - case AddrMode::AbsLngIdxX: return ReadOperandLong() + _state.X; + case AddrMode::AbsLngIdxX: return (ReadOperandLong() + _state.X) & 0xFFFFFF; case AddrMode::AbsJmp: return GetProgramAddress(ReadOperandWord()); case AddrMode::AbsLngJmp: return ReadOperandLong(); case AddrMode::AbsIdxXInd: return GetProgramAddress(ReadDataWord(GetProgramAddress(ReadOperandWord() + _state.X))); //JMP/JSR - case AddrMode::AbsInd: return GetProgramAddress(ReadDataWord(ReadOperandWord())); //JMP only + case AddrMode::AbsInd: return ReadDataWord(ReadOperandWord()); //JMP only case AddrMode::AbsIndLng: return ReadDataLong(ReadOperandWord()); //JML only case AddrMode::Acc: DummyRead(); return 0; case AddrMode::BlkMov: return ReadOperandWord(); - case AddrMode::DirIdxIndX: { - uint8_t operand = ReadOperandByte(); - uint8_t lsb = ReadData(GetDirectAddress(operand, _state.X)); - uint8_t msb = ReadData(GetDirectAddress(operand, _state.X + 1)); - return GetDataAddress((msb << 8) | lsb); - } - - case AddrMode::DirIdxX: return GetDirectAddress(ReadOperandByte(), _state.X); - case AddrMode::DirIdxY: return GetDirectAddress(ReadOperandByte(), _state.Y); - - case AddrMode::DirIndIdxY:{ - uint8_t operand = ReadOperandByte(); - uint8_t lsb = ReadData(GetDirectAddress(operand)); - uint8_t msb = ReadData(GetDirectAddress(operand, 1)); - return GetDataAddress((msb << 8) | lsb) + _state.Y; - } - - case AddrMode::DirIndLngIdxY: { - uint8_t operand = ReadOperandByte(); - uint8_t b1 = ReadData(GetDirectAddress(operand)); - uint8_t b2 = ReadData(GetDirectAddress(operand, 1)); - uint8_t b3 = ReadData(GetDirectAddress(operand, 2)); - return ((b3 << 16) | (b2 << 8) | b1) + _state.Y; - } - - case AddrMode::DirIndLng: { - uint8_t operand = ReadOperandByte(); - uint8_t b1 = ReadData(GetDirectAddress(operand)); - uint8_t b2 = ReadData(GetDirectAddress(operand, 1)); - uint8_t b3 = ReadData(GetDirectAddress(operand, 2)); - return (b3 << 16) | (b2 << 8) | b1; - } - - case AddrMode::DirInd: { - uint8_t operand = ReadOperandByte(); - uint8_t lsb = ReadData(GetDirectAddress(operand)); - uint8_t msb = ReadData(GetDirectAddress(operand, 1)); - return GetDataAddress((msb << 8) | lsb); - } - case AddrMode::Dir: return GetDirectAddress(ReadOperandByte()); + case AddrMode::DirIdxX: return GetDirectAddress(ReadOperandByte() + _state.X); + case AddrMode::DirIdxY: return GetDirectAddress(ReadOperandByte() + _state.Y); + + case AddrMode::DirInd: return GetDataAddress(GetDirectAddressIndirectWord(ReadOperandByte())); + case AddrMode::DirIdxIndX: return GetDataAddress(GetDirectAddressIndirectWord(ReadOperandByte() + _state.X)); + case AddrMode::DirIndIdxY: return (GetDataAddress(GetDirectAddressIndirectWord(ReadOperandByte())) + _state.Y) & 0xFFFFFF; + case AddrMode::DirIndLng: return GetDirectAddressIndirectLong(ReadOperandByte()); + case AddrMode::DirIndLngIdxY: return (GetDirectAddressIndirectLong(ReadOperandByte()) + _state.Y) & 0xFFFFFF; case AddrMode::Imm8: return ReadOperandByte(); case AddrMode::ImmX: return CheckFlag(ProcFlags::IndexMode8) ? ReadOperandByte() : ReadOperandWord(); @@ -300,12 +294,12 @@ uint32_t Cpu::FetchEffectiveAddress() case AddrMode::RelLng: return ReadOperandWord(); case AddrMode::Rel: return ReadOperandByte(); - case AddrMode::Stk: return _state.SP; + case AddrMode::Stk: return 0; case AddrMode::StkRel: return (uint16_t)(ReadOperandByte() + _state.SP); case AddrMode::StkRelIndIdxY: { uint16_t addr = (uint16_t)(ReadOperandByte() + _state.SP); - return GetDataAddress(addr) + _state.Y; + return (GetDataAddress(addr) + _state.Y) & 0xFFFFFF; } } diff --git a/Core/Cpu.h b/Core/Cpu.h index c476202..9656187 100644 --- a/Core/Cpu.h +++ b/Core/Cpu.h @@ -10,6 +10,7 @@ public: uint64_t opCount = 0; uint16_t GetPc() { return _state.PC; } CpuState GetState() { return _state; } + int32_t GetLastOperand() { return (int32_t)_operand; } private: static constexpr uint32_t NmiVector = 0x00FFFA; @@ -29,6 +30,7 @@ private: CpuState _state; AddrMode _instAddrMode; uint32_t _operand; + bool _nmiFlag; Func _opTable[256]; AddrMode _addrMode[256]; @@ -36,7 +38,11 @@ private: uint32_t GetProgramAddress(uint16_t addr); uint32_t GetDataAddress(uint16_t addr); - uint16_t GetDirectAddress(uint8_t baseAddress, uint16_t offset = 0, bool allowEmulationMode = true); + uint16_t GetDirectAddress(uint16_t offset, bool allowEmulationMode = true); + + uint16_t GetDirectAddressIndirectWord(uint16_t offset, bool allowEmulationMode = true); + uint32_t GetDirectAddressIndirectLong(uint16_t offset, bool allowEmulationMode = true); + uint8_t GetOpCode(); void DummyRead(); @@ -233,4 +239,6 @@ public: void Reset(); void Exec(); + + void SetNmiFlag(); }; \ No newline at end of file diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index d8de80f..a13ec71 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -28,26 +28,9 @@ void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType DisassemblyInfo disassemblyInfo(state, _memoryManager.get()); DebugState debugState; GetState(&debugState); + _traceLogger->LogEffectiveAddress(_cpu->GetLastOperand()); _traceLogger->Log(debugState, disassemblyInfo); - /*string out; - out += HexUtilities::ToHex(state.K) + HexUtilities::ToHex(state.PC); - out += " "; - disassemblyInfo.GetDisassembly(out, _memoryManager.get()); - - out += string(20 - out.size(), ' '); - - std::cout << out << - " A:$" << HexUtilities::ToHex(state.A) << - " X:$" << HexUtilities::ToHex(state.X) << - " Y:$" << HexUtilities::ToHex(state.Y) << - " S:$" << HexUtilities::ToHex(state.SP) << - " D:$" << HexUtilities::ToHex(state.D) << - " DB:$" << HexUtilities::ToHex(state.DBR) << - " P:$" << HexUtilities::ToHex(state.PS) << - std::endl; - //_traceLogger->Trace*/ - if(_cpuStepCount > 0) { _cpuStepCount--; while(_cpuStepCount == 0) { diff --git a/Core/DisassemblyInfo.cpp b/Core/DisassemblyInfo.cpp index 16f3928..a6ef3f3 100644 --- a/Core/DisassemblyInfo.cpp +++ b/Core/DisassemblyInfo.cpp @@ -13,6 +13,7 @@ DisassemblyInfo::DisassemblyInfo() DisassemblyInfo::DisassemblyInfo(CpuState &state, MemoryManager *memoryManager) { _flags = state.PS; + _effectiveAddress = -1; uint32_t addr = (state.K << 16) | state.PC; _byteCode[0] = memoryManager->Peek(addr); @@ -43,6 +44,7 @@ void DisassemblyInfo::GetDisassembly(string &out, uint32_t memoryAddr) switch(_addrMode) { case AddrMode::Abs: str.Write(operand); break; + case AddrMode::AbsJmp: str.Write(operand); break; case AddrMode::AbsIdxXInd: str.Write('(', operand, ",X)"); break; case AddrMode::AbsIdxX: str.Write(operand, ",X"); break; case AddrMode::AbsIdxY: str.Write(operand, ",Y"); break; @@ -50,6 +52,7 @@ void DisassemblyInfo::GetDisassembly(string &out, uint32_t memoryAddr) case AddrMode::AbsIndLng: str.Write('[', operand, ']'); break; case AddrMode::AbsLngIdxX: str.Write(operand, ",X"); break; case AddrMode::AbsLng: str.Write(operand); break; + case AddrMode::AbsLngJmp: str.Write(operand); break; case AddrMode::Acc: break; case AddrMode::BlkMov: str.Write(operand[0], operand[1], " <- ", operand[2], operand[3]); break; //TODO case AddrMode::DirIdxIndX: str.Write('(', operand, ",X)"); break; @@ -71,6 +74,8 @@ void DisassemblyInfo::GetDisassembly(string &out, uint32_t memoryAddr) case AddrMode::Stk: break; case AddrMode::StkRel: str.Write(operand, ",S"); break; case AddrMode::StkRelIndIdxY: str.Write('(', operand, ",S),Y"); break; + + default: throw new std::runtime_error("invalid address mode"); } out += str.ToString(); @@ -101,40 +106,43 @@ uint32_t DisassemblyInfo::GetOperandAddress(uint32_t memoryAddr) uint8_t DisassemblyInfo::GetOperandSize() { switch(_addrMode) { - case AddrMode::Abs: return 2; - case AddrMode::AbsIdxXInd: return 2; - case AddrMode::AbsIdxX: return 2; - case AddrMode::AbsIdxY: return 2; - - case AddrMode::AbsInd: return 2; - case AddrMode::AbsIndLng: return 2; + case AddrMode::Acc: + case AddrMode::Imp: + case AddrMode::Stk: + return 0; - case AddrMode::AbsLngIdxX: return 3; - case AddrMode::AbsLng: return 3; + case AddrMode::DirIdxIndX: + case AddrMode::DirIdxX: + case AddrMode::DirIdxY: + case AddrMode::DirIndIdxY: + case AddrMode::DirIndLngIdxY: + case AddrMode::DirIndLng: + case AddrMode::DirInd: + case AddrMode::Dir: + case AddrMode::Imm8: + case AddrMode::Rel: + case AddrMode::StkRel: + case AddrMode::StkRelIndIdxY: + return 1; - case AddrMode::Acc: return 0; - case AddrMode::BlkMov: return 2; - - case AddrMode::DirIdxIndX: return 1; - case AddrMode::DirIdxX: return 1; - case AddrMode::DirIdxY: return 1; - case AddrMode::DirIndIdxY: return 1; - case AddrMode::DirIndLngIdxY: return 1; - case AddrMode::DirIndLng: return 1; - case AddrMode::DirInd: return 1; - case AddrMode::Dir: return 1; + case AddrMode::Abs: + case AddrMode::AbsIdxXInd: + case AddrMode::AbsIdxX: + case AddrMode::AbsIdxY: + case AddrMode::AbsInd: + case AddrMode::AbsIndLng: + case AddrMode::AbsJmp: + case AddrMode::BlkMov: + case AddrMode::RelLng: + return 2; + + case AddrMode::AbsLngJmp: + case AddrMode::AbsLngIdxX: + case AddrMode::AbsLng: + return 3; - case AddrMode::Imm8: return 1; case AddrMode::ImmX: return (_flags & ProcFlags::IndexMode8) ? 1 : 2; case AddrMode::ImmM: return (_flags & ProcFlags::MemoryMode8) ? 1 : 2; - - case AddrMode::Imp: return 0; - case AddrMode::RelLng: return 2; - case AddrMode::Rel: return 1; - - case AddrMode::Stk: return 0; //TODO - case AddrMode::StkRel: return 1; - case AddrMode::StkRelIndIdxY: return 1; } throw new std::runtime_error("Invalid mode"); @@ -152,15 +160,78 @@ void DisassemblyInfo::GetByteCode(string &out) out += str.ToString(); } -int32_t DisassemblyInfo::GetEffectiveAddress(CpuState &cpuState, MemoryManager *memoryManager) +void DisassemblyInfo::GetEffectiveAddressString(string &out) { - uint32_t bank = (cpuState.K << 16); - //uint32_t opAddr = GetOperandAddress(); - switch(_addrMode) { - + int32_t effectiveAddress = GetEffectiveAddress(); + if(effectiveAddress >= 0) { + out += " [" + HexUtilities::ToHex24(effectiveAddress) + "]"; } } +void DisassemblyInfo::SetEffectiveAddress(int32_t effectiveAddress) +{ + _effectiveAddress = effectiveAddress; +} + +int32_t DisassemblyInfo::GetEffectiveAddress() +{ + if(_addrMode > AddrMode::ImmM && _addrMode != AddrMode::Acc && _addrMode != AddrMode::Imp && _addrMode != AddrMode::Stk) { + return _effectiveAddress; + } + return -1; + + /*auto getProgramAddress = [&state](uint16_t addr) { return (state.K << 16) | addr; }; + auto getDataAddress = [&state](uint16_t addr) { return (state.DBR << 16) | addr; }; + auto getDirectAddress = [&state](uint8_t baseAddress, uint16_t offset = 0, bool allowEmulationMode = true) { + if(allowEmulationMode && state.EmulationMode && (state.D & 0xFF) == 0) { + //TODO: Check if new instruction or not (PEI) + return (uint16_t)((state.D & 0xFF00) | ((baseAddress + offset) & 0xFF)); + } else { + return (uint16_t)(state.D + baseAddress + offset); + } + }; + + auto getDirectAddressIndirectWord = [&state, mm, &getDirectAddress](uint8_t baseAddress, uint16_t offset = 0, bool allowEmulationMode = true) { + uint8_t b1 = mm->Peek(getDirectAddress(baseAddress, offset + 0)); + uint8_t b2 = mm->Peek(getDirectAddress(baseAddress, offset + 1)); + return (b2 << 8) | b1; + }; + + auto getDirectAddressIndirectLong = [&state, mm, &getDirectAddress](uint8_t baseAddress, uint16_t offset = 0, bool allowEmulationMode = true) { + uint8_t b1 = mm->Peek(getDirectAddress(baseAddress, offset + 0)); + uint8_t b2 = mm->Peek(getDirectAddress(baseAddress, offset + 1)); + uint8_t b3 = mm->Peek(getDirectAddress(baseAddress, offset + 2)); + return (b3 << 16) | (b2 << 8) | b1; + }; + + + uint32_t bank = (state.K << 16); + uint32_t opAddr = GetOperandAddress(bank | state.PC); + switch(_addrMode) { + case AddrMode::AbsIdxX: return opAddr + state.X; + case AddrMode::AbsIdxY: return opAddr + state.Y; + case AddrMode::AbsLngIdxX: return opAddr + state.X; + case AddrMode::AbsIdxXInd: return getProgramAddress(mm->PeekWord(getProgramAddress(opAddr + state.X))); + case AddrMode::AbsInd: return getProgramAddress(mm->PeekWord(opAddr)); + case AddrMode::AbsIndLng: return mm->PeekLong(opAddr); + + case AddrMode::BlkMov: break; //TODO + + case AddrMode::Dir: return getDirectAddress(opAddr); + case AddrMode::DirIdxX: return getDirectAddress(opAddr, state.X); + case AddrMode::DirIdxY: return getDirectAddress(opAddr, state.Y); + + case AddrMode::DirInd: return getDirectAddressIndirectWord(opAddr); + case AddrMode::DirIdxIndX: return getDirectAddressIndirectWord(opAddr, state.X); + case AddrMode::DirIndIdxY: return getDirectAddressIndirectWord(opAddr) + state.Y; + case AddrMode::DirIndLng: return getDirectAddressIndirectLong(opAddr); + case AddrMode::DirIndLngIdxY: return getDirectAddressIndirectLong(opAddr) + state.Y; + + case AddrMode::StkRel: return opAddr + state.SP; + case AddrMode::StkRelIndIdxY: break; + }*/ +} + string DisassemblyInfo::OpName[256] = { //0 1 2 3 4 5 6 7 8 9 A B C D E F "BRK", "ORA", "COP", "ORA", "TSB", "ORA", "ASL", "ORA", "PHP", "ORA", "ASL", "PHD", "TSB", "ORA", "ASL", "ORA", // 0 diff --git a/Core/DisassemblyInfo.h b/Core/DisassemblyInfo.h index 538b9e3..580b06f 100644 --- a/Core/DisassemblyInfo.h +++ b/Core/DisassemblyInfo.h @@ -20,6 +20,7 @@ private: AddrMode _addrMode; uint8_t _flags; bool _emulationMode; + int32_t _effectiveAddress; public: DisassemblyInfo(); @@ -30,8 +31,9 @@ public: uint8_t GetOperandSize(); void GetByteCode(string &out); - int32_t GetEffectiveAddress(CpuState &cpuState, MemoryManager *memoryManager); - void GetEffectiveAddressString(string &out, CpuState& cpuState, MemoryManager *memoryManager); + void SetEffectiveAddress(int32_t effectiveAddress); + void GetEffectiveAddressString(string &out); + int32_t GetEffectiveAddress(); /*int32_t GetMemoryValue(CpuState& cpuState, MemoryManager* memoryManager); uint16_t GetJumpDestination(uint16_t pc, MemoryManager* memoryManager); diff --git a/Core/TraceLogger.cpp b/Core/TraceLogger.cpp index ed2e4da..2ed1b1c 100644 --- a/Core/TraceLogger.cpp +++ b/Core/TraceLogger.cpp @@ -217,9 +217,9 @@ void TraceLogger::GetTraceRow(string &output, CpuState &cpuState, PpuState &ppuS case RowDataType::EffectiveAddress: { - /*string effectiveAddress; - disassemblyInfo.GetEffectiveAddressString(effectiveAddress, cpuState, _memoryManager.get(), _options.UseLabels ? _labelManager.get() : nullptr); - WriteValue(output, effectiveAddress, rowPart);*/ + string effectiveAddress; + disassemblyInfo.GetEffectiveAddressString(effectiveAddress); + WriteValue(output, effectiveAddress, rowPart); break; } @@ -239,7 +239,7 @@ void TraceLogger::GetTraceRow(string &output, CpuState &cpuState, PpuState &ppuS } break; - case RowDataType::PC: WriteValue(output, pcAddress, rowPart); break; + case RowDataType::PC: WriteValue(output, HexUtilities::ToHex24(pcAddress), rowPart); break; case RowDataType::A: WriteValue(output, cpuState.A, rowPart); break; case RowDataType::X: WriteValue(output, cpuState.X, rowPart); break; case RowDataType::Y: WriteValue(output, cpuState.Y, rowPart); break; @@ -305,6 +305,15 @@ void TraceLogger::LogNonExec(OperationInfo& operationInfo) } }*/ +void TraceLogger::LogEffectiveAddress(uint32_t effectiveAddress) +{ + if(_currentPos > 0) { + _disassemblyCache[_currentPos - 1].SetEffectiveAddress(effectiveAddress); + } else { + _disassemblyCache[ExecutionLogSize - 1].SetEffectiveAddress(effectiveAddress); + } +} + void TraceLogger::Log(DebugState &state, DisassemblyInfo &disassemblyInfo) { auto lock = _lock.AcquireSafe(); @@ -329,7 +338,7 @@ const char* TraceLogger::GetExecutionTrace(uint32_t lineCount) for(int i = 0; i < (int)lineCount; i++) { int index = (startPos + i) % ExecutionLogSize; - _executionTrace += HexUtilities::ToHex((_cpuStateCacheCopy[index].K << 16) | _cpuStateCacheCopy[index].PC) + "\x1"; + _executionTrace += HexUtilities::ToHex24((_cpuStateCacheCopy[index].K << 16) | _cpuStateCacheCopy[index].PC) + "\x1"; string byteCode; _disassemblyCacheCopy[index].GetByteCode(byteCode); _executionTrace += byteCode + "\x1"; diff --git a/Core/TraceLogger.h b/Core/TraceLogger.h index 53f5d09..d5276a6 100644 --- a/Core/TraceLogger.h +++ b/Core/TraceLogger.h @@ -97,6 +97,8 @@ public: TraceLogger(Debugger* debugger, shared_ptr memoryManager); ~TraceLogger(); + void LogEffectiveAddress(uint32_t effectiveAddress); + void Log(DebugState &state, DisassemblyInfo &disassemblyInfo); //void LogNonExec(OperationInfo& operationInfo); void SetOptions(TraceLoggerOptions options); diff --git a/UI/Debugger/Controls/ctrlScrollableTextbox.cs b/UI/Debugger/Controls/ctrlScrollableTextbox.cs index 67d4f03..4819507 100644 --- a/UI/Debugger/Controls/ctrlScrollableTextbox.cs +++ b/UI/Debugger/Controls/ctrlScrollableTextbox.cs @@ -312,6 +312,11 @@ namespace Mesen.GUI.Debugger.Controls return true; }*/ + if(keyData == (Keys.Control | Keys.F)) { + this.OpenSearchBox(true); + return true; + } + switch(keyData) { case Keys.PageUp | Keys.Shift: this.ctrlTextbox.MoveSelectionUp(20); diff --git a/Utilities/HexUtilities.cpp b/Utilities/HexUtilities.cpp index 0697b33..54c4f51 100644 --- a/Utilities/HexUtilities.cpp +++ b/Utilities/HexUtilities.cpp @@ -51,6 +51,11 @@ string HexUtilities::ToHex(int32_t value, bool fullSize) return HexUtilities::ToHex((uint32_t)value, fullSize); } +string HexUtilities::ToHex24(int32_t value) +{ + return _hexCache[(value >> 16) & 0xFF] + _hexCache[(value >> 8) & 0xFF] + _hexCache[value & 0xFF]; +} + string HexUtilities::ToHex(uint32_t value, bool fullSize) { if(fullSize || value > 0xFFFFFF) { diff --git a/Utilities/HexUtilities.h b/Utilities/HexUtilities.h index b6f1a98..fe6769d 100644 --- a/Utilities/HexUtilities.h +++ b/Utilities/HexUtilities.h @@ -11,6 +11,7 @@ public: static string ToHex(uint16_t value); static string ToHex(uint32_t value, bool fullSize = false); static string ToHex(int32_t value, bool fullSize = false); + static string ToHex24(int32_t value); static string ToHex(vector &data); static int FromHex(string hex);