@@ -1,56 +1,58 @@ |
| 1 |
program rgb2sdas; |
1 |
unit rgb2sdas; |
| 2 |
|
2 |
|
| 3 |
{$mode objfpc}{$H+} |
3 |
{$mode objfpc}{$H+} |
| 4 |
|
4 |
|
|
|
5 |
interface |
|
|
6 |
|
| 5 |
uses |
7 |
uses |
| 6 |
{$IFDEF UNIX}{$IFDEF UseCThreads} |
8 |
{$IFDEF UNIX}{$IFDEF UseCThreads} |
| 7 |
cthreads, |
9 |
cthreads, |
| 8 |
{$ENDIF}{$ENDIF} |
10 |
{$ENDIF}{$ENDIF} |
| 9 |
Classes, SysUtils, strutils, math |
11 |
Classes, SysUtils, strutils, Math |
| 10 |
{ you can add units after this }; |
12 |
{ you can add units after this }; |
| 11 |
|
13 |
|
| 12 |
type |
14 |
type |
| 13 |
TRSymbol = packed record |
15 |
TRSymbol = packed record |
| 14 |
ID: Integer; |
16 |
ID: integer; |
| 15 |
Name: String; |
17 |
Name: string; |
| 16 |
SymType: Byte; |
18 |
SymType: byte; |
| 17 |
|
19 |
|
| 18 |
No: Integer; |
20 |
No: integer; |
| 19 |
|
21 |
|
| 20 |
FileName: String; |
22 |
FileName: string; |
| 21 |
LineNum, SectionID, Value: LongInt; |
23 |
LineNum, SectionID, Value: longint; |
| 22 |
end; |
24 |
end; |
| 23 |
|
25 |
|
| 24 |
TRPatch = packed record |
26 |
TRPatch = packed record |
| 25 |
SourceFile: String; |
27 |
SourceFile: string; |
| 26 |
Offset: LongInt; |
28 |
Offset: longint; |
| 27 |
PCSectionID: LongInt; |
29 |
PCSectionID: longint; |
| 28 |
PCOffset: LongInt; |
30 |
PCOffset: longint; |
| 29 |
PatchType: Byte; |
31 |
PatchType: byte; |
| 30 |
RPNSize: LongInt; |
32 |
RPNSize: longint; |
| 31 |
RPN: array of Byte; |
33 |
RPN: array of byte; |
| 32 |
end; |
34 |
end; |
| 33 |
|
35 |
|
| 34 |
TRSection = packed record |
36 |
TRSection = packed record |
| 35 |
ID: Integer; |
37 |
ID: integer; |
| 36 |
Name: String; |
38 |
Name: string; |
| 37 |
Size: LongInt; |
39 |
Size: longint; |
| 38 |
SectType: Byte; |
40 |
SectType: byte; |
| 39 |
Org: LongInt; |
41 |
Org: longint; |
| 40 |
Bank: LongInt; |
42 |
Bank: longint; |
| 41 |
Align: Byte; |
43 |
Align: byte; |
| 42 |
Ofs: LongInt; |
44 |
Ofs: longint; |
| 43 |
|
45 |
|
| 44 |
Data: array of Byte; |
46 |
Data: array of byte; |
| 45 |
NumberOfPatches: LongInt; |
47 |
NumberOfPatches: longint; |
| 46 |
Patches: array of TRPatch; |
48 |
Patches: array of TRPatch; |
| 47 |
end; |
49 |
end; |
| 48 |
|
50 |
|
| 49 |
TRObj = packed record |
51 |
TRObj = packed record |
| 50 |
ID: array[0..3] of AnsiChar; |
52 |
ID: array[0..3] of AnsiChar; |
| 51 |
RevisionNumber: LongInt; |
53 |
RevisionNumber: longint; |
| 52 |
NumberOfSymbols: LongInt; |
54 |
NumberOfSymbols: longint; |
| 53 |
NumberOfSections: LongInt; |
55 |
NumberOfSections: longint; |
| 54 |
|
56 |
|
| 55 |
Symbols: array of TRSymbol; |
57 |
Symbols: array of TRSymbol; |
| 56 |
Sections: array of TRSection; |
58 |
Sections: array of TRSection; |
@@ -87,28 +89,37 @@ type |
| 87 |
rpnSymbol); |
89 |
rpnSymbol); |
| 88 |
|
90 |
|
| 89 |
TRPNNode = record |
91 |
TRPNNode = record |
| 90 |
case Tag: TRPNTag of |
92 |
case Tag: TRPNTag of |
| 91 |
rpnBankSymbol: (BankSymbol: Integer); |
93 |
rpnBankSymbol: (BankSymbol: integer); |
| 92 |
rpnBankSection: (BankSection: Integer); |
94 |
rpnBankSection: (BankSection: integer); |
| 93 |
rpnInteger: (IntValue: Integer); |
95 |
rpnInteger: (IntValue: integer); |
| 94 |
rpnSymbol: (SymbolID: Integer); |
96 |
rpnSymbol: (SymbolID: integer); |
| 95 |
end; |
97 |
end; |
| 96 |
TRPN = array of TRPNNode; |
98 |
TRPN = array of TRPNNode; |
| 97 |
|
99 |
|
| 98 |
type |
100 |
type |
| 99 |
TObjFileStream = class(TFileStream) |
101 |
TObjFileStream = class(TFileStream) |
| 100 |
function ReadNullTerm: string; virtual; |
102 |
function ReadNullTerm: string; virtual; |
| 101 |
end; |
103 |
end; |
| 102 |
|
104 |
|
|
|
105 |
EObjectConversionException = class(Exception); |
|
|
106 |
|
|
|
107 |
procedure ConvertRGB2SDAS(Filename: string); |
|
|
108 |
|
|
|
109 |
implementation |
|
|
110 |
|
| 103 |
function TObjFileStream.ReadNullTerm: string; |
111 |
function TObjFileStream.ReadNullTerm: string; |
| 104 |
var B: Byte; |
112 |
var |
|
|
113 |
B: byte; |
| 105 |
begin |
114 |
begin |
| 106 |
Result := ''; |
115 |
Result := ''; |
| 107 |
while True do begin |
116 |
while True do |
|
|
117 |
begin |
| 108 |
B := ReadByte; |
118 |
B := ReadByte; |
| 109 |
if B = 0 then Exit; |
119 |
if B = 0 then |
|
|
120 |
Exit; |
| 110 |
Result += Chr(B); |
121 |
Result += Chr(B); |
| 111 |
end |
122 |
end; |
| 112 |
end; |
123 |
end; |
| 113 |
|
124 |
|
| 114 |
const |
125 |
const |
@@ -121,87 +132,107 @@ const |
| 121 |
SRAM = 6; |
132 |
SRAM = 6; |
| 122 |
OAM = 7; |
133 |
OAM = 7; |
| 123 |
|
134 |
|
| 124 |
const |
135 |
const |
| 125 |
SYM_LOCAL = 0; |
136 |
SYM_LOCAL = 0; |
| 126 |
SYM_IMPORT = 1; |
137 |
SYM_IMPORT = 1; |
| 127 |
SYM_EXPORT = 2; |
138 |
SYM_EXPORT = 2; |
| 128 |
|
139 |
|
| 129 |
const |
140 |
const |
| 130 |
PATCH_BYTE = 0; |
141 |
PATCH_BYTE = 0; |
| 131 |
PATCH_LE_WORD = 1; |
142 |
PATCH_LE_WORD = 1; |
| 132 |
PATCH_LE_LONG = 2; |
143 |
PATCH_LE_LONG = 2; |
| 133 |
PATCH_JR = 3; |
144 |
PATCH_JR = 3; |
| 134 |
|
145 |
|
| 135 |
procedure Die(const S: String); overload; |
146 |
procedure Die(const S: string); overload; |
| 136 |
begin WriteLn('ERROR:', S); Halt; end; |
147 |
begin |
| 137 |
procedure Die(const fmt: String; const params: array of const); overload; |
148 |
raise EObjectConversionException.Create(S); |
| 138 |
begin Die(format(fmt, params)); end; |
149 |
end; |
|
|
150 |
|
|
|
151 |
procedure Die(const fmt: string; const params: array of const); overload; |
|
|
152 |
begin |
|
|
153 |
Die(format(fmt, params)); |
|
|
154 |
end; |
| 139 |
|
155 |
|
| 140 |
function ReadObjFile(const afilename: string): TRObj; |
156 |
function ReadObjFile(const afilename: string): TRObj; |
| 141 |
const Sign : array[0..3] of AnsiChar = 'RGB9'; |
157 |
const |
| 142 |
var I, J: Integer; |
158 |
Sign: array[0..3] of AnsiChar = 'RGB9'; |
|
|
159 |
var |
|
|
160 |
I, J: integer; |
| 143 |
begin |
161 |
begin |
| 144 |
with TObjFileStream.Create(afilename, fmOpenRead) do try |
162 |
with TObjFileStream.Create(afilename, fmOpenRead) do |
| 145 |
Read(Result, SizeOf(TRObj) - SizeOf(Result.Symbols) - SizeOf(Result.Sections)); |
163 |
try |
| 146 |
if not (CompareMem(@Result.ID, @Sign, sizeof(Result.ID)) and (Result.RevisionNumber = 5)) then Die('Unsupported object file version!'); |
164 |
Read(Result, SizeOf(TRObj) - SizeOf(Result.Symbols) - SizeOf(Result.Sections)); |
| 147 |
SetLength(Result.Symbols, Result.NumberOfSymbols); |
165 |
if not (CompareMem(@Result.ID, @Sign, sizeof(Result.ID)) and |
| 148 |
SetLength(Result.Sections, Result.NumberOfSections); |
166 |
(Result.RevisionNumber = 5)) then |
| 149 |
|
167 |
Die('Unsupported object file version!'); |
| 150 |
for I := 0 to Result.NumberOfSymbols-1 do begin |
168 |
SetLength(Result.Symbols, Result.NumberOfSymbols); |
| 151 |
Result.Symbols[I] := Default(TRSymbol); |
169 |
SetLength(Result.Sections, Result.NumberOfSections); |
| 152 |
with Result.Symbols[I] do begin |
170 |
|
| 153 |
ID := I; |
171 |
for I := 0 to Result.NumberOfSymbols - 1 do |
| 154 |
Name := ReadNullTerm; |
172 |
begin |
| 155 |
Read(SymType, 1); |
173 |
Result.Symbols[I] := Default(TRSymbol); |
| 156 |
if ((SymType and $7F) <> SYM_IMPORT) then begin |
174 |
with Result.Symbols[I] do |
| 157 |
FileName := ReadNullTerm; |
175 |
begin |
| 158 |
Read(LineNum, SizeOf(LineNum)); |
176 |
ID := I; |
| 159 |
Read(SectionID, SizeOf(SectionID)); |
177 |
Name := ReadNullTerm; |
| 160 |
Read(Value, SizeOf(Value)); |
178 |
Read(SymType, 1); |
|
|
179 |
if ((SymType and $7F) <> SYM_IMPORT) then |
|
|
180 |
begin |
|
|
181 |
FileName := ReadNullTerm; |
|
|
182 |
Read(LineNum, SizeOf(LineNum)); |
|
|
183 |
Read(SectionID, SizeOf(SectionID)); |
|
|
184 |
Read(Value, SizeOf(Value)); |
|
|
185 |
end; |
| 161 |
end; |
186 |
end; |
| 162 |
end; |
187 |
end; |
| 163 |
end; |
|
|
| 164 |
|
188 |
|
| 165 |
for I := 0 to Result.NumberOfSections-1 do begin |
189 |
for I := 0 to Result.NumberOfSections - 1 do |
| 166 |
Result.Sections[I] := Default(TRSection); |
190 |
begin |
| 167 |
with Result.Sections[I] do begin |
191 |
Result.Sections[I] := Default(TRSection); |
| 168 |
ID := I; |
192 |
with Result.Sections[I] do |
| 169 |
Name := ReadNullTerm; |
193 |
begin |
| 170 |
Read(Size, SizeOf(Size)); |
194 |
ID := I; |
| 171 |
Read(SectType, SizeOf(SectType)); |
195 |
Name := ReadNullTerm; |
| 172 |
Read(Org, SizeOf(Org)); |
196 |
Read(Size, SizeOf(Size)); |
| 173 |
Read(Bank, SizeOf(Bank)); |
197 |
Read(SectType, SizeOf(SectType)); |
| 174 |
Read(Align, SizeOf(Align)); |
198 |
Read(Org, SizeOf(Org)); |
| 175 |
Read(Ofs, SizeOf(Ofs)); |
199 |
Read(Bank, SizeOf(Bank)); |
| 176 |
if ((SectType = ROMX) or (SectType = ROM0)) then begin |
200 |
Read(Align, SizeOf(Align)); |
| 177 |
SetLength(Data, Size); |
201 |
Read(Ofs, SizeOf(Ofs)); |
| 178 |
Read(Data[0], Size); |
202 |
if ((SectType = ROMX) or (SectType = ROM0)) then |
| 179 |
Read(NumberOfPatches, SizeOf(NumberOfPatches)); |
203 |
begin |
| 180 |
SetLength(Patches, NumberOfPatches); |
204 |
SetLength(Data, Size); |
|
|
205 |
Read(Data[0], Size); |
|
|
206 |
Read(NumberOfPatches, SizeOf(NumberOfPatches)); |
|
|
207 |
SetLength(Patches, NumberOfPatches); |
|
|
208 |
end; |
| 181 |
end; |
209 |
end; |
| 182 |
end; |
|
|
| 183 |
|
210 |
|
| 184 |
for J := 0 to Result.Sections[I].NumberOfPatches-1 do begin |
211 |
for J := 0 to Result.Sections[I].NumberOfPatches - 1 do |
| 185 |
with Result.Sections[I].Patches[J] do begin |
212 |
begin |
| 186 |
SourceFile := ReadNullTerm; |
213 |
with Result.Sections[I].Patches[J] do |
| 187 |
Read(Offset, SizeOf(Offset)); |
214 |
begin |
| 188 |
Read(PCSectionID, SizeOf(PCSectionID)); |
215 |
SourceFile := ReadNullTerm; |
| 189 |
Read(PCOffset, SizeOf(PCOffset)); |
216 |
Read(Offset, SizeOf(Offset)); |
| 190 |
Read(PatchType, SizeOf(PatchType)); |
217 |
Read(PCSectionID, SizeOf(PCSectionID)); |
| 191 |
Read(RPNSize, SizeOf(RPNSize)); |
218 |
Read(PCOffset, SizeOf(PCOffset)); |
| 192 |
SetLength(RPN, RPNSize); |
219 |
Read(PatchType, SizeOf(PatchType)); |
| 193 |
Read(RPN[0], RPNSize); |
220 |
Read(RPNSize, SizeOf(RPNSize)); |
|
|
221 |
SetLength(RPN, RPNSize); |
|
|
222 |
Read(RPN[0], RPNSize); |
|
|
223 |
end; |
| 194 |
end; |
224 |
end; |
| 195 |
end; |
225 |
end; |
|
|
226 |
finally |
|
|
227 |
Free; |
| 196 |
end; |
228 |
end; |
| 197 |
finally free; end; |
|
|
| 198 |
end; |
229 |
end; |
| 199 |
|
230 |
|
| 200 |
function RPNToString(const RPN: array of Byte; const Syms: array of TRSymbol): String; |
231 |
function RPNToString(const RPN: array of byte; const Syms: array of TRSymbol): string; |
| 201 |
var |
232 |
var |
| 202 |
I: Integer; |
233 |
I: integer; |
| 203 |
|
234 |
|
| 204 |
function ReadLong: LongWord; |
235 |
function ReadLong: longword; |
| 205 |
begin |
236 |
begin |
| 206 |
Inc(I); |
237 |
Inc(I); |
| 207 |
Result := RPN[I]; |
238 |
Result := RPN[I]; |
@@ -219,47 +250,157 @@ begin |
| 219 |
Result := ''; |
250 |
Result := ''; |
| 220 |
|
251 |
|
| 221 |
I := Low(RPN); |
252 |
I := Low(RPN); |
| 222 |
while I <= High(RPN) do begin |
253 |
while I <= High(RPN) do |
|
|
254 |
begin |
| 223 |
case RPN[I] of |
255 |
case RPN[I] of |
| 224 |
$00: begin Result += '+ '; Inc(I); end; |
256 |
$00: |
| 225 |
$01: begin Result += '- '; Inc(I); end; |
257 |
begin |
| 226 |
$02: begin Result += '* '; Inc(I); end; |
258 |
Result += '+ '; |
| 227 |
$03: begin Result += '/ '; Inc(I); end; |
259 |
Inc(I); |
| 228 |
$04: begin Result += '% '; Inc(I); end; |
260 |
end; |
| 229 |
$05: begin Result += 'neg '; Inc(I); end; |
261 |
$01: |
| 230 |
$10: begin Result += '| '; Inc(I); end; |
262 |
begin |
| 231 |
$11: begin Result += '& '; Inc(I); end; |
263 |
Result += '- '; |
| 232 |
$12: begin Result += '^ '; Inc(I); end; |
264 |
Inc(I); |
| 233 |
$13: begin Result += '~ '; Inc(I); end; |
265 |
end; |
| 234 |
$21: begin Result += '&& '; Inc(I); end; |
266 |
$02: |
| 235 |
$22: begin Result += '|| '; Inc(I); end; |
267 |
begin |
| 236 |
$23: begin Result += '! '; Inc(I); end; |
268 |
Result += '* '; |
| 237 |
$30: begin Result += '== '; Inc(I); end; |
269 |
Inc(I); |
| 238 |
$31: begin Result += '!= '; Inc(I); end; |
270 |
end; |
| 239 |
$32: begin Result += '> '; Inc(I); end; |
271 |
$03: |
| 240 |
$33: begin Result += '< '; Inc(I); end; |
272 |
begin |
| 241 |
$34: begin Result += '>= '; Inc(I); end; |
273 |
Result += '/ '; |
| 242 |
$35: begin Result += '<= '; Inc(I); end; |
274 |
Inc(I); |
| 243 |
$40: begin Result += '<< '; Inc(I); end; |
275 |
end; |
| 244 |
$41: begin Result += '>> '; Inc(I); end; |
276 |
$04: |
| 245 |
$50: begin Result += '(bank-sym ' + IntToStr(ReadLong)+') '; end; |
277 |
begin |
| 246 |
$51: begin Result += '(bank-section ' + IntToStr(ReadLong)+') '; end; |
278 |
Result += '% '; |
| 247 |
$52: begin Result += 'current-bank'; Inc(I); end; |
279 |
Inc(I); |
| 248 |
$60: begin Result += 'hram-check'; Inc(I); end; |
280 |
end; |
| 249 |
$61: begin Result += 'rst-check'; Inc(I); end; |
281 |
$05: |
| 250 |
$80: begin Result += '(int ' + IntToStr(ReadLong)+') '; end; |
282 |
begin |
| 251 |
$81: begin Result += '(sym ' + Syms[ReadLong].Name+') '; end; |
283 |
Result += 'neg '; |
| 252 |
else Exit('INVALID!'); |
284 |
Inc(I); |
|
|
285 |
end; |
|
|
286 |
$10: |
|
|
287 |
begin |
|
|
288 |
Result += '| '; |
|
|
289 |
Inc(I); |
|
|
290 |
end; |
|
|
291 |
$11: |
|
|
292 |
begin |
|
|
293 |
Result += '& '; |
|
|
294 |
Inc(I); |
|
|
295 |
end; |
|
|
296 |
$12: |
|
|
297 |
begin |
|
|
298 |
Result += '^ '; |
|
|
299 |
Inc(I); |
|
|
300 |
end; |
|
|
301 |
$13: |
|
|
302 |
begin |
|
|
303 |
Result += '~ '; |
|
|
304 |
Inc(I); |
|
|
305 |
end; |
|
|
306 |
$21: |
|
|
307 |
begin |
|
|
308 |
Result += '&& '; |
|
|
309 |
Inc(I); |
|
|
310 |
end; |
|
|
311 |
$22: |
|
|
312 |
begin |
|
|
313 |
Result += '|| '; |
|
|
314 |
Inc(I); |
|
|
315 |
end; |
|
|
316 |
$23: |
|
|
317 |
begin |
|
|
318 |
Result += '! '; |
|
|
319 |
Inc(I); |
|
|
320 |
end; |
|
|
321 |
$30: |
|
|
322 |
begin |
|
|
323 |
Result += '== '; |
|
|
324 |
Inc(I); |
|
|
325 |
end; |
|
|
326 |
$31: |
|
|
327 |
begin |
|
|
328 |
Result += '!= '; |
|
|
329 |
Inc(I); |
|
|
330 |
end; |
|
|
331 |
$32: |
|
|
332 |
begin |
|
|
333 |
Result += '> '; |
|
|
334 |
Inc(I); |
|
|
335 |
end; |
|
|
336 |
$33: |
|
|
337 |
begin |
|
|
338 |
Result += '< '; |
|
|
339 |
Inc(I); |
|
|
340 |
end; |
|
|
341 |
$34: |
|
|
342 |
begin |
|
|
343 |
Result += '>= '; |
|
|
344 |
Inc(I); |
|
|
345 |
end; |
|
|
346 |
$35: |
|
|
347 |
begin |
|
|
348 |
Result += '<= '; |
|
|
349 |
Inc(I); |
|
|
350 |
end; |
|
|
351 |
$40: |
|
|
352 |
begin |
|
|
353 |
Result += '<< '; |
|
|
354 |
Inc(I); |
|
|
355 |
end; |
|
|
356 |
$41: |
|
|
357 |
begin |
|
|
358 |
Result += '>> '; |
|
|
359 |
Inc(I); |
|
|
360 |
end; |
|
|
361 |
$50: |
|
|
362 |
begin |
|
|
363 |
Result += '(bank-sym ' + IntToStr(ReadLong) + ') '; |
|
|
364 |
end; |
|
|
365 |
$51: |
|
|
366 |
begin |
|
|
367 |
Result += '(bank-section ' + IntToStr(ReadLong) + ') '; |
|
|
368 |
end; |
|
|
369 |
$52: |
|
|
370 |
begin |
|
|
371 |
Result += 'current-bank'; |
|
|
372 |
Inc(I); |
|
|
373 |
end; |
|
|
374 |
$60: |
|
|
375 |
begin |
|
|
376 |
Result += 'hram-check'; |
|
|
377 |
Inc(I); |
|
|
378 |
end; |
|
|
379 |
$61: |
|
|
380 |
begin |
|
|
381 |
Result += 'rst-check'; |
|
|
382 |
Inc(I); |
|
|
383 |
end; |
|
|
384 |
$80: |
|
|
385 |
begin |
|
|
386 |
Result += '(int ' + IntToStr(ReadLong) + ') '; |
|
|
387 |
end; |
|
|
388 |
$81: |
|
|
389 |
begin |
|
|
390 |
Result += '(sym ' + Syms[ReadLong].Name + ') '; |
|
|
391 |
end; |
|
|
392 |
else |
|
|
393 |
Exit('INVALID!'); |
| 253 |
end; |
394 |
end; |
| 254 |
end; |
395 |
end; |
| 255 |
end; |
396 |
end; |
| 256 |
|
397 |
|
| 257 |
function ParseRPN(const RPN: array of Byte): TRPN; |
398 |
function ParseRPN(const RPN: array of byte): TRPN; |
| 258 |
var |
399 |
var |
| 259 |
I: Integer; |
400 |
I: integer; |
| 260 |
Node: TRPNNode; |
401 |
Node: TRPNNode; |
| 261 |
|
402 |
|
| 262 |
function ReadLong: LongWord; |
403 |
function ReadLong: longword; |
| 263 |
begin |
404 |
begin |
| 264 |
Inc(I); |
405 |
Inc(I); |
| 265 |
Result := RPN[I]; |
406 |
Result := RPN[I]; |
@@ -274,65 +415,169 @@ var |
| 274 |
end; |
415 |
end; |
| 275 |
|
416 |
|
| 276 |
function nd(Tag: TRPNTag): TRPNNode; |
417 |
function nd(Tag: TRPNTag): TRPNNode; |
| 277 |
begin Result.Tag := Tag; end; |
418 |
begin |
|
|
419 |
Result.Tag := Tag; |
|
|
420 |
end; |
| 278 |
|
421 |
|
| 279 |
procedure PushRPN(Node: TRPNNode); |
422 |
procedure PushRPN(Node: TRPNNode); |
| 280 |
begin |
423 |
begin |
| 281 |
SetLength(Result, Length(Result)+1); |
424 |
SetLength(Result, Length(Result) + 1); |
| 282 |
Result[High(Result)] := Node; |
425 |
Result[High(Result)] := Node; |
| 283 |
end; |
426 |
end; |
| 284 |
|
427 |
|
| 285 |
begin |
428 |
begin |
| 286 |
SetLength(Result, 0); |
429 |
SetLength(Result, 0); |
| 287 |
I := Low(RPN); |
430 |
I := Low(RPN); |
| 288 |
while I <= High(RPN) do begin |
431 |
while I <= High(RPN) do |
|
|
432 |
begin |
| 289 |
//Writeln(Format('Parsing %x, len=%d', [RPN[I], Length(Result)])); |
433 |
//Writeln(Format('Parsing %x, len=%d', [RPN[I], Length(Result)])); |
| 290 |
case RPN[I] of |
434 |
case RPN[I] of |
| 291 |
$00: begin PushRPN(Nd(rpnPlus)); Inc(I); end; |
435 |
$00: |
| 292 |
$01: begin PushRPN(Nd(rpnMinus)); Inc(I); end; |
436 |
begin |
| 293 |
$02: begin PushRPN(Nd(rpnTimes)); Inc(I); end; |
437 |
PushRPN(Nd(rpnPlus)); |
| 294 |
$03: begin PushRPN(Nd(rpnDiv)); Inc(I); end; |
438 |
Inc(I); |
| 295 |
$04: begin PushRPN(Nd(rpnMod)); Inc(I); end; |
439 |
end; |
| 296 |
$05: begin PushRPN(Nd(rpnNegate)); Inc(I); end; |
440 |
$01: |
| 297 |
$10: begin PushRPN(Nd(rpnOr)); Inc(I); end; |
441 |
begin |
| 298 |
$11: begin PushRPN(Nd(rpnAnd)); Inc(I); end; |
442 |
PushRPN(Nd(rpnMinus)); |
| 299 |
$12: begin PushRPN(Nd(rpnXor)); Inc(I); end; |
443 |
Inc(I); |
| 300 |
$13: begin PushRPN(Nd(rpnComplement)); Inc(I); end; |
444 |
end; |
| 301 |
$21: begin PushRPN(Nd(rpnBoolAnd)); Inc(I); end; |
445 |
$02: |
| 302 |
$22: begin PushRPN(Nd(rpnBoolOr)); Inc(I); end; |
446 |
begin |
| 303 |
$23: begin PushRPN(Nd(rpnBoolNeg)); Inc(I); end; |
447 |
PushRPN(Nd(rpnTimes)); |
| 304 |
$30: begin PushRPN(Nd(rpnEqual)); Inc(I); end; |
448 |
Inc(I); |
| 305 |
$31: begin PushRPN(Nd(rpnNotEqual)); Inc(I); end; |
449 |
end; |
| 306 |
$32: begin PushRPN(Nd(rpnGreater)); Inc(I); end; |
450 |
$03: |
| 307 |
$33: begin PushRPN(Nd(rpnLess)); Inc(I); end; |
451 |
begin |
| 308 |
$34: begin PushRPN(Nd(rpnGreaterEqual)); Inc(I); end; |
452 |
PushRPN(Nd(rpnDiv)); |
| 309 |
$35: begin PushRPN(Nd(rpnLessEqual)); Inc(I); end; |
453 |
Inc(I); |
| 310 |
$40: begin PushRPN(Nd(rpnShl)); Inc(I); end; |
454 |
end; |
| 311 |
$41: begin PushRPN(Nd(rpnShr)); Inc(I); end; |
455 |
$04: |
| 312 |
$50: begin |
456 |
begin |
| 313 |
Node.Tag := rpnBankSymbol; |
457 |
PushRPN(Nd(rpnMod)); |
| 314 |
Node.BankSymbol := ReadLong; |
458 |
Inc(I); |
| 315 |
PushRPN(Node); |
459 |
end; |
| 316 |
end; |
460 |
$05: |
| 317 |
$51: begin |
461 |
begin |
| 318 |
Node.Tag := rpnBankSection; |
462 |
PushRPN(Nd(rpnNegate)); |
| 319 |
Node.BankSection := ReadLong; |
463 |
Inc(I); |
| 320 |
PushRPN(Node); |
464 |
end; |
| 321 |
end; |
465 |
$10: |
| 322 |
$52: begin PushRPN(Nd(rpnCurrentBank)); Inc(I); end; |
466 |
begin |
| 323 |
$60: begin PushRPN(Nd(rpnHramCheck)); Inc(I); end; |
467 |
PushRPN(Nd(rpnOr)); |
| 324 |
$61: begin PushRPN(Nd(rpnRstCheck)); Inc(I); end; |
468 |
Inc(I); |
| 325 |
$80: begin |
469 |
end; |
| 326 |
Node.Tag := rpnInteger; |
470 |
$11: |
| 327 |
Node.IntValue := ReadLong; |
471 |
begin |
| 328 |
PushRPN(Node); |
472 |
PushRPN(Nd(rpnAnd)); |
| 329 |
end; |
473 |
Inc(I); |
| 330 |
$81: begin |
474 |
end; |
| 331 |
Node.Tag := rpnSymbol; |
475 |
$12: |
| 332 |
Node.SymbolID := ReadLong; |
476 |
begin |
| 333 |
PushRPN(Node); |
477 |
PushRPN(Nd(rpnXor)); |
| 334 |
end; |
478 |
Inc(I); |
| 335 |
else Die('Got malformed RPN!'); |
479 |
end; |
|
|
480 |
$13: |
|
|
481 |
begin |
|
|
482 |
PushRPN(Nd(rpnComplement)); |
|
|
483 |
Inc(I); |
|
|
484 |
end; |
|
|
485 |
$21: |
|
|
486 |
begin |
|
|
487 |
PushRPN(Nd(rpnBoolAnd)); |
|
|
488 |
Inc(I); |
|
|
489 |
end; |
|
|
490 |
$22: |
|
|
491 |
begin |
|
|
492 |
PushRPN(Nd(rpnBoolOr)); |
|
|
493 |
Inc(I); |
|
|
494 |
end; |
|
|
495 |
$23: |
|
|
496 |
begin |
|
|
497 |
PushRPN(Nd(rpnBoolNeg)); |
|
|
498 |
Inc(I); |
|
|
499 |
end; |
|
|
500 |
$30: |
|
|
501 |
begin |
|
|
502 |
PushRPN(Nd(rpnEqual)); |
|
|
503 |
Inc(I); |
|
|
504 |
end; |
|
|
505 |
$31: |
|
|
506 |
begin |
|
|
507 |
PushRPN(Nd(rpnNotEqual)); |
|
|
508 |
Inc(I); |
|
|
509 |
end; |
|
|
510 |
$32: |
|
|
511 |
begin |
|
|
512 |
PushRPN(Nd(rpnGreater)); |
|
|
513 |
Inc(I); |
|
|
514 |
end; |
|
|
515 |
$33: |
|
|
516 |
begin |
|
|
517 |
PushRPN(Nd(rpnLess)); |
|
|
518 |
Inc(I); |
|
|
519 |
end; |
|
|
520 |
$34: |
|
|
521 |
begin |
|
|
522 |
PushRPN(Nd(rpnGreaterEqual)); |
|
|
523 |
Inc(I); |
|
|
524 |
end; |
|
|
525 |
$35: |
|
|
526 |
begin |
|
|
527 |
PushRPN(Nd(rpnLessEqual)); |
|
|
528 |
Inc(I); |
|
|
529 |
end; |
|
|
530 |
$40: |
|
|
531 |
begin |
|
|
532 |
PushRPN(Nd(rpnShl)); |
|
|
533 |
Inc(I); |
|
|
534 |
end; |
|
|
535 |
$41: |
|
|
536 |
begin |
|
|
537 |
PushRPN(Nd(rpnShr)); |
|
|
538 |
Inc(I); |
|
|
539 |
end; |
|
|
540 |
$50: |
|
|
541 |
begin |
|
|
542 |
Node.Tag := rpnBankSymbol; |
|
|
543 |
Node.BankSymbol := ReadLong; |
|
|
544 |
PushRPN(Node); |
|
|
545 |
end; |
|
|
546 |
$51: |
|
|
547 |
begin |
|
|
548 |
Node.Tag := rpnBankSection; |
|
|
549 |
Node.BankSection := ReadLong; |
|
|
550 |
PushRPN(Node); |
|
|
551 |
end; |
|
|
552 |
$52: |
|
|
553 |
begin |
|
|
554 |
PushRPN(Nd(rpnCurrentBank)); |
|
|
555 |
Inc(I); |
|
|
556 |
end; |
|
|
557 |
$60: |
|
|
558 |
begin |
|
|
559 |
PushRPN(Nd(rpnHramCheck)); |
|
|
560 |
Inc(I); |
|
|
561 |
end; |
|
|
562 |
$61: |
|
|
563 |
begin |
|
|
564 |
PushRPN(Nd(rpnRstCheck)); |
|
|
565 |
Inc(I); |
|
|
566 |
end; |
|
|
567 |
$80: |
|
|
568 |
begin |
|
|
569 |
Node.Tag := rpnInteger; |
|
|
570 |
Node.IntValue := ReadLong; |
|
|
571 |
PushRPN(Node); |
|
|
572 |
end; |
|
|
573 |
$81: |
|
|
574 |
begin |
|
|
575 |
Node.Tag := rpnSymbol; |
|
|
576 |
Node.SymbolID := ReadLong; |
|
|
577 |
PushRPN(Node); |
|
|
578 |
end; |
|
|
579 |
else |
|
|
580 |
Die('Got malformed RPN!'); |
| 336 |
end; |
581 |
end; |
| 337 |
end; |
582 |
end; |
| 338 |
end; |
583 |
end; |
@@ -343,39 +588,45 @@ var |
| 343 |
Sym: TRSymbol; |
588 |
Sym: TRSymbol; |
| 344 |
Sect: TRSection; |
589 |
Sect: TRSection; |
| 345 |
Patch: TRPatch; |
590 |
Patch: TRPatch; |
| 346 |
SectSize: Integer; |
591 |
SectSize: integer; |
| 347 |
begin |
592 |
begin |
| 348 |
WriteLn('Symbols:'); |
593 |
WriteLn('Symbols:'); |
| 349 |
for Sym in O.Symbols do |
594 |
for Sym in O.Symbols do |
| 350 |
Writeln(Format(' %s on %d: type=%d, section=%d, value=%d', |
595 |
Writeln(Format(' %s on %d: type=%d, section=%d, value=%d', |
| 351 |
[Sym.Name, Sym.LineNum, Sym.SymType, Sym.SectionID, Sym.Value])); |
596 |
[Sym.Name, Sym.LineNum, Sym.SymType, Sym.SectionID, Sym.Value])); |
| 352 |
|
597 |
|
| 353 |
SectSize := 0; |
598 |
SectSize := 0; |
| 354 |
for Sect in O.Sections do |
599 |
for Sect in O.Sections do |
| 355 |
if (Sect.Org <> -1) and ((Sect.SectType = ROM0) or (Sect.SectType = ROMX)) then Inc(SectSize, Sect.Size); |
600 |
if (Sect.Org <> -1) and ((Sect.SectType = ROM0) or (Sect.SectType = ROMX)) then |
|
|
601 |
Inc(SectSize, Sect.Size); |
| 356 |
Writeln('Absolute sections: ', SectSize, ' bytes'); |
602 |
Writeln('Absolute sections: ', SectSize, ' bytes'); |
| 357 |
|
603 |
|
| 358 |
SectSize := 0; |
604 |
SectSize := 0; |
| 359 |
for Sect in O.Sections do |
605 |
for Sect in O.Sections do |
| 360 |
if (Sect.Org = -1) and ((Sect.SectType = ROM0) or (Sect.SectType = ROMX)) then Inc(SectSize, Sect.Size); |
606 |
if (Sect.Org = -1) and ((Sect.SectType = ROM0) or (Sect.SectType = ROMX)) then |
|
|
607 |
Inc(SectSize, Sect.Size); |
| 361 |
Writeln('Relative sections: ', SectSize, ' bytes'); |
608 |
Writeln('Relative sections: ', SectSize, ' bytes'); |
| 362 |
|
609 |
|
| 363 |
WriteLn('Sections:'); |
610 |
WriteLn('Sections:'); |
| 364 |
for Sect in O.Sections do begin |
611 |
for Sect in O.Sections do |
|
|
612 |
begin |
| 365 |
Writeln(Format(' %s with size %d: offset=%d, patches=%d, bank=%d', |
613 |
Writeln(Format(' %s with size %d: offset=%d, patches=%d, bank=%d', |
| 366 |
[Sect.Name, Sect.Size, Sect.Org, Sect.NumberOfPatches, Sect.Bank])); |
614 |
[Sect.Name, Sect.Size, Sect.Org, Sect.NumberOfPatches, Sect.Bank])); |
| 367 |
|
615 |
|
| 368 |
for Patch in Sect.Patches do |
616 |
for Patch in Sect.Patches do |
| 369 |
Writeln(Format(' %s: %d ; %s', [Patch.SourceFile, Patch.PatchType, RPNToString(Patch.RPN, O.Symbols)])); |
617 |
Writeln(Format(' %s: %d ; %s', [Patch.SourceFile, Patch.PatchType, |
|
|
618 |
RPNToString(Patch.RPN, O.Symbols)])); |
| 370 |
end; |
619 |
end; |
| 371 |
end; |
620 |
end; |
| 372 |
|
621 |
|
| 373 |
function FindPatch(const Section: TRSection; Index: Integer; out Patch: TRPatch): Boolean; |
622 |
function FindPatch(const Section: TRSection; Index: integer; |
|
|
623 |
out Patch: TRPatch): boolean; |
| 374 |
var |
624 |
var |
| 375 |
I: Integer; |
625 |
I: integer; |
| 376 |
begin |
626 |
begin |
| 377 |
for I := Low(Section.Patches) to High(Section.Patches) do |
627 |
for I := Low(Section.Patches) to High(Section.Patches) do |
| 378 |
if Section.Patches[I].Offset = Index then begin |
628 |
if Section.Patches[I].Offset = Index then |
|
|
629 |
begin |
| 379 |
Patch := Section.Patches[I]; |
630 |
Patch := Section.Patches[I]; |
| 380 |
Exit(True); |
631 |
Exit(True); |
| 381 |
end; |
632 |
end; |
@@ -383,6 +634,7 @@ begin |
| 383 |
Result := False; |
634 |
Result := False; |
| 384 |
end; |
635 |
end; |
| 385 |
|
636 |
|
|
|
637 |
procedure ConvertRGB2SDAS(Filename: string); |
| 386 |
var |
638 |
var |
| 387 |
RObj: TRObj; |
639 |
RObj: TRObj; |
| 388 |
|
640 |
|
@@ -392,38 +644,34 @@ var |
| 392 |
|
644 |
|
| 393 |
F: Text; |
645 |
F: Text; |
| 394 |
|
646 |
|
| 395 |
ValueToWrite: Word; |
647 |
ValueToWrite: word; |
| 396 |
RPN: TRPN; |
648 |
RPN: TRPN; |
| 397 |
I: Word; |
649 |
I: word; |
| 398 |
Sct: Word; |
650 |
Sct: word; |
| 399 |
WritePos: Word; |
651 |
WritePos: word; |
| 400 |
Idx: Integer; |
652 |
Idx: integer; |
| 401 |
CODESEG: string; |
653 |
CODESEG: string; |
| 402 |
DefaultBank: Integer = 1; |
654 |
DefaultBank: integer = 1; |
| 403 |
sourcename, tmp: string; |
655 |
sourcename, tmp: string; |
| 404 |
|
656 |
|
| 405 |
old_sym, new_sym: string; |
657 |
old_sym, new_sym: string; |
| 406 |
|
|
|
| 407 |
verbose: boolean = false; |
|
|
| 408 |
|
|
|
| 409 |
export_all: boolean = false; |
|
|
| 410 |
|
658 |
|
|
|
659 |
verbose: boolean = False; |
|
|
660 |
|
|
|
661 |
export_all: boolean = False; |
| 411 |
begin |
662 |
begin |
| 412 |
if (ParamCount() < 1) then begin |
663 |
sourcename := Filename; |
| 413 |
Writeln('Usage: rgb2sdas [-c<code_section>] [-v] [-e] [-r<symbol1>=<symbol2>] [-b<default_bank>] <object_name>'); |
664 |
if not FileExists(sourcename) then |
| 414 |
Halt; |
665 |
Die('File not found: %s', [sourcename]); |
| 415 |
end; |
666 |
|
| 416 |
|
667 |
old_sym := ''; |
| 417 |
sourcename:= ParamStr(ParamCount()); |
668 |
new_sym := ''; |
| 418 |
if not FileExists(sourcename) then Die('File not found: %s', [sourcename]); |
669 |
|
| 419 |
|
670 |
CODESEG := '_CODE'; |
| 420 |
old_sym:= ''; new_sym:= ''; |
671 |
{for I:= 1 to ParamCount() - 1 do begin |
| 421 |
|
|
|
| 422 |
CODESEG:= '_CODE'; |
|
|
| 423 |
for I:= 1 to ParamCount() - 1 do begin |
|
|
| 424 |
tmp:= ParamStr(i); |
672 |
tmp:= ParamStr(i); |
| 425 |
if (CompareText(tmp, '-v') = 0) then |
673 |
if (CompareText(tmp, '-v') = 0) then |
| 426 |
verbose:= true |
674 |
verbose:= true |
| 427 |
else if (CompareText(copy(tmp, 1, 2), '-e') = 0) then |
675 |
else if (CompareText(copy(tmp, 1, 2), '-e') = 0) then |
| 428 |
export_all:= true |
676 |
export_all:= true |
| 429 |
else if (CompareText(copy(tmp, 1, 2), '-c') = 0) then begin |
677 |
else if (CompareText(copy(tmp, 1, 2), '-c') = 0) then begin |
@@ -440,121 +688,173 @@ begin |
| 440 |
old_sym:= copy(tmp, 1, idx - 1); |
688 |
old_sym:= copy(tmp, 1, idx - 1); |
| 441 |
new_sym:= copy(tmp, idx + 1, length(tmp)); |
689 |
new_sym:= copy(tmp, idx + 1, length(tmp)); |
| 442 |
end; |
690 |
end; |
| 443 |
end; |
691 |
end; |
| 444 |
end; |
692 |
end;} |
| 445 |
|
693 |
|
| 446 |
RObj := ReadObjFile(sourcename); |
694 |
RObj := ReadObjFile(sourcename); |
| 447 |
if verbose then PrintObjFile(RObj); |
695 |
if verbose then |
|
|
696 |
PrintObjFile(RObj); |
| 448 |
|
697 |
|
| 449 |
Assign(F, sourcename + '.o'); |
698 |
Assign(F, sourcename + '.o'); |
| 450 |
Rewrite(F); |
699 |
Rewrite(F); |
| 451 |
try |
700 |
try |
| 452 |
Idx:= 0; |
701 |
Idx := 0; |
| 453 |
// pass 1: all imports first |
702 |
// pass 1: all imports first |
| 454 |
for I:= Low(RObj.Symbols) to High(RObj.Symbols) do with RObj.Symbols[I] do begin |
703 |
for I := Low(RObj.Symbols) to High(RObj.Symbols) do |
| 455 |
if ((SymType and $7f) = SYM_IMPORT) then begin |
704 |
with RObj.Symbols[I] do |
| 456 |
No:= Idx; |
705 |
begin |
| 457 |
Inc(Idx); |
706 |
if ((SymType and $7f) = SYM_IMPORT) then |
| 458 |
end else No:= -1; |
707 |
begin |
| 459 |
end; |
708 |
No := Idx; |
|
|
709 |
Inc(Idx); |
|
|
710 |
end |
|
|
711 |
else |
|
|
712 |
No := -1; |
|
|
713 |
end; |
| 460 |
// pass 2: all other (export local only when forced) |
714 |
// pass 2: all other (export local only when forced) |
| 461 |
for I:= Low(RObj.Symbols) to High(RObj.Symbols) do with RObj.Symbols[I] do begin |
715 |
for I := Low(RObj.Symbols) to High(RObj.Symbols) do |
| 462 |
case (SymType and $7f) of |
716 |
with RObj.Symbols[I] do |
| 463 |
SYM_LOCAL : if export_all then begin |
717 |
begin |
| 464 |
No:= Idx; |
718 |
case (SymType and $7f) of |
| 465 |
Inc(Idx); |
719 |
SYM_LOCAL: if export_all then |
| 466 |
end; |
720 |
begin |
| 467 |
SYM_IMPORT : ; |
721 |
No := Idx; |
| 468 |
SYM_EXPORT : begin |
722 |
Inc(Idx); |
| 469 |
// rename exported symbol if requested |
723 |
end; |
| 470 |
if (length(old_sym) > 0) and (Name = old_sym) then Name:= new_sym; |
724 |
SYM_IMPORT: ; |
| 471 |
No:= Idx; |
725 |
SYM_EXPORT: |
| 472 |
Inc(Idx); |
726 |
begin |
| 473 |
end; |
727 |
// rename exported symbol if requested |
| 474 |
else Die('Unsupported symbol type: %d', [SymType and $7f]); |
728 |
if (length(old_sym) > 0) and (Name = old_sym) then |
| 475 |
end; |
729 |
Name := new_sym; |
| 476 |
end; |
730 |
No := Idx; |
|
|
731 |
Inc(Idx); |
|
|
732 |
end; |
|
|
733 |
else |
|
|
734 |
Die('Unsupported symbol type: %d', [SymType and $7f]); |
|
|
735 |
end; |
|
|
736 |
end; |
| 477 |
|
737 |
|
| 478 |
// output object header |
738 |
// output object header |
| 479 |
Writeln(F, 'XL2'); |
739 |
Writeln(F, 'XL2'); |
| 480 |
Writeln(F, Format('H %x areas %x global symbols', [RObj.NumberOfSections, idx])); |
740 |
Writeln(F, Format('H %x areas %x global symbols', [RObj.NumberOfSections, idx])); |
| 481 |
Writeln(F, Format('M %s', [StringReplace(ExtractFileName(sourcename), '.', '_', [rfReplaceAll])])); |
741 |
Writeln(F, Format('M %s', [StringReplace(ExtractFileName(sourcename), |
|
|
742 |
'.', '_', [rfReplaceAll])])); |
| 482 |
Writeln(F, 'O -mgbz80'); |
743 |
Writeln(F, 'O -mgbz80'); |
| 483 |
|
744 |
|
| 484 |
// output all imported symbols |
745 |
// output all imported symbols |
| 485 |
for I:= Low(RObj.Symbols) to High(RObj.Symbols) do |
746 |
for I := Low(RObj.Symbols) to High(RObj.Symbols) do |
| 486 |
with RObj.Symbols[I] do |
747 |
with RObj.Symbols[I] do |
| 487 |
if (SymType = SYM_IMPORT) then |
748 |
if (SymType = SYM_IMPORT) then |
| 488 |
Writeln(F, Format('S %s Ref%.4x', [StringReplace(Name, '.', '____', [rfReplaceAll]), 0])); |
749 |
Writeln(F, Format('S %s Ref%.4x', |
| 489 |
|
750 |
[StringReplace(Name, '.', '____', [rfReplaceAll]), 0])); |
|
|
751 |
|
| 490 |
// output all sections and other symbols |
752 |
// output all sections and other symbols |
| 491 |
for Section in RObj.Sections do begin |
753 |
for Section in RObj.Sections do |
|
|
754 |
begin |
| 492 |
if Section.Org = -1 then |
755 |
if Section.Org = -1 then |
| 493 |
case Section.SectType of |
756 |
case Section.SectType of |
| 494 |
ROM0: Writeln(F, Format('A %s size %x flags 0 addr 0', [CODESEG, Section.Size])); |
757 |
ROM0: Writeln(F, Format('A %s size %x flags 0 addr 0', |
| 495 |
ROMX: if (DefaultBank = 0) then Writeln(F, Format('A %s size %x flags 0 addr 0', [CODESEG, Section.Size])) |
758 |
[CODESEG, Section.Size])); |
| 496 |
else Writeln(F, Format('A _CODE_%d size %x flags 0 addr 0', [max(DefaultBank, Section.Bank), Section.Size])); |
759 |
ROMX: if (DefaultBank = 0) then |
| 497 |
else Writeln(F, Format('A _DATA size %x flags 0 addr 0', [Section.Size])); |
760 |
Writeln(F, Format('A %s size %x flags 0 addr 0', [CODESEG, Section.Size])) |
| 498 |
end |
761 |
else |
| 499 |
else Die('absolute sections currently unsupported: %s', [Section.Name]); |
762 |
Writeln(F, Format('A _CODE_%d size %x flags 0 addr 0', |
|
|
763 |
[max(DefaultBank, Section.Bank), Section.Size])); |
|
|
764 |
else |
|
|
765 |
Writeln(F, Format('A _DATA size %x flags 0 addr 0', [Section.Size])); |
|
|
766 |
end |
|
|
767 |
else |
|
|
768 |
Die('absolute sections currently unsupported: %s', [Section.Name]); |
| 500 |
|
769 |
|
| 501 |
for Symbol in RObj.Symbols do |
770 |
for Symbol in RObj.Symbols do |
| 502 |
if Symbol.SectionID = Section.ID then begin |
771 |
if Symbol.SectionID = Section.ID then |
| 503 |
if (Symbol.SymType <> SYM_IMPORT) and (Symbol.No >= 0) then |
772 |
begin |
| 504 |
Writeln(F, Format('S %s Def%.4x', [StringReplace(Symbol.Name, '.', '____', [rfReplaceAll]), Symbol.Value])); |
773 |
if (Symbol.SymType <> SYM_IMPORT) and (Symbol.No >= 0) then |
|
|
774 |
Writeln(F, Format('S %s Def%.4x', |
|
|
775 |
[StringReplace(Symbol.Name, '.', '____', [rfReplaceAll]), Symbol.Value])); |
| 505 |
end; |
776 |
end; |
| 506 |
end; |
777 |
end; |
| 507 |
|
778 |
|
| 508 |
// convert object itself |
779 |
// convert object itself |
| 509 |
for Sct := Low(RObj.Sections) to High(RObj.Sections) do begin |
780 |
for Sct := Low(RObj.Sections) to High(RObj.Sections) do |
|
|
781 |
begin |
| 510 |
Section := RObj.Sections[Sct]; |
782 |
Section := RObj.Sections[Sct]; |
| 511 |
|
783 |
|
| 512 |
if (Section.SectType <> ROMX) and (Section.SectType <> ROM0) then Continue; |
784 |
if (Section.SectType <> ROMX) and (Section.SectType <> ROM0) then |
| 513 |
if Length(Section.Data) <= 0 then Continue; |
785 |
Continue; |
|
|
786 |
if Length(Section.Data) <= 0 then |
|
|
787 |
Continue; |
| 514 |
|
788 |
|
| 515 |
I := Low(Section.Data); |
789 |
I := Low(Section.Data); |
| 516 |
while I <= High(Section.Data) do begin |
790 |
while I <= High(Section.Data) do |
|
|
791 |
begin |
| 517 |
WritePos := I; |
792 |
WritePos := I; |
| 518 |
if (Section.Org <> -1) then Inc(WritePos, Section.Org); |
793 |
if (Section.Org <> -1) then |
|
|
794 |
Inc(WritePos, Section.Org); |
| 519 |
|
795 |
|
| 520 |
if FindPatch(Section, I, Patch) then begin |
796 |
if FindPatch(Section, I, Patch) then |
|
|
797 |
begin |
| 521 |
case Patch.PatchType of |
798 |
case Patch.PatchType of |
| 522 |
PATCH_LE_WORD : begin |
799 |
PATCH_LE_WORD: |
| 523 |
RPN := ParseRPN(Patch.RPN); |
800 |
begin |
| 524 |
Symbol := RObj.Symbols[RPN[0].SymbolID]; |
801 |
RPN := ParseRPN(Patch.RPN); |
| 525 |
ValueToWrite := Symbol.Value; |
802 |
Symbol := RObj.Symbols[RPN[0].SymbolID]; |
| 526 |
if RPN[High(RPN)].Tag = rpnPlus then |
803 |
ValueToWrite := Symbol.Value; |
| 527 |
Inc(ValueToWrite, RPN[1].IntValue); |
804 |
if RPN[High(RPN)].Tag = rpnPlus then |
| 528 |
|
805 |
Inc(ValueToWrite, RPN[1].IntValue); |
| 529 |
if (Symbol.SymType = SYM_IMPORT) then begin |
806 |
|
| 530 |
if (Symbol.No < 0) then Die('Trying to reference eliminated symbol'); |
807 |
if (Symbol.SymType = SYM_IMPORT) then |
| 531 |
Writeln(F, Format('T %.2x %.2x %.2x %.2x', [lo(WritePos), hi(WritePos), lo(ValueToWrite), hi(ValueToWrite)])); |
808 |
begin |
| 532 |
Writeln(F, Format('R 00 00 %.2x %.2x 02 02 %.2x %.2x', [lo(Sct), hi(Sct), lo(Symbol.No), hi(Symbol.No)])); |
809 |
if (Symbol.No < 0) then |
| 533 |
end else begin |
810 |
Die('Trying to reference eliminated symbol'); |
| 534 |
Writeln(F, Format('T %.2x %.2x %.2x %.2x', [lo(WritePos), hi(WritePos), lo(ValueToWrite), hi(ValueToWrite)])); |
811 |
Writeln(F, Format('T %.2x %.2x %.2x %.2x', |
| 535 |
Writeln(F, Format('R 00 00 %.2x %.2x 00 02 %.2x %.2x', [lo(Sct), hi(Sct), lo(Symbol.SectionID), hi(Symbol.SectionID)])); |
812 |
[lo(WritePos), hi(WritePos), lo(ValueToWrite), hi(ValueToWrite)])); |
| 536 |
end; |
813 |
Writeln(F, |
| 537 |
Inc(I, 2); |
814 |
Format('R 00 00 %.2x %.2x 02 02 %.2x %.2x', [lo(Sct), hi(Sct), |
| 538 |
end; |
815 |
lo(Symbol.No), hi(Symbol.No)])); |
| 539 |
PATCH_JR : begin |
816 |
end |
| 540 |
RPN := ParseRPN(Patch.RPN); |
817 |
else |
| 541 |
if Length(RPN) > 1 then Die('Not handling bigger RPN on JR'); |
818 |
begin |
| 542 |
Symbol := RObj.Symbols[RPN[0].SymbolID]; |
819 |
Writeln(F, Format('T %.2x %.2x %.2x %.2x', |
| 543 |
Writeln(F, Format('T %.2x %.2x %.2x', [lo(WritePos), hi(WritePos), Byte(Symbol.Value - I - 1)])); |
820 |
[lo(WritePos), hi(WritePos), lo(ValueToWrite), hi(ValueToWrite)])); |
| 544 |
Writeln(F, Format('R 00 00 %.2x %.2x', [lo(Sct), hi(Sct)])); |
821 |
Writeln(F, |
| 545 |
Inc(I); |
822 |
Format('R 00 00 %.2x %.2x 00 02 %.2x %.2x', [lo(Sct), hi(Sct), |
| 546 |
end |
823 |
lo(Symbol.SectionID), hi(Symbol.SectionID)])); |
| 547 |
else Die('Unsupported patch type: %d', [Patch.PatchType]); |
824 |
end; |
|
|
825 |
Inc(I, 2); |
|
|
826 |
end; |
|
|
827 |
PATCH_JR: |
|
|
828 |
begin |
|
|
829 |
RPN := ParseRPN(Patch.RPN); |
|
|
830 |
if Length(RPN) > 1 then |
|
|
831 |
Die('Not handling bigger RPN on JR'); |
|
|
832 |
Symbol := RObj.Symbols[RPN[0].SymbolID]; |
|
|
833 |
Writeln(F, Format('T %.2x %.2x %.2x', |
|
|
834 |
[lo(WritePos), hi(WritePos), byte(Symbol.Value - I - 1)])); |
|
|
835 |
Writeln(F, Format('R 00 00 %.2x %.2x', |
|
|
836 |
[lo(Sct), hi(Sct)])); |
|
|
837 |
Inc(I); |
|
|
838 |
end |
|
|
839 |
else |
|
|
840 |
Die('Unsupported patch type: %d', [Patch.PatchType]); |
| 548 |
end; |
841 |
end; |
| 549 |
end else begin |
842 |
end |
| 550 |
Writeln(F, Format('T %.2x %.2x %.2x', [lo(WritePos), hi(WritePos), Section.Data[I]])); |
843 |
else |
|
|
844 |
begin |
|
|
845 |
Writeln(F, Format('T %.2x %.2x %.2x', |
|
|
846 |
[lo(WritePos), hi(WritePos), Section.Data[I]])); |
| 551 |
Writeln(F, Format('R 00 00 %.2x %.2x', [lo(Sct), hi(Sct)])); |
847 |
Writeln(F, Format('R 00 00 %.2x %.2x', [lo(Sct), hi(Sct)])); |
| 552 |
Inc(I); |
848 |
Inc(I); |
| 553 |
end; |
849 |
end; |
| 554 |
end; |
850 |
end; |
| 555 |
end; |
851 |
end; |
| 556 |
|
852 |
|
| 557 |
Writeln('rgb2sdas converting ',sourcename,' --> ',sourcename,'.o result: success!'); |
853 |
//Writeln('rgb2sdas converting ',sourcename,' --> ',sourcename,'.o result: success!'); |
| 558 |
finally Close(F); end; |
854 |
finally |
| 559 |
end. |
855 |
Close(F); |
|
|
856 |
end; |
|
|
857 |
end; |
| 560 |
|
858 |
|
|
|
859 |
begin |
|
|
860 |
end. |