2016-11-22 22:38:14 -05:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "LabelManager.h"
|
|
|
|
#include "Debugger.h"
|
2017-03-31 22:14:16 -04:00
|
|
|
#include "BaseMapper.h"
|
2016-11-22 22:38:14 -05:00
|
|
|
|
|
|
|
LabelManager::LabelManager(shared_ptr<BaseMapper> mapper)
|
|
|
|
{
|
|
|
|
_mapper = mapper;
|
|
|
|
}
|
|
|
|
|
2018-06-09 21:25:49 -04:00
|
|
|
void LabelManager::DeleteLabels()
|
|
|
|
{
|
|
|
|
_codeComments.clear();
|
|
|
|
_codeLabels.clear();
|
|
|
|
_codeLabelReverseLookup.clear();
|
|
|
|
}
|
|
|
|
|
2016-11-22 22:38:14 -05:00
|
|
|
void LabelManager::SetLabel(uint32_t address, AddressType addressType, string label, string comment)
|
|
|
|
{
|
2017-12-27 12:03:35 -05:00
|
|
|
address = GetLabelAddress(address, addressType);
|
2016-11-22 22:38:14 -05:00
|
|
|
|
|
|
|
auto existingLabel = _codeLabels.find(address);
|
|
|
|
if(existingLabel != _codeLabels.end()) {
|
|
|
|
_codeLabelReverseLookup.erase(existingLabel->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
_codeLabels.erase(address);
|
|
|
|
if(!label.empty()) {
|
2017-03-04 15:18:00 -05:00
|
|
|
if(label.size() > 400) {
|
|
|
|
//Restrict labels to 400 bytes
|
|
|
|
label = label.substr(0, 400);
|
|
|
|
}
|
2016-11-22 22:38:14 -05:00
|
|
|
_codeLabels.emplace(address, label);
|
|
|
|
_codeLabelReverseLookup.emplace(label, address);
|
|
|
|
}
|
|
|
|
|
|
|
|
_codeComments.erase(address);
|
|
|
|
if(!comment.empty()) {
|
|
|
|
_codeComments.emplace(address, comment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-27 12:03:35 -05:00
|
|
|
int32_t LabelManager::GetLabelAddress(uint32_t absoluteAddr, AddressType addressType)
|
|
|
|
{
|
|
|
|
switch(addressType) {
|
|
|
|
case AddressType::InternalRam: absoluteAddr |= 0x70000000; break;
|
|
|
|
case AddressType::PrgRom: absoluteAddr |= 0x60000000; break;
|
|
|
|
case AddressType::WorkRam: absoluteAddr |= 0x50000000; break;
|
|
|
|
case AddressType::SaveRam: absoluteAddr |= 0x40000000; break;
|
|
|
|
case AddressType::Register: absoluteAddr |= 0x30000000; break;
|
|
|
|
}
|
|
|
|
return absoluteAddr;
|
|
|
|
}
|
|
|
|
|
2018-12-10 19:52:16 -05:00
|
|
|
int32_t LabelManager::GetLabelAddress(uint16_t relativeAddr)
|
2016-11-22 22:38:14 -05:00
|
|
|
{
|
|
|
|
if(relativeAddr < 0x2000) {
|
2016-11-23 18:48:29 -05:00
|
|
|
return relativeAddr | 0x70000000;
|
2016-11-22 22:38:14 -05:00
|
|
|
} else {
|
|
|
|
int32_t addr = _mapper->ToAbsoluteAddress(relativeAddr);
|
|
|
|
if(addr >= 0) {
|
|
|
|
//PRG ROM
|
2016-11-23 18:48:29 -05:00
|
|
|
return addr | 0x60000000;
|
2016-11-22 22:38:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
addr = _mapper->ToAbsoluteWorkRamAddress(relativeAddr);
|
|
|
|
if(addr >= 0) {
|
|
|
|
//Work RAM
|
2016-11-23 18:48:29 -05:00
|
|
|
return addr | 0x50000000;
|
2016-11-22 22:38:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
addr = _mapper->ToAbsoluteSaveRamAddress(relativeAddr);
|
|
|
|
if(addr >= 0) {
|
|
|
|
//Save RAM
|
2016-11-23 18:48:29 -05:00
|
|
|
return addr | 0x40000000;
|
|
|
|
}
|
2016-11-22 22:38:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-11-23 18:48:29 -05:00
|
|
|
string LabelManager::GetLabel(uint16_t relativeAddr, bool checkRegisters)
|
2016-11-22 22:38:14 -05:00
|
|
|
{
|
2018-12-10 19:52:16 -05:00
|
|
|
int32_t labelAddr = GetLabelAddress(relativeAddr);
|
2016-11-22 22:38:14 -05:00
|
|
|
|
|
|
|
if(labelAddr >= 0) {
|
|
|
|
auto result = _codeLabels.find(labelAddr);
|
|
|
|
if(result != _codeLabels.end()) {
|
|
|
|
return result->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-10 19:52:16 -05:00
|
|
|
if(checkRegisters) {
|
|
|
|
labelAddr = relativeAddr | 0x30000000;
|
|
|
|
|
|
|
|
auto result = _codeLabels.find(labelAddr);
|
|
|
|
if(result != _codeLabels.end()) {
|
|
|
|
return result->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-22 22:38:14 -05:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
string LabelManager::GetComment(uint16_t relativeAddr)
|
|
|
|
{
|
2018-12-10 19:52:16 -05:00
|
|
|
int32_t labelAddr = GetLabelAddress(relativeAddr);
|
2016-11-22 22:38:14 -05:00
|
|
|
|
|
|
|
if(labelAddr >= 0) {
|
|
|
|
auto result = _codeComments.find(labelAddr);
|
|
|
|
if(result != _codeComments.end()) {
|
|
|
|
return result->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
void LabelManager::GetLabelAndComment(uint16_t relativeAddr, string &label, string &comment)
|
|
|
|
{
|
2018-12-10 19:52:16 -05:00
|
|
|
int32_t labelAddr = GetLabelAddress(relativeAddr);
|
2017-03-09 23:50:20 -05:00
|
|
|
|
|
|
|
if(labelAddr >= 0) {
|
|
|
|
auto result = _codeLabels.find(labelAddr);
|
|
|
|
if(result != _codeLabels.end()) {
|
|
|
|
label = result->second;
|
|
|
|
} else {
|
|
|
|
label.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto commentResult = _codeComments.find(labelAddr);
|
|
|
|
if(commentResult != _codeComments.end()) {
|
|
|
|
comment = commentResult->second;
|
|
|
|
} else {
|
|
|
|
comment.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-02 20:44:48 -04:00
|
|
|
bool LabelManager::ContainsLabel(string &label)
|
|
|
|
{
|
|
|
|
return _codeLabelReverseLookup.find(label) != _codeLabelReverseLookup.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t LabelManager::GetLabelRelativeAddress(string &label)
|
2016-11-22 22:38:14 -05:00
|
|
|
{
|
|
|
|
auto result = _codeLabelReverseLookup.find(label);
|
|
|
|
if(result != _codeLabelReverseLookup.end()) {
|
2016-11-22 23:14:38 -05:00
|
|
|
uint32_t address = result->second;
|
|
|
|
AddressType type = AddressType::InternalRam;
|
2016-11-23 18:48:29 -05:00
|
|
|
if((address & 0x70000000) == 0x70000000) {
|
2016-11-22 23:14:38 -05:00
|
|
|
type = AddressType::InternalRam;
|
2016-11-23 18:48:29 -05:00
|
|
|
} else if((address & 0x60000000) == 0x60000000) {
|
2016-11-22 23:14:38 -05:00
|
|
|
type = AddressType::PrgRom;
|
2016-11-23 18:48:29 -05:00
|
|
|
} else if((address & 0x50000000) == 0x50000000) {
|
2016-11-22 23:14:38 -05:00
|
|
|
type = AddressType::WorkRam;
|
2016-11-23 18:48:29 -05:00
|
|
|
} else if((address & 0x40000000) == 0x40000000) {
|
2016-11-22 23:14:38 -05:00
|
|
|
type = AddressType::SaveRam;
|
2016-12-03 10:46:59 -05:00
|
|
|
} else if((address & 0x30000000) == 0x30000000) {
|
2016-11-23 18:48:29 -05:00
|
|
|
type = AddressType::Register;
|
2016-12-03 10:46:59 -05:00
|
|
|
} else {
|
2019-01-16 19:07:50 -05:00
|
|
|
//Label is out of scope
|
2016-11-22 23:14:38 -05:00
|
|
|
return -1;
|
|
|
|
}
|
2016-11-23 18:48:29 -05:00
|
|
|
return _mapper->FromAbsoluteAddress(address & 0x0FFFFFFF, type);
|
2016-11-22 22:38:14 -05:00
|
|
|
}
|
2019-01-16 19:07:50 -05:00
|
|
|
//Label doesn't exist
|
|
|
|
return -2;
|
2017-12-27 12:03:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool LabelManager::HasLabelOrComment(uint16_t relativeAddr)
|
|
|
|
{
|
2018-12-10 19:52:16 -05:00
|
|
|
int32_t labelAddr = GetLabelAddress(relativeAddr);
|
2017-12-27 12:03:35 -05:00
|
|
|
|
|
|
|
if(labelAddr >= 0) {
|
|
|
|
return
|
|
|
|
_codeLabels.find(labelAddr) != _codeLabels.end() ||
|
|
|
|
_codeComments.find(labelAddr) != _codeComments.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LabelManager::HasLabelOrComment(uint32_t absoluteAddr, AddressType addressType)
|
|
|
|
{
|
|
|
|
int32_t labelAddr = GetLabelAddress(absoluteAddr, addressType);
|
|
|
|
|
|
|
|
if(labelAddr >= 0) {
|
|
|
|
return
|
|
|
|
_codeLabels.find(labelAddr) != _codeLabels.end() ||
|
|
|
|
_codeComments.find(labelAddr) != _codeComments.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|