Debugger: Added ":" operator to return an address' offset in prg/sram/wram/etc.
This commit is contained in:
parent
fafb52df0d
commit
bc335e104d
3 changed files with 37 additions and 12 deletions
|
@ -11,9 +11,9 @@
|
|||
|
||||
const vector<string> ExpressionEvaluator::_binaryOperators = { { "*", "/", "%", "+", "-", "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||" } };
|
||||
const vector<int> ExpressionEvaluator::_binaryPrecedence = { { 10, 10, 10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 1 } };
|
||||
const vector<string> ExpressionEvaluator::_unaryOperators = { { "+", "-", "~", "!" } };
|
||||
const vector<int> ExpressionEvaluator::_unaryPrecedence = { { 11, 11, 11, 11 } };
|
||||
const std::unordered_set<string> ExpressionEvaluator::_operators = { { "*", "/", "%", "+", "-", "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||", "~", "!", "(", ")", "{", "}", "[", "]" } };
|
||||
const vector<string> ExpressionEvaluator::_unaryOperators = { { "+", "-", "~", "!", ":" } };
|
||||
const vector<int> ExpressionEvaluator::_unaryPrecedence = { { 11, 11, 11, 11, 11 } };
|
||||
const std::unordered_set<string> ExpressionEvaluator::_operators = { { "*", "/", "%", "+", "-", "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||", "~", "!", "(", ")", "{", "}", "[", "]", ":" } };
|
||||
|
||||
bool ExpressionEvaluator::IsOperator(string token, int &precedence, bool unaryOperator)
|
||||
{
|
||||
|
@ -105,8 +105,6 @@ bool ExpressionEvaluator::CheckSpecialTokens(string expression, size_t &pos, str
|
|||
output += std::to_string((int64_t)EvalValues::Value);
|
||||
} else if(token == "address") {
|
||||
output += std::to_string((int64_t)EvalValues::Address);
|
||||
} else if(token == "romaddress") {
|
||||
output += std::to_string((int64_t)EvalValues::AbsoluteAddress);
|
||||
} else if(token == "iswrite") {
|
||||
output += std::to_string((int64_t)EvalValues::IsWrite);
|
||||
} else if(token == "isread") {
|
||||
|
@ -388,7 +386,6 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, DebugState &state, E
|
|||
case EvalValues::Irq: token = state.CPU.IRQFlag; resultType = EvalResultType::Boolean; break;
|
||||
case EvalValues::Value: token = operationInfo.Value; break;
|
||||
case EvalValues::Address: token = operationInfo.Address; break;
|
||||
case EvalValues::AbsoluteAddress: token = _debugger->GetAbsoluteAddress(operationInfo.Address); break;
|
||||
case EvalValues::IsWrite: token = operationInfo.OperationType == MemoryOperationType::Write || operationInfo.OperationType == MemoryOperationType::DummyWrite; break;
|
||||
case EvalValues::IsRead: token = operationInfo.OperationType == MemoryOperationType::Read || operationInfo.OperationType == MemoryOperationType::DummyRead; break;
|
||||
case EvalValues::PreviousOpPC: token = state.CPU.PreviousDebugPC; break;
|
||||
|
@ -442,6 +439,16 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, DebugState &state, E
|
|||
case EvalOperators::Minus: token = -right; break;
|
||||
case EvalOperators::BinaryNot: token = ~right; break;
|
||||
case EvalOperators::LogicalNot: token = !right; break;
|
||||
case EvalOperators::AbsoluteAddress: {
|
||||
if(right >= 0) {
|
||||
AddressTypeInfo addressInfo;
|
||||
_debugger->GetAbsoluteAddressAndType((uint32_t)right, &addressInfo);
|
||||
token = addressInfo.Address;
|
||||
} else {
|
||||
token = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EvalOperators::Bracket: token = _debugger->GetMemoryDumper()->GetMemoryValue(DebugMemoryType::CpuMemory, (uint32_t)right); break;
|
||||
case EvalOperators::Braces: token = _debugger->GetMemoryDumper()->GetMemoryValueWord(DebugMemoryType::CpuMemory, (uint32_t)right); break;
|
||||
default: throw std::runtime_error("Invalid operator");
|
||||
|
@ -591,5 +598,12 @@ void ExpressionEvaluator::RunTests()
|
|||
test("%011", EvalResultType::Numeric, 3);
|
||||
test("%1011", EvalResultType::Numeric, 11);
|
||||
test("%12", EvalResultType::Invalid, 0);
|
||||
|
||||
test(":$00", EvalResultType::Numeric, 0);
|
||||
test(":50", EvalResultType::Numeric, 50);
|
||||
test(":$50", EvalResultType::Numeric, 0x50);
|
||||
test(":($1FFF+1)", EvalResultType::Numeric, -1);
|
||||
test(":$1FFF+1", EvalResultType::Numeric, 0x2000);
|
||||
test("1+:$100", EvalResultType::Numeric, 0x101);
|
||||
}
|
||||
#endif
|
|
@ -36,10 +36,11 @@ enum EvalOperators : int64_t
|
|||
Minus = 20000000051,
|
||||
BinaryNot = 20000000052,
|
||||
LogicalNot = 20000000053,
|
||||
AbsoluteAddress = 20000000054,
|
||||
|
||||
//Used to read ram address
|
||||
Bracket = 20000000054, //Read byte
|
||||
Braces = 20000000055, //Read word
|
||||
Bracket = 20000000060, //Read byte
|
||||
Braces = 20000000061, //Read word
|
||||
|
||||
//Special value, not used as an operator
|
||||
Parenthesis = 20000000100,
|
||||
|
@ -61,7 +62,6 @@ enum EvalValues : int64_t
|
|||
Irq = 20000000111,
|
||||
Value = 20000000112,
|
||||
Address = 20000000113,
|
||||
AbsoluteAddress = 20000000114,
|
||||
IsWrite = 20000000115,
|
||||
IsRead = 20000000116,
|
||||
PreviousOpPC = 20000000117,
|
||||
|
|
|
@ -133,6 +133,20 @@ The syntax is identical to C/C++ (e.g `&&` for AND, `||` for OR) and uses the sa
|
|||
Use the $ prefix to denote hexadecimal values (e.g: `$FF`) or the % prefix for binary values (e.g: `%1101`)
|
||||
{{% /notice %}}
|
||||
|
||||
#### Operators ####
|
||||
|
||||
The following operators are supported (same usage/precedence as C):
|
||||
`*`, `/`, `%`, `+`, `-`, `<<`, `>>`, `<`, `<=`, `>`, `>=`, `==`, `!=`, `&`, `^`, `|`, `&&`, `||`, `~`, `!`, `(`, `)`
|
||||
|
||||
Additionally, the following special operators exist:
|
||||
|
||||
* **[*address/label*]**: Surrounding a value/expression with brackets will read the corresponding memory address and return its value (1 byte).
|
||||
* e.g: `[$8000]` will read the value at address $8000 and return it.
|
||||
* **{*address/label*}**: Surrounding a value/expression with curly brackets will read the corresponding memory address and return its value (2 byte).
|
||||
* e.g: `{myLabel}` will read 2 bytes of memory at the address represented by the `myLabel` label and return its value
|
||||
* **:*address/label***: Prepending a `:` before an address/label will return the offset of the corresponding address within that memory type. If an address is not mapped to any type of memory, `-1` will be returned.
|
||||
* e.g: `:$8000` will return the offset in PRG ROM of the byte currently mapped at the CPU address $8000.
|
||||
|
||||
#### Special values ####
|
||||
|
||||
The following "variables" can be used in both the watch window and contional breakpoints to check the state of specific portions of the emulation core.
|
||||
|
@ -147,9 +161,6 @@ The following "variables" can be used in both the watch window and contional bre
|
|||
* **Frame**: PPU frame number (since power on/reset)
|
||||
* **Value**: Current value being read/written from/to memory
|
||||
* **Address**: Current CPU memory address being read/written
|
||||
* **RomAddress**: Current ROM address being read/written
|
||||
* **[<address>]**: (Byte) Memory value at <address> (CPU)
|
||||
* **{<address>}**: (Word) Memory value at <address> (CPU)
|
||||
|
||||
**Flags**
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue