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<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<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<string> ExpressionEvaluator::_unaryOperators = { { "+", "-", "~", "!", ":" } };
|
||||||
const vector<int> ExpressionEvaluator::_unaryPrecedence = { { 11, 11, 11, 11 } };
|
const vector<int> ExpressionEvaluator::_unaryPrecedence = { { 11, 11, 11, 11, 11 } };
|
||||||
const std::unordered_set<string> ExpressionEvaluator::_operators = { { "*", "/", "%", "+", "-", "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||", "~", "!", "(", ")", "{", "}", "[", "]" } };
|
const std::unordered_set<string> ExpressionEvaluator::_operators = { { "*", "/", "%", "+", "-", "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||", "~", "!", "(", ")", "{", "}", "[", "]", ":" } };
|
||||||
|
|
||||||
bool ExpressionEvaluator::IsOperator(string token, int &precedence, bool unaryOperator)
|
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);
|
output += std::to_string((int64_t)EvalValues::Value);
|
||||||
} else if(token == "address") {
|
} else if(token == "address") {
|
||||||
output += std::to_string((int64_t)EvalValues::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") {
|
} else if(token == "iswrite") {
|
||||||
output += std::to_string((int64_t)EvalValues::IsWrite);
|
output += std::to_string((int64_t)EvalValues::IsWrite);
|
||||||
} else if(token == "isread") {
|
} 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::Irq: token = state.CPU.IRQFlag; resultType = EvalResultType::Boolean; break;
|
||||||
case EvalValues::Value: token = operationInfo.Value; break;
|
case EvalValues::Value: token = operationInfo.Value; break;
|
||||||
case EvalValues::Address: token = operationInfo.Address; 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::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::IsRead: token = operationInfo.OperationType == MemoryOperationType::Read || operationInfo.OperationType == MemoryOperationType::DummyRead; break;
|
||||||
case EvalValues::PreviousOpPC: token = state.CPU.PreviousDebugPC; 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::Minus: token = -right; break;
|
||||||
case EvalOperators::BinaryNot: token = ~right; break;
|
case EvalOperators::BinaryNot: token = ~right; break;
|
||||||
case EvalOperators::LogicalNot: 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::Bracket: token = _debugger->GetMemoryDumper()->GetMemoryValue(DebugMemoryType::CpuMemory, (uint32_t)right); break;
|
||||||
case EvalOperators::Braces: token = _debugger->GetMemoryDumper()->GetMemoryValueWord(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");
|
default: throw std::runtime_error("Invalid operator");
|
||||||
|
@ -591,5 +598,12 @@ void ExpressionEvaluator::RunTests()
|
||||||
test("%011", EvalResultType::Numeric, 3);
|
test("%011", EvalResultType::Numeric, 3);
|
||||||
test("%1011", EvalResultType::Numeric, 11);
|
test("%1011", EvalResultType::Numeric, 11);
|
||||||
test("%12", EvalResultType::Invalid, 0);
|
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
|
#endif
|
|
@ -36,10 +36,11 @@ enum EvalOperators : int64_t
|
||||||
Minus = 20000000051,
|
Minus = 20000000051,
|
||||||
BinaryNot = 20000000052,
|
BinaryNot = 20000000052,
|
||||||
LogicalNot = 20000000053,
|
LogicalNot = 20000000053,
|
||||||
|
AbsoluteAddress = 20000000054,
|
||||||
|
|
||||||
//Used to read ram address
|
//Used to read ram address
|
||||||
Bracket = 20000000054, //Read byte
|
Bracket = 20000000060, //Read byte
|
||||||
Braces = 20000000055, //Read word
|
Braces = 20000000061, //Read word
|
||||||
|
|
||||||
//Special value, not used as an operator
|
//Special value, not used as an operator
|
||||||
Parenthesis = 20000000100,
|
Parenthesis = 20000000100,
|
||||||
|
@ -61,7 +62,6 @@ enum EvalValues : int64_t
|
||||||
Irq = 20000000111,
|
Irq = 20000000111,
|
||||||
Value = 20000000112,
|
Value = 20000000112,
|
||||||
Address = 20000000113,
|
Address = 20000000113,
|
||||||
AbsoluteAddress = 20000000114,
|
|
||||||
IsWrite = 20000000115,
|
IsWrite = 20000000115,
|
||||||
IsRead = 20000000116,
|
IsRead = 20000000116,
|
||||||
PreviousOpPC = 20000000117,
|
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`)
|
Use the $ prefix to denote hexadecimal values (e.g: `$FF`) or the % prefix for binary values (e.g: `%1101`)
|
||||||
{{% /notice %}}
|
{{% /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 ####
|
#### 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.
|
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)
|
* **Frame**: PPU frame number (since power on/reset)
|
||||||
* **Value**: Current value being read/written from/to memory
|
* **Value**: Current value being read/written from/to memory
|
||||||
* **Address**: Current CPU memory address being read/written
|
* **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**
|
**Flags**
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue