1 #include "stdafx.h"
2 #include "LabelManager.h"
3 #include "Debugger.h"
4 #include "BaseMapper.h"
5
LabelManager(shared_ptr<BaseMapper> mapper)6 LabelManager::LabelManager(shared_ptr<BaseMapper> mapper)
7 {
8 _mapper = mapper;
9 }
10
DeleteLabels()11 void LabelManager::DeleteLabels()
12 {
13 _codeComments.clear();
14 _codeLabels.clear();
15 _codeLabelReverseLookup.clear();
16 }
17
SetLabel(uint32_t address,AddressType addressType,string label,string comment)18 void LabelManager::SetLabel(uint32_t address, AddressType addressType, string label, string comment)
19 {
20 address = GetLabelAddress(address, addressType);
21
22 auto existingLabel = _codeLabels.find(address);
23 if(existingLabel != _codeLabels.end()) {
24 _codeLabelReverseLookup.erase(existingLabel->second);
25 }
26
27 _codeLabels.erase(address);
28 if(!label.empty()) {
29 if(label.size() > 400) {
30 //Restrict labels to 400 bytes
31 label = label.substr(0, 400);
32 }
33 _codeLabels.emplace(address, label);
34 _codeLabelReverseLookup.emplace(label, address);
35 }
36
37 _codeComments.erase(address);
38 if(!comment.empty()) {
39 _codeComments.emplace(address, comment);
40 }
41 }
42
GetLabelAddress(uint32_t absoluteAddr,AddressType addressType)43 int32_t LabelManager::GetLabelAddress(uint32_t absoluteAddr, AddressType addressType)
44 {
45 switch(addressType) {
46 case AddressType::InternalRam: absoluteAddr |= 0x70000000; break;
47 case AddressType::PrgRom: absoluteAddr |= 0x60000000; break;
48 case AddressType::WorkRam: absoluteAddr |= 0x50000000; break;
49 case AddressType::SaveRam: absoluteAddr |= 0x40000000; break;
50 case AddressType::Register: absoluteAddr |= 0x30000000; break;
51 }
52 return absoluteAddr;
53 }
54
GetLabelAddress(uint16_t relativeAddr)55 int32_t LabelManager::GetLabelAddress(uint16_t relativeAddr)
56 {
57 if(relativeAddr < 0x2000) {
58 return relativeAddr | 0x70000000;
59 } else {
60 int32_t addr = _mapper->ToAbsoluteAddress(relativeAddr);
61 if(addr >= 0) {
62 //PRG ROM
63 return addr | 0x60000000;
64 }
65
66 addr = _mapper->ToAbsoluteWorkRamAddress(relativeAddr);
67 if(addr >= 0) {
68 //Work RAM
69 return addr | 0x50000000;
70 }
71
72 addr = _mapper->ToAbsoluteSaveRamAddress(relativeAddr);
73 if(addr >= 0) {
74 //Save RAM
75 return addr | 0x40000000;
76 }
77 }
78
79 return -1;
80 }
81
GetLabel(uint16_t relativeAddr,bool checkRegisters)82 string LabelManager::GetLabel(uint16_t relativeAddr, bool checkRegisters)
83 {
84 int32_t labelAddr = GetLabelAddress(relativeAddr);
85
86 if(labelAddr >= 0) {
87 auto result = _codeLabels.find(labelAddr);
88 if(result != _codeLabels.end()) {
89 return result->second;
90 }
91 }
92
93 if(checkRegisters) {
94 labelAddr = relativeAddr | 0x30000000;
95
96 auto result = _codeLabels.find(labelAddr);
97 if(result != _codeLabels.end()) {
98 return result->second;
99 }
100 }
101
102 return "";
103 }
104
GetComment(uint16_t relativeAddr)105 string LabelManager::GetComment(uint16_t relativeAddr)
106 {
107 int32_t labelAddr = GetLabelAddress(relativeAddr);
108
109 if(labelAddr >= 0) {
110 auto result = _codeComments.find(labelAddr);
111 if(result != _codeComments.end()) {
112 return result->second;
113 }
114 }
115
116 return "";
117 }
118
GetLabelAndComment(uint16_t relativeAddr,string & label,string & comment)119 void LabelManager::GetLabelAndComment(uint16_t relativeAddr, string &label, string &comment)
120 {
121 int32_t labelAddr = GetLabelAddress(relativeAddr);
122
123 if(labelAddr >= 0) {
124 auto result = _codeLabels.find(labelAddr);
125 if(result != _codeLabels.end()) {
126 label = result->second;
127 } else {
128 label.clear();
129 }
130
131 auto commentResult = _codeComments.find(labelAddr);
132 if(commentResult != _codeComments.end()) {
133 comment = commentResult->second;
134 } else {
135 comment.clear();
136 }
137 }
138 }
139
ContainsLabel(string & label)140 bool LabelManager::ContainsLabel(string &label)
141 {
142 return _codeLabelReverseLookup.find(label) != _codeLabelReverseLookup.end();
143 }
144
GetLabelRelativeAddress(string & label)145 int32_t LabelManager::GetLabelRelativeAddress(string &label)
146 {
147 auto result = _codeLabelReverseLookup.find(label);
148 if(result != _codeLabelReverseLookup.end()) {
149 uint32_t address = result->second;
150 AddressType type = AddressType::InternalRam;
151 if((address & 0x70000000) == 0x70000000) {
152 type = AddressType::InternalRam;
153 } else if((address & 0x60000000) == 0x60000000) {
154 type = AddressType::PrgRom;
155 } else if((address & 0x50000000) == 0x50000000) {
156 type = AddressType::WorkRam;
157 } else if((address & 0x40000000) == 0x40000000) {
158 type = AddressType::SaveRam;
159 } else if((address & 0x30000000) == 0x30000000) {
160 type = AddressType::Register;
161 } else {
162 //Label is out of scope
163 return -1;
164 }
165 return _mapper->FromAbsoluteAddress(address & 0x0FFFFFFF, type);
166 }
167 //Label doesn't exist
168 return -2;
169 }
170
HasLabelOrComment(uint16_t relativeAddr)171 bool LabelManager::HasLabelOrComment(uint16_t relativeAddr)
172 {
173 int32_t labelAddr = GetLabelAddress(relativeAddr);
174
175 if(labelAddr >= 0) {
176 return
177 _codeLabels.find(labelAddr) != _codeLabels.end() ||
178 _codeComments.find(labelAddr) != _codeComments.end();
179 }
180
181 return false;
182 }
183
HasLabelOrComment(uint32_t absoluteAddr,AddressType addressType)184 bool LabelManager::HasLabelOrComment(uint32_t absoluteAddr, AddressType addressType)
185 {
186 int32_t labelAddr = GetLabelAddress(absoluteAddr, addressType);
187
188 if(labelAddr >= 0) {
189 return
190 _codeLabels.find(labelAddr) != _codeLabels.end() ||
191 _codeComments.find(labelAddr) != _codeComments.end();
192 }
193
194 return false;
195 }
196