forked from Clownacy/asl-releases
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasmdef.c
436 lines (367 loc) · 16.9 KB
/
asmdef.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
/* asmdef.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* global benutzte Variablen */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <errno.h>
#include "strutil.h"
#include "stringlists.h"
#include "chunks.h"
#include "asmdef.h"
#include "asmsub.h"
#include "errmsg.h"
char SrcSuffix[] = ".asm"; /* Standardendungen: Hauptdatei */
char IncSuffix[] = ".inc"; /* Includedatei */
char PrgSuffix[] = ".p"; /* Programmdatei */
char LstSuffix[] = ".lst"; /* Listingdatei */
char MacSuffix[] = ".mac"; /* Makroausgabe */
char PreSuffix[] = ".i"; /* Ausgabe Makroprozessor */
char LogSuffix[] = ".log"; /* Fehlerdatei */
char MapSuffix[] = ".map"; /* Debug-Info/Map-Format */
char OBJSuffix[] = ".obj";
const char *EnvName = "ASCMD"; /* Environment-Variable fuer Default-
Parameter */
StringPtr SourceFile; /* Hauptquelldatei */
StringPtr CursUp; /* " " Cursor hoch */
LargeWord *PCs; /* Programmzaehler */
Boolean RelSegs; /* relokatibles Segment ? */
LargeWord StartAdr; /* Programmstartadresse */
Boolean StartAdrPresent; /* " definiert? */
LargeWord AfterBSRAddr; /* address right behind last BSR */
LargeWord *Phases; /* Verschiebungen */
Word Grans[SegCountPlusStruct]; /* Groesse der Adressierungselemente */
Word ListGrans[SegCountPlusStruct]; /* Wortgroesse im Listing */
ChunkList SegChunks[SegCountPlusStruct]; /* Belegungen */
Integer ActPC; /* gewaehlter Programmzaehler */
Boolean PCsUsed[SegCountPlusStruct]; /* PCs bereits initialisiert ? */
LargeWord *SegInits; /* Segmentstartwerte */
LargeWord *SegLimits; /* Segmentgrenzwerte */
LongInt ValidSegs; /* erlaubte Segmente */
Boolean ENDOccured; /* END-Statement aufgetreten ? */
Boolean Retracted; /* Codes zurueckgenommen ? */
Boolean ListToStdout, ListToNull; /* Listing auf Konsole/Nulldevice ? */
unsigned ASSUMERecCnt;
const ASSUMERec *pASSUMERecs;
void (*pASSUMEOverride)(void);
Integer PassNo; /* Durchlaufsnummer */
Integer JmpErrors; /* Anzahl fraglicher Sprungfehler */
Boolean ThrowErrors; /* Fehler verwerfen bei Repass ? */
LongWord MaxErrors; /* terminate upon n errors? */
Boolean TreatWarningsAsErrors; /* treat warnings like erros? */
Boolean Repass; /* noch ein Durchlauf erforderlich */
Byte MaxSymPass; /* Pass, nach dem Symbole definiert sein muessen */
Byte ShareMode; /* 0=kein SHARED,1=Pascal-,2=C-Datei, 3=ASM-Datei */
DebugType DebugMode; /* Ausgabeformat Debug-Datei */
Word NoICEMask; /* which symbols to use in NoICE dbg file */
Byte ListMode; /* 0=kein Listing,1=Konsole,2=auf Datei */
Byte ListOn; /* Listing erzeugen ? */
Integer MaxIncludeLevel; /* maximum include nesting level */
Boolean MakeUseList; /* Belegungsliste ? */
Boolean MakeCrossList; /* Querverweisliste ? */
Boolean MakeSectionList; /* Sektionsliste ? */
Boolean MakeIncludeList; /* Includeliste ? */
Boolean DefRelaxedMode; /* alle Integer-Syntaxen zulassen ? */
Boolean DefCompMode, CompMode; /* enable compatibility mode */
Word ListMask; /* Listingmaske */
ShortInt ExtendErrors; /* erweiterte Fehlermeldungen */
Integer EnumSegment; /* ENUM state & config */
LongInt EnumIncrement, EnumCurrentValue;
Boolean NumericErrors; /* Fehlermeldungen mit Nummer */
Boolean CodeOutput; /* Code erzeugen */
Boolean MacProOutput; /* Makroprozessorausgabe schreiben */
Boolean MacroOutput; /* gelesene Makros schreiben */
ShortInt QuietMode; /* keine Meldungen */
Boolean HardRanges; /* Bereichsfehler echte Fehler ? */
const char *DivideChars; /* Trennzeichen fuer Parameter. Inhalt Read Only! */
Boolean HasAttrs; /* Opcode hat Attribut */
const char *AttrChars; /* Zeichen, mit denen Attribut abgetrennt wird */
Boolean MsgIfRepass; /* Meldungen, falls neuer Pass erforderlich */
Integer PassNoForMessage; /* falls ja: ab welchem Pass ? */
Boolean CaseSensitive; /* Gross/Kleinschreibung unterscheiden ? */
LongInt NestMax; /* max. nesting level of a macro */
Boolean GNUErrors; /* GNU-error-style messages ? */
FILE *PrgFile = NULL; /* Codedatei */
StringPtr ErrorPath, ErrorName; /* Ausgabedatei Fehlermeldungen */
StringPtr OutName; /* Name Code-Datei */
Integer CurrIncludeLevel; /* current include nesting level */
StringPtr CurrFileName; /* mom. bearbeitete Datei */
LongInt MomLineCounter; /* Position in mom. Datei */
LongInt CurrLine; /* virtuelle Position */
LongInt LineSum; /* Gesamtzahl Quellzeilen */
LongInt MacLineSum; /* inkl. Makroexpansion */
LongInt NOPCode; /* Maschinenbefehl NOP zum Stopfen */
Boolean TurnWords; /* TRUE = Motorola-Wortformat */
/* FALSE = Intel-Wortformat */
Byte HeaderID; /* Kennbyte des Codeheaders */
const char *PCSymbol; /* Symbol, womit Programmzaehler erreicht wird. Inhalt Read Only! */
Boolean (*SetIsOccupiedFnc)(void), /* TRUE: SET instr, to be parsed by code generator */
(*SaveIsOccupiedFnc)(void), /* ditto for SAVE */
(*RestoreIsOccupiedFnc)(void); /* ditto for RESTORE */
Boolean SwitchIsOccupied, /* TRUE: SWITCH/PAGE/SHIFT ist Prozessorbefehl */
PageIsOccupied,
ShiftIsOccupied;
#ifdef __PROTOS__
Boolean (*DecodeAttrPart)(void); /* dissect attribute of instruction */
void (*MakeCode)(void); /* Codeerzeugungsprozedur */
Boolean (*ChkPC)(LargeWord Addr); /* ueberprueft Codelaengenueberschreitungen */
Boolean (*IsDef)(void); /* ist Label nicht als solches zu werten ? */
void (*SwitchFrom)(void) = NULL; /* bevor von einer CPU weggeschaltet wird */
void (*InternSymbol)(char *Asc, TempResult *Erg); /* vordefinierte Symbole ? */
#else
Boolean (*DecodeAttrPart)();
void (*MakeCode)();
Boolean (*ChkPC)();
Boolean (*IsDef)();
void (*SwitchFrom)();
void (*InternSymbol)();
#endif
DissectBitProc DissectBit;
DissectRegProc DissectReg;
tQualifyQuoteFnc QualifyQuote;
StringPtr IncludeList; /* Suchpfade fuer Includedateien */
Integer IncDepth, NextIncDepth; /* Verschachtelungstiefe INCLUDEs */
FILE *ErrorFile = NULL; /* Fehlerausgabe */
FILE *LstFile = NULL; /* Listdatei */
FILE *ShareFile = NULL; /* Sharefile */
FILE *MacProFile = NULL; /* Makroprozessorausgabe */
FILE *MacroFile = NULL; /* Ausgabedatei Makroliste */
Boolean InMacroFlag; /* momentan wird Makro expandiert */
StringPtr LstName; /* Name der Listdatei */
StringPtr MacroName, MacProName;
tLstMacroExp DoLst, NextDoLst; /* Listing an */
StringPtr ShareName; /* Name des Sharefiles */
CPUVar MomCPU, MomVirtCPU; /* definierter/vorgegaukelter Prozessortyp */
StringPtr MomCPUArgs; /* Arguments for Current Processor Type */
char DefCPU[20]; /* per Kommandozeile vorgegebene CPU */
char MomCPUIdent[20], /* dessen Name in ASCII */
MomFPUIdent[20], /* ditto FPU */
MomPMMUIdent[20]; /* ditto PMMU */
Boolean FPUAvail, /* Koprozessor erlaubt ? */
PMMUAvail; /* MMU-Befehle erlaubt? */
Boolean DoPadding, /* auf gerade Byte-Zahl ausrichten ? */
TargetBigEndian; /* Datenablage Big Endian? */
Boolean Packing; /* gepackte Ablage ? */
Boolean DefSupAllowed, SupAllowed; /* Supervisormode freigegeben */
Boolean Maximum; /* CPU nicht kastriert */
Boolean DoBranchExt; /* Spruenge automatisch verlaengern */
int OutRadixBase; /* dito fuer Ausgabe */
int ListRadixBase; /* ditto for listing */
const char *pCommentLeadIn; /* list of comment lead-in sequences */
tStrComp *ArgStr; /* Komponenten der Zeile */
StringPtr pLOpPart;
tStrComp LabPart, CommPart, ArgPart, OpPart, AttrPart;
char AttrSplit;
int ArgCnt; /* Argumentzahl */
int AllocArgCnt;
as_dynstr_t OneLine; /* eingelesene Zeile */
#ifdef PROFILE_MEMO
unsigned NumMemo;
unsigned long NumMemoCnt, NumMemoSum;
#endif
Byte LstCounter; /* Zeilenzaehler fuer automatischen Umbruch */
Word PageCounter[ChapMax + 1]; /* hierarchische Seitenzaehler */
Byte ChapDepth; /* momentane Kapitelverschachtelung */
StringPtr ListLine; /* alternative Ausgabe vor Listing fuer EQU */
Byte PageLength, PageWidth; /* Seitenlaenge/breite in Zeilen/Spalten */
tLstMacroExpMod LstMacroExpModOverride, /* Override macro expansion ? */
LstMacroExpModDefault;
Boolean DottedStructs; /* structure elements with dots */
StringPtr PrtInitString; /* Druckerinitialisierungsstring */
StringPtr PrtExitString; /* Druckerdeinitialisierungsstring */
StringPtr PrtTitleString; /* Titelzeile */
LongInt MomSectionHandle; /* mom. Namensraum */
PSaveSection SectionStack; /* gespeicherte Sektionshandles */
tSavePhase *pPhaseStacks[SegCount]; /* saves nested PHASE values */
tSymbolSize AttrPartOpSize; /* instruction operand size deduced from insn attribute */
LongWord MaxCodeLen = 0; /* max. length of generated code */
LongInt CodeLen; /* Laenge des erzeugten Befehls */
LongWord *DAsmCode; /* Zwischenspeicher erzeugter Code */
Word *WAsmCode;
Byte *BAsmCode;
Boolean DontPrint; /* Flag:PC veraendert, aber keinen Code erzeugt */
Word ActListGran; /* uebersteuerte List-Granularitaet */
Byte StopfZahl; /* Anzahl der im 2.Pass festgestellten
ueberfluessigen Worte, die mit NOP ge-
fuellt werden muessen */
Boolean SuppWarns;
PTransTable TransTables, /* Liste mit Codepages */
CurrTransTable; /* aktuelle Codepage */
PDefinement FirstDefine; /* Liste von Praeprozessor-Defines */
PSaveState FirstSaveState; /* gesicherte Zustaende */
Boolean MakeDebug; /* Debugginghilfe */
FILE *Debug;
Boolean WasIF, WasMACRO;
void AsmDefInit(void)
{
LongInt z;
DoLst = eLstMacroExpAll;
PassNo = 1;
MaxSymPass = 1;
LineSum = 0;
for (z = 0; z <= ChapMax; PageCounter[z++] = 0);
LstCounter = 0;
ChapDepth = 0;
PrtInitString[0] = '\0';
PrtExitString[0] = '\0';
PrtTitleString[0] = '\0';
CurrFileName[0] = '\0';
MomLineCounter = 0;
FirstDefine = NULL;
FirstSaveState = NULL;
}
void NullProc(void)
{
}
void Default_InternSymbol(char *Asc, TempResult *Erg)
{
UNUSED(Asc);
Erg->Typ = TempNone;
}
void Default_DissectBit(char *pDest, size_t DestSize, LargeWord BitSpec)
{
HexString(pDest, DestSize, BitSpec, 0);
}
static char *GetString(void)
{
return (char*)malloc(STRINGSIZE * sizeof(char));
}
int SetMaxCodeLen(LongWord NewMaxCodeLen)
{
if (NewMaxCodeLen > MaxCodeLen_Max)
return ENOMEM;
if (NewMaxCodeLen > MaxCodeLen)
{
void *pNewMem;
if (!MaxCodeLen)
pNewMem = (LongWord *) malloc(NewMaxCodeLen);
else
pNewMem = (LongWord *) realloc(DAsmCode, NewMaxCodeLen);
if (!pNewMem)
return ENOMEM;
DAsmCode = (LongWord *)pNewMem;
WAsmCode = (Word *) DAsmCode;
BAsmCode = (Byte *) DAsmCode;
MaxCodeLen = NewMaxCodeLen;
}
return 0;
}
/*!------------------------------------------------------------------------
* \fn AppendArg(size_t ReqSize)
* \brief extend list of arguments by one more at the end
* \param ReqSize length of argument to store (excluding NUL at end)
* ------------------------------------------------------------------------ */
/* NOTICE: Due to port from Pascal sources, ArgStr[] is still indexed starting at
one instead of zero:
- ArgStr[0] is unused.
- If ArgCnt == n, ArgStr[1] to ArgStr[n] are used. */
void AppendArg(size_t ReqSize)
{
if (ArgCnt >= ArgCntMax)
WrXError(ErrNum_InternalError, "MaxArgCnt");
++ArgCnt;
if (ArgCnt >= AllocArgCnt)
{
size_t NewArgStrSize = sizeof(*ArgStr) * (ArgCnt + 1); /* one more, [0] is unused */
int z;
ArgStr = ArgStr ? (tStrComp*)realloc(ArgStr, NewArgStrSize) : (tStrComp*)malloc(NewArgStrSize);
for (z = AllocArgCnt; z <= ArgCnt; z++)
StrCompAlloc(&ArgStr[z], STRINGSIZE);
AllocArgCnt = ArgCnt + 1;
}
if (ArgStr[ArgCnt].str.capacity <= ReqSize)
{
if (as_dynstr_realloc(&ArgStr[ArgCnt].str, as_dynstr_roundup_len(ReqSize)))
WrXError(ErrNum_InternalError, "out of memory");
}
}
/*!------------------------------------------------------------------------
* \fn InsertArg(unsigned Index, size_t ReqSize)
* \brief insert one more arg @ given position
* \param Index insertion position
* \param ReqSize requested size of new arg
* ------------------------------------------------------------------------ */
void InsertArg(int Index, size_t ReqSize)
{
int z;
/* 0 should never be passed... */
if (Index < 1)
Index = 1;
/* Insertion beyond end means appending */
if (Index > ArgCnt)
{
AppendArg(ReqSize);
return;
}
/* current last arg dictates length of new last arg */
AppendArg(strlen(ArgStr[ArgCnt].str.p_str));
for (z = ArgCnt; z > Index; z--)
{
as_dynstr_copy(&ArgStr[z].str, &ArgStr[z - 1].str);
ArgStr[z].Pos = ArgStr[z - 1].Pos;
}
if (ArgStr[Index].str.capacity < ReqSize + 1)
{
if (as_dynstr_realloc(&ArgStr[Index].str, as_dynstr_roundup_len(ReqSize)))
WrXError(ErrNum_InternalError, "out of memory");
}
}
Boolean SetIsOccupied(void)
{
return SetIsOccupiedFnc && SetIsOccupiedFnc();
}
Boolean SaveIsOccupied(void)
{
return SaveIsOccupiedFnc && SaveIsOccupiedFnc();
}
Boolean RestoreIsOccupied(void)
{
return RestoreIsOccupiedFnc && RestoreIsOccupiedFnc();
}
void asmdef_init(void)
{
SwitchFrom = NullProc;
InternSymbol = Default_InternSymbol;
DissectBit = Default_DissectBit;
DissectReg = NULL;
QualifyQuote = NULL;
SetMaxCodeLen(MaxCodeLen_Ini);
/* auf diese Weise wird PCSymbol defaultmaessig nicht erreichbar
da das schon von den Konstantenparsern im Formelparser abgefangen
wuerde */
PCSymbol = "--PC--SYMBOL--";
*DefCPU = '\0';
ArgStr = NULL;
AllocArgCnt = 0;
SourceFile = GetString();
CursUp = GetString();
ErrorPath = GetString();
ErrorName = GetString();
OutName = GetString();
CurrFileName = GetString();
IncludeList = GetString();
LstName = GetString();
MacroName = GetString();
MacProName = GetString();
ShareName = GetString();
StrCompAlloc(&LabPart, STRINGSIZE);
StrCompAlloc(&OpPart, STRINGSIZE);
StrCompAlloc(&AttrPart, STRINGSIZE);
StrCompAlloc(&ArgPart, STRINGSIZE);
StrCompAlloc(&CommPart, STRINGSIZE);
pLOpPart = GetString();
as_dynstr_ini(&OneLine, STRINGSIZE);
ListLine = GetString();
PrtInitString = GetString();
PrtExitString = GetString();
PrtTitleString = GetString();
MomCPUArgs = GetString();
SegInits = (LargeWord*)calloc(SegCount, sizeof(*SegInits));
SegLimits = (LargeWord*)calloc(SegCount, sizeof(*SegLimits));
Phases = (LargeWord*)calloc(SegCountPlusStruct, sizeof(*Phases));
PCs = (LargeWord*)calloc(SegCountPlusStruct, sizeof(*PCs));
}