1 /* asmallg.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* von allen Codegeneratoren benutzte Pseudobefehle */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "nls.h"
16 #include "strutil.h"
17 #include "stringlists.h"
18 #include "bpemu.h"
19 #include "console.h"
20 #include "chunks.h"
21 #include "asmdef.h"
22 #include "asmsub.h"
23 #include "errmsg.h"
24 #include "as.h"
25 #include "as.rsc"
26 #include "asmpars.h"
27 #include "asmmac.h"
28 #include "asmstructs.h"
29 #include "asmcode.h"
30 #include "asmrelocs.h"
31 #include "asmitree.h"
32 #include "codepseudo.h"
33 #include "nlmessages.h"
34 #include "asmallg.h"
35
36 /*--------------------------------------------------------------------------*/
37
38
39 static PInstTable PseudoTable = NULL, ONOFFTable;
40
41 /*--------------------------------------------------------------------------*/
42
DefChkPC(LargeWord Addr)43 static Boolean DefChkPC(LargeWord Addr)
44 {
45 if (!((1 << ActPC) & ValidSegs))
46 return False;
47 else
48 return (Addr <= SegLimits[ActPC]);
49 }
50
51 /*!------------------------------------------------------------------------
52 * \fn ParseCPUArgs(tStrComp *pArgs, const tCPUArg *pCPUArgs)
53 * \brief parse possible arguments of CPU
54 * \param pArgs arguments set by user (may be NULL)
55 * \param pCPUArgs arguments provided by target (may be NULL)
56 * ------------------------------------------------------------------------ */
57
ParseCPUArgs(const tStrComp * pArgs,const tCPUArg * pCPUArgs)58 static void ParseCPUArgs(const tStrComp *pArgs, const tCPUArg *pCPUArgs)
59 {
60 const tCPUArg *pCPUArg;
61 char *pNext, *pSep;
62 tStrComp Args, Remainder, NameComp, ValueComp;
63 LongInt VarValue;
64 Boolean OK;
65 String ArgStr;
66
67 /* always reset to defaults, also when no user arguments are given */
68
69 if (!pCPUArgs)
70 return;
71 for (pCPUArg = pCPUArgs; pCPUArg->pName; pCPUArg++)
72 *pCPUArg->pValue = pCPUArg->DefValue;
73
74 if (!pArgs)
75 return;
76 StrCompMkTemp(&Args, ArgStr);
77 StrCompCopy(&Args, pArgs);
78 do
79 {
80 pNext = strchr(Args.Str, ':');
81 if (pNext)
82 StrCompSplitRef(&Args, &Remainder, &Args, pNext);
83 pSep = strchr(Args.Str, '=');
84 if (!pSep) WrStrErrorPos(ErrNum_ArgValueMissing, &Args);
85 else
86 {
87 StrCompSplitRef(&NameComp, &ValueComp, &Args, pSep);
88 KillPrefBlanksStrCompRef(&NameComp); KillPostBlanksStrComp(&NameComp);
89 KillPrefBlanksStrCompRef(&ValueComp); KillPostBlanksStrComp(&ValueComp);
90
91 VarValue = EvalStrIntExpression(&ValueComp, Int32, &OK);
92 if (OK)
93 {
94 for (pCPUArg = pCPUArgs; pCPUArg->pName; pCPUArg++)
95 if (!as_strcasecmp(NameComp.Str, pCPUArg->pName))
96 break;
97 if (!pCPUArg->pName) WrStrErrorPos(ErrNum_UnknownArg, &NameComp);
98 else if (ChkRange(VarValue, pCPUArg->Min, pCPUArg->Max))
99 *pCPUArg->pValue = VarValue;
100 }
101 }
102 if (pNext)
103 Args = Remainder;
104 }
105 while (pNext);
106 }
107
SetCPUCore(const tCPUDef * pCPUDef,const tStrComp * pCPUArgs)108 static void SetCPUCore(const tCPUDef *pCPUDef, const tStrComp *pCPUArgs)
109 {
110 LargeInt HCPU;
111 int Digit, Base;
112 const char *pRun;
113
114 tStrComp TmpComp;
115 String TmpCompStr;
116 StrCompMkTemp(&TmpComp, TmpCompStr);
117
118 strmaxcpy(MomCPUIdent, pCPUDef->Name, sizeof(MomCPUIdent));
119 MomCPU = pCPUDef->Orig;
120 MomVirtCPU = pCPUDef->Number;
121 HCPU = 0;
122 Base = 10;
123 for (pRun = MomCPUIdent; *pRun; pRun++)
124 {
125 if (isdigit(*pRun))
126 Base = 16;
127 Digit = DigitVal(*pRun, Base);
128 if (Digit >= 0)
129 HCPU = (HCPU << 4) + Digit;
130 }
131
132 strmaxcpy(TmpCompStr, MomCPUName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, HCPU, SegNone, True);
133 strmaxcpy(TmpCompStr, MomCPUIdentName, sizeof(TmpCompStr)); EnterStringSymbol(&TmpComp, MomCPUIdent, True);
134
135 InternSymbol = Default_InternSymbol;
136 ConstModeWeirdNoTerm = False;
137 DissectBit = Default_DissectBit;
138 DissectReg = NULL;
139 QualifyQuote = NULL;
140 SetIsOccupiedFnc = NULL;
141 DecodeAttrPart = NULL;
142 SwitchIsOccupied =
143 PageIsOccupied =
144 ShiftIsOccupied = False;
145 ChkPC = DefChkPC;
146 ASSUMERecCnt = 0;
147 pASSUMERecs = NULL;
148 pASSUMEOverride = NULL;
149 if (SwitchFrom)
150 {
151 SwitchFrom();
152 SwitchFrom = NULL;
153 }
154 strmaxcpy(MomCPUArgs, pCPUArgs ? pCPUArgs->Str : "", sizeof(MomCPUArgs));
155 ParseCPUArgs(pCPUArgs, pCPUDef->pArgs);
156 pCPUDef->SwitchProc(pCPUDef->pUserData);
157
158 DontPrint = True;
159 }
160
SetCPUByType(CPUVar NewCPU,const tStrComp * pCPUArgs)161 void SetCPUByType(CPUVar NewCPU, const tStrComp *pCPUArgs)
162 {
163 const tCPUDef *pCPUDef;
164
165 pCPUDef = LookupCPUDefByVar(NewCPU);
166 if (pCPUDef)
167 SetCPUCore(pCPUDef, pCPUArgs);
168 }
169
SetCPUByName(const tStrComp * pName)170 Boolean SetCPUByName(const tStrComp *pName)
171 {
172 const tCPUDef *pCPUDef;
173
174 pCPUDef = LookupCPUDefByName(pName->Str);
175 if (!pCPUDef)
176 return False;
177 else
178 {
179 int l = strlen(pCPUDef->Name);
180
181 if (pName->Str[l] == ':')
182 {
183 tStrComp ArgComp;
184
185 StrCompRefRight(&ArgComp, pName, l + 1);
186 SetCPUCore(pCPUDef, &ArgComp);
187 }
188 else
189 SetCPUCore(pCPUDef, NULL);
190 return True;
191 }
192 }
193
SetNSeg(Byte NSeg)194 static void SetNSeg(Byte NSeg)
195 {
196 if ((ActPC != NSeg) || (!PCsUsed[ActPC]))
197 {
198 ActPC = NSeg;
199 if (!PCsUsed[ActPC])
200 PCs[ActPC] = SegInits[ActPC];
201 PCsUsed[ActPC] = True;
202 DontPrint = True;
203 }
204 }
205
IntLine(char * pDest,size_t DestSize,LargeWord Inp,TConstMode ThisConstMode)206 static void IntLine(char *pDest, size_t DestSize, LargeWord Inp, TConstMode ThisConstMode)
207 {
208 switch (ThisConstMode)
209 {
210 case ConstModeIntel:
211 as_snprintf(pDest, DestSize, "%lllx%s", Inp, GetIntelSuffix(16));
212 if (*pDest > '9')
213 strmaxprep(pDest, "0", DestSize);
214 break;
215 case ConstModeMoto:
216 as_snprintf(pDest, DestSize, "$%lllx", Inp);
217 break;
218 case ConstModeC:
219 as_snprintf(pDest, DestSize, "0x%lllx", Inp);
220 break;
221 case ConstModeWeird:
222 as_snprintf(pDest, DestSize, "x'%lllx'", Inp);
223 break;
224 }
225 }
226
227
CodeSECTION(Word Index)228 static void CodeSECTION(Word Index)
229 {
230 PSaveSection Neu;
231 String ExpName;
232 UNUSED(Index);
233
234 if (ChkArgCnt(1, 1)
235 && ExpandStrSymbol(ExpName, sizeof(ExpName), &ArgStr[1]))
236 {
237 if (!ChkSymbName(ExpName)) WrStrErrorPos(ErrNum_InvSymName, &ArgStr[1]);
238 else if ((PassNo == 1) && (GetSectionHandle(ExpName, False, MomSectionHandle) != -2)) WrError(ErrNum_DoubleSection);
239 else
240 {
241 Neu = (PSaveSection) malloc(sizeof(TSaveSection));
242 Neu->Next = SectionStack;
243 Neu->Handle = MomSectionHandle;
244 Neu->LocSyms = NULL;
245 Neu->GlobSyms = NULL;
246 Neu->ExportSyms = NULL;
247 SetMomSection(GetSectionHandle(ExpName, True, MomSectionHandle));
248 SectionStack = Neu;
249 }
250 }
251 }
252
253
CodeENDSECTION_ChkEmptList(PForwardSymbol * Root)254 static void CodeENDSECTION_ChkEmptList(PForwardSymbol *Root)
255 {
256 PForwardSymbol Tmp;
257 String XError;
258
259 while (*Root)
260 {
261 strmaxcpy(XError, (*Root)->Name, STRINGSIZE);
262 strmaxcat(XError, ", ", STRINGSIZE);
263 strmaxcat(XError, (*Root)->pErrorPos, STRINGSIZE);
264 WrXError(ErrNum_UndefdForward, XError);
265 free((*Root)->Name);
266 free((*Root)->pErrorPos);
267 Tmp = (*Root);
268 *Root = Tmp->Next; free(Tmp);
269 }
270 }
271
CodeENDSECTION(Word Index)272 static void CodeENDSECTION(Word Index)
273 {
274 PSaveSection Tmp;
275 String ExpName;
276 UNUSED(Index);
277
278 if (!ChkArgCnt(0, 1));
279 else if (!SectionStack) WrError(ErrNum_NotInSection);
280 else if ((ArgCnt == 0) || (ExpandStrSymbol(ExpName, sizeof(ExpName), &ArgStr[1])))
281 {
282 if ((ArgCnt == 1) && (GetSectionHandle(ExpName, False, SectionStack->Handle) != MomSectionHandle)) WrStrErrorPos(ErrNum_WrongEndSect, &ArgStr[1]);
283 else
284 {
285 Tmp = SectionStack;
286 SectionStack = Tmp->Next;
287 CodeENDSECTION_ChkEmptList(&(Tmp->LocSyms));
288 CodeENDSECTION_ChkEmptList(&(Tmp->GlobSyms));
289 CodeENDSECTION_ChkEmptList(&(Tmp->ExportSyms));
290 if (ArgCnt == 0)
291 as_snprintf(ListLine, STRINGSIZE, "[%s]", GetSectionName(MomSectionHandle));
292 SetMomSection(Tmp->Handle);
293 free(Tmp);
294 }
295 }
296 }
297
298
CodeCPU(Word Index)299 static void CodeCPU(Word Index)
300 {
301 UNUSED(Index);
302
303 if (!ChkArgCnt(1, 1));
304 else if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
305 else
306 {
307 NLS_UpString(ArgStr[1].Str);
308 if (SetCPUByName(&ArgStr[1]))
309 SetNSeg(SegCode);
310 else
311 WrStrErrorPos(ErrNum_InvCPUType, &ArgStr[1]);
312 }
313 }
314
315
CodeSETEQU(Word MayChange)316 static void CodeSETEQU(Word MayChange)
317 {
318 TempResult t;
319 Integer DestSeg;
320 int ValIndex = *LabPart.Str ? 1 : 2;
321
322 if (ChkArgCnt(ValIndex, ValIndex + 1))
323 {
324 EvalStrExpression(&ArgStr[ValIndex], &t);
325 if (!mFirstPassUnknown(t.Flags))
326 {
327 if (ArgCnt == ValIndex)
328 DestSeg = SegNone;
329 else
330 {
331 NLS_UpString(ArgStr[ValIndex + 1].Str);
332 if (!strcmp(ArgStr[ValIndex + 1].Str, "MOMSEGMENT"))
333 DestSeg = ActPC;
334 else if (*ArgStr[ValIndex + 1].Str == '\0')
335 DestSeg = SegNone;
336 else
337 {
338 for (DestSeg = 0; DestSeg <= PCMax; DestSeg++)
339 if (!strcmp(ArgStr[ValIndex + 1].Str, SegNames[DestSeg]))
340 break;
341 }
342 }
343 if (DestSeg > PCMax) WrStrErrorPos(ErrNum_UnknownSegment, &ArgStr[ValIndex + 1]);
344 else
345 {
346 const tStrComp *pName = *LabPart.Str ? &LabPart : &ArgStr[1];
347
348 SetListLineVal(&t);
349 PushLocHandle(-1);
350 switch (t.Typ)
351 {
352 case TempInt:
353 EnterIntSymbol(pName, t.Contents.Int, DestSeg, MayChange);
354 if (AttrPartOpSize != eSymbolSizeUnknown)
355 SetSymbolOrStructElemSize(pName, AttrPartOpSize);
356 break;
357 case TempFloat:
358 EnterFloatSymbol(pName, t.Contents.Float, MayChange);
359 break;
360 case TempString:
361 EnterDynStringSymbolWithFlags(pName, &t.Contents.Ascii, MayChange, t.Flags);
362 break;
363 case TempReg:
364 EnterRegSymbol(pName, &t.Contents.RegDescr, t.DataSize, MayChange, False);
365 break;
366 default:
367 break;
368 }
369 PopLocHandle();
370 }
371 }
372 }
373 }
374
CodeREGCore(const tStrComp * pNameArg,const tStrComp * pValueArg)375 static void CodeREGCore(const tStrComp *pNameArg, const tStrComp *pValueArg)
376 {
377 if (InternSymbol)
378 {
379 TempResult t;
380
381 t.Typ = TempNone;
382 InternSymbol(pValueArg->Str, &t);
383 switch (t.Typ)
384 {
385 case TempReg:
386 goto Set;
387 case TempNone:
388 {
389 tEvalResult EvalResult;
390 tErrorNum ErrorNum;
391
392 ErrorNum = EvalStrRegExpressionWithResult(pValueArg, &t.Contents.RegDescr, &EvalResult);
393
394 switch (ErrorNum)
395 {
396 case ErrNum_SymbolUndef:
397 /* ignore undefined symbols in first pass */
398 if (PassNo <= MaxSymPass)
399 {
400 Repass = True;
401 return;
402 }
403 break;
404 case ErrNum_RegWrongTarget:
405 /* REG is architecture-agnostic */
406 EvalResult.OK = True;
407 break;
408 default:
409 break;
410 }
411
412 if (EvalResult.OK)
413 {
414 t.DataSize = EvalResult.DataSize;
415 goto Set;
416 }
417 else
418 WrStrErrorPos(ErrorNum, pValueArg);
419
420 break;
421 }
422 Set:
423 EnterRegSymbol(pNameArg, &t.Contents.RegDescr, t.DataSize, False, True);
424 break;
425 default:
426 WrStrErrorPos(ErrNum_ExpectReg, pValueArg);
427 return;
428 }
429 }
430 }
431
CodeREG(Word Index)432 void CodeREG(Word Index)
433 {
434 UNUSED(Index);
435
436 if (ChkArgCnt(1, 1))
437 CodeREGCore(&LabPart, &ArgStr[1]);
438 }
439
CodeNAMEREG(Word Index)440 void CodeNAMEREG(Word Index)
441 {
442 UNUSED(Index);
443
444 if (ChkArgCnt(2, 2))
445 CodeREGCore(&ArgStr[2], &ArgStr[1]);
446 }
447
CodeORG(Word Index)448 static void CodeORG(Word Index)
449 {
450 LargeWord HVal;
451 Boolean ValOK;
452 tSymbolFlags Flags;
453 UNUSED(Index);
454
455 if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
456 else if (ChkArgCnt(1, 1))
457 {
458 #ifndef HAS64
459 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &ValOK, &Flags);
460 #else
461 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int64, &ValOK, &Flags);
462 #endif
463 if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
464 if (ValOK && !mFirstPassUnknown(Flags) && (PCs[ActPC] != HVal))
465 {
466 PCs[ActPC] = HVal;
467 DontPrint = True;
468 }
469 }
470 }
471
CodeRORG(Word Index)472 static void CodeRORG(Word Index)
473 {
474 LargeInt HVal;
475 Boolean ValOK;
476 tSymbolFlags Flags;
477 UNUSED(Index);
478
479 if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
480 else if (ChkArgCnt(1, 1))
481 {
482 #ifndef HAS64
483 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], SInt32, &ValOK, &Flags);
484 #else
485 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int64, &ValOK, &Flags);
486 #endif
487 if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
488 else if (ValOK)
489 {
490 PCs[ActPC] += HVal;
491 DontPrint = True;
492 }
493 }
494 }
495
CodeSHARED_BuildComment(char * c,size_t DestSize)496 static void CodeSHARED_BuildComment(char *c, size_t DestSize)
497 {
498 switch (ShareMode)
499 {
500 case 1:
501 as_snprintf(c, DestSize, "(* %s *)", CommPart.Str);
502 break;
503 case 2:
504 as_snprintf(c, DestSize, "/* %s */", CommPart.Str);
505 break;
506 case 3:
507 as_snprintf(c, DestSize, "; %s", CommPart.Str);
508 break;
509 }
510 }
511
CodeSHARED(Word Index)512 static void CodeSHARED(Word Index)
513 {
514 tStrComp *pArg;
515 String s, c;
516 TempResult t;
517 UNUSED(Index);
518
519 if (ShareMode == 0) WrError(ErrNum_NoShareFile);
520 else if ((ArgCnt == 0) && (*CommPart.Str != '\0'))
521 {
522 CodeSHARED_BuildComment(c, sizeof(c));
523 errno = 0;
524 fprintf(ShareFile, "%s\n", c); ChkIO(ErrNum_FileWriteError);
525 }
526 else
527 forallargs (pArg, True)
528 {
529 LookupSymbol(pArg, &t, False, TempAll);
530
531 switch (t.Typ)
532 {
533 case TempInt:
534 switch (ShareMode)
535 {
536 case 1:
537 IntLine(s, sizeof(s), t.Contents.Int, ConstModeMoto);
538 break;
539 case 2:
540 IntLine(s, sizeof(s), t.Contents.Int, ConstModeC);
541 break;
542 case 3:
543 IntLine(s, sizeof(s), t.Contents.Int, ConstMode);
544 break;
545 }
546 break;
547 case TempFloat:
548 as_snprintf(s, sizeof(s), "%0.17g", t.Contents.Float);
549 break;
550 case TempString:
551 DynString2CString(s + 1, &t.Contents.Ascii, sizeof(s) - 1);
552 if (ShareMode == 1)
553 {
554 *s = '\'';
555 strmaxcat(s, "\'", STRINGSIZE);
556 }
557 else
558 {
559 *s = '\"';
560 strmaxcat(s, "\"", STRINGSIZE);
561 }
562 break;
563 default:
564 continue;
565 }
566
567 if ((pArg == ArgStr + 1) && (*CommPart.Str != '\0'))
568 {
569 CodeSHARED_BuildComment(c, sizeof(c));
570 strmaxprep(c, " ", STRINGSIZE);
571 }
572 else
573 *c = '\0';
574 errno = 0;
575 switch (ShareMode)
576 {
577 case 1:
578 fprintf(ShareFile, "%s = %s;%s\n", pArg->Str, s, c);
579 break;
580 case 2:
581 fprintf(ShareFile, "#define %s %s%s\n", pArg->Str, s, c);
582 break;
583 case 3:
584 strmaxprep(s, IsSymbolChangeable(pArg) ? "set " : "equ ", STRINGSIZE);
585 fprintf(ShareFile, "%s %s%s\n", pArg->Str, s, c);
586 break;
587 }
588 ChkIO(ErrNum_FileWriteError);
589 }
590 }
591
CodeEXPORT(Word Index)592 static void CodeEXPORT(Word Index)
593 {
594 tStrComp *pArg;
595 TempResult t;
596 UNUSED(Index);
597
598 forallargs (pArg, True)
599 {
600 LookupSymbol(pArg, &t, True, TempInt);
601 if (TempNone == t.Typ)
602 continue;
603 if (t.Relocs == NULL)
604 AddExport(pArg->Str, t.Contents.Int, 0);
605 else if ((t.Relocs->Next != NULL) || (strcmp(t.Relocs->Ref, RelName_SegStart)))
606 WrStrErrorPos(ErrNum_Unexportable, pArg);
607 else
608 AddExport(pArg->Str, t.Contents.Int, RelFlag_Relative);
609 if (t.Relocs)
610 FreeRelocs(&t.Relocs);
611 }
612 }
613
CodePAGE(Word Index)614 static void CodePAGE(Word Index)
615 {
616 Integer LVal, WVal;
617 Boolean ValOK;
618 UNUSED(Index);
619
620 if (!ChkArgCnt(1, 2));
621 else if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
622 else
623 {
624 LVal = EvalStrIntExpression(&ArgStr[1], UInt8, &ValOK);
625 if (ValOK)
626 {
627 if ((LVal < 5) && (LVal != 0))
628 LVal = 5;
629 if (ArgCnt == 1)
630 {
631 WVal = 0;
632 ValOK = True;
633 }
634 else
635 WVal = EvalStrIntExpression(&ArgStr[2], UInt8, &ValOK);
636 if (ValOK)
637 {
638 if ((WVal < 5) && (WVal != 0))
639 WVal = 5;
640 PageLength = LVal;
641 PageWidth = WVal;
642 }
643 }
644 }
645 }
646
647
CodeNEWPAGE(Word Index)648 static void CodeNEWPAGE(Word Index)
649 {
650 ShortInt HVal8;
651 Boolean ValOK;
652 UNUSED(Index);
653
654 if (!ChkArgCnt(0, 1));
655 else if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
656 else
657 {
658 if (ArgCnt == 0)
659 {
660 HVal8 = 0;
661 ValOK = True;
662 }
663 else
664 HVal8 = EvalStrIntExpression(&ArgStr[1], Int8, &ValOK);
665 if ((ValOK) || (ArgCnt == 0))
666 {
667 if (HVal8 > ChapMax)
668 HVal8 = ChapMax;
669 else if (HVal8 < 0)
670 HVal8 = 0;
671 NewPage(HVal8, True);
672 }
673 }
674 }
675
676
CodeString(Word Index)677 static void CodeString(Word Index)
678 {
679 String tmp;
680 Boolean OK;
681
682 if (ChkArgCnt(1, 1))
683 {
684 EvalStrStringExpression(&ArgStr[1], &OK, tmp);
685 if (!OK) WrError(ErrNum_InvString);
686 else
687 {
688 switch (Index)
689 {
690 case 0:
691 strmaxcpy(PrtInitString, tmp, STRINGSIZE);
692 break;
693 case 1:
694 strmaxcpy(PrtExitString, tmp, STRINGSIZE);
695 break;
696 case 2:
697 strmaxcpy(PrtTitleString, tmp, STRINGSIZE);
698 break;
699 }
700 }
701 }
702 }
703
704
CodePHASE(Word Index)705 static void CodePHASE(Word Index)
706 {
707 Boolean OK;
708 LongInt HVal;
709 UNUSED(Index);
710
711 if (!ChkArgCnt(1, 1));
712 else if (ActPC == StructSeg) WrError(ErrNum_PhaseDisallowed);
713 else
714 {
715 HVal = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
716 if (OK)
717 {
718 tSavePhase *pSavePhase;
719
720 pSavePhase = (tSavePhase*)calloc(1, sizeof (*pSavePhase));
721 pSavePhase->SaveValue = Phases[ActPC];
722 pSavePhase->pNext = pPhaseStacks[ActPC];
723 pPhaseStacks[ActPC] = pSavePhase;
724 Phases[ActPC] = HVal - ProgCounter();
725 }
726 }
727 }
728
729
CodeDEPHASE(Word Index)730 static void CodeDEPHASE(Word Index)
731 {
732 UNUSED(Index);
733
734 if (!ChkArgCnt(0, 0));
735 else if (ActPC == StructSeg) WrError(ErrNum_PhaseDisallowed);
736 else if (pPhaseStacks[ActPC])
737 {
738 tSavePhase *pSavePhase;
739
740 pSavePhase = pPhaseStacks[ActPC];
741 pPhaseStacks[ActPC] = pSavePhase->pNext;
742 Phases[ActPC] = pSavePhase->SaveValue;
743 free(pSavePhase);
744 }
745 else
746 Phases[ActPC] = 0;
747 }
748
749
CodeWARNING(Word Index)750 static void CodeWARNING(Word Index)
751 {
752 String mess;
753 Boolean OK;
754 UNUSED(Index);
755
756 if (ChkArgCnt(1, 1))
757 {
758 EvalStrStringExpression(&ArgStr[1], &OK, mess);
759 if (!OK) WrError(ErrNum_InvString);
760 else
761 WrErrorString(mess, "", True, False, NULL, NULL);
762 }
763 }
764
765
CodeMESSAGE(Word Index)766 static void CodeMESSAGE(Word Index)
767 {
768 String mess;
769 Boolean OK;
770 UNUSED(Index);
771
772 if (ChkArgCnt(1, 1))
773 {
774 EvalStrStringExpression(&ArgStr[1], &OK, mess);
775 if (!OK) WrError(ErrNum_InvString);
776 else
777 {
778 WrConsoleLine(mess, True);
779 if (strcmp(LstName, "/dev/null"))
780 WrLstLine(mess);
781 }
782 }
783 }
784
785
CodeERROR(Word Index)786 static void CodeERROR(Word Index)
787 {
788 String mess;
789 Boolean OK;
790 UNUSED(Index);
791
792 if (ChkArgCnt(1, 1))
793 {
794 EvalStrStringExpression(&ArgStr[1], &OK, mess);
795 if (!OK) WrError(ErrNum_InvString);
796 else
797 WrErrorString(mess, "", False, False, NULL, NULL);
798 }
799 }
800
801
CodeFATAL(Word Index)802 static void CodeFATAL(Word Index)
803 {
804 String mess;
805 Boolean OK;
806 UNUSED(Index);
807
808 if (ChkArgCnt(1, 1))
809 {
810 EvalStrStringExpression(&ArgStr[1], &OK, mess);
811 if (!OK) WrError(ErrNum_InvString);
812 else
813 WrErrorString(mess, "", False, True, NULL, NULL);
814 }
815 }
816
CodeCHARSET(Word Index)817 static void CodeCHARSET(Word Index)
818 {
819 TempResult t;
820 FILE *f;
821 unsigned char tfield[256];
822 LongWord Start, l, TStart, Stop, z;
823 Boolean OK;
824 UNUSED(Index);
825
826 if (!ChkArgCnt(0, 3));
827 else if (ArgCnt == 0)
828 {
829 for (z = 0; z < 256; z++)
830 CharTransTable[z] = z;
831 }
832 else
833 {
834 EvalStrExpression(&ArgStr[1], &t);
835 if ((t.Typ == TempString) && (t.Flags & eSymbolFlag_StringSingleQuoted))
836 TempResultToInt(&t);
837 switch (t.Typ)
838 {
839 case TempInt:
840 if (mFirstPassUnknown(t.Flags))
841 t.Contents.Int &= 255;
842 if (ChkRange(t.Contents.Int, 0, 255))
843 {
844 if (ChkArgCnt(2, 3))
845 {
846 Start = t.Contents.Int;
847 EvalStrExpression(&ArgStr[2], &t);
848 if ((t.Typ == TempString) && (t.Flags & eSymbolFlag_StringSingleQuoted))
849 TempResultToInt(&t);
850 switch (t.Typ)
851 {
852 case TempInt: /* �bersetzungsbereich als Character-Angabe */
853 if (mFirstPassUnknown(t.Flags))
854 t.Contents.Int &= 255;
855 if (ArgCnt == 2)
856 {
857 Stop = Start;
858 TStart = t.Contents.Int;
859 OK = ChkRange(TStart, 0, 255);
860 }
861 else
862 {
863 Stop = t.Contents.Int;
864 OK = ChkRange(Stop, Start, 255);
865 if (OK)
866 TStart = EvalStrIntExpression(&ArgStr[3], UInt8, &OK);
867 else
868 TStart = 0;
869 }
870 if (OK)
871 for (z = Start; z <= Stop; z++)
872 CharTransTable[z] = TStart + (z - Start);
873 break;
874 case TempString:
875 l = t.Contents.Ascii.Length; /* Uebersetzungsstring ab Start */
876 if (Start + l > 256) WrError(ErrNum_OverRange);
877 else
878 for (z = 0; z < l; z++)
879 CharTransTable[Start + z] = t.Contents.Ascii.Contents[z];
880 break;
881 case TempFloat:
882 WrStrErrorPos(ErrNum_StringOrIntButFloat, &ArgStr[2]);
883 break;
884 default:
885 break;
886 }
887 }
888 }
889 break;
890 case TempString:
891 if (ChkArgCnt(1, 1)) /* Tabelle von Datei lesen */
892 {
893 String Tmp;
894
895 DynString2CString(Tmp, &t.Contents.Ascii, sizeof(Tmp));
896 f = fopen(Tmp, OPENRDMODE);
897 if (!f) ChkIO(ErrNum_OpeningFile);
898 if (fread(tfield, sizeof(char), 256, f) != 256) ChkIO(ErrNum_FileReadError);
899 fclose(f);
900 memcpy(CharTransTable, tfield, sizeof(char) * 256);
901 }
902 break;
903 case TempFloat:
904 WrStrErrorPos(ErrNum_StringOrIntButFloat, &ArgStr[1]);
905 break;
906 default:
907 break;
908 }
909 }
910 }
911
CodePRSET(Word Index)912 static void CodePRSET(Word Index)
913 {
914 int z, z2;
915 UNUSED(Index);
916
917 for (z = 0; z < 16; z++)
918 {
919 for (z2 = 0; z2 < 16; z2++)
920 printf(" %02x", CharTransTable[z*16 + z2]);
921 printf(" ");
922 for (z2 = 0; z2 < 16; z2++)
923 printf("%c", CharTransTable[z * 16 + z2] > ' ' ? CharTransTable[z*16 + z2] : '.');
924 putchar('\n');
925 }
926 }
927
CodeCODEPAGE(Word Index)928 static void CodeCODEPAGE(Word Index)
929 {
930 PTransTable Prev, Run, New, Source;
931 int erg = 0;
932 UNUSED(Index);
933
934 if (!ChkArgCnt(1, 2));
935 else if (!ChkSymbName(ArgStr[1].Str)) WrStrErrorPos(ErrNum_InvSymName, &ArgStr[1]);
936 else
937 {
938 if (!CaseSensitive)
939 {
940 UpString(ArgStr[1].Str);
941 if (ArgCnt == 2)
942 UpString(ArgStr[2].Str);
943 }
944
945 if (ArgCnt == 1)
946 Source = CurrTransTable;
947 else
948 {
949 for (Source = TransTables; Source; Source = Source->Next)
950 if (!strcmp(Source->Name, ArgStr[2].Str))
951 break;
952 }
953
954 if (!Source) WrStrErrorPos(ErrNum_UnknownCodepage, &ArgStr[2]);
955 else
956 {
957 for (Prev = NULL, Run = TransTables; Run; Prev = Run, Run = Run->Next)
958 if ((erg = strcmp(ArgStr[1].Str, Run->Name)) <= 0)
959 break;
960
961 if ((!Run) || (erg < 0))
962 {
963 New = (PTransTable) malloc(sizeof(TTransTable));
964 New->Next = Run;
965 New->Name = as_strdup(ArgStr[1].Str);
966 New->Table = (unsigned char *) malloc(256 * sizeof(char));
967 memcpy(New->Table, Source->Table, 256 * sizeof(char));
968 if (!Prev)
969 TransTables = New;
970 else
971 Prev->Next = New;
972 CurrTransTable = New;
973 }
974 else
975 CurrTransTable = Run;
976 }
977 }
978 }
979
980
CodeFUNCTION(Word Index)981 static void CodeFUNCTION(Word Index)
982 {
983 String FName;
984 Boolean OK;
985 int z;
986 UNUSED(Index);
987
988 if (ChkArgCnt(2, ArgCntMax))
989 {
990 OK = True;
991 z = 1;
992 do
993 {
994 OK = (OK && ChkMacSymbName(ArgStr[z].Str));
995 if (!OK)
996 WrStrErrorPos(ErrNum_InvSymName, &ArgStr[z]);
997 z++;
998 }
999 while ((z < ArgCnt) && (OK));
1000 if (OK)
1001 {
1002 strmaxcpy(FName, ArgStr[ArgCnt].Str, STRINGSIZE);
1003 for (z = 1; z < ArgCnt; z++)
1004 CompressLine(ArgStr[z].Str, z, FName, STRINGSIZE, CaseSensitive);
1005 EnterFunction(&LabPart, FName, ArgCnt - 1);
1006 }
1007 }
1008 }
1009
1010
CodeSAVE(Word Index)1011 static void CodeSAVE(Word Index)
1012 {
1013 PSaveState Neu;
1014 UNUSED(Index);
1015
1016 if (ChkArgCnt(0, 0))
1017 {
1018 Neu = (PSaveState) malloc(sizeof(TSaveState));
1019 Neu->Next = FirstSaveState;
1020 Neu->SaveCPU = MomCPU;
1021 Neu->pSaveCPUArgs = as_strdup(MomCPUArgs);
1022 Neu->SavePC = ActPC;
1023 Neu->SaveListOn = ListOn;
1024 Neu->SaveLstMacroExp = GetLstMacroExp();
1025 Neu->SaveLstMacroExpModDefault = LstMacroExpModDefault;
1026 Neu->SaveLstMacroExpModOverride = LstMacroExpModOverride;
1027 Neu->SaveTransTable = CurrTransTable;
1028 Neu->SaveEnumSegment = EnumSegment;
1029 Neu->SaveEnumIncrement = EnumIncrement;
1030 Neu->SaveEnumCurrentValue = EnumCurrentValue;
1031 FirstSaveState = Neu;
1032 }
1033 }
1034
1035
CodeRESTORE(Word Index)1036 static void CodeRESTORE(Word Index)
1037 {
1038 PSaveState Old;
1039 UNUSED(Index);
1040
1041 if (!ChkArgCnt(0, 0));
1042 else if (!FirstSaveState) WrError(ErrNum_NoSaveFrame);
1043 else
1044 {
1045 tStrComp TmpComp;
1046 String TmpCompStr;
1047 StrCompMkTemp(&TmpComp, TmpCompStr);
1048
1049 Old = FirstSaveState; FirstSaveState = Old->Next;
1050 if (Old->SavePC != ActPC)
1051 {
1052 ActPC = Old->SavePC;
1053 DontPrint = True;
1054 }
1055 if (Old->SaveCPU != MomCPU)
1056 {
1057 StrCompMkTemp(&TmpComp, Old->pSaveCPUArgs);
1058 SetCPUByType(Old->SaveCPU, &TmpComp);
1059 }
1060 strmaxcpy(TmpCompStr, ListOnName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, ListOn = Old->SaveListOn, 0, True);
1061 SetLstMacroExp(Old->SaveLstMacroExp);
1062 LstMacroExpModDefault = Old->SaveLstMacroExpModDefault;
1063 LstMacroExpModOverride = Old->SaveLstMacroExpModOverride;
1064 CurrTransTable = Old->SaveTransTable;
1065 free(Old->pSaveCPUArgs);
1066 free(Old);
1067 }
1068 }
1069
1070
CodeMACEXP(Word Index)1071 static void CodeMACEXP(Word Index)
1072 {
1073 /* will deprecate this in 1..2 years, 2018-01-21 */
1074
1075 #if 0
1076 if (Index & 0x10)
1077 {
1078 char Msg[70];
1079
1080 as_snprintf(Msg, sizeof(Msg), getmessage(Num_ErrMsgDeprecated_Instead), "MACEXP_DFT");
1081 WrXError(ErrNum_Deprecated, Msg);
1082 }
1083 #endif
1084
1085 /* allow zero arguments for MACEXP_OVR, to remove all overrides */
1086
1087 if (!ChkArgCnt((Index & 0x0f) ? 0 : 1, ArgCntMax));
1088 else if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
1089 else
1090 {
1091 tStrComp *pArg;
1092 tLstMacroExpMod LstMacroExpMod;
1093 tLstMacroExp Mod;
1094 Boolean Set;
1095 Boolean OK = True;
1096
1097 InitLstMacroExpMod(&LstMacroExpMod);
1098 forallargs (pArg, True)
1099 {
1100 if (!as_strcasecmp(pArg->Str, "ON"))
1101 {
1102 Mod = eLstMacroExpAll; Set = True;
1103 }
1104 else if (!as_strcasecmp(pArg->Str, "OFF"))
1105 {
1106 Mod = eLstMacroExpAll; Set = False;
1107 }
1108 else if (!as_strcasecmp(pArg->Str, "NOIF"))
1109 {
1110 Mod= eLstMacroExpIf; Set = False;
1111 }
1112 else if (!as_strcasecmp(pArg->Str, "NOMACRO"))
1113 {
1114 Mod = eLstMacroExpMacro; Set = False;
1115 }
1116 else if (!as_strcasecmp(pArg->Str, "NOREST"))
1117 {
1118 Mod = eLstMacroExpRest; Set = False;
1119 }
1120 else if (!as_strcasecmp(pArg->Str, "IF"))
1121 {
1122 Mod = eLstMacroExpIf; Set = True;
1123 }
1124 else if (!as_strcasecmp(pArg->Str, "MACRO"))
1125 {
1126 Mod = eLstMacroExpMacro; Set = True;
1127 }
1128 else if (!as_strcasecmp(pArg->Str, "REST"))
1129 {
1130 Mod = eLstMacroExpRest; Set = True;
1131 }
1132 else
1133 OK = False;
1134 if (!OK)
1135 {
1136 WrStrErrorPos(ErrNum_TooManyMacExpMod, pArg);
1137 break;
1138 }
1139 else if (!AddLstMacroExpMod(&LstMacroExpMod, Set, Mod))
1140 {
1141 WrStrErrorPos(ErrNum_TooManyArgs, pArg);
1142 break;
1143 }
1144 }
1145 if (OK)
1146 {
1147 if (!ChkLstMacroExpMod(&LstMacroExpMod)) WrError(ErrNum_ConflictingMacExpMod);
1148 else if (Index) /* Override */
1149 LstMacroExpModOverride = LstMacroExpMod;
1150 else
1151 {
1152 /* keep LstMacroExp and LstMacroExpModDefault in sync! */
1153 LstMacroExpModDefault = LstMacroExpMod;
1154 SetLstMacroExp(ApplyLstMacroExpMod(eLstMacroExpAll, &LstMacroExpModDefault));
1155 }
1156 }
1157 }
1158 }
1159
DecodeSegment(const tStrComp * pArg,Integer StartSeg,Integer * pResult)1160 static Boolean DecodeSegment(const tStrComp *pArg, Integer StartSeg, Integer *pResult)
1161 {
1162 Integer SegZ;
1163 Word Mask;
1164
1165 for (SegZ = StartSeg, Mask = 1 << StartSeg; SegZ <= PCMax; SegZ++, Mask <<= 1)
1166 if ((ValidSegs & Mask) && !as_strcasecmp(pArg->Str, SegNames[SegZ]))
1167 {
1168 *pResult = SegZ;
1169 return True;
1170 }
1171 WrStrErrorPos(ErrNum_UnknownSegment, pArg);
1172 return False;
1173 }
1174
CodeSEGMENT(Word Index)1175 static void CodeSEGMENT(Word Index)
1176 {
1177 Integer NewSegment;
1178 UNUSED(Index);
1179
1180 if (ChkArgCnt(1, 1)
1181 && DecodeSegment(&ArgStr[1], SegCode, &NewSegment))
1182 SetNSeg(NewSegment);
1183 }
1184
1185
CodeLABEL(Word Index)1186 static void CodeLABEL(Word Index)
1187 {
1188 LongInt Erg;
1189 Boolean OK;
1190 tSymbolFlags Flags;
1191 UNUSED(Index);
1192
1193 if (ChkArgCnt(1, 1))
1194 {
1195 Erg = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
1196 if (OK && !mFirstPassUnknown(Flags))
1197 {
1198 PushLocHandle(-1);
1199 EnterIntSymbol(&LabPart, Erg, SegCode, False);
1200 *ListLine = '=';
1201 IntLine(ListLine + 1, STRINGSIZE - 1, Erg, ConstMode);
1202 PopLocHandle();
1203 }
1204 }
1205 }
1206
1207
CodeREAD(Word Index)1208 static void CodeREAD(Word Index)
1209 {
1210 String ExpStr;
1211 tStrComp Exp;
1212 TempResult Erg;
1213 Boolean OK;
1214 LongInt SaveLocHandle;
1215 UNUSED(Index);
1216
1217 StrCompMkTemp(&Exp, ExpStr);
1218 if (ChkArgCnt(1, 2))
1219 {
1220 if (ArgCnt == 2) EvalStrStringExpression(&ArgStr[1], &OK, Exp.Str);
1221 else
1222 {
1223 as_snprintf(Exp.Str, sizeof(ExpStr), "Read %s ? ", ArgStr[1].Str);
1224 OK = True;
1225 }
1226 if (OK)
1227 {
1228 printf("%s", Exp.Str);
1229 fflush(stdout);
1230 if (!fgets(Exp.Str, STRINGSIZE, stdin))
1231 OK = False;
1232 else
1233 {
1234 UpString(Exp.Str);
1235 EvalStrExpression(&Exp, &Erg);
1236 }
1237 if (OK)
1238 {
1239 SetListLineVal(&Erg);
1240 SaveLocHandle = MomLocHandle;
1241 MomLocHandle = -1;
1242 if (mFirstPassUnknown(Erg.Flags)) WrError(ErrNum_FirstPassCalc);
1243 else switch (Erg.Typ)
1244 {
1245 case TempInt:
1246 EnterIntSymbol(&ArgStr[ArgCnt], Erg.Contents.Int, SegNone, True);
1247 break;
1248 case TempFloat:
1249 EnterFloatSymbol(&ArgStr[ArgCnt], Erg.Contents.Float, True);
1250 break;
1251 case TempString:
1252 EnterDynStringSymbol(&ArgStr[ArgCnt], &Erg.Contents.Ascii, True);
1253 break;
1254 default:
1255 break;
1256 }
1257 MomLocHandle = SaveLocHandle;
1258 }
1259 }
1260 }
1261 }
1262
CodeRADIX(Word Index)1263 static void CodeRADIX(Word Index)
1264 {
1265 Boolean OK;
1266 LargeWord tmp;
1267
1268 if (ChkArgCnt(1, 1))
1269 {
1270 tmp = ConstLongInt(ArgStr[1].Str, &OK, 10);
1271 if (!OK) WrError(ErrNum_ExpectInt);
1272 else if (ChkRange(tmp, 2, 36))
1273 {
1274 if (Index == 1)
1275 OutRadixBase = tmp;
1276 else
1277 RadixBase = tmp;
1278 }
1279 }
1280 }
1281
CodeALIGN(Word Index)1282 static void CodeALIGN(Word Index)
1283 {
1284 UNUSED(Index);
1285
1286 if (ChkArgCnt(1, 2))
1287 {
1288 Word AlignValue;
1289 Byte AlignFill = 0;
1290 Boolean OK = True;
1291 tSymbolFlags Flags = eSymbolFlag_None;
1292 LongInt NewPC;
1293
1294 if (2 == ArgCnt)
1295 AlignFill = EvalStrIntExpressionWithFlags(&ArgStr[2], Int8, &OK, &Flags);
1296 if (OK)
1297 AlignValue = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
1298 if (OK)
1299 {
1300 if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
1301 else
1302 {
1303 NewPC = EProgCounter() + AlignValue - 1;
1304 NewPC -= NewPC % AlignValue;
1305 CodeLen = NewPC - EProgCounter();
1306 if (1 == ArgCnt)
1307 {
1308 DontPrint = !!CodeLen;
1309 BookKeeping();
1310 }
1311 else if (CodeLen > (LongInt)MaxCodeLen) WrError(ErrNum_CodeOverflow);
1312 else
1313 {
1314 memset(BAsmCode, AlignFill, CodeLen);
1315 DontPrint = False;
1316 }
1317 }
1318 }
1319 }
1320 }
1321
CodeASSUME(Word Index)1322 static void CodeASSUME(Word Index)
1323 {
1324 int z1;
1325 unsigned z2;
1326 Boolean OK;
1327 tSymbolFlags Flags;
1328 LongInt HVal;
1329 tStrComp RegPart, ValPart;
1330 char *pSep, EmptyStr[] = "";
1331
1332 UNUSED(Index);
1333
1334 /* CPU-specific override? */
1335
1336 if (pASSUMEOverride)
1337 {
1338 pASSUMEOverride();
1339 return;
1340 }
1341
1342 if (ChkArgCnt(1, ArgCntMax))
1343 {
1344 z1 = 1;
1345 OK = True;
1346 while ((z1 <= ArgCnt) && (OK))
1347 {
1348 pSep = QuotPos(ArgStr[z1].Str, ':');
1349 if (pSep)
1350 StrCompSplitRef(&RegPart, &ValPart, &ArgStr[z1], pSep);
1351 else
1352 {
1353 RegPart = ArgStr[z1];
1354 StrCompMkTemp(&ValPart, EmptyStr);
1355 }
1356 z2 = 0;
1357 NLS_UpString(RegPart.Str);
1358 while ((z2 < ASSUMERecCnt) && (strcmp(pASSUMERecs[z2].Name, RegPart.Str)))
1359 z2++;
1360 OK = (z2 < ASSUMERecCnt);
1361 if (!OK) WrStrErrorPos(ErrNum_InvRegName, &RegPart);
1362 else
1363 {
1364 if (!as_strcasecmp(ValPart.Str, "NOTHING"))
1365 {
1366 if (pASSUMERecs[z2].NothingVal == -1) WrError(ErrNum_InvAddrMode);
1367 else
1368 *(pASSUMERecs[z2].Dest) = pASSUMERecs[z2].NothingVal;
1369 }
1370 else
1371 {
1372 HVal = EvalStrIntExpressionWithFlags(&ValPart, Int32, &OK, &Flags);
1373 if (OK)
1374 {
1375 if (mFirstPassUnknown(Flags))
1376 {
1377 WrError(ErrNum_FirstPassCalc);
1378 OK = False;
1379 }
1380 else if (ChkRange(HVal, pASSUMERecs[z2].Min, pASSUMERecs[z2].Max))
1381 *(pASSUMERecs[z2].Dest) = HVal;
1382 }
1383 }
1384 if (pASSUMERecs[z2].pPostProc)
1385 pASSUMERecs[z2].pPostProc();
1386 }
1387 z1++;
1388 }
1389 }
1390 }
1391
CodeENUM(Word IsNext)1392 static void CodeENUM(Word IsNext)
1393 {
1394 int z;
1395 char *p = NULL;
1396 Boolean OK;
1397 tSymbolFlags Flags;
1398 LongInt First = 0, Last = 0;
1399 tStrComp SymPart;
1400
1401 if (!IsNext)
1402 EnumCurrentValue = 0;
1403 if (ChkArgCnt(1, ArgCntMax))
1404 {
1405 for (z = 1; z <= ArgCnt; z++)
1406 {
1407 p = QuotPos(ArgStr[z].Str, '=');
1408 if (p)
1409 {
1410 StrCompSplitRef(&ArgStr[z], &SymPart, &ArgStr[z], p);
1411 EnumCurrentValue = EvalStrIntExpressionWithFlags(&SymPart, Int32, &OK, &Flags);
1412 if (!OK)
1413 return;
1414 if (mFirstPassUnknown(Flags))
1415 {
1416 WrStrErrorPos(ErrNum_FirstPassCalc, &SymPart);
1417 return;
1418 }
1419 *p = '\0';
1420 }
1421 EnterIntSymbol(&ArgStr[z], EnumCurrentValue, EnumSegment, False);
1422 if (z == 1)
1423 First = EnumCurrentValue;
1424 else if (z == ArgCnt)
1425 Last = EnumCurrentValue;
1426 EnumCurrentValue += EnumIncrement;
1427 }
1428 }
1429 *ListLine = '=';
1430 IntLine(ListLine + 1, STRINGSIZE - 1, First, ConstMode);
1431 if (ArgCnt != 1)
1432 {
1433 int l;
1434
1435 strmaxcat(ListLine, "..", STRINGSIZE);
1436 l = strlen(ListLine);
1437 IntLine(ListLine + l, STRINGSIZE - l, Last, ConstMode);
1438 }
1439 }
1440
CodeENUMCONF(Word Index)1441 static void CodeENUMCONF(Word Index)
1442 {
1443 UNUSED(Index);
1444
1445 if (ChkArgCnt(1, 2))
1446 {
1447 Boolean OK;
1448 LongInt NewIncrement;
1449
1450 NewIncrement = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
1451 if (!OK)
1452 return;
1453 EnumIncrement = NewIncrement;
1454
1455 if (ArgCnt >= 2)
1456 {
1457 Integer NewSegment;
1458
1459 if (DecodeSegment(&ArgStr[2], SegNone, &NewSegment))
1460 EnumSegment = NewSegment;
1461 }
1462 }
1463 }
1464
CodeEND(Word Index)1465 static void CodeEND(Word Index)
1466 {
1467 UNUSED(Index);
1468
1469 if (ChkArgCnt(0, 1))
1470 {
1471 if (ArgCnt == 1)
1472 {
1473 LongInt HVal;
1474 tEvalResult EvalResult;
1475
1476 HVal = EvalStrIntExpressionWithResult(&ArgStr[1], Int32, &EvalResult);
1477 if (EvalResult.OK)
1478 {
1479 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1480 StartAdr = HVal;
1481 StartAdrPresent = True;
1482 }
1483 }
1484 ENDOccured = True;
1485 }
1486 }
1487
1488
CodeLISTING(Word Index)1489 static void CodeLISTING(Word Index)
1490 {
1491 Byte Value = 0xff;
1492 Boolean OK;
1493 UNUSED(Index);
1494
1495 if (!ChkArgCnt(1, 1));
1496 else if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
1497 else
1498 {
1499 OK = True;
1500 NLS_UpString(ArgStr[1].Str);
1501 if (!strcmp(ArgStr[1].Str, "OFF"))
1502 Value = 0;
1503 else if (!strcmp(ArgStr[1].Str, "ON"))
1504 Value = 1;
1505 else if (!strcmp(ArgStr[1].Str, "NOSKIPPED"))
1506 Value = 2;
1507 else if (!strcmp(ArgStr[1].Str, "PURECODE"))
1508 Value = 3;
1509 else
1510 OK = False;
1511 if (!OK) WrStrErrorPos(ErrNum_OnlyOnOff, &ArgStr[1]);
1512 else
1513 {
1514 tStrComp TmpComp;
1515 String TmpCompStr;
1516
1517 StrCompMkTemp(&TmpComp, TmpCompStr);
1518 strmaxcpy(TmpCompStr, ListOnName, sizeof(TmpCompStr));
1519 EnterIntSymbol(&TmpComp, ListOn = Value, 0, True);
1520 }
1521 }
1522 }
1523
INCLUDE_SearchCore(tStrComp * pDest,const tStrComp * pArg,Boolean SearchPath)1524 void INCLUDE_SearchCore(tStrComp *pDest, const tStrComp *pArg, Boolean SearchPath)
1525 {
1526 StrCompCopy(pDest, &ArgStr[1]);
1527
1528 if (pDest->Str[0] == '"')
1529 {
1530 int l;
1531
1532 StrCompIncRefLeft(pDest, 1);
1533 l = strlen(pDest->Str);
1534 if ((l > 0) && (pDest->Str[l - 1] == '"'))
1535 StrCompShorten(pDest, 1);
1536 else
1537 {
1538 WrStrErrorPos(ErrNum_BrackErr, pArg);
1539 return;
1540 }
1541 }
1542 AddSuffix(pDest->Str, IncSuffix);
1543
1544 if (SearchPath)
1545 {
1546 String FoundFileName;
1547
1548 if (FSearch(FoundFileName, sizeof(FoundFileName), pDest->Str, CurrFileName, SearchPath ? IncludeList : ""))
1549 ChkStrIO(ErrNum_OpeningFile, &ArgStr[1]);
1550 strmaxcpy(pDest->Str, FExpand(FoundFileName), STRINGSIZE - 1);
1551 }
1552 }
1553
CodeBINCLUDE(Word Index)1554 static void CodeBINCLUDE(Word Index)
1555 {
1556 FILE *F;
1557 LongInt Len = -1;
1558 LongWord Ofs = 0, Curr, Rest, FSize;
1559 Word RLen;
1560 Boolean OK, SaveTurnWords;
1561 tSymbolFlags Flags;
1562 LargeWord OldPC;
1563 UNUSED(Index);
1564
1565 if (!ChkArgCnt(1, 3));
1566 else if (ActPC == StructSeg) WrError(ErrNum_NotInStruct);
1567 else
1568 {
1569 if (ArgCnt == 1)
1570 OK = True;
1571 else
1572 {
1573 Ofs = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &OK, &Flags);
1574 if (mFirstPassUnknown(Flags))
1575 {
1576 WrError(ErrNum_FirstPassCalc);
1577 OK = False;
1578 }
1579 if (OK)
1580 {
1581 if (ArgCnt == 2)
1582 Len = -1;
1583 else
1584 {
1585 Len = EvalStrIntExpressionWithFlags(&ArgStr[3], Int32, &OK, &Flags);
1586 if (mFirstPassUnknown(Flags))
1587 {
1588 WrError(ErrNum_FirstPassCalc);
1589 OK = False;
1590 }
1591 }
1592 }
1593 }
1594 if (OK)
1595 {
1596 tStrComp FNameArg;
1597 String FNameArgStr;
1598
1599 StrCompMkTemp(&FNameArg, FNameArgStr);
1600 INCLUDE_SearchCore(&FNameArg, &ArgStr[1], True);
1601
1602 F = fopen(FNameArg.Str, OPENRDMODE);
1603 if (F == NULL) ChkIO(ErrNum_OpeningFile);
1604 errno = 0; FSize = FileSize(F); ChkIO(ErrNum_FileReadError);
1605 if (Len == -1)
1606 {
1607 if ((Len = FSize - Ofs) < 0)
1608 {
1609 fclose(F); WrError(ErrNum_ShortRead); return;
1610 }
1611 }
1612 if (!ChkPC(PCs[ActPC] + Len - 1)) WrError(ErrNum_AdrOverflow);
1613 else
1614 {
1615 errno = 0; fseek(F, Ofs, SEEK_SET); ChkIO(ErrNum_FileReadError);
1616 Rest = Len;
1617 SaveTurnWords = TurnWords;
1618 TurnWords = False;
1619 OldPC = ProgCounter();
1620 do
1621 {
1622 Curr = (Rest <= 256) ? Rest : 256;
1623 errno = 0; RLen = fread(BAsmCode, 1, Curr, F); ChkIO(ErrNum_FileReadError);
1624 CodeLen = RLen;
1625 WriteBytes();
1626 PCs[ActPC] += CodeLen;
1627 Rest -= RLen;
1628 }
1629 while ((Rest != 0) && (RLen == Curr));
1630 if (Rest != 0) WrError(ErrNum_ShortRead);
1631 TurnWords = SaveTurnWords;
1632 DontPrint = True;
1633 CodeLen = ProgCounter() - OldPC;
1634 PCs[ActPC] = OldPC;
1635 }
1636 fclose(F);
1637 }
1638 }
1639 }
1640
CodePUSHV(Word Index)1641 static void CodePUSHV(Word Index)
1642 {
1643 int z;
1644 UNUSED(Index);
1645
1646 if (ChkArgCnt(2, ArgCntMax))
1647 {
1648 if (!CaseSensitive)
1649 NLS_UpString(ArgStr[1].Str);
1650 for (z = 2; z <= ArgCnt; z++)
1651 PushSymbol(&ArgStr[z], &ArgStr[1]);
1652 }
1653 }
1654
CodePOPV(Word Index)1655 static void CodePOPV(Word Index)
1656 {
1657 int z;
1658 UNUSED(Index);
1659
1660 if (ChkArgCnt(2, ArgCntMax))
1661 {
1662 if (!CaseSensitive)
1663 NLS_UpString(ArgStr[1].Str);
1664 for (z = 2; z <= ArgCnt; z++)
1665 PopSymbol(&ArgStr[z], &ArgStr[1]);
1666 }
1667 }
1668
CodePPSyms_SearchSym(PForwardSymbol Root,char * Comp)1669 static PForwardSymbol CodePPSyms_SearchSym(PForwardSymbol Root, char *Comp)
1670 {
1671 PForwardSymbol Lauf = Root;
1672 UNUSED(Comp);
1673
1674 while (Lauf && strcmp(Lauf->Name, Comp))
1675 Lauf = Lauf->Next;
1676 return Lauf;
1677 }
1678
1679
CodeSTRUCT(Word IsUnion)1680 static void CodeSTRUCT(Word IsUnion)
1681 {
1682 PStructStack NStruct;
1683 tStrComp *pArg;
1684 Boolean OK, DoExt;
1685 char ExtChar;
1686 String StructName;
1687
1688 if (!ChkArgCnt(0, ArgCntMax))
1689 return;
1690
1691 /* unnamed struct/union only allowed if embedded into at least one named struct/union */
1692
1693 if (!*LabPart.Str)
1694 {
1695 if (!pInnermostNamedStruct)
1696 {
1697 WrError(ErrNum_FreestandingUnnamedStruct);
1698 return;
1699 }
1700 }
1701 else
1702 {
1703 if (!ChkSymbName(LabPart.Str))
1704 {
1705 WrXError(ErrNum_InvSymName, LabPart.Str);
1706 return;
1707 }
1708 if (!CaseSensitive)
1709 NLS_UpString(LabPart.Str);
1710 }
1711
1712 /* compose name of nested structures */
1713
1714 if (*LabPart.Str)
1715 BuildStructName(StructName, sizeof(StructName), LabPart.Str);
1716 else
1717 *StructName = '\0';
1718
1719 /* If named and embedded into another struct, add as element to innermost named parent struct.
1720 Add up all offsets of unnamed structs in between. */
1721
1722 if (StructStack && (*LabPart.Str))
1723 {
1724 PStructStack pRun;
1725 LargeWord Offset = ProgCounter();
1726 PStructElem pElement = CreateStructElem(LabPart.Str);
1727
1728 for (pRun = StructStack; pRun && pRun != pInnermostNamedStruct; pRun = pRun->Next)
1729 Offset += pRun->SaveCurrPC;
1730 pElement->Offset = Offset;
1731 pElement->IsStruct = True;
1732 AddStructElem(pInnermostNamedStruct->StructRec, pElement);
1733 AddStructSymbol(LabPart.Str, ProgCounter());
1734 }
1735
1736 NStruct = (PStructStack) malloc(sizeof(TStructStack));
1737 NStruct->Name = as_strdup(StructName);
1738 NStruct->pBaseName = NStruct->Name + strlen(NStruct->Name) - strlen(LabPart.Str); /* NULL -> complain too long */
1739 NStruct->SaveCurrPC = ProgCounter();
1740 DoExt = True;
1741 ExtChar = DottedStructs ? '.' : '_';
1742 NStruct->Next = StructStack;
1743 OK = True;
1744 forallargs (pArg, True)
1745 if (OK)
1746 {
1747 if (!as_strcasecmp(pArg->Str, "EXTNAMES"))
1748 DoExt = True;
1749 else if (!as_strcasecmp(pArg->Str, "NOEXTNAMES"))
1750 DoExt = False;
1751 else if (!as_strcasecmp(pArg->Str, "DOTS"))
1752 ExtChar = '.';
1753 else if (!as_strcasecmp(pArg->Str, "NODOTS"))
1754 ExtChar = '_';
1755 else
1756 {
1757 WrStrErrorPos(ErrNum_InvStructDir, pArg);
1758 OK = False;
1759 }
1760 }
1761 if (OK)
1762 {
1763 NStruct->StructRec = CreateStructRec();
1764 NStruct->StructRec->ExtChar = ExtChar;
1765 NStruct->StructRec->DoExt = DoExt;
1766 NStruct->StructRec->IsUnion = IsUnion;
1767 StructStack = NStruct;
1768 if (ActPC != StructSeg)
1769 StructSaveSeg = ActPC;
1770 if (NStruct->Name[0])
1771 pInnermostNamedStruct = NStruct;
1772 ActPC = StructSeg;
1773 PCs[ActPC] = 0;
1774 Phases[ActPC] = 0;
1775 Grans[ActPC] = Grans[SegCode];
1776 ListGrans[ActPC] = ListGrans[SegCode];
1777 ClearChunk(SegChunks + StructSeg);
1778 CodeLen = 0;
1779 DontPrint = True;
1780 }
1781 else
1782 {
1783 free(NStruct->Name);
1784 free(NStruct);
1785 }
1786 }
1787
CodeENDSTRUCT(Word IsUnion)1788 static void CodeENDSTRUCT(Word IsUnion)
1789 {
1790 Boolean OK;
1791 PStructStack OStruct;
1792 TempResult t;
1793
1794 if (!ChkArgCnt(0, 1));
1795 else if (!StructStack) WrError(ErrNum_MissingStruct);
1796 else
1797 {
1798 if (IsUnion && !StructStack->StructRec->IsUnion)
1799 WrXError(ErrNum_STRUCTEndedByENDUNION, StructStack->Name);
1800
1801 if (*LabPart.Str == '\0') OK = True;
1802 else
1803 {
1804 if (!CaseSensitive)
1805 NLS_UpString(LabPart.Str);
1806 OK = !strcmp(LabPart.Str, StructStack->pBaseName);
1807 if (!OK) WrError(ErrNum_WrongStruct);
1808 }
1809 if (OK)
1810 {
1811 LargeWord TotLen;
1812
1813 /* unchain current struct from stack */
1814
1815 OStruct = StructStack;
1816 StructStack = OStruct->Next;
1817
1818 /* resolve referenced symbols in structure */
1819
1820 ResolveStructReferences(OStruct->StructRec);
1821
1822 /* find new innermost named struct */
1823
1824 for (pInnermostNamedStruct = StructStack;
1825 pInnermostNamedStruct;
1826 pInnermostNamedStruct = pInnermostNamedStruct->Next)
1827 {
1828 if (pInnermostNamedStruct->Name[0])
1829 break;
1830 }
1831
1832 BumpStructLength(OStruct->StructRec, ProgCounter());
1833 TotLen = OStruct->StructRec->TotLen;
1834
1835 /* add symbol for struct length if not nameless */
1836
1837 if (ArgCnt == 0)
1838 {
1839 if (OStruct->Name[0])
1840 {
1841 String tmp2;
1842 tStrComp TmpComp;
1843
1844 as_snprintf(tmp2, sizeof(tmp2), "%s%clen", OStruct->Name, OStruct->StructRec->ExtChar);
1845 StrCompMkTemp(&TmpComp, tmp2);
1846 EnterIntSymbol(&TmpComp, TotLen, SegNone, False);
1847 }
1848 }
1849 else
1850 EnterIntSymbol(&ArgStr[1], TotLen, SegNone, False);
1851
1852 t.Typ = TempInt;
1853 t.Contents.Int = TotLen;
1854 SetListLineVal(&t);
1855
1856 /* If named, store completed structure.
1857 Otherwise, discard temporary struct. */
1858
1859 if (OStruct->Name[0])
1860 AddStruct(OStruct->StructRec, OStruct->Name, True);
1861 else
1862 DestroyStructRec(OStruct->StructRec);
1863 OStruct->StructRec = NULL;
1864
1865 /* set PC back to outer's struct value, plus size of
1866 just completed struct, or non-struct value: */
1867
1868 PCs[ActPC] = OStruct->SaveCurrPC;
1869 if (!StructStack)
1870 {
1871 ActPC = StructSaveSeg;
1872 CodeLen = 0;
1873 }
1874 else
1875 {
1876 CodeLen = TotLen;
1877 }
1878
1879 /* free struct stack elements no longer needed */
1880
1881 free(OStruct->Name);
1882 free(OStruct);
1883 ClearChunk(SegChunks + StructSeg);
1884 DontPrint = True;
1885 }
1886 }
1887 }
1888
CodeEXTERN(Word Index)1889 static void CodeEXTERN(Word Index)
1890 {
1891 char *Split;
1892 int i;
1893 Boolean OK;
1894 Byte Type;
1895 UNUSED(Index);
1896
1897 if (ChkArgCnt(1, ArgCntMax))
1898 {
1899 i = 1;
1900 OK = True;
1901 while ((OK) && (i <= ArgCnt))
1902 {
1903 Split = strrchr(ArgStr[i].Str, ':');
1904 if (Split == NULL)
1905 Type = SegNone;
1906 else
1907 {
1908 *Split = '\0';
1909 for (Type = SegNone + 1; Type <= PCMax; Type++)
1910 if (!as_strcasecmp(Split + 1, SegNames[Type]))
1911 break;
1912 }
1913 if (Type > PCMax) WrXError(ErrNum_UnknownSegment, Split + 1);
1914 else
1915 {
1916 EnterExtSymbol(&ArgStr[i], 0, Type, FALSE);
1917 }
1918 i++;
1919 }
1920 }
1921 }
1922
CodeNESTMAX(Word Index)1923 static void CodeNESTMAX(Word Index)
1924 {
1925 LongInt Temp;
1926 Boolean OK;
1927 tSymbolFlags Flags;
1928 UNUSED(Index);
1929
1930 if (ChkArgCnt(1, 1))
1931 {
1932 Temp = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &OK, &Flags);
1933 if (OK)
1934 {
1935 if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
1936 else NestMax = Temp;
1937 }
1938 }
1939 }
1940
CodeSEGTYPE(Word Index)1941 static void CodeSEGTYPE(Word Index)
1942 {
1943 UNUSED(Index);
1944
1945 if (ChkArgCnt(0, 0))
1946 RelSegs = (as_toupper(*OpPart.Str) == 'R');
1947 }
1948
CodePPSyms(PForwardSymbol * Orig,PForwardSymbol * Alt1,PForwardSymbol * Alt2)1949 static void CodePPSyms(PForwardSymbol *Orig,
1950 PForwardSymbol *Alt1,
1951 PForwardSymbol *Alt2)
1952 {
1953 PForwardSymbol Lauf;
1954 tStrComp *pArg, SymArg, SectionArg;
1955 String Sym, Section;
1956 char *pSplit;
1957
1958 if (ChkArgCnt(1, ArgCntMax))
1959 forallargs (pArg, True)
1960 {
1961 pSplit = QuotPos(pArg->Str, ':');
1962 if (pSplit)
1963 {
1964 StrCompSplitRef(&SymArg, &SectionArg, pArg, pSplit);
1965 if (!ExpandStrSymbol(Sym, sizeof(Sym), &SymArg))
1966 return;
1967 }
1968 else
1969 {
1970 if (!ExpandStrSymbol(Sym, sizeof(Sym), pArg))
1971 return;
1972 *Section = '\0';
1973 StrCompMkTemp(&SectionArg, Section);
1974 }
1975 if (!CaseSensitive)
1976 NLS_UpString(Sym);
1977 Lauf = CodePPSyms_SearchSym(*Alt1, Sym);
1978 if (Lauf) WrStrErrorPos(ErrNum_ContForward, pArg);
1979 else
1980 {
1981 Lauf = CodePPSyms_SearchSym(*Alt2, Sym);
1982 if (Lauf) WrStrErrorPos(ErrNum_ContForward, pArg);
1983 else
1984 {
1985 Lauf = CodePPSyms_SearchSym(*Orig, Sym);
1986 if (!Lauf)
1987 {
1988 Lauf = (PForwardSymbol) malloc(sizeof(TForwardSymbol));
1989 Lauf->Next = (*Orig); *Orig = Lauf;
1990 Lauf->Name = as_strdup(Sym);
1991 Lauf->pErrorPos = GetErrorPos();
1992 }
1993 IdentifySection(&SectionArg, &Lauf->DestSection);
1994 }
1995 }
1996 }
1997 }
1998
1999 /*------------------------------------------------------------------------*/
2000
2001 #define ONOFFMax 32
2002 static int ONOFFCnt = 0;
2003 typedef struct
2004 {
2005 Boolean Persist, *FlagAddr;
2006 const char *FlagName;
2007 const char *InstName;
2008 } ONOFFTab;
2009 static ONOFFTab *ONOFFList;
2010
DecodeONOFF(Word Index)2011 static void DecodeONOFF(Word Index)
2012 {
2013 ONOFFTab *Tab = ONOFFList + Index;
2014
2015 if (ChkArgCnt(1, 1))
2016 {
2017 NLS_UpString(ArgStr[1].Str);
2018 if (*AttrPart.Str != '\0') WrError(ErrNum_UseLessAttr);
2019 else
2020 {
2021 Boolean IsON = !as_strcasecmp(ArgStr[1].Str, "ON");
2022 if ((!IsON) && (as_strcasecmp(ArgStr[1].Str, "OFF"))) WrStrErrorPos(ErrNum_OnlyOnOff, &ArgStr[1]);
2023 else
2024 SetFlag(Tab->FlagAddr, Tab->FlagName, IsON);
2025 }
2026 }
2027 }
2028
AddONOFF(const char * InstName,Boolean * Flag,const char * FlagName,Boolean Persist)2029 void AddONOFF(const char *InstName, Boolean *Flag, const char *FlagName, Boolean Persist)
2030 {
2031 if (ONOFFCnt == ONOFFMax) exit(255);
2032 ONOFFList[ONOFFCnt].Persist = Persist;
2033 ONOFFList[ONOFFCnt].FlagAddr = Flag;
2034 ONOFFList[ONOFFCnt].FlagName = FlagName;
2035 ONOFFList[ONOFFCnt].InstName = InstName;
2036 AddInstTable(ONOFFTable, InstName, ONOFFCnt++, DecodeONOFF);
2037 }
2038
ClearONOFF(void)2039 void ClearONOFF(void)
2040 {
2041 int z, z2;
2042
2043 for (z = 0; z < ONOFFCnt; z++)
2044 if (!ONOFFList[z].Persist)
2045 break;
2046
2047 for (z2 = ONOFFCnt - 1; z2 >= z; z2--)
2048 RemoveInstTable(ONOFFTable, ONOFFList[z2].InstName);
2049
2050 ONOFFCnt = z;
2051 }
2052
2053 /*------------------------------------------------------------------------*/
2054
2055 typedef struct
2056 {
2057 const char *Name;
2058 InstProc Proc;
2059 Word Index;
2060 } PseudoOrder;
2061 static const PseudoOrder Pseudos[] =
2062 {
2063 {"ALIGN", CodeALIGN , 0 },
2064 {"ASEG", CodeSEGTYPE , 0 },
2065 {"ASSUME", CodeASSUME , 0 },
2066 {"BINCLUDE", CodeBINCLUDE , 0 },
2067 {"CHARSET", CodeCHARSET , 0 },
2068 {"CODEPAGE", CodeCODEPAGE , 0 },
2069 {"CPU", CodeCPU , 0 },
2070 {"DEPHASE", CodeDEPHASE , 0 },
2071 {"END", CodeEND , 0 },
2072 {"ENDEXPECT", CodeENDEXPECT , 0 },
2073 {"ENDS", CodeENDSTRUCT , 0 },
2074 {"ENDSECTION", CodeENDSECTION , 0 },
2075 {"ENDSTRUC", CodeENDSTRUCT , 0 },
2076 {"ENDSTRUCT", CodeENDSTRUCT , 0 },
2077 {"ENDUNION", CodeENDSTRUCT , 1 },
2078 {"ENUM", CodeENUM , 0 },
2079 {"ENUMCONF", CodeENUMCONF , 0 },
2080 {"EQU", CodeSETEQU , 0 },
2081 {"ERROR", CodeERROR , 0 },
2082 {"EXPECT", CodeEXPECT , 0 },
2083 {"EXPORT_SYM", CodeEXPORT , 0 },
2084 {"EXTERN_SYM", CodeEXTERN , 0 },
2085 {"FATAL", CodeFATAL , 0 },
2086 {"FUNCTION", CodeFUNCTION , 0 },
2087 {"LABEL", CodeLABEL , 0 },
2088 {"LISTING", CodeLISTING , 0 },
2089 {"MESSAGE", CodeMESSAGE , 0 },
2090 {"NEWPAGE", CodeNEWPAGE , 0 },
2091 {"NESTMAX", CodeNESTMAX , 0 },
2092 {"NEXTENUM", CodeENUM , 1 },
2093 {"ORG", CodeORG , 0 },
2094 {"OUTRADIX", CodeRADIX , 1 },
2095 {"PHASE", CodePHASE , 0 },
2096 {"POPV", CodePOPV , 0 },
2097 {"PRSET", CodePRSET , 0 },
2098 {"PRTINIT", CodeString , 0 },
2099 {"PRTEXIT", CodeString , 1 },
2100 {"TITLE", CodeString , 2 },
2101 {"PUSHV", CodePUSHV , 0 },
2102 {"RADIX", CodeRADIX , 0 },
2103 {"READ", CodeREAD , 0 },
2104 {"RESTORE", CodeRESTORE , 0 },
2105 {"MACEXP", CodeMACEXP , 0x10 },
2106 {"MACEXP_DFT", CodeMACEXP , 0 },
2107 {"MACEXP_OVR", CodeMACEXP , 1 },
2108 {"RORG", CodeRORG , 0 },
2109 {"RSEG", CodeSEGTYPE , 0 },
2110 {"SAVE", CodeSAVE , 0 },
2111 {"SECTION", CodeSECTION , 0 },
2112 {"SEGMENT", CodeSEGMENT , 0 },
2113 {"SHARED", CodeSHARED , 0 },
2114 {"STRUC", CodeSTRUCT , 0 },
2115 {"STRUCT", CodeSTRUCT , 0 },
2116 {"UNION", CodeSTRUCT , 1 },
2117 {"WARNING", CodeWARNING , 0 },
2118 {"=", CodeSETEQU , 0 },
2119 {":=", CodeSETEQU , 1 },
2120 {"" , NULL , 0 }
2121 };
2122
CodeGlobalPseudo(void)2123 Boolean CodeGlobalPseudo(void)
2124 {
2125 switch (*OpPart.Str)
2126 {
2127 case 'S':
2128 if (!SetIsOccupied() && Memo("SET"))
2129 {
2130 CodeSETEQU(True);
2131 return True;
2132 }
2133 break;
2134 case 'E':
2135 if (Memo("EVAL"))
2136 {
2137 CodeSETEQU(True);
2138 return True;
2139 }
2140 break;
2141 case 'P':
2142 if ((!PageIsOccupied && Memo("PAGE"))
2143 || (PageIsOccupied && Memo("PAGESIZE")))
2144 {
2145 CodePAGE(0);
2146 return True;
2147 }
2148 break;
2149 }
2150
2151 if (LookupInstTable(ONOFFTable, OpPart.Str))
2152 return True;
2153
2154 if (LookupInstTable(PseudoTable, OpPart.Str))
2155 return True;
2156
2157 if (SectionStack)
2158 {
2159 if (Memo("FORWARD"))
2160 {
2161 if (PassNo <= MaxSymPass)
2162 CodePPSyms(&(SectionStack->LocSyms),
2163 &(SectionStack->GlobSyms),
2164 &(SectionStack->ExportSyms));
2165 return True;
2166 }
2167 if (Memo("PUBLIC"))
2168 {
2169 CodePPSyms(&(SectionStack->GlobSyms),
2170 &(SectionStack->LocSyms),
2171 &(SectionStack->ExportSyms));
2172 return True;
2173 }
2174 if (Memo("GLOBAL"))
2175 {
2176 CodePPSyms(&(SectionStack->ExportSyms),
2177 &(SectionStack->LocSyms),
2178 &(SectionStack->GlobSyms));
2179 return True;
2180 }
2181 }
2182
2183 return False;
2184 }
2185
2186
codeallg_init(void)2187 void codeallg_init(void)
2188 {
2189 const PseudoOrder *POrder;
2190
2191 ONOFFList = (ONOFFTab*)calloc(ONOFFMax, sizeof(*ONOFFList));
2192
2193 PseudoTable = CreateInstTable(201);
2194 for (POrder = Pseudos; POrder->Proc; POrder++)
2195 AddInstTable(PseudoTable, POrder->Name, POrder->Index, POrder->Proc);
2196 ONOFFTable = CreateInstTable(47);
2197 AddONOFF("RELAXED", &RelaxedMode, RelaxedName, True);
2198 AddONOFF("DOTTEDSTRUCTS", &DottedStructs, DottedStructsName, True);
2199 }
2200