@@ -41,10 +41,75 @@ begin |
| 41 |
WriteBufferToAddress(SymbolAddress(Symbol), Buffer, Count); |
41 |
WriteBufferToAddress(SymbolAddress(Symbol), Buffer, Count); |
| 42 |
end; |
42 |
end; |
| 43 |
|
43 |
|
|
|
44 |
procedure ParseSymLine(const Line: String); |
|
|
45 |
var |
|
|
46 |
S, Location, Name, AddrPart: String; |
|
|
47 |
SemiPos, I: Integer; |
|
|
48 |
Tokens: TStringList; |
|
|
49 |
Addr: Integer; |
|
|
50 |
begin |
|
|
51 |
S := Line; |
|
|
52 |
|
|
|
53 |
// Strip comment starting at ';' |
|
|
54 |
SemiPos := Pos(';', S); |
|
|
55 |
if SemiPos > 0 then |
|
|
56 |
S := Copy(S, 1, SemiPos - 1); |
|
|
57 |
|
|
|
58 |
S := Trim(S); |
|
|
59 |
if S = '' then Exit; |
|
|
60 |
|
|
|
61 |
// Split on runs of whitespace (spaces/tabs) |
|
|
62 |
Tokens := TStringList.Create; |
|
|
63 |
try |
|
|
64 |
I := 1; |
|
|
65 |
while I <= Length(S) do begin |
|
|
66 |
while (I <= Length(S)) and ((S[I] = ' ') or (S[I] = #9)) do Inc(I); |
|
|
67 |
if I > Length(S) then Break; |
|
|
68 |
AddrPart := ''; |
|
|
69 |
while (I <= Length(S)) and (S[I] <> ' ') and (S[I] <> #9) do begin |
|
|
70 |
AddrPart := AddrPart + S[I]; |
|
|
71 |
Inc(I); |
|
|
72 |
end; |
|
|
73 |
if AddrPart <> '' then Tokens.Add(AddrPart); |
|
|
74 |
end; |
|
|
75 |
|
|
|
76 |
// Single-token lines are reserved for future extensions; ignore silently. |
|
|
77 |
if Tokens.Count < 2 then Exit; |
|
|
78 |
|
|
|
79 |
Location := Tokens[0]; |
|
|
80 |
Name := Tokens[1]; |
|
|
81 |
|
|
|
82 |
// Location forms: "bank:address", "BOOT:address", or bare "address". |
|
|
83 |
SemiPos := Pos(':', Location); |
|
|
84 |
if SemiPos > 0 then |
|
|
85 |
AddrPart := Copy(Location, SemiPos + 1, Length(Location)) |
|
|
86 |
else |
|
|
87 |
AddrPart := Location; |
|
|
88 |
|
|
|
89 |
if AddrPart = '' then begin |
|
|
90 |
DebugLn(['[WARNING] Skipping malformed sym line: ', Line]); |
|
|
91 |
Exit; |
|
|
92 |
end; |
|
|
93 |
|
|
|
94 |
try |
|
|
95 |
Addr := StrToInt('x' + AddrPart); |
|
|
96 |
except |
|
|
97 |
on E: EConvertError do begin |
|
|
98 |
DebugLn(['[WARNING] Skipping sym line with bad address: ', Line]); |
|
|
99 |
Exit; |
|
|
100 |
end; |
|
|
101 |
end; |
|
|
102 |
|
|
|
103 |
if SymbolTable.IndexOf(Name) = -1 then |
|
|
104 |
SymbolTable.Add(Name, Addr); |
|
|
105 |
finally |
|
|
106 |
Tokens.Free; |
|
|
107 |
end; |
|
|
108 |
end; |
|
|
109 |
|
| 44 |
procedure ParseSymFile(F: String); |
110 |
procedure ParseSymFile(F: String); |
| 45 |
var |
111 |
var |
| 46 |
SL: TStringList; |
112 |
SL: TStringList; |
| 47 |
SA: TStringArray; |
|
|
| 48 |
S: String; |
113 |
S: String; |
| 49 |
begin |
114 |
begin |
| 50 |
SymbolTable.Clear; |
115 |
SymbolTable.Clear; |
@@ -52,15 +117,8 @@ begin |
| 52 |
SL := TStringList.Create; |
117 |
SL := TStringList.Create; |
| 53 |
try |
118 |
try |
| 54 |
SL.LoadFromFile(F); |
119 |
SL.LoadFromFile(F); |
| 55 |
|
120 |
for S in SL do |
| 56 |
// Drop the first two lines |
121 |
ParseSymLine(S); |
| 57 |
SL.Delete(0); |
|
|
| 58 |
SL.Delete(0); |
|
|
| 59 |
|
|
|
| 60 |
for S in SL do begin |
|
|
| 61 |
SA := S.Split(' '); |
|
|
| 62 |
SymbolTable.Add(SA[1], StrToInt('x'+SA[0].Substring(3))); |
|
|
| 63 |
end; |
|
|
| 64 |
finally |
122 |
finally |
| 65 |
SL.Free; |
123 |
SL.Free; |
| 66 |
end; |
124 |
end; |