--- /dev/null
+/* codecop8.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Codegeneratormodul COP8-Familie */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+
+#include <string.h>
+
+#include "bpemu.h"
+#include "strutil.h"
+#include "chunks.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmitree.h"
+#include "codepseudo.h"
+#include "intpseudo.h"
+#include "natpseudo.h"
+#include "codevars.h"
+#include "errmsg.h"
+
+#include "codecop8.h"
+
+#define ModNone (-1)
+#define ModAcc 0
+#define MModAcc (1 << ModAcc)
+#define ModBInd 1
+#define MModBInd (1 << ModBInd)
+#define ModBInc 2
+#define MModBInc (1 << ModBInc)
+#define ModBDec 3
+#define MModBDec (1 << ModBDec)
+#define ModXInd 4
+#define MModXInd (1 << ModXInd)
+#define ModXInc 5
+#define MModXInc (1 << ModXInc)
+#define ModXDec 6
+#define MModXDec (1 << ModXDec)
+#define ModDir 7
+#define MModDir (1 << ModDir)
+#define ModImm 8
+#define MModImm (1 << ModImm)
+
+#define DirPrefix 0xbd
+#define BReg 0xfe
+
+#define BitOrderCnt 3
+
+static CPUVar CPUCOP87L84;
+
+typedef struct
+{
+ ShortInt Mode;
+ Byte Val;
+ tSymbolFlags ValSymFlags;
+} tAdrResult;
+
+/*---------------------------------------------------------------------------*/
+
+static ShortInt DecodeAdr(const tStrComp *pArg, Word Mask, tAdrResult *pResult)
+{
+ static const char ModStrings[ModXDec + 1][5] =
+ {
+ "A", "[B]", "[B+]", "[B-]",
+ "[X]", "[X+]", "[X-]"
+ };
+
+ int z;
+ tEvalResult EvalResult;
+
+ pResult->Mode = ModNone;
+
+ /* indirekt/Akku */
+
+ for (z = ModAcc; z <= ModXDec; z++)
+ if (!as_strcasecmp(pArg->str.p_str, ModStrings[z]))
+ {
+ pResult->Mode = z;
+ goto chk;
+ }
+
+ /* immediate */
+
+ if (*pArg->str.p_str == '#')
+ {
+ pResult->Val = EvalStrIntExpressionOffsWithResult(pArg, 1, Int8, &EvalResult);
+ if (EvalResult.OK)
+ {
+ pResult->Mode = ModImm;
+ pResult->ValSymFlags = EvalResult.Flags;
+ }
+ goto chk;
+ }
+
+ /* direkt */
+
+ pResult->Val = EvalStrIntExpressionWithResult(pArg, Int8, &EvalResult);
+ if (EvalResult.OK)
+ {
+ pResult->Mode = ModDir;
+ pResult->ValSymFlags = EvalResult.Flags;
+ ChkSpace(SegData, EvalResult.AddrSpaceMask);
+ }
+
+chk:
+ if ((pResult->Mode != ModNone) && !(Mask & (1 << pResult->Mode)))
+ {
+ pResult->Mode = ModNone; WrError(ErrNum_InvAddrMode);
+ }
+ return pResult->Mode;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void DecodeFixed(Word Code)
+{
+ if (ChkArgCnt(0, 0))
+ {
+ BAsmCode[0] = Code;
+ CodeLen = 1;
+ }
+}
+
+static void DecodeLD(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(2, 2))
+ {
+ tAdrResult DestResult;
+
+ switch (DecodeAdr(&ArgStr[1], MModAcc | MModDir | MModBInd | MModBInc | MModBDec, &DestResult))
+ {
+ case ModAcc:
+ {
+ tAdrResult SrcResult;
+
+ switch(DecodeAdr(&ArgStr[2], MModDir | MModImm | MModBInd | MModXInd | MModBInc | MModXInc | MModBDec | MModXDec, &SrcResult))
+ {
+ case ModDir:
+ BAsmCode[0] = 0x9d;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0x98;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ break;
+ case ModBInd:
+ BAsmCode[0] = 0xae;
+ CodeLen = 1;
+ break;
+ case ModXInd:
+ BAsmCode[0] = 0xbe;
+ CodeLen = 1;
+ break;
+ case ModBInc:
+ BAsmCode[0] = 0xaa;
+ CodeLen = 1;
+ break;
+ case ModXInc:
+ BAsmCode[0] = 0xba;
+ CodeLen = 1;
+ break;
+ case ModBDec:
+ BAsmCode[0] = 0xab;
+ CodeLen = 1;
+ break;
+ case ModXDec:
+ BAsmCode[0] = 0xbb;
+ CodeLen = 1;
+ break;
+ }
+ break;
+ }
+ case ModDir:
+ {
+ tAdrResult SrcResult;
+
+ if (DecodeAdr(&ArgStr[2], MModImm, &SrcResult) == ModImm)
+ {
+ if (DestResult.Val == BReg)
+ {
+ if (SrcResult.Val <= 15)
+ {
+ BAsmCode[0] = 0x5f - SrcResult.Val;
+ CodeLen = 1;
+ }
+ else
+ {
+ BAsmCode[0] = 0x9f;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ }
+ }
+ else if (DestResult.Val >= 0xf0)
+ {
+ BAsmCode[0] = DestResult.Val - 0x20;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ }
+ else
+ {
+ BAsmCode[0] = 0xbc;
+ BAsmCode[1] = DestResult.Val;
+ BAsmCode[2] = SrcResult.Val;
+ CodeLen = 3;
+ }
+ }
+ break;
+ }
+ case ModBInd:
+ {
+ tAdrResult SrcResult;
+
+ if (DecodeAdr(&ArgStr[2], MModImm, &SrcResult) != ModNone)
+ {
+ BAsmCode[0] = 0x9e;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ }
+ break;
+ }
+ case ModBInc:
+ {
+ tAdrResult SrcResult;
+
+ if (DecodeAdr(&ArgStr[2], MModImm, &SrcResult) != ModNone)
+ {
+ BAsmCode[0] = 0x9a;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ }
+ break;
+ }
+ case ModBDec:
+ {
+ tAdrResult SrcResult;
+
+ if (DecodeAdr(&ArgStr[2], MModImm, &SrcResult) != ModNone)
+ {
+ BAsmCode[0] = 0x9b;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ }
+ break;
+ }
+ }
+ }
+}
+
+static void DecodeX(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(2, 2))
+ {
+ tStrComp *pAccArg, *pMemArg;
+ tAdrResult DestResult;
+
+ if (as_strcasecmp(ArgStr[1].str.p_str, "A"))
+ {
+ pAccArg = &ArgStr[2];
+ pMemArg = &ArgStr[1];
+ }
+ else
+ {
+ pAccArg = &ArgStr[1];
+ pMemArg = &ArgStr[2];
+ }
+ if (DecodeAdr(pAccArg, MModAcc, &DestResult) != ModNone)
+ {
+ tAdrResult SrcResult;
+
+ switch (DecodeAdr(pMemArg, MModDir | MModBInd | MModXInd | MModBInc | MModXInc | MModBDec | MModXDec, &SrcResult))
+ {
+ case ModDir:
+ BAsmCode[0] = 0x9c;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ break;
+ case ModBInd:
+ BAsmCode[0] = 0xa6;
+ CodeLen = 1;
+ break;
+ case ModBInc:
+ BAsmCode[0] = 0xa2;
+ CodeLen = 1;
+ break;
+ case ModBDec:
+ BAsmCode[0] = 0xa3;
+ CodeLen = 1;
+ break;
+ case ModXInd:
+ BAsmCode[0] = 0xb6;
+ CodeLen = 1;
+ break;
+ case ModXInc:
+ BAsmCode[0] = 0xb2;
+ CodeLen = 1;
+ break;
+ case ModXDec:
+ BAsmCode[0] = 0xb3;
+ CodeLen = 1;
+ break;
+ }
+ }
+ }
+}
+
+static void DecodeAcc(Word Code)
+{
+ if (ChkArgCnt(1, 1))
+ {
+ tAdrResult DestResult;
+
+ if (DecodeAdr(&ArgStr[1], MModAcc, &DestResult) == ModAcc)
+ {
+ BAsmCode[0] = Code;
+ CodeLen = 1;
+ }
+ }
+}
+
+static void DecodeAccMem(Word Code)
+{
+ if (ChkArgCnt(2, 2))
+ {
+ tAdrResult DestResult;
+
+ if (DecodeAdr(&ArgStr[1], MModAcc, &DestResult) != ModNone)
+ {
+ tAdrResult SrcResult;
+
+ switch (DecodeAdr(&ArgStr[2], MModDir | MModImm | MModBInd, &SrcResult))
+ {
+ case ModBInd:
+ BAsmCode[0] = Code;
+ CodeLen = 1;
+ break;
+ case ModImm:
+ BAsmCode[0] = Code + 0x10;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ break;
+ case ModDir:
+ BAsmCode[0] = DirPrefix;
+ BAsmCode[1] = SrcResult.Val;
+ BAsmCode[2] = Code;
+ CodeLen = 3;
+ break;
+ }
+ }
+ }
+}
+
+static void DecodeANDSZ(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(2, 2))
+ {
+ tAdrResult DestResult;
+
+ if (DecodeAdr(&ArgStr[1], MModAcc, &DestResult) != ModNone)
+ {
+ tAdrResult SrcResult;
+
+ if (DecodeAdr(&ArgStr[2], MModImm, &SrcResult) == ModImm)
+ {
+ BAsmCode[0] = 0x60;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ }
+ }
+ }
+}
+
+static void DecodeIFEQ(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(2, 2))
+ {
+ tAdrResult DestResult;
+
+ switch (DecodeAdr(&ArgStr[1], MModAcc | MModDir, &DestResult))
+ {
+ case ModAcc:
+ {
+ tAdrResult SrcResult;
+
+ switch (DecodeAdr(&ArgStr[2], MModDir | MModBInd | MModImm, &SrcResult))
+ {
+ case ModDir:
+ BAsmCode[0] = DirPrefix;
+ BAsmCode[1] = SrcResult.Val;
+ BAsmCode[2] = 0x82;
+ CodeLen = 3;
+ break;
+ case ModBInd:
+ BAsmCode[0] = 0x82;
+ CodeLen = 1;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0x92;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ break;
+ }
+ break;
+ }
+ case ModDir:
+ {
+ tAdrResult SrcResult;
+
+ BAsmCode[1] = DestResult.Val;
+ if (DecodeAdr(&ArgStr[2], MModImm, &SrcResult) == ModImm)
+ {
+ BAsmCode[0] = 0xa9;
+ BAsmCode[2] = SrcResult.Val;
+ CodeLen = 3;
+ }
+ break;
+ }
+ }
+ }
+}
+
+static void DecodeIFNE(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(2, 2))
+ {
+ tAdrResult DestResult;
+
+ switch (DecodeAdr(&ArgStr[1], MModAcc, &DestResult))
+ {
+ case ModAcc:
+ {
+ tAdrResult SrcResult;
+
+ switch (DecodeAdr(&ArgStr[2], MModDir | MModBInd | MModImm, &SrcResult))
+ {
+ case ModDir:
+ BAsmCode[0] = DirPrefix;
+ BAsmCode[1] = SrcResult.Val;
+ BAsmCode[2] = 0xb9;
+ CodeLen = 3;
+ break;
+ case ModBInd:
+ BAsmCode[0] = 0xb9;
+ CodeLen = 1;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0x99;
+ BAsmCode[1] = SrcResult.Val;
+ CodeLen = 2;
+ break;
+ }
+ break;
+ }
+ }
+ }
+}
+
+static void DecodeIFBNE(Word Code)
+{
+ UNUSED(Code);
+
+ if (!ChkArgCnt(1, 1));
+ else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
+ else
+ {
+ Boolean OK;
+
+ BAsmCode[0] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt4, &OK);
+ if (OK)
+ {
+ BAsmCode[0] += 0x40;
+ CodeLen = 1;
+ }
+ }
+}
+
+static void DecodeBit(Word Code)
+{
+ if (ChkArgCnt(2, 2))
+ {
+ Boolean OK;
+
+ Byte HReg = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
+ if (OK)
+ {
+ tAdrResult DestResult;
+
+ switch (DecodeAdr(&ArgStr[2], MModDir | MModBInd, &DestResult))
+ {
+ case ModDir:
+ BAsmCode[0] = DirPrefix;
+ BAsmCode[1] = DestResult.Val;
+ BAsmCode[2] = Code + HReg;
+ CodeLen = 3;
+ break;
+ case ModBInd:
+ BAsmCode[0] = Code + HReg;
+ CodeLen = 1;
+ break;
+ }
+ }
+ }
+}
+
+static void DecodeJMP_JSR(Word Code)
+{
+ if (ChkArgCnt(1, 1))
+ {
+ tEvalResult EvalResult;
+ Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
+
+ if (EvalResult.OK && ChkSamePage(EProgCounter() + 2, AdrWord, 12, EvalResult.Flags))
+ {
+ ChkSpace(SegCode, EvalResult.AddrSpaceMask);
+ BAsmCode[0] = 0x20 + Code + ((AdrWord >> 8) & 15);
+ BAsmCode[1] = Lo(AdrWord);
+ CodeLen = 2;
+ }
+ }
+}
+
+static void DecodeJMPL_JSRL(Word Code)
+{
+ if (ChkArgCnt(1, 1))
+ {
+ tEvalResult EvalResult;
+ Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
+
+ if (EvalResult.OK)
+ {
+ ChkSpace(SegCode, EvalResult.AddrSpaceMask);
+ BAsmCode[0] = Code;
+ BAsmCode[1] = Hi(AdrWord);
+ BAsmCode[2] = Lo(AdrWord);
+ CodeLen = 3;
+ }
+ }
+}
+
+static void DecodeJP(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(1, 1))
+ {
+ Boolean OK;
+ tSymbolFlags Flags;
+
+ Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags) - (EProgCounter() + 1);
+ if (OK)
+ {
+ if (AdrInt == 0)
+ {
+ BAsmCode[0] = NOPCode;
+ CodeLen = 1;
+ WrError(ErrNum_DistNull);
+ }
+ else if (((AdrInt > 31) || (AdrInt < -32)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
+ else
+ {
+ BAsmCode[0] = AdrInt & 0xff;
+ CodeLen = 1;
+ }
+ }
+ }
+ return;
+}
+
+static void DecodeDRSZ(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(1, 1))
+ {
+ tAdrResult DestResult;
+
+ if (DecodeAdr(&ArgStr[1], MModDir, &DestResult) == ModDir)
+ {
+ if (mFirstPassUnknown(DestResult.ValSymFlags))
+ DestResult.Val |= 0xf0;
+ if (DestResult.Val < 0xf0) WrError(ErrNum_UnderRange);
+ else
+ {
+ BAsmCode[0] = DestResult.Val - 0x30;
+ CodeLen = 1;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void AddFixed(const char *NName, Byte NCode)
+{
+ AddInstTable(InstTable, NName, NCode, DecodeFixed);
+}
+
+static void AddAcc(const char *NName, Byte NCode)
+{
+ AddInstTable(InstTable, NName, NCode, DecodeAcc);
+}
+
+static void AddAccMem(const char *NName, Byte NCode)
+{
+ AddInstTable(InstTable, NName, NCode, DecodeAccMem);
+}
+
+static void AddBit(const char *NName, Byte NCode)
+{
+ AddInstTable(InstTable, NName, NCode, DecodeBit);
+}
+
+static void InitFields(void)
+{
+ InstTable = CreateInstTable(103);
+ AddInstTable(InstTable, "LD", 0, DecodeLD);
+ AddInstTable(InstTable, "X", 0, DecodeX);
+ AddInstTable(InstTable, "ANDSZ", 0, DecodeANDSZ);
+ AddInstTable(InstTable, "IFEQ", 0, DecodeIFEQ);
+ AddInstTable(InstTable, "IFNE", 0, DecodeIFNE);
+ AddInstTable(InstTable, "IFBNE", 0, DecodeIFBNE);
+ AddInstTable(InstTable, "JMP", 0, DecodeJMP_JSR);
+ AddInstTable(InstTable, "JSR", 0x10, DecodeJMP_JSR);
+ AddInstTable(InstTable, "JMPL", 0xac, DecodeJMPL_JSRL);
+ AddInstTable(InstTable, "JSRL", 0xad, DecodeJMPL_JSRL);
+ AddInstTable(InstTable, "JP", 0, DecodeJP);
+ AddInstTable(InstTable, "DRSZ", 0, DecodeDRSZ);
+
+ AddFixed("LAID" , 0xa4); AddFixed("SC" , 0xa1); AddFixed("RC" , 0xa0);
+ AddFixed("IFC" , 0x88); AddFixed("IFNC" , 0x89); AddFixed("VIS" , 0xb4);
+ AddFixed("JID" , 0xa5); AddFixed("RET" , 0x8e); AddFixed("RETSK", 0x8d);
+ AddFixed("RETI" , 0x8f); AddFixed("INTR" , 0x00); AddFixed("NOP" , 0xb8);
+ AddFixed("RPND" , 0xb5);
+
+ AddAcc("CLR" , 0x64); AddAcc("INC" , 0x8a); AddAcc("DEC" , 0x8b);
+ AddAcc("DCOR" , 0x66); AddAcc("RRC" , 0xb0); AddAcc("RLC" , 0xa8);
+ AddAcc("SWAP" , 0x65); AddAcc("POP" , 0x8c); AddAcc("PUSH" , 0x67);
+
+ AddAccMem("ADD" , 0x84); AddAccMem("ADC" , 0x80); AddAccMem("SUBC" , 0x81);
+ AddAccMem("AND" , 0x85); AddAccMem("OR" , 0x87); AddAccMem("XOR" , 0x86);
+ AddAccMem("IFGT" , 0x83);
+
+ AddBit("IFBIT", 0x70); AddBit("SBIT", 0x78); AddBit("RBIT", 0x68);
+}
+
+static void DeinitFields(void)
+{
+ DestroyInstTable(InstTable);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void MakeCode_COP8(void)
+{
+ CodeLen = 0; DontPrint = False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodeNatPseudo()) return;
+ if (DecodeIntelPseudo(False)) return;
+
+ if (!LookupInstTable(InstTable, OpPart.str.p_str))
+ WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
+}
+
+static Boolean IsDef_COP8(void)
+{
+ return (Memo("SFR"));
+}
+
+static void SwitchFrom_COP8(void)
+{
+ DeinitFields();
+}
+
+static void SwitchTo_COP8(void)
+{
+ TurnWords = False;
+ SetIntConstMode(eIntConstModeC);
+
+ PCSymbol = ".";
+ HeaderID = 0x6f;
+ NOPCode = 0xb8;
+ DivideChars = ",";
+ HasAttrs = False;
+
+ ValidSegs = (1 << SegCode) | (1 << SegData);
+ Grans[SegCode] = 1;
+ ListGrans[SegCode] = 1;
+ SegInits[SegCode] =0;
+ SegLimits[SegCode] = 0x1fff;
+ Grans[SegData] = 1;
+ ListGrans[SegData] = 1;
+ SegInits[SegData] = 0;
+ SegLimits[SegData] = 0xff;
+
+ MakeCode = MakeCode_COP8;
+ IsDef = IsDef_COP8;
+ SwitchFrom = SwitchFrom_COP8;
+ InitFields();
+}
+
+void codecop8_init(void)
+{
+ CPUCOP87L84 = AddCPU("COP87L84", SwitchTo_COP8);
+}
--- /dev/null
+#ifndef _CODECOP8_H
+#define _CODECOP8_H
+/* codecop8.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Codegeneratormodul COP8-Familie */
+/* */
+/* Historie: 7.10.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+extern void codecop8_init(void);
+#endif /* _CODECOP8_H */
--- /dev/null
+#ifndef _ADDRSPACE_H
+#define _ADDRSPACE_H
+/* addrspace.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS */
+/* */
+/* Address Space enumeration */
+/* */
+/*****************************************************************************/
+
+/* NOTE: these constants are used in the .P files, so DO NOT CHANGE existing
+ enums; only attach new enums at the end! */
+
+typedef enum
+{
+ SegNone = 0,
+ SegCode = 1,
+ SegData = 2,
+ SegIData = 3,
+ SegXData = 4,
+ SegYData = 5,
+ SegBData = 6,
+ SegIO = 7,
+ SegReg = 8,
+ SegRData = 9,
+ SegEEData = 10,
+ SegCount = 11,
+ StructSeg = SegCount,
+ SegCountPlusStruct = 12
+} as_addrspace_t;
+
+#ifdef __cplusplus
+#include "cppops.h"
+DefCPPOps_Enum(as_addrspace_t)
+#endif
+
+extern const char *SegNames[SegCountPlusStruct];
+extern char SegShorts[SegCountPlusStruct];
+
+extern as_addrspace_t addrspace_lookup(const char *p_name);
+
+#endif /* _ADDRSPACE_H */
--- /dev/null
+#ifndef _AS_H
+#define _AS_H
+/* as.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Hauptmodul */
+/* */
+/*****************************************************************************/
+
+extern char *GetErrorPos(void);
+
+extern void WriteCode(void);
+
+#endif /* _AS_H */
--- /dev/null
+#ifndef AS_RSC
+#define AS_RSC
+#define MsgId1 1647083959
+#define MsgId2 1634938482
+#define Num_ErrName 0
+#define Num_WarnName 1
+#define Num_InLineName 2
+#define Num_GNUErrorMsg1 3
+#define Num_GNUErrorMsgN 4
+#define Num_ErrMsgUselessDisp 5
+#define Num_ErrMsgShortAddrPossible 6
+#define Num_ErrMsgShortJumpPossible 7
+#define Num_ErrMsgNoShareFile 8
+#define Num_ErrMsgBigDecFloat 9
+#define Num_ErrMsgPrivOrder 10
+#define Num_ErrMsgDistNull 11
+#define Num_ErrMsgWrongSegment 12
+#define Num_ErrMsgInAccSegment 13
+#define Num_ErrMsgPhaseErr 14
+#define Num_ErrMsgOverlap 15
+#define Num_ErrMsgOverlapReg 16
+#define Num_ErrMsgNoCaseHit 17
+#define Num_ErrMsgInAccPage 18
+#define Num_ErrMsgRMustBeEven 19
+#define Num_ErrMsgObsolete 20
+#define Num_ErrMsgUnpredictable 21
+#define Num_ErrMsgAlphaNoSense 22
+#define Num_ErrMsgSenseless 23
+#define Num_ErrMsgRepassUnknown 24
+#define Num_ErrMsgAddrNotAligned 25
+#define Num_ErrMsgIOAddrNotAllowed 26
+#define Num_ErrMsgPipeline 27
+#define Num_ErrMsgDoubleAdrRegUse 28
+#define Num_ErrMsgNotBitAddressable 29
+#define Num_ErrMsgStackNotEmpty 30
+#define Num_ErrMsgNULCharacter 31
+#define Num_ErrMsgPageCrossing 32
+#define Num_ErrMsgWUnderRange 33
+#define Num_ErrMsgWOverRange 34
+#define Num_ErrMsgNegDUP 35
+#define Num_ErrMsgConvIndX 36
+#define Num_ErrMsgNullResMem 37
+#define Num_ErrMsgBitNumberTruncated 38
+#define Num_ErrMsgInvRegisterPointer 39
+#define Num_ErrMsgMacArgRedef 40
+#define Num_ErrMsgDeprecated 41
+#define Num_ErrMsgDeprecated_Instead 42
+#define Num_ErrMsgSrcLEThanDest 43
+#define Num_ErrMsgTrapValidInstruction 44
+#define Num_ErrMsgPaddingAdded 45
+#define Num_ErrMsgRegNumWraparound 46
+#define Num_ErrMsgIndexedForIndirect 47
+#define Num_ErrMsgDoubleDef 48
+#define Num_ErrMsgSymbolUndef 49
+#define Num_ErrMsgInvSymName 50
+#define Num_ErrMsgInvFormat 51
+#define Num_ErrMsgUseLessAttr 52
+#define Num_ErrMsgUndefAttr 53
+#define Num_ErrMsgTooLongAttr 54
+#define Num_ErrMsgWrongArgCnt 55
+#define Num_ErrMsgWrongOptCnt 56
+#define Num_ErrMsgOnlyImmAddr 57
+#define Num_ErrMsgInvOpSize 58
+#define Num_ErrMsgConfOpSizes 59
+#define Num_ErrMsgUndefOpSizes 60
+#define Num_ErrMsgStringOrIntButFloat 61
+#define Num_ErrMsgIntButFloat 62
+#define Num_ErrMsgFloatButString 63
+#define Num_ErrMsgOpTypeMismatch 64
+#define Num_ErrMsgStringButInt 65
+#define Num_ErrMsgStringButFloat 66
+#define Num_ErrMsgTooManyArgs 67
+#define Num_ErrMsgIntButString 68
+#define Num_ErrMsgIntOrFloatButString 69
+#define Num_ErrMsgExpectString 70
+#define Num_ErrMsgExpectInt 71
+#define Num_ErrMsgStringOrIntOrFloatButReg 72
+#define Num_ErrMsgExpectIntOrString 73
+#define Num_ErrMsgExpectReg 74
+#define Num_ErrMsgRegWrongTarget 75
+#define Num_ErrMsgUnknownInstruction 76
+#define Num_ErrMsgBrackErr 77
+#define Num_ErrMsgDivByZero 78
+#define Num_ErrMsgUnderRange 79
+#define Num_ErrMsgOverRange 80
+#define Num_ErrMsgNotPwr2 81
+#define Num_ErrMsgNotAligned 82
+#define Num_ErrMsgDistTooBig 83
+#define Num_ErrMsgInAccReg 84
+#define Num_ErrMsgNoShortAddr 85
+#define Num_ErrMsgInvAddrMode 86
+#define Num_ErrMsgAddrMustBeEven 87
+#define Num_ErrMsgAddrMustBeAligned 88
+#define Num_ErrMsgInvParAddrMode 89
+#define Num_ErrMsgUndefCond 90
+#define Num_ErrMsgIncompCond 91
+#define Num_ErrMsgUnknownFlag 92
+#define Num_ErrMsgDuplicateFlag 93
+#define Num_ErrMsgUnknownInt 94
+#define Num_ErrMsgDuplicateInt 95
+#define Num_ErrMsgJmpDistTooBig 96
+#define Num_ErrMsgDistIsOdd 97
+#define Num_ErrMsgSkipTargetMismatch 98
+#define Num_ErrMsgInvShiftArg 99
+#define Num_ErrMsgOnly1 100
+#define Num_ErrMsgRange18 101
+#define Num_ErrMsgShiftCntTooBig 102
+#define Num_ErrMsgInvRegList 103
+#define Num_ErrMsgInvCmpMode 104
+#define Num_ErrMsgInvCPUType 105
+#define Num_ErrMsgInvFPUType 106
+#define Num_ErrMsgInvPMMUType 107
+#define Num_ErrMsgInvCtrlReg 108
+#define Num_ErrMsgInvReg 109
+#define Num_ErrMsgDoubleReg 110
+#define Num_ErrMsgRegBankMismatch 111
+#define Num_ErrMsgUndefRegSize 112
+#define Num_ErrMsgInvOpOnReg 113
+#define Num_ErrMsgNoSaveFrame 114
+#define Num_ErrMsgNoRestoreFrame 115
+#define Num_ErrMsgUnknownMacArg 116
+#define Num_ErrMsgMissEndif 117
+#define Num_ErrMsgInvIfConst 118
+#define Num_ErrMsgDoubleSection 119
+#define Num_ErrMsgInvSection 120
+#define Num_ErrMsgMissingEndSect 121
+#define Num_ErrMsgWrongEndSect 122
+#define Num_ErrMsgNotInSection 123
+#define Num_ErrMsgUndefdForward 124
+#define Num_ErrMsgContForward 125
+#define Num_ErrMsgInvFuncArgCnt 126
+#define Num_ErrMsgMissingLTORG 127
+#define Num_ErrMsgInstructionNotOnThisCPUSupported 128
+#define Num_ErrMsgAddrModeNotOnThisCPUSupported 129
+#define Num_ErrMsgFPUNotEnabled 130
+#define Num_ErrMsgPMMUNotEnabled 131
+#define Num_ErrMsgFullPMMUNotEnabled 132
+#define Num_ErrMsgCustomNotEnabled 133
+#define Num_ErrMsgZ80SyntaxNotEnabled 134
+#define Num_ErrMsgZ80SyntaxExclusive 135
+#define Num_ErrMsgInstructionNotOnThisFPUSupported 136
+#define Num_ErrMsgInvBitPos 137
+#define Num_ErrMsgOnlyOnOff 138
+#define Num_ErrMsgStackEmpty 139
+#define Num_ErrMsgNotOneBit 140
+#define Num_ErrMsgMissingStruct 141
+#define Num_ErrMsgOpenStruct 142
+#define Num_ErrMsgWrongStruct 143
+#define Num_ErrMsgPhaseDisallowed 144
+#define Num_ErrMsgInvStructDir 145
+#define Num_ErrMsgDoubleStruct 146
+#define Num_ErrMsgUnresolvedStructRef 147
+#define Num_ErrMsgDuplicateStructElem 148
+#define Num_ErrMsgNotRepeatable 149
+#define Num_ErrMsgShortRead 150
+#define Num_ErrMsgUnknownCodepage 151
+#define Num_ErrMsgRomOffs063 152
+#define Num_ErrMsgInvFCode 153
+#define Num_ErrMsgInvFMask 154
+#define Num_ErrMsgInvMMUReg 155
+#define Num_ErrMsgLevel07 156
+#define Num_ErrMsgInvBitMask 157
+#define Num_ErrMsgInvRegPair 158
+#define Num_ErrMsgOpenMacro 159
+#define Num_ErrMsgOpenIRP 160
+#define Num_ErrMsgOpenIRPC 161
+#define Num_ErrMsgOpenREPT 162
+#define Num_ErrMsgOpenWHILE 163
+#define Num_ErrMsgDoubleMacro 164
+#define Num_ErrMsgTooManyMacParams 165
+#define Num_ErrMsgUndefKeyArg 166
+#define Num_ErrMsgNoPosArg 167
+#define Num_ErrMsgEXITMOutsideMacro 168
+#define Num_ErrMsgFirstPassCalc 169
+#define Num_ErrMsgTooManyNestedIfs 170
+#define Num_ErrMsgMissingIf 171
+#define Num_ErrMsgRekMacro 172
+#define Num_ErrMsgUnknownFunc 173
+#define Num_ErrMsgInvFuncArg 174
+#define Num_ErrMsgFloatOverflow 175
+#define Num_ErrMsgInvArgPair 176
+#define Num_ErrMsgNotOnThisAddress 177
+#define Num_ErrMsgNotFromThisAddress 178
+#define Num_ErrMsgTargOnDiffPage 179
+#define Num_ErrMsgTargOnDiffSection 180
+#define Num_ErrMsgCodeOverflow 181
+#define Num_ErrMsgMixDBDS 182
+#define Num_ErrMsgNotInStruct 183
+#define Num_ErrMsgParNotPossible 184
+#define Num_ErrMsgAdrOverflow 185
+#define Num_ErrMsgInvSegment 186
+#define Num_ErrMsgUnknownSegment 187
+#define Num_ErrMsgUnknownSegReg 188
+#define Num_ErrMsgInvString 189
+#define Num_ErrMsgInvRegName 190
+#define Num_ErrMsgInvArg 191
+#define Num_ErrMsgNoIndir 192
+#define Num_ErrMsgNotInThisSegment 193
+#define Num_ErrMsgNotInMaxmode 194
+#define Num_ErrMsgOnlyInMaxmode 195
+#define Num_ErrMsgPackCrossBoundary 196
+#define Num_ErrMsgUnitMultipleUsed 197
+#define Num_ErrMsgMultipleLongRead 198
+#define Num_ErrMsgMultipleLongWrite 199
+#define Num_ErrMsgLongReadWithStore 200
+#define Num_ErrMsgTooManyRegisterReads 201
+#define Num_ErrMsgOverlapDests 202
+#define Num_ErrMsgTooManyBranchesInExPacket 203
+#define Num_ErrMsgCannotUseUnit 204
+#define Num_ErrMsgInvEscSequence 205
+#define Num_ErrMsgInvPrefixCombination 206
+#define Num_ErrMsgConstantRedefinedAsVariable 207
+#define Num_ErrMsgVariableRedefinedAsConstant 208
+#define Num_ErrMsgStructNameMissing 209
+#define Num_ErrMsgEmptyArgument 210
+#define Num_ErrMsgUnimplemented 211
+#define Num_ErrMsgFreestandingUnnamedStruct 212
+#define Num_ErrMsgSTRUCTEndedByENDUNION 213
+#define Num_ErrMsgAddrOnDifferentPage 214
+#define Num_ErrMsgUnknownMacExpMod 215
+#define Num_ErrMsgTooManyMacExpMod 216
+#define Num_ErrMsgConflictingMacExpMod 217
+#define Num_ErrMsgInvalidPrepDir 218
+#define Num_ErrMsgExpectedError 219
+#define Num_ErrMsgNoNestExpect 220
+#define Num_ErrMsgMissingENDEXPECT 221
+#define Num_ErrMsgMissingEXPECT 222
+#define Num_ErrMsgNoDefCkptReg 223
+#define Num_ErrMsgInvBitField 224
+#define Num_ErrMsgArgValueMissing 225
+#define Num_ErrMsgUnknownArg 226
+#define Num_ErrMsgIndexRegMustBe16Bit 227
+#define Num_ErrMsgIOAddrRegMustBe16Bit 228
+#define Num_ErrMsgSegAddrRegMustBe32Bit 229
+#define Num_ErrMsgNonSegAddrRegMustBe16Bit 230
+#define Num_ErrMsgInvStructArgument 231
+#define Num_ErrMsgTooManyArrayDimensions 232
+#define Num_ErrMsgInvIntFormat 233
+#define Num_ErrMsgInvIntFormatList 234
+#define Num_ErrMsgInvScale 235
+#define Num_ErrMsgConfStringOpt 236
+#define Num_ErrMsgUnknownStringOpt 237
+#define Num_ErrMsgInvCacheInvMode 238
+#define Num_ErrMsgInvCfgList 239
+#define Num_ErrMsgConfBitBltOpt 240
+#define Num_ErrMsgUnknownBitBltOpt 241
+#define Num_ErrMsgInternalError 242
+#define Num_ErrMsgOpeningFile 243
+#define Num_ErrMsgListWrError 244
+#define Num_ErrMsgFileReadError 245
+#define Num_ErrMsgFileWriteError 246
+#define Num_ErrMsgIntError 247
+#define Num_ErrMsgHeapOvfl 248
+#define Num_ErrMsgStackOvfl 249
+#define Num_ErrMsgMaxIncLevelExceeded 250
+#define Num_ErrMsgTooManyErrors 251
+#define Num_ErrMsgIsFatal 252
+#define Num_ErrMsgOvlyError 253
+#define Num_PrevDefMsg 254
+#define Num_ErrMsgInvSwapSize 255
+#define Num_ErrMsgSwapTooBig 256
+#define Num_ErrMsgNoRelocs 257
+#define Num_ErrMsgUnresRelocs 258
+#define Num_ErrMsgUnexportable 259
+#define Num_ErrMsgArgCntZero 260
+#define Num_ErrMsgArgCntOne 261
+#define Num_ErrMsgArgCntMulti 262
+#define Num_ErrMsgArgCntFromTo 263
+#define Num_ErrMsgArgCntEitherOr 264
+#define Num_ErrMsgAddrArgCnt 265
+#define Num_ErrMsgCannotSplitArg 266
+#define Num_ErrMsgMinCPUSupported 267
+#define Num_ErrMsgMaxCPUSupported 268
+#define Num_ErrMsgRangeCPUSupported 269
+#define Num_ErrMsgOnlyCPUSupported1 270
+#define Num_ErrMsgOnlyCPUSupportedOr 271
+#define Num_ErrMsgOnlyCPUSupported2 272
+#define Num_HeadingFileNameLab 273
+#define Num_HeadingPageLab 274
+#define Num_ListSymListHead1 275
+#define Num_ListSymListHead2 276
+#define Num_ListSymSumMsg 277
+#define Num_ListSymSumsMsg 278
+#define Num_ListUSymSumMsg 279
+#define Num_ListUSymSumsMsg 280
+#define Num_ListRegDefListHead1 281
+#define Num_ListRegDefListHead2 282
+#define Num_ListRegDefSumMsg 283
+#define Num_ListRegDefSumsMsg 284
+#define Num_ListRegDefUSumMsg 285
+#define Num_ListRegDefUSumsMsg 286
+#define Num_ListCodepageListHead1 287
+#define Num_ListCodepageListHead2 288
+#define Num_ListCodepageChange 289
+#define Num_ListCodepagePChange 290
+#define Num_ListCodepageSumMsg 291
+#define Num_ListCodepageSumsMsg 292
+#define Num_ListMacListHead1 293
+#define Num_ListMacListHead2 294
+#define Num_ListMacSumMsg 295
+#define Num_ListMacSumsMsg 296
+#define Num_ListStructListHead1 297
+#define Num_ListStructListHead2 298
+#define Num_ListStructSumMsg 299
+#define Num_ListStructSumsMsg 300
+#define Num_ListFuncListHead1 301
+#define Num_ListFuncListHead2 302
+#define Num_ListDefListHead1 303
+#define Num_ListDefListHead2 304
+#define Num_ListSegListHead1 305
+#define Num_ListSegListHead2 306
+#define Num_ListCrossListHead1 307
+#define Num_ListCrossListHead2 308
+#define Num_ListSectionListHead1 309
+#define Num_ListSectionListHead2 310
+#define Num_ListIncludeListHead1 311
+#define Num_ListIncludeListHead2 312
+#define Num_ListCrossSymName 313
+#define Num_ListCrossFileName 314
+#define Num_ListPlurName 315
+#define Num_ListHourName 316
+#define Num_ListMinuName 317
+#define Num_ListSecoName 318
+#define Num_InfoMessAssembling 319
+#define Num_InfoMessPass 320
+#define Num_InfoMessPass1 321
+#define Num_InfoMessPass2 322
+#define Num_InfoMessAssTime 323
+#define Num_InfoMessAssLine 324
+#define Num_InfoMessAssLines 325
+#define Num_InfoMessPassCnt 326
+#define Num_InfoMessPPassCnt 327
+#define Num_InfoMessNoPass 328
+#define Num_InfoMessMacAssLine 329
+#define Num_InfoMessMacAssLines 330
+#define Num_InfoMessWarnCnt 331
+#define Num_InfoMessWarnPCnt 332
+#define Num_InfoMessErrCnt 333
+#define Num_InfoMessErrPCnt 334
+#define Num_InfoMessRemainMem 335
+#define Num_InfoMessRemainStack 336
+#define Num_InfoMessNFilesFound 337
+#define Num_InfoMessMacroAss 338
+#define Num_InfoMessVar 339
+#define Num_InfoMessHead1 340
+#define Num_InfoMessHead2 341
+#define Num_KeyWaitMsg 342
+#define Num_ErrMsgInvParam 343
+#define Num_ErrMsgInvEnvParam 344
+#define Num_InvMsgSource 345
+#define Num_InfoMessHelp 346
+#endif /* #ifndef AS_RSC */
--- /dev/null
+#ifndef _ASMDEBUG_H
+#define _ASMDEBUG_H
+/* asmdebug.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Verwaltung der Debug-Informationen zur Assemblierzeit */
+/* */
+/* Historie: 16. 5.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+extern void AddLineInfo(Boolean InMacro, LongInt LineNum, char *FileName,
+ ShortInt Space, LargeInt Address, LargeInt Len);
+
+extern void InitLineInfo(void);
+
+extern void ClearLineInfo(void);
+
+extern void DumpDebugInfo(void);
+
+extern void asmdebug_init(void);
+#endif /* _ASMDEBUG_H */
--- /dev/null
+/* 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 <string.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 */
+Boolean 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 DefSupAllowed; /* Supervisormode freigegeben */
+
+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));
+}
--- /dev/null
+#ifndef _ASMDEF_H
+#define _ASMDEF_H
+/* asmdef.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* global benutzte Variablen und Definitionen */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "chunks.h"
+#include "fileformat.h"
+#include "dynstr.h"
+#include "intformat.h"
+#include "strcomp.h"
+#include "lstmacroexp.h"
+#include "cpulist.h"
+#include "tempresult.h"
+#include "addrspace.h"
+
+typedef struct _TCrossRef
+{
+ struct _TCrossRef *Next;
+ Byte FileNum;
+ LongInt LineNum;
+ Integer OccNum;
+} TCrossRef,*PCrossRef;
+
+
+typedef struct _TPatchEntry
+{
+ struct _TPatchEntry *Next;
+ LargeWord Address;
+ char *Ref;
+ Word len;
+ LongWord RelocType;
+} TPatchEntry, *PPatchEntry;
+
+typedef struct _TExportEntry
+{
+ struct _TExportEntry *Next;
+ char *Name;
+ Word len;
+ LongWord Flags;
+ LargeWord Value;
+} TExportEntry, *PExportEntry;
+
+typedef enum
+{
+ DebugNone,
+ DebugMAP,
+ DebugAOUT,
+ DebugCOFF,
+ DebugELF,
+ DebugAtmel,
+ DebugNoICE
+} DebugType;
+
+#define Char_NUL 0
+#define Char_BEL '\a'
+#define Char_BS '\b'
+#define Char_HT 9
+#define Char_LF '\n'
+#define Char_FF 12
+#define Char_CR 13
+#define Char_ESC 27
+
+#define ListMask_FormFeed (1 << 0)
+#define ListMask_SymbolList (1 << 1)
+#define ListMask_MacroList (1 << 2)
+#define ListMask_FunctionList (1 << 3)
+#define ListMask_LineNums (1 << 4)
+#define ListMask_DefineList (1 << 5)
+#define ListMask_RegDefList (1 << 6)
+#define ListMask_Codepages (1 << 7)
+#define ListMask_StructList (1 << 8)
+
+extern char SrcSuffix[],IncSuffix[],PrgSuffix[],LstSuffix[],
+ MacSuffix[],PreSuffix[],LogSuffix[],MapSuffix[],
+ OBJSuffix[];
+
+#define MomCPUName "MOMCPU" /* mom. Prozessortyp */
+#define MomCPUIdentName "MOMCPUNAME" /* mom. Prozessortyp */
+#define MomFPUIdentName "MOMFPUNAME" /* mom. Koprozessortyp */
+#define MomPMMUIdentName "MOMPMMUNAME" /* mom. MMU-Typ */
+#define DoPaddingName "PADDING" /* Padding an */
+#define PackingName "PACKING" /* gepackte Ablage an */
+#define ListOnName "LISTON" /* Listing an/aus */
+#define RelaxedName "RELAXED" /* alle Zahlenschreibweisen zugelassen */
+#define BranchExtName "BRANCHEXT" /* Spruenge autom. verlaengern */
+#define FlagTrueName "TRUE" /* Flagkonstanten */
+#define FlagFalseName "FALSE"
+#define PiName "CONSTPI" /* Zahl Pi */
+#define DateName "DATE" /* Datum & Zeit */
+#define TimeName "TIME"
+#define VerName "VERSION" /* speichert Versionsnummer */
+#define CaseSensName "CASESENSITIVE" /* zeigt Gross/Kleinunterscheidung an */
+#define Has64Name "HAS64" /* arbeitet Parser mit 64-Bit-Integers ? */
+#define ArchName "ARCHITECTURE" /* Zielarchitektur von AS */
+#define AttrName "ATTRIBUTE" /* Attributansprache in Makros */
+#define LabelName "__LABEL__" /* Labelansprache in Makros */
+#define ArgCName "ARGCOUNT" /* Argumentzahlansprache in Makros */
+#define AllArgName "ALLARGS" /* Ansprache Argumentliste in Makros */
+#define DefStackName "DEFSTACK" /* Default-Stack */
+#define NestMaxName "NESTMAX" /* max. nesting level of a macro */
+#define DottedStructsName "DOTTEDSTRUCTS" /* struct elements by default with . */
+#define CompModeName "COMPMODE" /* compatibility mode */
+
+extern const char *EnvName;
+
+/* This results from the tokenized representation of macro arguments
+ in macro bodys: (31*16) - 4 for special arguments: */
+
+#define ArgCntMax 476
+
+#define ChapMax 4
+
+#define AscOfs '0'
+
+#define MaxCodeLen_Ini 256
+#define MaxCodeLen_Max 65535
+extern LongWord MaxCodeLen;
+
+#define DEF_NESTMAX 256
+
+typedef void (*SimpProc)(
+#ifdef __PROTOS__
+void
+#endif
+);
+
+typedef void (*DissectBitProc)(
+#ifdef __PROTOS__
+char *pDest, size_t DestSize, LargeWord Inp
+#endif
+);
+
+typedef Boolean (*tQualifyQuoteFnc)(const char *pStart, const char *pQuotePos);
+
+typedef Word WordField[6]; /* fuer Zahlenumwandlung */
+typedef struct _TTransTable
+{
+ struct _TTransTable *Next;
+ char *Name;
+ unsigned char *Table;
+} TTransTable, *PTransTable;
+
+typedef struct _TSaveState
+{
+ struct _TSaveState *Next;
+ CPUVar SaveCPU;
+ char *pSaveCPUArgs;
+ Integer SavePC;
+ Byte SaveListOn;
+ tLstMacroExp SaveLstMacroExp;
+ tLstMacroExpMod SaveLstMacroExpModDefault,
+ SaveLstMacroExpModOverride;
+ PTransTable SaveTransTable;
+ Integer SaveEnumSegment;
+ LongInt SaveEnumCurrentValue, SaveEnumIncrement;
+} TSaveState,*PSaveState;
+
+typedef struct _TForwardSymbol
+{
+ struct _TForwardSymbol *Next;
+ StringPtr Name;
+ LongInt DestSection;
+ StringPtr pErrorPos;
+} TForwardSymbol, *PForwardSymbol;
+
+typedef struct _TSaveSection
+{
+ struct _TSaveSection *Next;
+ PForwardSymbol LocSyms, GlobSyms, ExportSyms;
+ LongInt Handle;
+} TSaveSection, *PSaveSection;
+
+typedef struct sSavePhase
+{
+ struct sSavePhase *pNext;
+ LargeWord SaveValue;
+} tSavePhase;
+
+typedef struct _TDefinement
+{
+ struct _TDefinement *Next;
+ StringPtr TransFrom, TransTo;
+ Byte Compiled[256];
+} TDefinement, *PDefinement;
+
+typedef struct _ASSUMERec
+{
+ const char *Name;
+ LongInt *Dest;
+ LongInt Min,Max;
+ LongInt NothingVal;
+ void (*pPostProc)(void);
+} ASSUMERec;
+
+extern StringPtr SourceFile;
+
+extern StringPtr CursUp;
+
+extern LargeWord *PCs;
+extern Boolean RelSegs;
+extern LargeWord StartAdr;
+extern LargeWord AfterBSRAddr;
+extern Boolean StartAdrPresent;
+extern LargeWord *Phases;
+extern Word Grans[SegCountPlusStruct];
+extern Word ListGrans[SegCountPlusStruct];
+extern ChunkList SegChunks[SegCountPlusStruct];
+extern Integer ActPC;
+extern Boolean PCsUsed[SegCountPlusStruct];
+extern LargeWord *SegInits;
+extern LargeWord *SegLimits;
+extern LongInt ValidSegs;
+extern Boolean ENDOccured;
+extern Boolean Retracted;
+extern Boolean ListToStdout,ListToNull;
+
+extern unsigned ASSUMERecCnt;
+extern const ASSUMERec *pASSUMERecs;
+extern void (*pASSUMEOverride)(void);
+
+extern Integer PassNo;
+extern Integer JmpErrors;
+extern Boolean ThrowErrors;
+extern Boolean Repass;
+extern Byte MaxSymPass;
+extern Byte ShareMode;
+extern DebugType DebugMode;
+extern Word NoICEMask;
+extern Byte ListMode;
+extern Byte ListOn;
+extern Integer MaxIncludeLevel;
+extern Boolean MakeUseList;
+extern Boolean MakeCrossList;
+extern Boolean MakeSectionList;
+extern Boolean MakeIncludeList;
+extern Boolean DefRelaxedMode;
+extern Boolean CompMode, DefCompMode;
+extern Word ListMask;
+extern ShortInt ExtendErrors;
+extern Integer EnumSegment;
+extern LongInt EnumIncrement, EnumCurrentValue;
+extern LongWord MaxErrors;
+extern Boolean TreatWarningsAsErrors;
+
+extern LongInt MomSectionHandle;
+extern PSaveSection SectionStack;
+extern tSavePhase *pPhaseStacks[SegCount];
+
+extern tSymbolSize AttrPartOpSize;
+extern LongInt CodeLen;
+extern Byte *BAsmCode;
+extern Word *WAsmCode;
+extern LongWord *DAsmCode;
+
+extern Boolean DontPrint;
+extern Word ActListGran;
+
+extern Boolean NumericErrors;
+extern Boolean CodeOutput;
+extern Boolean MacProOutput;
+extern Boolean MacroOutput;
+extern Boolean QuietMode;
+extern Boolean HardRanges;
+extern const char *DivideChars;
+extern Boolean HasAttrs;
+extern const char *AttrChars;
+extern Boolean MsgIfRepass;
+extern Integer PassNoForMessage;
+extern Boolean CaseSensitive;
+extern LongInt NestMax;
+extern Boolean GNUErrors;
+
+extern FILE *PrgFile;
+
+extern StringPtr ErrorPath,ErrorName;
+extern StringPtr OutName;
+extern Integer CurrIncludeLevel;
+extern StringPtr CurrFileName;
+extern LongInt CurrLine;
+extern LongInt MomLineCounter;
+extern LongInt LineSum;
+extern LongInt MacLineSum;
+
+extern LongInt NOPCode;
+extern Boolean TurnWords;
+extern Byte HeaderID;
+extern const char *PCSymbol;
+extern tIntConstMode IntConstMode;
+extern Boolean IntConstModeIBMNoTerm;
+extern Boolean (*SetIsOccupiedFnc)(void),
+ (*SaveIsOccupiedFnc)(void),
+ (*RestoreIsOccupiedFnc)(void);
+extern Boolean SwitchIsOccupied, PageIsOccupied, ShiftIsOccupied;
+extern Boolean (*DecodeAttrPart)(void);
+extern void (*MakeCode)(void);
+extern Boolean (*ChkPC)(LargeWord Addr);
+extern Boolean (*IsDef)(void);
+extern void (*SwitchFrom)(void);
+extern void (*InternSymbol)(char *Asc, TempResult *Erg);
+extern DissectBitProc DissectBit;
+extern DissectRegProc DissectReg;
+extern tQualifyQuoteFnc QualifyQuote;
+
+extern StringPtr IncludeList;
+extern Integer IncDepth,NextIncDepth;
+extern FILE *ErrorFile;
+extern FILE *LstFile;
+extern FILE *ShareFile;
+extern FILE *MacProFile;
+extern FILE *MacroFile;
+extern Boolean InMacroFlag;
+extern StringPtr LstName, MacroName, MacProName;
+extern tLstMacroExp DoLst, NextDoLst;
+extern StringPtr ShareName;
+extern CPUVar MomCPU, MomVirtCPU;
+extern StringPtr MomCPUArgs;
+extern char DefCPU[20];
+extern char MomCPUIdent[20],
+ MomFPUIdent[20],
+ MomPMMUIdent[20];
+
+extern Boolean DefSupAllowed;
+
+extern int OutRadixBase, ListRadixBase;
+extern const char *pCommentLeadIn;
+
+extern tStrComp *ArgStr;
+extern StringPtr pLOpPart;
+extern tStrComp LabPart, CommPart, ArgPart, OpPart, AttrPart;
+extern char AttrSplit;
+extern int ArgCnt;
+extern as_dynstr_t OneLine;
+#ifdef PROFILE_MEMO
+extern unsigned NumMemo;
+extern unsigned long NumMemoSum, NumMemoCnt;
+#endif
+
+#define forallargs(pArg, cond) \
+ for (pArg = ArgStr + 1; (cond) && (pArg <= ArgStr + ArgCnt); pArg++)
+
+extern Byte LstCounter;
+extern Word PageCounter[ChapMax+1];
+extern Byte ChapDepth;
+extern StringPtr ListLine;
+extern Byte PageLength, PageWidth;
+extern tLstMacroExpMod LstMacroExpModOverride, LstMacroExpModDefault;
+extern Boolean DottedStructs;
+extern StringPtr PrtInitString;
+extern StringPtr PrtExitString;
+extern StringPtr PrtTitleString;
+
+extern Byte StopfZahl;
+
+extern Boolean SuppWarns;
+
+#define CharTransTable CurrTransTable->Table
+extern PTransTable TransTables, CurrTransTable;
+
+extern PDefinement FirstDefine;
+
+extern PSaveState FirstSaveState;
+
+extern Boolean MakeDebug;
+extern FILE *Debug;
+
+extern Boolean WasIF, WasMACRO;
+
+extern void AsmDefInit(void);
+
+extern void NullProc(void);
+
+extern int SetMaxCodeLen(LongWord NewMaxCodeLen);
+
+extern void Default_InternSymbol(char *Asc, TempResult *Erg);
+
+extern void Default_DissectBit(char *pDest, size_t DestSize, LargeWord BitSpec);
+
+extern void AppendArg(size_t ReqSize);
+extern void InsertArg(int Index, size_t ReqSize);
+
+
+extern Boolean SetIsOccupied(void);
+extern Boolean SaveIsOccupied(void);
+extern Boolean RestoreIsOccupied(void);
+
+extern void asmdef_init(void);
+#endif /* _ASMDEF_H */
--- /dev/null
+/* asmerr.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Error Message Writing */
+/* */
+/*****************************************************************************/
+
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "console.h"
+#include "strutil.h"
+#include "nlmessages.h"
+#include "stdhandl.h"
+#include "as.h"
+#include "as.rsc"
+#include "ioerrs.h"
+#include "asmerr.h"
+
+typedef struct sExpectError
+{
+ struct sExpectError *pNext;
+ tErrorNum Num;
+} tExpectError;
+
+Word ErrorCount, WarnCount;
+static tExpectError *pExpectErrors = NULL;
+static Boolean InExpect = False;
+
+static void ClearExpectErrors(void)
+{
+ tExpectError *pOld;
+
+ while (pExpectErrors)
+ {
+ pOld = pExpectErrors;
+ pExpectErrors = pExpectErrors->pNext;
+ free(pOld);
+ }
+}
+
+static void AddExpectError(tExpectError *pExpectError)
+{
+ pExpectError->pNext = pExpectErrors;
+ pExpectErrors = pExpectError;
+}
+
+static tExpectError *FindAndTakeExpectError(tErrorNum Num)
+{
+ tExpectError *pRun, *pPrev;
+
+ for (pRun = pExpectErrors, pPrev = NULL; pRun; pPrev = pRun, pRun = pRun->pNext)
+ if (Num == pRun->Num)
+ {
+ if (pPrev)
+ pPrev->pNext = pRun->pNext;
+ else
+ pExpectErrors = pRun->pNext;
+ return pRun;
+ }
+ return NULL;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GenLineMarker(char *pDest, unsigned DestSize, char Marker, const struct sLineComp *pLineComp, * const char *pPrefix)
+ * \brief print a line, optionally with a marking of a component below
+ * \param pDest where to write
+ * \param DestSize destination buffer size
+ * \param Marker character to use for marking
+ * \param pLineComp position and length of optional marker
+ * \param pPrefix what to print before (under)line
+ * ------------------------------------------------------------------------ */
+
+static void GenLineMarker(char *pDest, unsigned DestSize, char Marker, const struct sLineComp *pLineComp, const char *pPrefix)
+{
+ char *pRun;
+ int z;
+
+ strmaxcpy(pDest, pPrefix, DestSize);
+ pRun = pDest + strlen(pDest);
+
+ for (z = 0; (z < pLineComp->StartCol) && (pRun - pDest + 1 < (int)DestSize); z++)
+ *pRun++ = ' ';
+ for (z = 0; (z < (int)pLineComp->Len) && (pRun - pDest + 1 < (int)DestSize); z++)
+ *pRun++ = Marker;
+ *pRun = '\0';
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GenLineForMarking(char *pDest, unsigned DestSize, const char *pSrc, const char *pPrefix)
+ * \brief generate a line, in compressed form for optional marking of a component below
+ * \param pDest where to write
+ * \param DestSize destination buffer size
+ * \param pSrc line to print/underline
+ * \param pPrefix what to print before (under)line
+ * ------------------------------------------------------------------------ */
+
+static void GenLineForMarking(char *pDest, unsigned DestSize, const char *pSrc, const char *pPrefix)
+{
+ char *pRun;
+
+ strmaxcpy(pDest, pPrefix, DestSize);
+ pRun = pDest + strlen(pDest);
+
+ /* replace TABs in line with spaces - column counting counts TAB as one character */
+
+ for (; *pSrc && (pRun - pDest + 1 < (int)DestSize); pSrc++)
+ *pRun++ = TabCompressed(*pSrc);
+ *pRun = '\0';
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EmergencyStop(void)
+ * \brief instantly stop upon fatal error
+ * ------------------------------------------------------------------------ */
+
+static void EmergencyStop(void)
+{
+ CloseIfOpen(&ErrorFile);
+ CloseIfOpen(&LstFile);
+ if (ShareMode != 0)
+ {
+ CloseIfOpen(&ShareFile);
+ unlink(ShareName);
+ }
+ if (MacProOutput)
+ {
+ CloseIfOpen(&MacProFile);
+ unlink(MacProName);
+ }
+ if (MacroOutput)
+ {
+ CloseIfOpen(&MacroFile);
+ unlink(MacroName);
+ }
+ if (MakeDebug)
+ CloseIfOpen(&Debug);
+ if (CodeOutput)
+ {
+ CloseIfOpen(&PrgFile);
+ unlink(OutName);
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ErrorNum2String(tErrorNum Num, char Buf, int BufSize)
+ * \brief convert error # to string
+ * \param Num numeric error
+ * \param Buf buffer for complex messages
+ * \param BufSize capacity of Buf
+ * \return * to message
+ * ------------------------------------------------------------------------ */
+
+static const char *ErrorNum2String(tErrorNum Num, char *Buf, int BufSize)
+{
+ int msgno = -1;
+
+ *Buf = '\0';
+ switch (Num)
+ {
+ case ErrNum_UselessDisp:
+ msgno = Num_ErrMsgUselessDisp; break;
+ case ErrNum_ShortAddrPossible:
+ msgno = Num_ErrMsgShortAddrPossible; break;
+ case ErrNum_ShortJumpPossible:
+ msgno = Num_ErrMsgShortJumpPossible; break;
+ case ErrNum_NoShareFile:
+ msgno = Num_ErrMsgNoShareFile; break;
+ case ErrNum_BigDecFloat:
+ msgno = Num_ErrMsgBigDecFloat; break;
+ case ErrNum_PrivOrder:
+ msgno = Num_ErrMsgPrivOrder; break;
+ case ErrNum_DistNull:
+ msgno = Num_ErrMsgDistNull; break;
+ case ErrNum_WrongSegment:
+ msgno = Num_ErrMsgWrongSegment; break;
+ case ErrNum_InAccSegment:
+ msgno = Num_ErrMsgInAccSegment; break;
+ case ErrNum_PhaseErr:
+ msgno = Num_ErrMsgPhaseErr; break;
+ case ErrNum_Overlap:
+ msgno = Num_ErrMsgOverlap; break;
+ case ErrNum_OverlapReg:
+ msgno = Num_ErrMsgOverlapReg; break;
+ case ErrNum_NoCaseHit:
+ msgno = Num_ErrMsgNoCaseHit; break;
+ case ErrNum_InAccPage:
+ msgno = Num_ErrMsgInAccPage; break;
+ case ErrNum_RMustBeEven:
+ msgno = Num_ErrMsgRMustBeEven; break;
+ case ErrNum_Obsolete:
+ msgno = Num_ErrMsgObsolete; break;
+ case ErrNum_Unpredictable:
+ msgno = Num_ErrMsgUnpredictable; break;
+ case ErrNum_AlphaNoSense:
+ msgno = Num_ErrMsgAlphaNoSense; break;
+ case ErrNum_Senseless:
+ msgno = Num_ErrMsgSenseless; break;
+ case ErrNum_RepassUnknown:
+ msgno = Num_ErrMsgRepassUnknown; break;
+ case ErrNum_AddrNotAligned:
+ msgno = Num_ErrMsgAddrNotAligned; break;
+ case ErrNum_IOAddrNotAllowed:
+ msgno = Num_ErrMsgIOAddrNotAllowed; break;
+ case ErrNum_Pipeline:
+ msgno = Num_ErrMsgPipeline; break;
+ case ErrNum_DoubleAdrRegUse:
+ msgno = Num_ErrMsgDoubleAdrRegUse; break;
+ case ErrNum_NotBitAddressable:
+ msgno = Num_ErrMsgNotBitAddressable; break;
+ case ErrNum_StackNotEmpty:
+ msgno = Num_ErrMsgStackNotEmpty; break;
+ case ErrNum_NULCharacter:
+ msgno = Num_ErrMsgNULCharacter; break;
+ case ErrNum_PageCrossing:
+ msgno = Num_ErrMsgPageCrossing; break;
+ case ErrNum_WUnderRange:
+ msgno = Num_ErrMsgWUnderRange; break;
+ case ErrNum_WOverRange:
+ msgno = Num_ErrMsgWOverRange; break;
+ case ErrNum_NegDUP:
+ msgno = Num_ErrMsgNegDUP; break;
+ case ErrNum_ConvIndX:
+ msgno = Num_ErrMsgConvIndX; break;
+ case ErrNum_NullResMem:
+ msgno = Num_ErrMsgNullResMem; break;
+ case ErrNum_BitNumberTruncated:
+ msgno = Num_ErrMsgBitNumberTruncated; break;
+ case ErrNum_InvRegisterPointer:
+ msgno = Num_ErrMsgInvRegisterPointer; break;
+ case ErrNum_MacArgRedef:
+ msgno = Num_ErrMsgMacArgRedef; break;
+ case ErrNum_Deprecated:
+ msgno = Num_ErrMsgDeprecated; break;
+ case ErrNum_SrcLEThanDest:
+ msgno = Num_ErrMsgSrcLEThanDest; break;
+ case ErrNum_TrapValidInstruction:
+ msgno = Num_ErrMsgTrapValidInstruction; break;
+ case ErrNum_PaddingAdded:
+ msgno = Num_ErrMsgPaddingAdded; break;
+ case ErrNum_RegNumWraparound:
+ msgno = Num_ErrMsgRegNumWraparound; break;
+ case ErrNum_IndexedForIndirect:
+ msgno = Num_ErrMsgIndexedForIndirect; break;
+ case ErrNum_DoubleDef:
+ msgno = Num_ErrMsgDoubleDef; break;
+ case ErrNum_SymbolUndef:
+ msgno = Num_ErrMsgSymbolUndef; break;
+ case ErrNum_InvSymName:
+ msgno = Num_ErrMsgInvSymName; break;
+ case ErrNum_InvFormat:
+ msgno = Num_ErrMsgInvFormat; break;
+ case ErrNum_UseLessAttr:
+ msgno = Num_ErrMsgUseLessAttr; break;
+ case ErrNum_TooLongAttr:
+ msgno = Num_ErrMsgTooLongAttr; break;
+ case ErrNum_UndefAttr:
+ msgno = Num_ErrMsgUndefAttr; break;
+ case ErrNum_WrongArgCnt:
+ msgno = Num_ErrMsgWrongArgCnt; break;
+ case ErrNum_CannotSplitArg:
+ msgno = Num_ErrMsgCannotSplitArg; break;
+ case ErrNum_WrongOptCnt:
+ msgno = Num_ErrMsgWrongOptCnt; break;
+ case ErrNum_OnlyImmAddr:
+ msgno = Num_ErrMsgOnlyImmAddr; break;
+ case ErrNum_InvOpSize:
+ msgno = Num_ErrMsgInvOpSize; break;
+ case ErrNum_ConfOpSizes:
+ msgno = Num_ErrMsgConfOpSizes; break;
+ case ErrNum_UndefOpSizes:
+ msgno = Num_ErrMsgUndefOpSizes; break;
+ case ErrNum_StringOrIntButFloat:
+ msgno = Num_ErrMsgStringOrIntButFloat; break;
+ case ErrNum_IntButFloat:
+ msgno = Num_ErrMsgIntButFloat; break;
+ case ErrNum_FloatButString:
+ msgno = Num_ErrMsgFloatButString; break;
+ case ErrNum_OpTypeMismatch:
+ msgno = Num_ErrMsgOpTypeMismatch; break;
+ case ErrNum_StringButInt:
+ msgno = Num_ErrMsgStringButInt; break;
+ case ErrNum_StringButFloat:
+ msgno = Num_ErrMsgStringButFloat; break;
+ case ErrNum_TooManyArgs:
+ msgno = Num_ErrMsgTooManyArgs; break;
+ case ErrNum_IntButString:
+ msgno = Num_ErrMsgIntButString; break;
+ case ErrNum_IntOrFloatButString:
+ msgno = Num_ErrMsgIntOrFloatButString; break;
+ case ErrNum_ExpectString:
+ msgno = Num_ErrMsgExpectString; break;
+ case ErrNum_ExpectInt:
+ msgno = Num_ErrMsgExpectInt; break;
+ case ErrNum_StringOrIntOrFloatButReg:
+ msgno = Num_ErrMsgStringOrIntOrFloatButReg; break;
+ case ErrNum_ExpectIntOrString:
+ msgno = Num_ErrMsgExpectIntOrString; break;
+ case ErrNum_ExpectReg:
+ msgno = Num_ErrMsgExpectReg; break;
+ case ErrNum_RegWrongTarget:
+ msgno = Num_ErrMsgRegWrongTarget; break;
+ case ErrNum_NoRelocs:
+ msgno = Num_ErrMsgNoRelocs; break;
+ case ErrNum_UnresRelocs:
+ msgno = Num_ErrMsgUnresRelocs; break;
+ case ErrNum_Unexportable:
+ msgno = Num_ErrMsgUnexportable; break;
+ case ErrNum_UnknownInstruction:
+ msgno = Num_ErrMsgUnknownInstruction; break;
+ case ErrNum_BrackErr:
+ msgno = Num_ErrMsgBrackErr; break;
+ case ErrNum_DivByZero:
+ msgno = Num_ErrMsgDivByZero; break;
+ case ErrNum_UnderRange:
+ msgno = Num_ErrMsgUnderRange; break;
+ case ErrNum_OverRange:
+ msgno = Num_ErrMsgOverRange; break;
+ case ErrNum_NotPwr2:
+ msgno = Num_ErrMsgNotPwr2; break;
+ case ErrNum_NotAligned:
+ msgno = Num_ErrMsgNotAligned; break;
+ case ErrNum_DistTooBig:
+ msgno = Num_ErrMsgDistTooBig; break;
+ case ErrNum_InAccReg:
+ msgno = Num_ErrMsgInAccReg; break;
+ case ErrNum_NoShortAddr:
+ msgno = Num_ErrMsgNoShortAddr; break;
+ case ErrNum_InvAddrMode:
+ msgno = Num_ErrMsgInvAddrMode; break;
+ case ErrNum_AddrMustBeEven:
+ msgno = Num_ErrMsgAddrMustBeEven; break;
+ case ErrNum_AddrMustBeAligned:
+ msgno = Num_ErrMsgAddrMustBeAligned; break;
+ case ErrNum_InvParAddrMode:
+ msgno = Num_ErrMsgInvParAddrMode; break;
+ case ErrNum_UndefCond:
+ msgno = Num_ErrMsgUndefCond; break;
+ case ErrNum_IncompCond:
+ msgno = Num_ErrMsgIncompCond; break;
+ case ErrNum_UnknownFlag:
+ msgno = Num_ErrMsgUnknownFlag; break;
+ case ErrNum_DuplicateFlag:
+ msgno = Num_ErrMsgDuplicateFlag; break;
+ case ErrNum_UnknownInt:
+ msgno = Num_ErrMsgUnknownInt; break;
+ case ErrNum_DuplicateInt:
+ msgno = Num_ErrMsgDuplicateInt; break;
+ case ErrNum_JmpDistTooBig:
+ msgno = Num_ErrMsgJmpDistTooBig; break;
+ case ErrNum_DistIsOdd:
+ msgno = Num_ErrMsgDistIsOdd; break;
+ case ErrNum_SkipTargetMismatch:
+ msgno = Num_ErrMsgSkipTargetMismatch; break;
+ case ErrNum_InvShiftArg:
+ msgno = Num_ErrMsgInvShiftArg; break;
+ case ErrNum_Only1:
+ msgno = Num_ErrMsgOnly1; break;
+ case ErrNum_Range18:
+ msgno = Num_ErrMsgRange18; break;
+ case ErrNum_ShiftCntTooBig:
+ msgno = Num_ErrMsgShiftCntTooBig; break;
+ case ErrNum_InvRegList:
+ msgno = Num_ErrMsgInvRegList; break;
+ case ErrNum_InvCmpMode:
+ msgno = Num_ErrMsgInvCmpMode; break;
+ case ErrNum_InvCPUType:
+ msgno = Num_ErrMsgInvCPUType; break;
+ case ErrNum_InvFPUType:
+ msgno = Num_ErrMsgInvFPUType; break;
+ case ErrNum_InvPMMUType:
+ msgno = Num_ErrMsgInvPMMUType; break;
+ case ErrNum_InvCtrlReg:
+ msgno = Num_ErrMsgInvCtrlReg; break;
+ case ErrNum_InvReg:
+ msgno = Num_ErrMsgInvReg; break;
+ case ErrNum_DoubleReg:
+ msgno = Num_ErrMsgDoubleReg; break;
+ case ErrNum_RegBankMismatch:
+ msgno = Num_ErrMsgRegBankMismatch; break;
+ case ErrNum_UndefRegSize:
+ msgno = Num_ErrMsgUndefRegSize; break;
+ case ErrNum_InvOpOnReg:
+ msgno = Num_ErrMsgInvOpOnReg; break;
+ case ErrNum_NoSaveFrame:
+ msgno = Num_ErrMsgNoSaveFrame; break;
+ case ErrNum_NoRestoreFrame:
+ msgno = Num_ErrMsgNoRestoreFrame; break;
+ case ErrNum_UnknownMacArg:
+ msgno = Num_ErrMsgUnknownMacArg; break;
+ case ErrNum_MissEndif:
+ msgno = Num_ErrMsgMissEndif; break;
+ case ErrNum_InvIfConst:
+ msgno = Num_ErrMsgInvIfConst; break;
+ case ErrNum_DoubleSection:
+ msgno = Num_ErrMsgDoubleSection; break;
+ case ErrNum_InvSection:
+ msgno = Num_ErrMsgInvSection; break;
+ case ErrNum_MissingEndSect:
+ msgno = Num_ErrMsgMissingEndSect; break;
+ case ErrNum_WrongEndSect:
+ msgno = Num_ErrMsgWrongEndSect; break;
+ case ErrNum_NotInSection:
+ msgno = Num_ErrMsgNotInSection; break;
+ case ErrNum_UndefdForward:
+ msgno = Num_ErrMsgUndefdForward; break;
+ case ErrNum_ContForward:
+ msgno = Num_ErrMsgContForward; break;
+ case ErrNum_InvFuncArgCnt:
+ msgno = Num_ErrMsgInvFuncArgCnt; break;
+ case ErrNum_MsgMissingLTORG:
+ msgno = Num_ErrMsgMissingLTORG; break;
+ case ErrNum_InstructionNotSupported:
+ as_snprintf(Buf, BufSize, getmessage(Num_ErrMsgInstructionNotOnThisCPUSupported), MomCPUIdent);
+ break;
+ case ErrNum_FPUNotEnabled:
+ msgno = Num_ErrMsgFPUNotEnabled; break;
+ case ErrNum_PMMUNotEnabled:
+ msgno = Num_ErrMsgPMMUNotEnabled; break;
+ case ErrNum_FullPMMUNotEnabled:
+ msgno = Num_ErrMsgFullPMMUNotEnabled; break;
+ case ErrNum_Z80SyntaxNotEnabled:
+ msgno = Num_ErrMsgZ80SyntaxNotEnabled; break;
+ case ErrNum_Z80SyntaxExclusive:
+ msgno = Num_ErrMsgZ80SyntaxExclusive; break;
+ case ErrNum_FPUInstructionNotSupported:
+ as_snprintf(Buf, BufSize, getmessage(Num_ErrMsgInstructionNotOnThisFPUSupported), MomFPUIdent);
+ break;
+ case ErrNum_AddrModeNotSupported:
+ as_snprintf(Buf, BufSize, getmessage(Num_ErrMsgAddrModeNotOnThisCPUSupported), MomCPUIdent);
+ break;
+ case ErrNum_CustomNotEnabled:
+ msgno = Num_ErrMsgCustomNotEnabled; break;
+ case ErrNum_InvBitPos:
+ msgno = Num_ErrMsgInvBitPos; break;
+ case ErrNum_OnlyOnOff:
+ msgno = Num_ErrMsgOnlyOnOff; break;
+ case ErrNum_StackEmpty:
+ msgno = Num_ErrMsgStackEmpty; break;
+ case ErrNum_NotOneBit:
+ msgno = Num_ErrMsgNotOneBit; break;
+ case ErrNum_MissingStruct:
+ msgno = Num_ErrMsgMissingStruct; break;
+ case ErrNum_OpenStruct:
+ msgno = Num_ErrMsgOpenStruct; break;
+ case ErrNum_WrongStruct:
+ msgno = Num_ErrMsgWrongStruct; break;
+ case ErrNum_PhaseDisallowed:
+ msgno = Num_ErrMsgPhaseDisallowed; break;
+ case ErrNum_InvStructDir:
+ msgno = Num_ErrMsgInvStructDir; break;
+ case ErrNum_DoubleStruct:
+ msgno = Num_ErrMsgDoubleStruct; break;
+ case ErrNum_UnresolvedStructRef:
+ msgno = Num_ErrMsgUnresolvedStructRef; break;
+ case ErrNum_DuplicateStructElem:
+ msgno = Num_ErrMsgDuplicateStructElem; break;
+ case ErrNum_NotRepeatable:
+ msgno = Num_ErrMsgNotRepeatable; break;
+ case ErrNum_ShortRead:
+ msgno = Num_ErrMsgShortRead; break;
+ case ErrNum_UnknownCodepage:
+ msgno = Num_ErrMsgUnknownCodepage; break;
+ case ErrNum_RomOffs063:
+ msgno = Num_ErrMsgRomOffs063; break;
+ case ErrNum_InvFCode:
+ msgno = Num_ErrMsgInvFCode; break;
+ case ErrNum_InvFMask:
+ msgno = Num_ErrMsgInvFMask; break;
+ case ErrNum_InvMMUReg:
+ msgno = Num_ErrMsgInvMMUReg; break;
+ case ErrNum_Level07:
+ msgno = Num_ErrMsgLevel07; break;
+ case ErrNum_InvBitMask:
+ msgno = Num_ErrMsgInvBitMask; break;
+ case ErrNum_InvRegPair:
+ msgno = Num_ErrMsgInvRegPair; break;
+ case ErrNum_OpenMacro:
+ msgno = Num_ErrMsgOpenMacro; break;
+ case ErrNum_OpenIRP:
+ msgno = Num_ErrMsgOpenIRP; break;
+ case ErrNum_OpenIRPC:
+ msgno = Num_ErrMsgOpenIRPC; break;
+ case ErrNum_OpenREPT:
+ msgno = Num_ErrMsgOpenREPT; break;
+ case ErrNum_OpenWHILE:
+ msgno = Num_ErrMsgOpenWHILE; break;
+ case ErrNum_EXITMOutsideMacro:
+ msgno = Num_ErrMsgEXITMOutsideMacro; break;
+ case ErrNum_TooManyMacParams:
+ msgno = Num_ErrMsgTooManyMacParams; break;
+ case ErrNum_UndefKeyArg:
+ msgno = Num_ErrMsgUndefKeyArg; break;
+ case ErrNum_NoPosArg:
+ msgno = Num_ErrMsgNoPosArg; break;
+ case ErrNum_DoubleMacro:
+ msgno = Num_ErrMsgDoubleMacro; break;
+ case ErrNum_FirstPassCalc:
+ msgno = Num_ErrMsgFirstPassCalc; break;
+ case ErrNum_TooManyNestedIfs:
+ msgno = Num_ErrMsgTooManyNestedIfs; break;
+ case ErrNum_MissingIf:
+ msgno = Num_ErrMsgMissingIf; break;
+ case ErrNum_RekMacro:
+ msgno = Num_ErrMsgRekMacro; break;
+ case ErrNum_UnknownFunc:
+ msgno = Num_ErrMsgUnknownFunc; break;
+ case ErrNum_InvFuncArg:
+ msgno = Num_ErrMsgInvFuncArg; break;
+ case ErrNum_FloatOverflow:
+ msgno = Num_ErrMsgFloatOverflow; break;
+ case ErrNum_InvArgPair:
+ msgno = Num_ErrMsgInvArgPair; break;
+ case ErrNum_NotOnThisAddress:
+ msgno = Num_ErrMsgNotOnThisAddress; break;
+ case ErrNum_NotFromThisAddress:
+ msgno = Num_ErrMsgNotFromThisAddress; break;
+ case ErrNum_TargOnDiffPage:
+ msgno = Num_ErrMsgTargOnDiffPage; break;
+ case ErrNum_TargOnDiffSection:
+ msgno = Num_ErrMsgTargOnDiffSection; break;
+ case ErrNum_CodeOverflow:
+ msgno = Num_ErrMsgCodeOverflow; break;
+ case ErrNum_AdrOverflow:
+ msgno = Num_ErrMsgAdrOverflow; break;
+ case ErrNum_MixDBDS:
+ msgno = Num_ErrMsgMixDBDS; break;
+ case ErrNum_NotInStruct:
+ msgno = Num_ErrMsgNotInStruct; break;
+ case ErrNum_ParNotPossible:
+ msgno = Num_ErrMsgParNotPossible; break;
+ case ErrNum_InvSegment:
+ msgno = Num_ErrMsgInvSegment; break;
+ case ErrNum_UnknownSegment:
+ msgno = Num_ErrMsgUnknownSegment; break;
+ case ErrNum_UnknownSegReg:
+ msgno = Num_ErrMsgUnknownSegReg; break;
+ case ErrNum_InvString:
+ msgno = Num_ErrMsgInvString; break;
+ case ErrNum_InvRegName:
+ msgno = Num_ErrMsgInvRegName; break;
+ case ErrNum_InvArg:
+ msgno = Num_ErrMsgInvArg; break;
+ case ErrNum_NoIndir:
+ msgno = Num_ErrMsgNoIndir; break;
+ case ErrNum_NotInThisSegment:
+ msgno = Num_ErrMsgNotInThisSegment; break;
+ case ErrNum_NotInMaxmode:
+ msgno = Num_ErrMsgNotInMaxmode; break;
+ case ErrNum_OnlyInMaxmode:
+ msgno = Num_ErrMsgOnlyInMaxmode; break;
+ case ErrNum_PackCrossBoundary:
+ msgno = Num_ErrMsgPackCrossBoundary; break;
+ case ErrNum_UnitMultipleUsed:
+ msgno = Num_ErrMsgUnitMultipleUsed; break;
+ case ErrNum_MultipleLongRead:
+ msgno = Num_ErrMsgMultipleLongRead; break;
+ case ErrNum_MultipleLongWrite:
+ msgno = Num_ErrMsgMultipleLongWrite; break;
+ case ErrNum_LongReadWithStore:
+ msgno = Num_ErrMsgLongReadWithStore; break;
+ case ErrNum_TooManyRegisterReads:
+ msgno = Num_ErrMsgTooManyRegisterReads; break;
+ case ErrNum_OverlapDests:
+ msgno = Num_ErrMsgOverlapDests; break;
+ case ErrNum_TooManyBranchesInExPacket:
+ msgno = Num_ErrMsgTooManyBranchesInExPacket; break;
+ case ErrNum_CannotUseUnit:
+ msgno = Num_ErrMsgCannotUseUnit; break;
+ case ErrNum_InvEscSequence:
+ msgno = Num_ErrMsgInvEscSequence; break;
+ case ErrNum_InvPrefixCombination:
+ msgno = Num_ErrMsgInvPrefixCombination; break;
+ case ErrNum_ConstantRedefinedAsVariable:
+ msgno = Num_ErrMsgConstantRedefinedAsVariable; break;
+ case ErrNum_VariableRedefinedAsConstant:
+ msgno = Num_ErrMsgVariableRedefinedAsConstant; break;
+ case ErrNum_StructNameMissing:
+ msgno = Num_ErrMsgStructNameMissing; break;
+ case ErrNum_EmptyArgument:
+ msgno = Num_ErrMsgEmptyArgument; break;
+ case ErrNum_Unimplemented:
+ msgno = Num_ErrMsgUnimplemented; break;
+ case ErrNum_FreestandingUnnamedStruct:
+ msgno = Num_ErrMsgFreestandingUnnamedStruct; break;
+ case ErrNum_STRUCTEndedByENDUNION:
+ msgno = Num_ErrMsgSTRUCTEndedByENDUNION; break;
+ case ErrNum_AddrOnDifferentPage:
+ msgno = Num_ErrMsgAddrOnDifferentPage; break;
+ case ErrNum_UnknownMacExpMod:
+ msgno = Num_ErrMsgUnknownMacExpMod; break;
+ case ErrNum_TooManyMacExpMod:
+ msgno = Num_ErrMsgTooManyMacExpMod; break;
+ case ErrNum_ConflictingMacExpMod:
+ msgno = Num_ErrMsgConflictingMacExpMod; break;
+ case ErrNum_InvalidPrepDir:
+ msgno = Num_ErrMsgInvalidPrepDir; break;
+ case ErrNum_ExpectedError:
+ msgno = Num_ErrMsgExpectedError; break;
+ case ErrNum_NoNestExpect:
+ msgno = Num_ErrMsgNoNestExpect; break;
+ case ErrNum_MissingENDEXPECT:
+ msgno = Num_ErrMsgMissingENDEXPECT; break;
+ case ErrNum_MissingEXPECT:
+ msgno = Num_ErrMsgMissingEXPECT; break;
+ case ErrNum_NoDefCkptReg:
+ msgno = Num_ErrMsgNoDefCkptReg; break;
+ case ErrNum_InvBitField:
+ msgno = Num_ErrMsgInvBitField; break;
+ case ErrNum_ArgValueMissing:
+ msgno = Num_ErrMsgArgValueMissing; break;
+ case ErrNum_UnknownArg:
+ msgno = Num_ErrMsgUnknownArg; break;
+ case ErrNum_IndexRegMustBe16Bit:
+ msgno = Num_ErrMsgIndexRegMustBe16Bit; break;
+ case ErrNum_IOAddrRegMustBe16Bit:
+ msgno = Num_ErrMsgIOAddrRegMustBe16Bit; break;
+ case ErrNum_SegAddrRegMustBe32Bit:
+ msgno = Num_ErrMsgSegAddrRegMustBe32Bit; break;
+ case ErrNum_NonSegAddrRegMustBe16Bit:
+ msgno = Num_ErrMsgNonSegAddrRegMustBe16Bit; break;
+ case ErrNum_InvStructArgument:
+ msgno = Num_ErrMsgInvStructArgument; break;
+ case ErrNum_TooManyArrayDimensions:
+ msgno = Num_ErrMsgTooManyArrayDimensions; break;
+ case ErrNum_InvIntFormat:
+ msgno = Num_ErrMsgInvIntFormat; break;
+ case ErrNum_InvIntFormatList:
+ msgno = Num_ErrMsgInvIntFormatList; break;
+ case ErrNum_InvScale:
+ msgno = Num_ErrMsgInvScale; break;
+ case ErrNum_ConfStringOpt:
+ msgno = Num_ErrMsgConfStringOpt; break;
+ case ErrNum_UnknownStringOpt:
+ msgno = Num_ErrMsgUnknownStringOpt; break;
+ case ErrNum_InvCacheInvMode:
+ msgno = Num_ErrMsgInvCacheInvMode; break;
+ case ErrNum_InvCfgList:
+ msgno = Num_ErrMsgInvCfgList; break;
+ case ErrNum_ConfBitBltOpt:
+ msgno = Num_ErrMsgConfBitBltOpt; break;
+ case ErrNum_UnknownBitBltOpt:
+ msgno = Num_ErrMsgUnknownBitBltOpt; break;
+ case ErrNum_InternalError:
+ msgno = Num_ErrMsgInternalError; break;
+ case ErrNum_OpeningFile:
+ msgno = Num_ErrMsgOpeningFile; break;
+ case ErrNum_ListWrError:
+ msgno = Num_ErrMsgListWrError; break;
+ case ErrNum_FileReadError:
+ msgno = Num_ErrMsgFileReadError; break;
+ case ErrNum_FileWriteError:
+ msgno = Num_ErrMsgFileWriteError; break;
+ case ErrNum_HeapOvfl:
+ msgno = Num_ErrMsgHeapOvfl; break;
+ case ErrNum_StackOvfl:
+ msgno = Num_ErrMsgStackOvfl; break;
+ case ErrNum_MaxIncLevelExceeded:
+ msgno = Num_ErrMsgMaxIncLevelExceeded; break;
+ default:
+ as_snprintf(Buf, BufSize, "%s %d", getmessage(Num_ErrMsgIntError), (int) Num);
+ }
+ return (msgno != -1) ? getmessage(msgno) : Buf;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn WrErrorString(const char *pMessage, const char *pAdd, Boolean Warning, Boolean Fatal,
+ const char *pExtendError, const struct sLineComp *pLineComp)
+ * \brief write error message, combined with string component of current src line
+ * \param pMessage textual error message
+ * \param Warning error is warning?
+ * \param Fatal error is fatal?
+ * \param pExtendError extended error explanation
+ * \param pLineComp associated string component
+ * ------------------------------------------------------------------------ */
+
+void WrErrorString(const char *pMessage, const char *pAdd, Boolean Warning, Boolean Fatal,
+ const char *pExtendError, const struct sLineComp *pLineComp)
+{
+ String ErrStr[4];
+ unsigned ErrStrCount = 0, z;
+ char *p;
+ int l;
+ const char *pLeadIn = GNUErrors ? "" : "> > > ";
+ FILE *pErrFile;
+ Boolean ErrorsWrittenToListing = False;
+
+ if (TreatWarningsAsErrors && Warning && !Fatal)
+ Warning = False;
+
+ strcpy(ErrStr[ErrStrCount], pLeadIn);
+ p = GetErrorPos();
+ if (p)
+ {
+ l = strlen(p) - 1;
+ if ((l >= 0) && (p[l] == ' '))
+ p[l] = '\0';
+ strmaxcat(ErrStr[ErrStrCount], p, STRINGSIZE);
+ free(p);
+ }
+ if (pLineComp)
+ {
+ char Num[20];
+
+ as_snprintf(Num, sizeof(Num), ":%d", pLineComp->StartCol + 1);
+ strmaxcat(ErrStr[ErrStrCount], Num, STRINGSIZE);
+ }
+ if (Warning || !GNUErrors)
+ {
+ strmaxcat(ErrStr[ErrStrCount], ": ", STRINGSIZE);
+ strmaxcat(ErrStr[ErrStrCount], getmessage(Warning ? Num_WarnName : Num_ErrName), STRINGSIZE);
+ }
+ strmaxcat(ErrStr[ErrStrCount], pAdd, STRINGSIZE);
+ strmaxcat(ErrStr[ErrStrCount], ": ", STRINGSIZE);
+ if (Warning)
+ WarnCount++;
+ else
+ ErrorCount++;
+
+ strmaxcat(ErrStr[ErrStrCount], pMessage, STRINGSIZE);
+ if ((ExtendErrors > 0) && pExtendError)
+ {
+ if (GNUErrors)
+ strmaxcat(ErrStr[ErrStrCount], " '", STRINGSIZE);
+ else
+ strcpy(ErrStr[++ErrStrCount], pLeadIn);
+ strmaxcat(ErrStr[ErrStrCount], pExtendError, STRINGSIZE);
+ if (GNUErrors)
+ strmaxcat(ErrStr[ErrStrCount], "'", STRINGSIZE);
+ }
+ if ((ExtendErrors > 1) || ((ExtendErrors > 0) && pLineComp))
+ {
+ strcpy(ErrStr[++ErrStrCount], "");
+ GenLineForMarking(ErrStr[ErrStrCount], STRINGSIZE, OneLine.p_str, pLeadIn);
+ if (pLineComp)
+ {
+ strcpy(ErrStr[++ErrStrCount], "");
+ GenLineMarker(ErrStr[ErrStrCount], STRINGSIZE, '~', pLineComp, pLeadIn);
+ }
+ }
+
+ if (strcmp(LstName, "/dev/null") && !Fatal)
+ {
+ for (z = 0; z <= ErrStrCount; z++)
+ WrLstLine(ErrStr[z]);
+ ErrorsWrittenToListing = True;
+ }
+
+ if (!ErrorFile)
+ OpenWithStandard(&ErrorFile, ErrorName);
+ pErrFile = ErrorFile ? ErrorFile : stdout;
+ if (strcmp(LstName, "!1") || !ListOn || !ErrorsWrittenToListing)
+ {
+ for (z = 0; z <= ErrStrCount; z++)
+ if (ErrorFile)
+ fprintf(pErrFile, "%s\n", ErrStr[z]);
+ else
+ WrConsoleLine(ErrStr[z], True);
+ }
+
+ if (Fatal)
+ fprintf(pErrFile, "%s\n", getmessage(Num_ErrMsgIsFatal));
+ else if (MaxErrors && (ErrorCount >= MaxErrors))
+ {
+ fprintf(pErrFile, "%s\n", getmessage(Num_ErrMsgTooManyErrors));
+ Fatal = True;
+ }
+
+ if (Fatal)
+ {
+ EmergencyStop();
+ exit(3);
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn WrXErrorPos(tErrorNum Num, const char *pExtendError, const struct sLineComp *pLineComp)
+ * \brief write number-coded error message, combined with extended explamation and string component of current src line
+ * \param Num error number
+ * \param pExtendError extended error explanation
+ * \param pLineComp associated string component
+ * ------------------------------------------------------------------------ */
+
+void WrXErrorPos(tErrorNum Num, const char *pExtendError, const struct sLineComp *pLineComp)
+{
+ String h;
+ char Add[11];
+ const char *pErrorMsg;
+ tExpectError *pExpectError;
+
+ pExpectError = FindAndTakeExpectError(Num);
+ if (pExpectError)
+ {
+ free(pExpectError);
+ return;
+ }
+
+ if (!CodeOutput && (Num == ErrNum_UnknownInstruction))
+ return;
+
+ if (SuppWarns && (Num < 1000))
+ return;
+
+ pErrorMsg = ErrorNum2String(Num, h, sizeof(h));
+
+ if (((Num == ErrNum_TargOnDiffPage) || (Num == ErrNum_JmpDistTooBig))
+ && !Repass)
+ JmpErrors++;
+
+ if (NumericErrors)
+ as_snprintf(Add, sizeof(Add), " #%d", (int)Num);
+ else
+ *Add = '\0';
+ WrErrorString(pErrorMsg, Add, Num < 1000, Num >= 10000, pExtendError, pLineComp);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn WrStrErrorPos(tErrorNum Num, const const struct sLineComp *pLineComp)
+ * \brief write number-coded error message, combined with string component of current src line
+ * \param Num error number
+ * \param pStrComp associated string component
+ * ------------------------------------------------------------------------ */
+
+void WrStrErrorPos(tErrorNum Num, const struct sStrComp *pStrComp)
+{
+ WrXErrorPos(Num, pStrComp->str.p_str, &pStrComp->Pos);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn WrError(tErrorNum Num)
+ * \brief write number-coded error message, without any explanation
+ * \param Num error number
+ * ------------------------------------------------------------------------ */
+
+void WrError(tErrorNum Num)
+{
+ WrXErrorPos(Num, NULL, NULL);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn WrXError(tErrorNum Num, const char *pExtError)
+ * \brief write number-coded error message with extended explanation
+ * \param Num error number
+ * \param pExtendError extended error explanation
+ * ------------------------------------------------------------------------ */
+
+void WrXError(tErrorNum Num, const char *pExtError)
+{
+ WrXErrorPos(Num, pExtError, NULL);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn void ChkIO(tErrorNum ErrNo)
+ * \brief check for I/O error and report given error if yes
+ * \param ErrNo error number to report if error occured
+ * ------------------------------------------------------------------------ */
+
+void ChkIO(tErrorNum ErrNo)
+{
+ int io;
+
+ io = errno;
+ if ((io == 0) || (io == 19) || (io == 25))
+ return;
+
+ WrXError(ErrNo, GetErrorMsg(io));
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkXIO(tErrorNum ErrNo, char *pExtError)
+ * \brief check for I/O error and report given error if yes
+ * \param ErrNo error number to report if error occured
+ * \param pExtError, file name, as plain string
+ * ------------------------------------------------------------------------ */
+
+void ChkXIO(tErrorNum ErrNo, char *pExtError)
+{
+ tStrComp TmpComp;
+
+ StrCompMkTemp(&TmpComp, pExtError, 0);
+ ChkStrIO(ErrNo, &TmpComp);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn void ChkIO(tErrorNum ErrNo)
+ * \brief check for I/O error and report given error if yes
+ * \param ErrNo error number to report if error occured
+ * \param pComp, file name, as string component with position
+ * ------------------------------------------------------------------------ */
+
+void ChkStrIO(tErrorNum ErrNo, const struct sStrComp *pComp)
+{
+ int io;
+ String s;
+
+ io = errno;
+ if ((io == 0) || (io == 19) || (io == 25))
+ return;
+
+ as_snprintf(s, STRINGSIZE, "%s: %s", pComp->str.p_str, GetErrorMsg(io));
+ if ((pComp->Pos.StartCol >= 0) || pComp->Pos.Len)
+ WrXErrorPos(ErrNo, s, &pComp->Pos);
+ else
+ WrXError(ErrNo, s);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn CodeEXPECT(Word Code)
+ * \brief process EXPECT command
+ * ------------------------------------------------------------------------ */
+
+void CodeEXPECT(Word Code)
+{
+ UNUSED(Code);
+
+ if (!ChkArgCnt(1, ArgCntMax));
+ else if (InExpect) WrStrErrorPos(ErrNum_NoNestExpect, &OpPart);
+ else
+ {
+ int z;
+ Boolean OK;
+ tErrorNum Num;
+
+ for (z = 1; z <= ArgCnt; z++)
+ {
+ Num = (tErrorNum)EvalStrIntExpression(&ArgStr[z], UInt16, &OK);
+ if (OK)
+ {
+ tExpectError *pNew = (tExpectError*)calloc(1, sizeof(*pNew));
+ pNew->Num = Num;
+ AddExpectError(pNew);
+ }
+ }
+ InExpect = True;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn CodeENDEXPECT(Word Code)
+ * \brief process ENDEXPECT command
+ * ------------------------------------------------------------------------ */
+
+void CodeENDEXPECT(Word Code)
+{
+ UNUSED(Code);
+
+ if (!ChkArgCnt(0, 0));
+ else if (!InExpect) WrStrErrorPos(ErrNum_MissingEXPECT, &OpPart);
+ else
+ {
+ tExpectError *pCurr;
+ String h;
+
+ while (pExpectErrors)
+ {
+ pCurr = pExpectErrors;
+ pExpectErrors = pCurr->pNext;
+ WrXError(ErrNum_ExpectedError, ErrorNum2String(pCurr->Num, h, sizeof(h)));
+ free(pCurr);
+ }
+ InExpect = False;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn AsmErrPassInit(void)
+ * \brief module initialization prior to (another) pass through sources
+ * ------------------------------------------------------------------------ */
+
+void AsmErrPassInit(void)
+{
+ ErrorCount = 0;
+ WarnCount = 0;
+ ClearExpectErrors();
+ InExpect = False;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn AsmErrPassExit(void)
+ * \brief module checks & cleanups after a pass through sources
+ * ------------------------------------------------------------------------ */
+
+void AsmErrPassExit(void)
+{
+ if (InExpect)
+ WrError(ErrNum_MissingENDEXPECT);
+ ClearExpectErrors();
+ InExpect = False;
+}
--- /dev/null
+#ifndef _ASMERR_H
+#define _ASMERR_H
+/* asmerr.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Error Handling Functions */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+#include "errmsg.h"
+
+extern Word ErrorCount, WarnCount;
+
+struct sLineComp;
+struct sStrComp;
+extern void WrErrorString(const char *Message, const char *Add, Boolean Warning, Boolean Fatal,
+ const char *pExtendError, const struct sLineComp *pLineComp);
+
+extern void WrError(tErrorNum Num);
+
+extern void WrXError(tErrorNum Num, const char *pExtError);
+
+extern void WrXErrorPos(tErrorNum Num, const char *pExtError, const struct sLineComp *pLineComp);
+
+extern void WrStrErrorPos(tErrorNum Num, const struct sStrComp *pStrComp);
+
+
+extern void CodeEXPECT(Word Code);
+extern void CodeENDEXPECT(Word Code);
+
+
+extern void AsmErrPassInit(void);
+extern void AsmErrPassExit(void);
+
+extern void ChkIO(tErrorNum ErrNo);
+extern void ChkXIO(tErrorNum ErrNo, char *pExtError);
+extern void ChkStrIO(tErrorNum ErrNo, const struct sStrComp *pComp);
+
+#endif /* _ASMERR_H */
+
--- /dev/null
+#ifndef _ASMFNUMS_H
+#define _ASMFNUMS_H
+/* asmfnums.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Verwaltung von Datei-Nummern */
+/* */
+/* Historie: 15. 5.96 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+extern void InitFileList(void);
+
+extern void ClearFileList(void);
+
+extern void AddFile(char *FName);
+
+extern Integer GetFileNum(char *Name);
+
+extern const char *GetFileName(int Num);
+
+extern Integer GetFileCount(void);
+
+extern void AddAddressRange(int File, LargeWord Start, LargeWord Len);
+
+extern void GetAddressRange(int File, LargeWord *Start, LargeWord *End);
+
+extern void ResetAddressRanges(void);
+
+extern void asmfnums_init(void);
+#endif /* _ASMFNUMS_H */
--- /dev/null
+/* asmitree.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Opcode-Abfrage als Binaerbaum */
+/* */
+/* Historie: 30.10.1996 Grundsteinlegung */
+/* 8.10.1997 Hash-Tabelle */
+/* 6.12.1998 dynamisches Kopieren der Namen */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+
+#include "chunks.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmsub.h"
+
+#include "asmitree.h"
+
+/*---------------------------------------------------------------------------*/
+
+static Boolean AddSingle(PInstTreeNode *Node, char *NName, InstProc NProc, Word NIndex)
+{
+ PInstTreeNode p1, p2;
+ Boolean Result = False;
+
+ ChkStack();
+
+ if (!*Node)
+ {
+ *Node = (PInstTreeNode) malloc(sizeof(TInstTreeNode));
+ (*Node)->Left = NULL;
+ (*Node)->Right = NULL;
+ (*Node)->Proc = NProc;
+ (*Node)->Index = NIndex;
+ (*Node)->Balance = 0;
+ (*Node)->Name = as_strdup(NName);
+ Result = True;
+ }
+ else if (strcmp(NName, (*Node)->Name) < 0)
+ {
+ if (AddSingle(&((*Node)->Left), NName, NProc, NIndex))
+ switch ((*Node)->Balance)
+ {
+ case 1:
+ (*Node)->Balance = 0;
+ break;
+ case 0:
+ (*Node)->Balance = -1;
+ Result = True;
+ break;
+ case -1:
+ p1 = (*Node)->Left;
+ if (p1->Balance == -1)
+ {
+ (*Node)->Left = p1->Right;
+ p1->Right = (*Node);
+ (*Node)->Balance = 0;
+ *Node = p1;
+ }
+ else
+ {
+ p2 = p1->Right;
+ p1->Right = p2->Left;
+ p2->Left = p1;
+ (*Node)->Left = p2->Right;
+ p2->Right = (*Node);
+ (*Node)->Balance = (p2->Balance == -1) ? 1 : 0;
+ p1->Balance = (p2->Balance == 1) ? -1 : 0;
+ *Node = p2;
+ }
+ (*Node)->Balance = 0;
+ break;
+ }
+ }
+ else
+ {
+ if (AddSingle(&((*Node)->Right), NName, NProc, NIndex))
+ switch ((*Node)->Balance)
+ {
+ case -1:
+ (*Node)->Balance = 0;
+ break;
+ case 0:
+ (*Node)->Balance = 1;
+ Result = True;
+ break;
+ case 1:
+ p1 = (*Node)->Right;
+ if (p1->Balance == 1)
+ {
+ (*Node)->Right = p1->Left;
+ p1->Left = (*Node);
+ (*Node)->Balance = 0;
+ *Node = p1;
+ }
+ else
+ {
+ p2 = p1->Left;
+ p1->Left = p2->Right;
+ p2->Right = p1;
+ (*Node)->Right = p2->Left;
+ p2->Left = (*Node);
+ (*Node)->Balance = (p2->Balance == 1) ? -1 : 0;
+ p1->Balance = (p2->Balance == -1) ? 1 : 0;
+ *Node = p2;
+ }
+ (*Node)->Balance = 0;
+ break;
+ }
+ }
+ return Result;
+}
+
+void AddInstTree(PInstTreeNode *Root, char *NName, InstProc NProc, Word NIndex)
+{
+ AddSingle(Root, NName, NProc, NIndex);
+}
+
+static void ClearSingle(PInstTreeNode *Node)
+{
+ ChkStack();
+
+ if (*Node)
+ {
+ free((*Node)->Name);
+ ClearSingle(&((*Node)->Left));
+ ClearSingle(&((*Node)->Right));
+ free(*Node);
+ *Node = NULL;
+ }
+}
+
+void ClearInstTree(PInstTreeNode *Root)
+{
+ ClearSingle(Root);
+}
+
+Boolean SearchInstTree(PInstTreeNode Root, char *OpPart)
+{
+ int z;
+
+ z = 0;
+ while ((Root) && (strcmp(Root->Name, OpPart)))
+ {
+ Root = (strcmp(OpPart, Root->Name) < 0) ? Root->Left : Root->Right;
+ z++;
+ }
+
+ if (!Root)
+ return False;
+ else
+ {
+ Root->Proc(Root->Index);
+ return True;
+ }
+}
+
+static void PNode(PInstTreeNode Node, Word Lev)
+{
+ ChkStack();
+ if (Node)
+ {
+ PNode(Node->Left, Lev + 1);
+ printf("%*s %s %p %p %d\n", 5 * Lev, "", Node->Name, (void*)Node->Left, (void*)Node->Right, Node->Balance);
+ PNode(Node->Right, Lev + 1);
+ }
+}
+
+void PrintInstTree(PInstTreeNode Root)
+{
+ PNode(Root, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int GetKey(const char *Name, LongWord TableSize)
+{
+ register unsigned char *p;
+ LongWord tmp = 0;
+
+ for (p = (unsigned char *)Name; *p != '\0'; p++)
+ tmp = (tmp << 2) + ((LongWord)*p);
+ return tmp % TableSize;
+}
+
+PInstTable CreateInstTable(int TableSize)
+{
+ int z;
+ PInstTableEntry tmp;
+ PInstTable tab;
+
+ tmp = (PInstTableEntry) malloc(sizeof(TInstTableEntry) * TableSize);
+ for (z = 0; z < TableSize; z++)
+ tmp[z].Name = NULL;
+ tab = (PInstTable) malloc(sizeof(TInstTable));
+ tab->Fill = 0;
+ tab->Size = TableSize;
+ tab->Entries = tmp;
+ tab->Dynamic = FALSE;
+ return tab;
+}
+
+void SetDynamicInstTable(PInstTable Table)
+{
+ Table->Dynamic = TRUE;
+}
+
+void DestroyInstTable(PInstTable tab)
+{
+ int z;
+
+ if (tab->Dynamic)
+ for (z = 0; z < tab->Size; z++)
+ free(tab->Entries[z].Name);
+
+ free(tab->Entries);
+ free(tab);
+}
+
+void AddInstTable(PInstTable tab, const char *Name, Word Index, InstProc Proc)
+{
+ LongWord h0 = GetKey(Name, tab->Size), z = 0;
+
+ /* mindestens ein freies Element lassen, damit der Sucher garantiert terminiert */
+
+ if (tab->Size - 1 <= tab->Fill)
+ {
+ fprintf(stderr, "\nhash table overflow\n");
+ exit(255);
+ }
+ while (1)
+ {
+ if (!tab->Entries[h0].Name)
+ {
+ tab->Entries[h0].Name = (tab->Dynamic) ? as_strdup(Name) : (char*)Name;
+ tab->Entries[h0].Proc = Proc;
+ tab->Entries[h0].Index = Index;
+ tab->Entries[h0].Coll = z;
+ tab->Fill++;
+ return;
+ }
+ if (!strcmp(tab->Entries[h0].Name, Name))
+ {
+ printf("%s double in table\n", Name);
+ exit(255);
+ }
+ z++;
+ if ((LongInt)(++h0) == tab->Size)
+ h0 = 0;
+ }
+}
+
+void RemoveInstTable(PInstTable tab, const char *Name)
+{
+ LongWord h0 = GetKey(Name, tab->Size);
+
+ while (1)
+ {
+ if (!tab->Entries[h0].Name)
+ return;
+ else if (!strcmp(tab->Entries[h0].Name, Name))
+ {
+ tab->Entries[h0].Name = NULL;
+ tab->Entries[h0].Proc = NULL;
+ tab->Fill--;
+ return;
+ }
+ if ((LongInt)(++h0) == tab->Size)
+ h0 = 0;
+ }
+}
+
+Boolean LookupInstTable(PInstTable tab, const char *Name)
+{
+ LongWord h0 = GetKey(Name, tab->Size);
+
+ while (1)
+ {
+ if (!tab->Entries[h0].Name)
+ return False;
+ else if (!strcmp(tab->Entries[h0].Name, Name))
+ {
+ tab->Entries[h0].Proc(tab->Entries[h0].Index);
+ return True;
+ }
+ if ((LongInt)(++h0) == tab->Size)
+ h0 = 0;
+ }
+}
+
+void PrintInstTable(FILE *stream, PInstTable tab)
+{
+ int z;
+
+ for (z = 0; z < tab->Size; z++)
+ if (tab->Entries[z].Name)
+ fprintf(stream, "[%3d]: %-10s Index %4d Coll %2d\n", z,
+ tab->Entries[z].Name, tab->Entries[z].Index, tab->Entries[z].Coll);
+}
+
+/*----------------------------------------------------------------------------*/
+
+void asmitree_init(void)
+{
+}
--- /dev/null
+#ifndef _ASMITREE_H
+#define _ASMITREE_H
+/* asmitree.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Opcode-Abfrage als Binaerbaum */
+/* */
+/* Historie: 30.10.1996 Grundsteinlegung */
+/* 6.12.1998 dynamische Variante */
+/* */
+/*****************************************************************************/
+
+typedef void (*InstProc)(
+#ifdef __PROTOS__
+Word Index
+#endif
+);
+
+typedef struct _TInstTreeNode
+{
+ struct _TInstTreeNode *Left,*Right;
+ InstProc Proc;
+ char *Name;
+ Word Index;
+ ShortInt Balance;
+} TInstTreeNode,*PInstTreeNode;
+
+typedef struct _TInstTableEntry
+{
+ InstProc Proc;
+ char *Name;
+ Word Index;
+ int Coll;
+}
+TInstTableEntry,*PInstTableEntry;
+
+struct sInstTable
+{
+ int Fill,Size;
+ Boolean Dynamic;
+ PInstTableEntry Entries;
+};
+typedef struct sInstTable TInstTable;
+typedef struct sInstTable *PInstTable;
+
+extern void AddInstTree(PInstTreeNode *Root, char *NName, InstProc NProc, Word NIndex);
+
+extern void ClearInstTree(PInstTreeNode *Root);
+
+extern Boolean SearchInstTree(PInstTreeNode Root, char *OpPart);
+
+extern void PrintInstTree(PInstTreeNode Root);
+
+
+extern PInstTable CreateInstTable(int TableSize);
+
+extern void SetDynamicInstTable(PInstTable Table);
+
+extern void DestroyInstTable(PInstTable tab);
+
+extern void AddInstTable(PInstTable tab, const char *Name, Word Index, InstProc Proc);
+
+extern void RemoveInstTable(PInstTable tab, const char *Name);
+
+extern Boolean LookupInstTable(PInstTable tab, const char *Name);
+
+extern void PrintInstTable(FILE *stream, PInstTable tab);
+
+extern void asmitree_init(void);
+
+#endif /* _ASMITREE_H */
--- /dev/null
+/* asmpars.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Verwaltung von Symbolen und das ganze Drumherum... */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "endian.h"
+#include "bpemu.h"
+#include "nls.h"
+#include "nlmessages.h"
+#include "as.rsc"
+#include "strutil.h"
+#include "strcomp.h"
+
+#include "asmdef.h"
+#include "asmsub.h"
+#include "errmsg.h"
+#include "asmfnums.h"
+#include "asmrelocs.h"
+#include "asmstructs.h"
+#include "chunks.h"
+#include "trees.h"
+#include "operator.h"
+#include "function.h"
+#include "intformat.h"
+#include "ieeefloat.h"
+
+#include "asmpars.h"
+
+#define LOCSYMSIGHT 3 /* max. sight for nameless temporary symbols */
+
+#define LEAVE goto func_exit
+#define LEAVE2 goto func_exit2
+
+/* Mask, Min & Max are computed at initialization */
+
+tIntTypeDef IntTypeDefs[IntTypeCnt] =
+{
+ { 0x0001, 0, 0, 0 }, /* UInt1 */
+ { 0x0002, 0, 0, 0 }, /* UInt2 */
+ { 0x0003, 0, 0, 0 }, /* UInt3 */
+ { 0x8004, 0, 0, 0 }, /* SInt4 */
+ { 0x0004, 0, 0, 0 }, /* UInt4 */
+ { 0xc004, 0, 0, 0 }, /* Int4 */
+ { 0x8005, 0, 0, 0 }, /* SInt5 */
+ { 0x0005, 0, 0, 0 }, /* UInt5 */
+ { 0xc005, 0, 0, 0 }, /* Int5 */
+ { 0x8006, 0, 0, 0 }, /* SInt6 */
+ { 0x0006, 0, 0, 0 }, /* UInt6 */
+ { 0x8007, 0, 0, 0 }, /* SInt7 */
+ { 0x0007, 0, 0, 0 }, /* UInt7 */
+ { 0x8008, 0, 0, 0 }, /* SInt8 */
+ { 0x0008, 0, 0, 0 }, /* UInt8 */
+ { 0xc008, 0, 0, 0 }, /* Int8 */
+ { 0x8009, 0, 0, 0 }, /* SInt9 */
+ { 0x0009, 0, 0, 0 }, /* UInt9 */
+ { 0x000a, 0, 0, 0 }, /* UInt10 */
+ { 0xc00a, 0, 0, 0 }, /* Int10 */
+ { 0x000b, 0, 0, 0 }, /* UInt11 */
+ { 0x000c, 0, 0, 0 }, /* UInt12 */
+ { 0xc00c, 0, 0, 0 }, /* Int12 */
+ { 0x000d, 0, 0, 0 }, /* UInt13 */
+ { 0x000e, 0, 0, 0 }, /* UInt14 */
+ { 0xc00e, 0, 0, 0 }, /* Int14 */
+ { 0x800f, 0, 0, 0 }, /* SInt15 */
+ { 0x000f, 0, 0, 0 }, /* UInt15 */
+ { 0x8010, 0, 0, 0 }, /* SInt16 */
+ { 0x0010, 0, 0, 0 }, /* UInt16 */
+ { 0xc010, 0, 0, 0 }, /* Int16 */
+ { 0x0011, 0, 0, 0 }, /* UInt17 */
+ { 0x0012, 0, 0, 0 }, /* UInt18 */
+ { 0x0013, 0, 0, 0 }, /* UInt19 */
+ { 0x8014, 0, 0, 0 }, /* SInt20 */
+ { 0x0014, 0, 0, 0 }, /* UInt20 */
+ { 0xc014, 0, 0, 0 }, /* Int20 */
+ { 0x0015, 0, 0, 0 }, /* UInt21 */
+ { 0x0016, 0, 0, 0 }, /* UInt22 */
+ { 0x0017, 0, 0, 0 }, /* UInt23 */
+ { 0x8018, 0, 0, 0 }, /* SInt24 */
+ { 0x0018, 0, 0, 0 }, /* UInt24 */
+ { 0xc018, 0, 0, 0 }, /* Int24 */
+ { 0x801e, 0, 0, 0 }, /* SInt30 */
+ { 0x001e, 0, 0, 0 }, /* UInt30 */
+ { 0xc01e, 0, 0, 0 }, /* Int30 */
+ { 0x8020, 0, 0, 0 }, /* SInt32 */
+ { 0x0020, 0, 0, 0 }, /* UInt32 */
+ { 0xc020, 0, 0, 0 }, /* Int32 */
+#ifdef HAS64
+ { 0x8040, 0, 0, 0 }, /* SInt64 */
+ { 0x0040, 0, 0, 0 }, /* UInt64 */
+ { 0xc040, 0, 0, 0 }, /* Int64 */
+#endif
+};
+
+typedef struct
+{
+ Boolean Back;
+ LongInt Counter;
+} TTmpSymLog;
+
+LongInt MomLocHandle; /* Merker, den lokale Symbole erhalten */
+LongInt TmpSymCounter, /* counters for local symbols */
+ FwdSymCounter,
+ BackSymCounter;
+char TmpSymCounterVal[10]; /* representation as string */
+TTmpSymLog TmpSymLog[LOCSYMSIGHT];
+LongInt TmpSymLogDepth;
+
+LongInt LocHandleCnt; /* mom. verwendeter lokaler Handle */
+
+typedef struct sSymbolEntry
+{
+ TTree Tree;
+ Boolean Defined, Used, Changeable, changed;
+ TempResult SymWert;
+ LargeInt unchanged_value;
+ PCrossRef RefList;
+ Byte FileNum;
+ LongInt LineNum;
+} TSymbolEntry, *PSymbolEntry;
+
+typedef struct sSymbolStackEntry
+{
+ struct sSymbolStackEntry *Next;
+ TempResult Contents;
+} TSymbolStackEntry, *PSymbolStackEntry;
+
+typedef struct sSymbolStack
+{
+ struct sSymbolStack *Next;
+ char *Name;
+ PSymbolStackEntry Contents;
+} TSymbolStack, *PSymbolStack;
+
+typedef struct sDefSymbol
+{
+ struct sDefSymbol *Next;
+ char *SymName;
+ TempResult Wert;
+} TDefSymbol, *PDefSymbol;
+
+typedef struct sCToken
+{
+ struct sCToken *Next;
+ char *Name;
+ LongInt Parent;
+ ChunkList Usage;
+} TCToken, *PCToken;
+
+typedef struct sLocHeap
+{
+ struct sLocHeap *Next;
+ LongInt Cont;
+} TLocHeap, *PLocHandle;
+
+typedef struct sRegDefList
+{
+ struct sRegDefList *Next;
+ LongInt Section;
+ char *Value;
+ Boolean Used;
+} TRegDefList, *PRegDefList;
+
+typedef struct sRegDef
+{
+ struct sRegDef *Left, *Right;
+ char *Orig;
+ PRegDefList Defs, DoneDefs;
+} TRegDef, *PRegDef;
+
+static PSymbolEntry FirstSymbol, FirstLocSymbol;
+static PDefSymbol FirstDefSymbol;
+/*static*/ PCToken FirstSection;
+static Boolean DoRefs, /* Querverweise protokollieren */
+ RegistersDefined;
+static PLocHandle FirstLocHandle;
+static PSymbolStack FirstStack;
+static PCToken MomSection;
+static char *LastGlobSymbol;
+static PFunction FirstFunction; /* Liste definierter Funktionen */
+
+void AsmParsInit(void)
+{
+ FirstSymbol = NULL;
+
+ FirstLocSymbol = NULL; MomLocHandle = -1; SetMomSection(-1);
+ FirstSection = NULL;
+ FirstLocHandle = NULL;
+ FirstStack = NULL;
+ FirstFunction = NULL;
+ DoRefs = True;
+ RadixBase = 10;
+ OutRadixBase = 16;
+ RegistersDefined = False;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn range_not_checkable(IntType type)
+ * \brief can integer type's range not be checked on host system?
+ * \param type integer type
+ * \return true if range can NOT be checked
+ * ------------------------------------------------------------------------ */
+
+static Boolean range_not_checkable(IntType type)
+{
+#ifndef HAS64
+ return (((int)type) >= ((int)SInt32));
+#else
+ return (((int)type) >= ((int)SInt64));
+#endif
+}
+
+/*!------------------------------------------------------------------------
+ * \fn RangeCheck(LargeInt Wert, IntType Typ)
+ * \brief check whether value is within integer type's ranges
+ * \param Wert value to check
+ * \param Typ integer type giving range
+ * \return true if within range
+ * ------------------------------------------------------------------------ */
+
+Boolean RangeCheck(LargeInt Wert, IntType Typ)
+{
+ return range_not_checkable(Typ) || ((Wert >= IntTypeDefs[(int)Typ].Min) && (Wert <= IntTypeDefs[(int)Typ].Max));
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkRangeByType(LargeInt value, IntType type, const struct sStrComp *p_comp)
+ * \brief check whether value is within integer type's ranges, and throw error if not
+ * \param value value to check
+ * \param type integer type giving range
+ * \param p_comp corresponding source argument
+ * \return true if within range
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkRangeByType(LargeInt value, IntType type, const struct sStrComp *p_comp)
+{
+ return range_not_checkable(type) || ChkRangePos(value, IntTypeDefs[(int)type].Min, IntTypeDefs[(int)type].Max, p_comp);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkRangeWarnByType(LargeInt value, IntType type, const struct sStrComp *p_comp)
+ * \brief check whether value is within integer type's ranges, and throw warning if not
+ * \param value value to check
+ * \param type integer type giving range
+ * \param p_comp corresponding source argument
+ * \return true if within range
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkRangeWarnByType(LargeInt value, IntType type, const struct sStrComp *p_comp)
+{
+ return range_not_checkable(type) || ChkRangeWarnPos(value, IntTypeDefs[(int)type].Min, IntTypeDefs[(int)type].Max, p_comp);
+}
+
+Boolean FloatRangeCheck(Double Wert, FloatType Typ)
+{
+ /* NaN/Infinity is representable in all formats */
+
+ int numclass = as_fpclassify(Wert);
+ if ((numclass == AS_FP_NAN) || (numclass == AS_FP_INFINITE))
+ return True;
+
+ switch (Typ)
+ {
+ case Float16:
+ return (fabs(Wert) <= 65504.0);
+ case Float32:
+ return (fabs(Wert) <= 3.4e38);
+ case Float64:
+ return (fabs(Wert) <= 1.7e308);
+/** case FloatCo: return fabs(Wert) <= 9.22e18; */
+ case Float80:
+ return True;
+ case FloatDec:
+ return True;
+ default:
+ return False;
+ }
+/** if (Typ == FloatDec) && (fabs(Wert) > 1e1000) WrError(ErrNum_BigDecFloat);**/
+}
+
+Boolean SingleBit(LargeInt Inp, LargeInt *Erg)
+{
+ *Erg = 0;
+ do
+ {
+ if (!Odd(Inp))
+ (*Erg)++;
+ if (!Odd(Inp))
+ Inp = Inp >> 1;
+ }
+ while ((*Erg != LARGEBITS) && (!Odd(Inp)));
+ return (*Erg != LARGEBITS) && (Inp == 1);
+}
+
+IntType GetSmallestUIntType(LargeWord MaxValue)
+{
+ IntType Result;
+
+ Result = (IntType) 0;
+ for (Result = (IntType) 0; Result < IntTypeCnt; Result++)
+ {
+ if (IntTypeDefs[Result].Min < 0)
+ continue;
+ if (IntTypeDefs[Result].Max >= (LargeInt)MaxValue)
+ return Result;
+ }
+ return UInt32;
+}
+
+IntType GetUIntTypeByBits(unsigned Bits)
+{
+ IntType Result;
+ for (Result = (IntType) 0; Result < IntTypeCnt; Result++)
+ {
+ if (IntTypeDefs[Result].SignAndWidth & 0x8000)
+ continue;
+ if (Lo(IntTypeDefs[Result].SignAndWidth) == Bits)
+ return Result;
+ }
+ fprintf(stderr, "define unsigned int type with %u bits\n", Bits);
+ exit(255);
+}
+
+static Boolean ProcessBk(char **Start, char *Erg)
+{
+ LongInt System = 0, Acc = 0, Digit = 0;
+ char ch;
+ int cnt;
+ Boolean Finish;
+
+ switch (as_toupper(**Start))
+ {
+ case '\'': case '\\': case '"':
+ *Erg = **Start;
+ (*Start)++;
+ return True;
+ case 'H':
+ *Erg = '\'';
+ (*Start)++;
+ return True;
+ case 'I':
+ *Erg = '"';
+ (*Start)++;
+ return True;
+ case 'B':
+ *Erg = Char_BS;
+ (*Start)++;
+ return True;
+ case 'A':
+ *Erg = Char_BEL;
+ (*Start)++;
+ return True;
+ case 'E':
+ *Erg = Char_ESC;
+ (*Start)++;
+ return True;
+ case 'T':
+ *Erg = Char_HT;
+ (*Start)++;
+ return True;
+ case 'N':
+ *Erg = Char_LF;
+ (*Start)++;
+ return True;
+ case 'R':
+ *Erg = Char_CR;
+ (*Start)++;
+ return True;
+ case 'X':
+ System = 16;
+ (*Start)++;
+ /* fall-through */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (System == 0)
+ System = (**Start == '0') ? 8 : 10;
+ cnt = (System == 16) ? 1 : ((System == 10) ? 0 : -1);
+ do
+ {
+ ch = as_toupper(**Start);
+ Finish = False;
+ if ((ch >= '0') && (ch <= '9'))
+ Digit = ch - '0';
+ else if ((System == 16) && (ch >= 'A') && (ch <= 'F'))
+ Digit = (ch - 'A') + 10;
+ else
+ Finish = True;
+ if (!Finish)
+ {
+ (*Start)++;
+ cnt++;
+ if (Digit >= System)
+ {
+ WrError(ErrNum_OverRange);
+ return False;
+ }
+ Acc = (Acc * System) + Digit;
+ }
+ }
+ while ((!Finish) && (cnt < 3));
+ if (!ChkRange(Acc, 0, 255))
+ return False;
+ *Erg = Acc;
+ return True;
+ default:
+ WrError(ErrNum_InvEscSequence);
+ return False;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn NonZString2Int(const struct as_nonz_dynstr *p_str)
+ * \brief convert string to its "ASCII representation"
+ * \param p_str string containing characters
+ * \return -1 or converted int
+ * ------------------------------------------------------------------------ */
+
+LargeInt NonZString2Int(const struct as_nonz_dynstr *p_str)
+{
+ if ((p_str->len > 0) && (p_str->len <= 4))
+ {
+ const char *pRun;
+ Byte Digit;
+ LargeInt Result;
+
+ Result = 0;
+ for (pRun = p_str->p_str;
+ pRun < p_str->p_str + p_str->len;
+ pRun++)
+ {
+ Digit = (usint) *pRun;
+ Result = (Result << 8) | CharTransTable[Digit & 0xff];
+ }
+ return Result;
+ }
+ return -1;
+}
+
+Boolean Int2NonZString(struct as_nonz_dynstr *p_str, LargeInt Src)
+{
+ int Search;
+ Byte Digit;
+ char *pDest;
+
+ if (p_str->capacity < 32)
+ as_nonz_dynstr_realloc(p_str, 32);
+ p_str->len = 0;
+ pDest = &p_str->p_str[p_str->capacity];
+ while (Src && (p_str->len < p_str->capacity))
+ {
+ Digit = Src & 0xff;
+ Src = (Src >> 8) & 0xfffffful;
+ for (Search = 0; Search < 256; Search++)
+ if (CharTransTable[Search] == Digit)
+ {
+ *(--pDest) = Search;
+ p_str->len++;
+ break;
+ }
+ }
+ memmove(p_str->p_str, pDest, p_str->len);
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn TempResultToInt(TempResult *pResult)
+ * \brief convert TempResult to integer
+ * \param pResult tempresult to convert
+ * \return 0 or error code
+ * ------------------------------------------------------------------------ */
+
+int TempResultToInt(TempResult *pResult)
+{
+ switch (pResult->Typ)
+ {
+ case TempInt:
+ break;
+ case TempString:
+ {
+ LargeInt Result = NonZString2Int(&pResult->Contents.str);
+ if (Result >= 0)
+ {
+ as_tempres_set_int(pResult, Result);
+ break;
+ }
+ /* else */
+ }
+ /* fall-through */
+ default:
+ pResult->Typ = TempNone;
+ return -1;
+ }
+ return 0;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn MultiCharToInt(TempResult *pResult, unsigned MaxLen)
+ * \brief optionally convert multi-character constant to integer
+ * \param pResult holding value
+ * \param MaxLen maximum lenght of multi-character constant
+ * \return True if converted
+ * ------------------------------------------------------------------------ */
+
+Boolean MultiCharToInt(TempResult *pResult, unsigned MaxLen)
+{
+ if ((pResult->Typ == TempString)
+ && (pResult->Contents.str.len <= MaxLen)
+ && (pResult->Flags & eSymbolFlag_StringSingleQuoted))
+ {
+ TempResultToInt(pResult);
+ return True;
+ }
+ return False;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ExpandStrSymbol(char *pDest, size_t DestSize, const tStrComp *pSrc)
+ * \brief expand symbol name from string component
+ * \param pDest dest buffer
+ * \param DestSize size of dest buffer
+ * \param pSrc source component
+ * \return True if success
+ * ------------------------------------------------------------------------ */
+
+Boolean ExpandStrSymbol(char *pDest, size_t DestSize, const tStrComp *pSrc)
+{
+ tStrComp SrcComp;
+ const char *pStart;
+
+ *pDest = '\0'; StrCompRefRight(&SrcComp, pSrc, 0);
+ while (True)
+ {
+ pStart = QuotPos(SrcComp.str.p_str, '{');
+ if (pStart)
+ {
+ unsigned ls = pStart - SrcComp.str.p_str, ld = strlen(pDest);
+ String Expr, Result;
+ tStrComp ExprComp;
+ tEvalResult EvalResult;
+ const char *pStop;
+
+ if (ld + ls + 1 > DestSize)
+ ls = DestSize - 1 - ld;
+ memcpy(pDest + ld, SrcComp.str.p_str, ls);
+ pDest[ld + ls] = '\0';
+
+ pStop = QuotPos(pStart + 1, '}');
+ if (!pStop)
+ {
+ WrStrErrorPos(ErrNum_InvSymName, pSrc);
+ return False;
+ }
+ StrCompMkTemp(&ExprComp, Expr, sizeof(Expr));
+ StrCompCopySub(&ExprComp, &SrcComp, pStart + 1 - SrcComp.str.p_str, pStop - pStart - 1);
+ EvalStrStringExpressionWithResult(&ExprComp, &EvalResult, Result);
+ if (!EvalResult.OK)
+ return False;
+ if (mFirstPassUnknown(EvalResult.Flags))
+ {
+ WrStrErrorPos(ErrNum_FirstPassCalc, &ExprComp);
+ return False;
+ }
+ if (!CaseSensitive)
+ UpString(Result);
+ strmaxcat(pDest, Result, DestSize);
+ StrCompIncRefLeft(&SrcComp, pStop + 1 - SrcComp.str.p_str);
+ }
+ else
+ {
+ strmaxcat(pDest, SrcComp.str.p_str, DestSize);
+ return True;
+ }
+ }
+}
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+/* check whether this is a local symbol and expand local counter if yes. They
+ have to be handled in different places of the parser, therefore two separate
+ functions */
+
+void InitTmpSymbols(void)
+{
+ TmpSymCounter = FwdSymCounter = BackSymCounter = 0;
+ *TmpSymCounterVal = '\0';
+ TmpSymLogDepth = 0;
+ *LastGlobSymbol = '\0';
+}
+
+static void AddTmpSymLog(Boolean Back, LongInt Counter)
+{
+ /* shift out oldest value */
+
+ if (TmpSymLogDepth)
+ {
+ LongInt ShiftCnt = min(TmpSymLogDepth, LOCSYMSIGHT - 1);
+
+ memmove(TmpSymLog + 1, TmpSymLog, sizeof(TTmpSymLog) * (ShiftCnt));
+ }
+
+ /* insert new one */
+
+ TmpSymLog[0].Back = Back;
+ TmpSymLog[0].Counter = Counter;
+ if (TmpSymLogDepth < LOCSYMSIGHT)
+ TmpSymLogDepth++;
+}
+
+static Boolean ChkTmp1(char *Name, as_symbol_source_t symbol_source)
+{
+ char *Src, *Dest;
+ Boolean Result = FALSE;
+
+ /* $$-Symbols: append current $$-counter */
+
+ if (!strncmp(Name, "$$", 2))
+ {
+ /* manually copy since this will implicitly give us the point to append
+ the number */
+
+ for (Src = Name + 2, Dest = Name; *Src; *(Dest++) = *(Src++));
+
+ /* append number. only generate the number once */
+
+ if (*TmpSymCounterVal == '\0')
+ as_snprintf(TmpSymCounterVal, sizeof(TmpSymCounterVal), "%d", TmpSymCounter);
+ strcpy(Dest, TmpSymCounterVal);
+ Result = TRUE;
+ }
+
+ /* no special local symbol: increment $$-counter */
+
+ else if (symbol_source != e_symbol_source_none)
+ {
+ TmpSymCounter++;
+ *TmpSymCounterVal = '\0';
+ }
+
+ return Result;
+}
+
+static Boolean ChkTmp2(char *pDest, const char *pSrc, as_symbol_source_t symbol_source)
+{
+ const char *pRun, *pBegin, *pEnd;
+ int Cnt;
+ Boolean Result = FALSE;
+
+ for (pBegin = pSrc; as_isspace(*pBegin); pBegin++);
+ for (pEnd = pSrc + strlen(pSrc); (pEnd > pBegin) && as_isspace(*(pEnd - 1)); pEnd--);
+
+ /* Note: We have to deal with three symbol definitions:
+
+ "-" for backward-only referencing
+ "+" for forward-only referencing
+ "/" for either way of referencing
+
+ "/" and "+" are both expanded to forward symbol names, so the
+ forward refencing to both types is unproblematic, however
+ only "/" and "-" are stored in the backlog of the three
+ most-recent symbols for backward referencing.
+ */
+
+ /* backward references ? */
+
+ if (*pBegin == '-')
+ {
+ for (pRun = pBegin; *pRun; pRun++)
+ if (*pRun != '-')
+ break;
+ Cnt = pRun - pBegin;
+ if (pRun == pEnd)
+ {
+ if ((symbol_source != e_symbol_source_none) && (Cnt == 1))
+ {
+ as_snprintf(pDest, STRINGSIZE, "__back%d", (int)BackSymCounter);
+ AddTmpSymLog(TRUE, BackSymCounter);
+ BackSymCounter++;
+ Result = TRUE;
+ }
+
+ /* TmpSymLogDepth cannot become larger than LOCSYMSIGHT, so we only
+ have to check against the log's actual depth. */
+
+ else if (Cnt <= TmpSymLogDepth)
+ {
+ Cnt--;
+ as_snprintf(pDest, STRINGSIZE, "__%s%d",
+ TmpSymLog[Cnt].Back ? "back" : "forw",
+ (int)TmpSymLog[Cnt].Counter);
+ Result = TRUE;
+ }
+ }
+ }
+
+ /* forward references ? */
+
+ else if (*pBegin == '+')
+ {
+ for (pRun = pBegin; *pRun; pRun++)
+ if (*pRun != '+')
+ break;
+ Cnt = pRun - pBegin;
+ if (pRun == pEnd)
+ {
+ if ((symbol_source != e_symbol_source_none) && (Cnt == 1))
+ {
+ as_snprintf(pDest, STRINGSIZE, "__forw%d", (int)FwdSymCounter++);
+ Result = TRUE;
+ }
+ else if (Cnt <= LOCSYMSIGHT)
+ {
+ as_snprintf(pDest, STRINGSIZE, "__forw%d", (int)(FwdSymCounter + (Cnt - 1)));
+ Result = TRUE;
+ }
+ }
+ }
+
+ /* slash: only allowed for definition, but add to log for backward ref. */
+
+ else if ((pEnd - pBegin == 1) && (*pBegin == '/') && (symbol_source != e_symbol_source_none))
+ {
+ AddTmpSymLog(FALSE, FwdSymCounter);
+ as_snprintf(pDest, STRINGSIZE, "__forw%d", (int)FwdSymCounter);
+ FwdSymCounter++;
+ Result = TRUE;
+ }
+
+ return Result;
+}
+
+static Boolean ChkTmp3(char *Name, as_symbol_source_t symbol_source)
+{
+ if ('.' == *Name)
+ {
+ strmaxprep2(Name, LastGlobSymbol, STRINGSIZE);
+ return True;
+ }
+
+#if 0
+ if (symbol_source == e_symbol_source_label)
+#else
+ if (symbol_source != e_symbol_source_none)
+#endif
+ strmaxcpy(LastGlobSymbol, Name, STRINGSIZE);
+ return False;
+}
+
+static Boolean ChkTmp(char *Name, as_symbol_source_t symbol_source)
+{
+ Boolean IsTmp1, IsTmp2, IsTmp3;
+
+ IsTmp1 = ChkTmp1(Name, symbol_source);
+ IsTmp2 = ChkTmp2(Name, Name, symbol_source);
+ IsTmp3 = ChkTmp3(Name, IsTmp2 ? e_symbol_source_none : symbol_source);
+ return IsTmp1 || IsTmp2 || IsTmp3;
+}
+
+Boolean IdentifySection(const tStrComp *pName, LongInt *Erg)
+{
+ PSaveSection SLauf;
+ String ExpName;
+ sint Depth;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return False;
+ if (!CaseSensitive)
+ NLS_UpString(ExpName);
+
+ if (*ExpName == '\0')
+ {
+ *Erg = -1;
+ return True;
+ }
+ else if (((strlen(ExpName) == 6) || (strlen(ExpName) == 7))
+ && (!as_strncasecmp(ExpName, "PARENT", 6))
+ && ((strlen(ExpName) == 6) || ((ExpName[6] >= '0') && (ExpName[6] <= '9'))))
+ {
+ Depth = (strlen(ExpName) == 6) ? 1 : ExpName[6] - AscOfs;
+ SLauf = SectionStack;
+ *Erg = MomSectionHandle;
+ while ((Depth > 0) && (*Erg != -2))
+ {
+ if (!SLauf) *Erg = -2;
+ else
+ {
+ *Erg = SLauf->Handle;
+ SLauf = SLauf->Next;
+ }
+ Depth--;
+ }
+ if (*Erg == -2)
+ {
+ WrError(ErrNum_InvSection);
+ return False;
+ }
+ else
+ return True;
+ }
+ else if (!strcmp(ExpName, GetSectionName(MomSectionHandle)))
+ {
+ *Erg = MomSectionHandle;
+ return True;
+ }
+ else
+ {
+ SLauf = SectionStack;
+ while ((SLauf) && (strcmp(GetSectionName(SLauf->Handle), ExpName)))
+ SLauf = SLauf->Next;
+ if (!SLauf)
+ {
+ WrError(ErrNum_InvSection);
+ return False;
+ }
+ else
+ {
+ *Erg = SLauf->Handle;
+ return True;
+ }
+ }
+}
+
+static Boolean GetSymSection(char *Name, LongInt *Erg, const tStrComp *pUnexpComp)
+{
+ String Part;
+ tStrComp TmpComp;
+ char *q;
+ int l = strlen(Name);
+
+ if (!l || (Name[l - 1] != ']'))
+ {
+ *Erg = -2;
+ return True;
+ }
+
+ Name[l - 1] = '\0';
+ q = RQuotPos(Name, '[');
+ Name[l - 1] = ']';
+ if (Name + l - q <= 1)
+ {
+ if (pUnexpComp)
+ WrStrErrorPos(ErrNum_InvSymName, pUnexpComp);
+ else
+ WrXError(ErrNum_InvSymName, Name);
+ return False;
+ }
+
+ Name[l - 1] = '\0';
+ strmaxcpy(Part, q + 1, STRINGSIZE);
+ *q = '\0';
+
+ StrCompMkTemp(&TmpComp, Part, sizeof(Part));
+ return IdentifySection(&TmpComp, Erg);
+}
+
+/*****************************************************************************
+ * Function: ConstIntVal
+ * Purpose: evaluate integer constant
+ * Result: integer value
+ *****************************************************************************/
+
+static LargeInt ConstIntVal(const char *pExpr, IntType Typ, Boolean *pResult)
+{
+ LargeInt Wert;
+ Boolean NegFlag = False;
+ int Digit;
+ tIntCheckCtx Ctx;
+ const tIntFormatList *pIntFormat;
+
+ /* empty string is interpreted as 0 */
+
+ if (!*pExpr)
+ {
+ *pResult = True;
+ return 0;
+ }
+
+ *pResult = False;
+
+ /* sign: */
+
+ switch (*pExpr)
+ {
+ case '-':
+ NegFlag = True;
+ /* else fall-through */
+ case '+':
+ pExpr++;
+ break;
+ }
+ Ctx.pExpr = pExpr;
+ Ctx.ExprLen = strlen(pExpr);
+ Ctx.Base = -1;
+
+ for (pIntFormat = IntFormatList; pIntFormat->Check; pIntFormat++)
+ if (pIntFormat->Check(&Ctx, pIntFormat->Ch))
+ {
+ Ctx.Base = (pIntFormat->Base > 0) ? pIntFormat->Base : RadixBase;
+ break;
+ }
+ if (Ctx.Base <= 0)
+ return -1;
+
+ /* we may have decremented Ctx.ExprLen, so do not run until string end */
+
+ Wert = 0;
+ while (Ctx.ExprLen > 0)
+ {
+ Digit = DigitVal(as_toupper(*Ctx.pExpr), Ctx.Base);
+ if (Digit == -1)
+ return -1;
+ Wert = Wert * Ctx.Base + Digit;
+ Ctx.pExpr++; Ctx.ExprLen--;
+ }
+
+ if (NegFlag)
+ Wert = -Wert;
+
+ /* post-processing, range check */
+
+ *pResult = RangeCheck(Wert, Typ);
+ if (*pResult)
+ return Wert;
+ else if (HardRanges)
+ {
+ WrError(ErrNum_OverRange);
+ return -1;
+ }
+ else
+ {
+ *pResult = True;
+ WrError(ErrNum_WOverRange);
+ return Wert & IntTypeDefs[(int)Typ].Mask;
+ }
+}
+
+/*****************************************************************************
+ * Function: ConstFloatVal
+ * Purpose: evaluate floating point constant
+ * Result: value
+ *****************************************************************************/
+
+static Double ConstFloatVal(const char *pExpr, FloatType Typ, Boolean *pResult)
+{
+ Double Erg;
+ char *pEnd;
+
+ UNUSED(Typ);
+
+ if (*pExpr)
+ {
+ /* Some strtod() implementations interpret hex constants starting with '0x'. We
+ don't want this here. Either 0x for hex constants is allowed, then it should
+ have been parsed before by ConstIntVal(), or not, then we don't want the constant
+ be stored as float. */
+
+ if ((strlen(pExpr) >= 2)
+ && (pExpr[0] == '0')
+ && (toupper(pExpr[1]) == 'X'))
+ {
+ Erg = 0;
+ *pResult = False;
+ }
+
+ else
+ {
+ Erg = strtod(pExpr, &pEnd);
+ *pResult = (*pEnd == '\0');
+ }
+ }
+ else
+ {
+ Erg = 0.0;
+ *pResult = True;
+ }
+ return Erg;
+}
+
+/*****************************************************************************
+ * Function: ConstStringVal
+ * Purpose: evaluate string constant
+ * Result: value
+ *****************************************************************************/
+
+static void ConstStringVal(const tStrComp *pExpr, TempResult *pDest, Boolean *pResult)
+{
+ tStrComp Raw, Copy, Remainder;
+ char *pPos, QuoteChar;
+ int l, TLen;
+
+ *pResult = False;
+
+ l = strlen(pExpr->str.p_str);
+ if (l < 2)
+ return;
+ switch (*pExpr->str.p_str)
+ {
+ case '"':
+ case '\'':
+ QuoteChar = *pExpr->str.p_str;
+ if (pExpr->str.p_str[l - 1] == QuoteChar)
+ {
+ if ('\'' == QuoteChar)
+ pDest->Flags |= eSymbolFlag_StringSingleQuoted;
+ break;
+ }
+ /* conditional fall-through */
+ default:
+ return;
+ }
+
+ StrCompAlloc(&Raw, STRINGSIZE);
+ StrCompCopySub(&Raw, pExpr, 1, l - 2);
+ /* use LEAVE from now on instead of return */
+
+ /* go through source */
+
+ as_tempres_set_c_str(pDest, "");
+ StrCompRefRight(&Copy, &Raw, 0);
+ while (1)
+ {
+ pPos = strchr(Copy.str.p_str, '\\');
+ if (pPos)
+ StrCompSplitRef(&Copy, &Remainder, &Copy, pPos);
+
+ /* " before \ -> not a simple string but something like "...." ... " */
+
+ if (strchr(Copy.str.p_str, QuoteChar))
+ {
+ as_tempres_set_none(pDest);
+ LEAVE;
+ }
+
+ /* copy part up to next '\' verbatim: */
+
+ as_nonz_dynstr_append_raw(&pDest->Contents.str, Copy.str.p_str, strlen(Copy.str.p_str));
+
+ /* are we done? If not, advance pointer to behind '\' */
+
+ if (!pPos)
+ break;
+ Copy = Remainder;
+
+ /* treat escaped section: stringification? */
+
+ if (*Copy.str.p_str == '{')
+ {
+ TempResult t;
+ char *pStr;
+ String Str;
+ Boolean OK = True;
+
+ as_tempres_ini(&t);
+ StrCompIncRefLeft(&Copy, 1);
+
+ /* cut out part in {...} */
+
+ pPos = QuotPos(Copy.str.p_str, '}');
+ if (!pPos)
+ {
+ OK = False;
+ LEAVE2;
+ }
+ StrCompSplitRef(&Copy, &Remainder, &Copy, pPos);
+ KillPrefBlanksStrCompRef(&Copy);
+ KillPostBlanksStrComp(&Copy);
+
+ /* evaluate expression */
+
+ EvalStrExpression(&Copy, &t);
+ if (t.Relocs)
+ {
+ WrStrErrorPos(ErrNum_NoRelocs, &Copy);
+ FreeRelocs(&t.Relocs);
+ as_tempres_set_none(&t);
+ }
+
+ /* append result */
+
+ switch (t.Typ)
+ {
+ case TempInt:
+ TLen = SysString(Str, sizeof(Str), t.Contents.Int, OutRadixBase, 0, False, HexStartCharacter, SplitByteCharacter);
+ pStr = Str;
+ break;
+ case TempFloat:
+ FloatString(Str, sizeof(Str), t.Contents.Float);
+ pStr = Str;
+ TLen = strlen(pStr);
+ break;
+ case TempString:
+ pStr = t.Contents.str.p_str;
+ TLen = t.Contents.str.len;
+ break;
+ default:
+ *pResult = True;
+ OK = False;
+ }
+ if (OK)
+ {
+ as_nonz_dynstr_append_raw(&pDest->Contents.str, pStr, TLen);
+ pDest->Flags |= t.Flags & eSymbolFlags_Promotable;
+ }
+
+ /* advance source pointer to behind '}' */
+
+ Copy = Remainder;
+
+ func_exit2:
+ as_tempres_free(&t);
+ if (!OK)
+ {
+ as_tempres_set_none(pDest);
+ LEAVE;
+ }
+ }
+
+ /* simple character escape: */
+
+ else
+ {
+ char Res, *pNext = Copy.str.p_str;
+
+ if (!ProcessBk(&pNext, &Res))
+ {
+ as_tempres_set_none(pDest);
+ LEAVE;
+ }
+ as_nonz_dynstr_append_raw(&pDest->Contents.str, &Res, 1);
+ StrCompIncRefLeft(&Copy, pNext - Copy.str.p_str);
+ }
+ }
+
+ *pResult = True;
+func_exit:
+ StrCompFree(&Raw);
+}
+
+
+static PSymbolEntry FindLocNode(
+#ifdef __PROTOS__
+const char *Name, TempType SearchType
+#endif
+);
+
+static PSymbolEntry FindNode(
+#ifdef __PROTOS__
+const char *Name, TempType SearchType
+#endif
+);
+
+/*!------------------------------------------------------------------------
+ * \fn EvalResultClear(tEvalResult *pResult)
+ * \brief reset all elements of EvalResult
+ * ------------------------------------------------------------------------ */
+
+void EvalResultClear(tEvalResult *pResult)
+{
+ pResult->OK = False;
+ pResult->Flags = eSymbolFlag_None;
+ pResult->AddrSpaceMask = 0;
+ pResult->DataSize = eSymbolSizeUnknown;
+}
+
+/*****************************************************************************
+ * Function: EvalStrExpression
+ * Purpose: evaluate expression
+ * Result: implicitly in pErg
+ *****************************************************************************/
+
+#define LEAVE goto func_exit
+
+static tErrorNum DeduceExpectTypeErrMsgMask(unsigned Mask, TempType ActType)
+{
+ switch (ActType)
+ {
+ case TempInt:
+ switch (Mask)
+ {
+ case TempString:
+ return ErrNum_StringButInt;
+ /* int is convertible to float, so combinations are impossible: */
+ case TempFloat:
+ case TempFloat | TempString:
+ default:
+ return ErrNum_InternalError;
+ }
+ case TempFloat:
+ switch (Mask)
+ {
+ case TempInt:
+ return ErrNum_IntButFloat;
+ case TempString:
+ return ErrNum_StringButFloat;
+ case TempInt | TempString:
+ return ErrNum_StringOrIntButFloat;
+ default:
+ return ErrNum_InternalError;
+ }
+ case TempString:
+ switch (Mask)
+ {
+ case TempInt:
+ return ErrNum_IntButString;
+ case TempFloat:
+ return ErrNum_FloatButString;
+ case TempInt | TempFloat:
+ return ErrNum_IntOrFloatButString;
+ default:
+ return ErrNum_InternalError;
+ }
+ case TempReg:
+ switch (Mask)
+ {
+ case TempInt:
+ return ErrNum_ExpectInt;
+ case TempString:
+ return ErrNum_ExpectString;
+ case TempInt | TempString:
+ return ErrNum_ExpectIntOrString;
+ case TempInt | TempFloat | TempString:
+ return ErrNum_StringOrIntOrFloatButReg;
+ default:
+ return ErrNum_InternalError;
+ }
+ default:
+ return ErrNum_InternalError;
+ }
+}
+
+static Byte GetOpTypeMask(Byte TotMask, int OpIndex)
+{
+ return (TotMask >> (OpIndex * 4)) & 15;
+}
+
+static Byte TryConvert(Byte TypeMask, TempType ActType, int OpIndex)
+{
+ if (TypeMask & ActType)
+ return 0 << (4 * OpIndex);
+ if ((TypeMask & TempFloat) && (ActType == TempInt))
+ return 1 << (4 * OpIndex);
+ if ((TypeMask & TempInt) && (ActType == TempString))
+ return 2 << (4 * OpIndex);
+ if ((TypeMask & TempFloat) && (ActType == TempString))
+ return (1|2) << (4 * OpIndex);
+ return 255;
+}
+
+void EvalStrExpression(const tStrComp *pExpr, TempResult *pErg)
+{
+ const Operator *pOp;
+ const Operator *FOps[OPERATOR_MAXCNT];
+ LongInt FOpCnt = 0;
+
+ Boolean OK;
+ tStrComp InArgs[3];
+ TempResult InVals[3];
+ int z1, cnt;
+ char Save = '\0';
+ sint LKlamm, RKlamm, WKlamm, zop;
+ sint OpMax, OpPos = -1;
+ Boolean InSgl, InDbl, NextEscaped, ThisEscaped;
+ PFunction ValFunc;
+ tStrComp CopyComp, STempComp;
+ char *KlPos, *zp, *pOpPos;
+ const tFunction *pFunction;
+ PRelocEntry TReloc;
+ tSymbolFlags PromotedFlags;
+ unsigned PromotedAddrSpaceMask;
+ tSymbolSize PromotedDataSize;
+
+ ChkStack();
+
+ for (z1 = 0; z1 < 3; z1++)
+ as_tempres_ini(&InVals[z1]);
+ StrCompAlloc(&CopyComp, STRINGSIZE);
+ StrCompAlloc(&STempComp, STRINGSIZE);
+
+ if (MakeDebug)
+ fprintf(Debug, "Parse '%s'\n", pExpr->str.p_str);
+
+ /* Annahme Fehler */
+
+ as_tempres_set_none(pErg);
+ pErg->Relocs = NULL;
+ pErg->Flags = eSymbolFlag_None;
+ pErg->AddrSpaceMask = 0;
+ pErg->DataSize = eSymbolSizeUnknown;
+
+ StrCompCopy(&CopyComp, pExpr);
+ KillPrefBlanksStrComp(&CopyComp);
+ KillPostBlanksStrComp(&CopyComp);
+
+ /* sort out local symbols like - and +++. Do it now to get them out of the
+ formula parser's way. */
+
+ ChkTmp2(CopyComp.str.p_str, CopyComp.str.p_str, e_symbol_source_none);
+ StrCompCopy(&STempComp, &CopyComp);
+
+ /* Programmzaehler ? */
+
+ if (PCSymbol && (!as_strcasecmp(CopyComp.str.p_str, PCSymbol)))
+ {
+ as_tempres_set_int(pErg, EProgCounter());
+ pErg->Relocs = NULL;
+ pErg->AddrSpaceMask |= 1 << ActPC;
+ LEAVE;
+ }
+
+ /* Konstanten ? */
+
+ pErg->Contents.Int = ConstIntVal(CopyComp.str.p_str, (IntType) (IntTypeCnt - 1), &OK);
+ if (OK)
+ {
+ pErg->Typ = TempInt;
+ pErg->Relocs = NULL;
+ LEAVE;
+ }
+
+ pErg->Contents.Float = ConstFloatVal(CopyComp.str.p_str, Float80, &OK);
+ if (OK)
+ {
+ pErg->Typ = TempFloat;
+ pErg->Relocs = NULL;
+ LEAVE;
+ }
+
+ ConstStringVal(&CopyComp, pErg, &OK);
+ if (OK)
+ {
+ pErg->Relocs = NULL;
+ LEAVE;
+ }
+
+ /* durch Codegenerator gegebene Konstanten ? */
+
+ pErg->Relocs = NULL;
+ InternSymbol(CopyComp.str.p_str, pErg);
+ if (pErg->Typ != TempNone)
+ {
+ LEAVE;
+ }
+
+ /* find out which operators *might* occur in expression */
+
+ OpMax = 0;
+ LKlamm = 0;
+ RKlamm = 0;
+ WKlamm = 0;
+ InSgl =
+ InDbl =
+ ThisEscaped =
+ NextEscaped = False;
+ for (pOp = Operators + 1; pOp->Id; pOp++)
+ {
+ pOpPos = (pOp->IdLen == 1) ? (strchr(CopyComp.str.p_str, *pOp->Id)) : (strstr(CopyComp.str.p_str, pOp->Id));
+ if (pOpPos)
+ FOps[FOpCnt++] = pOp;
+ }
+
+ /* nach Operator hoechster Rangstufe ausserhalb Klammern suchen */
+
+ for (zp = CopyComp.str.p_str; *zp; zp++, ThisEscaped = NextEscaped)
+ {
+ NextEscaped = False;
+ switch (*zp)
+ {
+ case '(':
+ if (!(InSgl || InDbl))
+ LKlamm++;
+ break;
+ case ')':
+ if (!(InSgl || InDbl))
+ RKlamm++;
+ break;
+ case '{':
+ if (!(InSgl || InDbl))
+ WKlamm++;
+ break;
+ case '}':
+ if (!(InSgl || InDbl))
+ WKlamm--;
+ break;
+ case '"':
+ if (!InSgl && !ThisEscaped)
+ InDbl = !InDbl;
+ break;
+ case '\'':
+ if (!InDbl && !ThisEscaped)
+ {
+ if (InSgl || !QualifyQuote || QualifyQuote(CopyComp.str.p_str, zp))
+ InSgl = !InSgl;
+ }
+ break;
+ case '\\':
+ if ((InDbl || InSgl) && !ThisEscaped)
+ NextEscaped = True;
+ break;
+ default:
+ if ((LKlamm == RKlamm) && (WKlamm == 0) && (!InSgl) && (!InDbl))
+ {
+ Boolean OpFnd = False;
+ sint OpLen = 0, LocOpMax = 0;
+
+ for (zop = 0; zop < FOpCnt; zop++)
+ {
+ pOp = FOps[zop];
+ if ((!strncmp(zp, pOp->Id, pOp->IdLen)) && (pOp->IdLen >= OpLen))
+ {
+ OpFnd = True;
+ OpLen = pOp->IdLen;
+ LocOpMax = pOp - Operators;
+ if (Operators[LocOpMax].Priority >= Operators[OpMax].Priority)
+ {
+ OpMax = LocOpMax;
+ OpPos = zp - CopyComp.str.p_str;
+ }
+ }
+ }
+ if (OpFnd)
+ zp += Operators[LocOpMax].IdLen - 1;
+ }
+ }
+ }
+
+ /* Klammerfehler ? */
+
+ if (LKlamm != RKlamm)
+ {
+ WrStrErrorPos(ErrNum_BrackErr, &CopyComp);
+ LEAVE;
+ }
+
+ /* Operator gefunden ? */
+
+ if (OpMax)
+ {
+ int ThisArgCnt, CompLen, z, z2;
+ Byte ThisOpMatch, BestOpMatch, BestOpMatchIdx, SumCombinations, TypeMask;
+
+ pOp = Operators + OpMax;
+
+ /* Minuszeichen sowohl mit einem als auch 2 Operanden */
+
+ if (!strcmp(pOp->Id, "-"))
+ {
+ if (!OpPos)
+ pOp = &MinusMonadicOperator;
+ }
+
+ else if (!strcmp(pOp->Id, "^"))
+ {
+ if (!OpPos && pPotMonadicOperator)
+ pOp = pPotMonadicOperator;
+ }
+
+ /* Operandenzahl pruefen */
+
+ CompLen = strlen(CopyComp.str.p_str);
+ if (CompLen <= 1)
+ ThisArgCnt = 0;
+ else if (!OpPos || (OpPos == (int)strlen(CopyComp.str.p_str) - 1))
+ ThisArgCnt = 1;
+ else
+ ThisArgCnt = 2;
+ if (!ChkArgCntExtPos(ThisArgCnt, pOp->Dyadic ? 2 : 1, pOp->Dyadic ? 2 : 1, &CopyComp.Pos))
+ LEAVE;
+
+ /* Teilausdruecke rekursiv auswerten */
+
+ Save = StrCompSplitRef(&InArgs[0], &InArgs[1], &CopyComp, CopyComp.str.p_str + OpPos);
+ StrCompIncRefLeft(&InArgs[1], strlen(pOp->Id) - 1);
+ EvalStrExpression(&InArgs[1], &InVals[1]);
+ if (pOp->Dyadic)
+ EvalStrExpression(&InArgs[0], &InVals[0]);
+ else if (InVals[1].Typ == TempFloat)
+ as_tempres_set_float(&InVals[0], 0.0);
+ else
+ {
+ as_tempres_set_int(&InVals[0], 0);
+ InVals[0].Relocs = NULL;
+ }
+ CopyComp.str.p_str[OpPos] = Save;
+
+ /* Abbruch, falls dabei Fehler */
+
+ if ((InVals[0].Typ == TempNone) || (InVals[1].Typ == TempNone))
+ LEAVE;
+
+ /* relokatible Symbole nur fuer + und - erlaubt */
+
+ if ((OpMax != 12) && (OpMax != 13) && (InVals[0].Relocs || InVals[1].Relocs))
+ {
+ WrStrErrorPos(ErrNum_NoRelocs, &CopyComp);
+ LEAVE;
+ }
+
+ /* see whether data types match operator's restrictions: */
+
+ BestOpMatch = 255; BestOpMatchIdx = OPERATOR_MAXCOMB;
+ SumCombinations = 0;
+ for (z = 0; z < OPERATOR_MAXCOMB; z++)
+ {
+ if (!pOp->TypeCombinations[z])
+ break;
+ SumCombinations |= pOp->TypeCombinations[z];
+
+ ThisOpMatch = 0;
+ for (z2 = pOp->Dyadic ? 0 : 1; z2 < 2; z2++)
+ ThisOpMatch |= TryConvert(GetOpTypeMask(pOp->TypeCombinations[z], z2), InVals[z2].Typ, z2);
+ if (ThisOpMatch < BestOpMatch)
+ {
+ BestOpMatch = ThisOpMatch;
+ BestOpMatchIdx = z;
+ }
+ if (!BestOpMatch)
+ break;
+ }
+
+ /* did not find a way to satisfy restrictions, even by conversions? */
+
+ if (BestOpMatch >= 255)
+ {
+ for (z2 = pOp->Dyadic ? 0 : 1; z2 < 2; z2++)
+ {
+ TypeMask = GetOpTypeMask(SumCombinations, z2);
+ if (!(TypeMask & InVals[z2].Typ))
+ WrStrErrorPos(DeduceExpectTypeErrMsgMask(TypeMask, InVals[z2].Typ), &InArgs[z2]);
+ }
+ LEAVE;
+ }
+
+ /* necessary conversions: */
+
+ for (z2 = pOp->Dyadic ? 0 : 1; z2 < 2; z2++)
+ {
+ TypeMask = (BestOpMatch >> (z2 * 4)) & 15;
+ if (TypeMask & 2) /* String -> Int */
+ TempResultToInt(&InVals[z2]);
+ if (TypeMask & 1) /* Int -> Float */
+ TempResultToFloat(&InVals[z2]);
+ }
+
+ /* actual operation */
+
+ (void)BestOpMatchIdx;
+ pOp->pFunc(pErg, &InVals[0], &InVals[1]);
+ LEAVE;
+ } /* if (OpMax) */
+
+ /* kein Operator gefunden: Klammerausdruck ? */
+
+ if (LKlamm != 0)
+ {
+ tStrComp FName, FArg, Remainder;
+
+ /* erste Klammer suchen, Funktionsnamen abtrennen */
+
+ KlPos = strchr(CopyComp.str.p_str, '(');
+
+ /* Funktionsnamen abschneiden */
+
+ StrCompSplitRef(&FName, &FArg, &CopyComp, KlPos);
+ StrCompShorten(&FArg, 1);
+ KillPostBlanksStrComp(&FName);
+
+ /* Nullfunktion: nur Argument */
+
+ if (*FName.str.p_str == '\0')
+ {
+ EvalStrExpression(&FArg, pErg);
+ LEAVE;
+ }
+
+ /* selbstdefinierte Funktion ? */
+
+ ValFunc = FindFunction(FName.str.p_str);
+ if (ValFunc)
+ {
+ as_dynstr_t CompArgStr;
+ tStrComp CompArg;
+ as_dynstr_t stemp;
+
+ PromotedFlags = eSymbolFlag_None;
+ PromotedAddrSpaceMask = 0;
+ PromotedDataSize = eSymbolSizeUnknown;
+ as_dynstr_ini_c_str(&CompArgStr, ValFunc->Definition);
+ as_dynstr_ini(&stemp, STRINGSIZE);
+ for (z1 = 1; z1 <= ValFunc->ArguCnt; z1++)
+ {
+ if (!*FArg.str.p_str)
+ {
+ WrError(ErrNum_InvFuncArgCnt);
+ LEAVE2;
+ }
+
+ KlPos = QuotPos(FArg.str.p_str, ',');
+ if (KlPos)
+ StrCompSplitRef(&FArg, &Remainder, &FArg, KlPos);
+
+ EvalStrExpression(&FArg, &InVals[0]);
+ if (InVals[0].Relocs)
+ {
+ WrStrErrorPos(ErrNum_NoRelocs, &FArg);
+ FreeRelocs(&InVals[0].Relocs);
+ LEAVE2;
+ }
+ PromotedFlags |= InVals[0].Flags & eSymbolFlags_Promotable;
+ PromotedAddrSpaceMask |= InVals[0].AddrSpaceMask;
+ if (PromotedDataSize == eSymbolSizeUnknown) PromotedDataSize = InVals[0].DataSize;
+
+ if (KlPos)
+ FArg = Remainder;
+ else
+ StrCompReset(&FArg);
+
+ as_sdprintf(&stemp, "(");
+ if (as_tempres_append_dynstr(&stemp, &InVals[0]))
+ LEAVE2;
+ as_sdprcatf(&stemp, ")");
+ ExpandLine(stemp.p_str, z1, &CompArgStr);
+ }
+ if (*FArg.str.p_str)
+ {
+ WrError(ErrNum_InvFuncArgCnt);
+ LEAVE2;
+ }
+ StrCompMkTemp(&CompArg, CompArgStr.p_str, CompArgStr.capacity);
+ EvalStrExpression(&CompArg, pErg);
+ pErg->Flags |= PromotedFlags;
+ pErg->AddrSpaceMask |= PromotedAddrSpaceMask;
+ if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = PromotedDataSize;
+func_exit2:
+ as_dynstr_free(&stemp);
+ as_dynstr_free(&CompArgStr);
+ LEAVE;
+ }
+
+ /* hier einmal umwandeln ist effizienter */
+
+ NLS_UpString(FName.str.p_str);
+
+ /* symbolbezogene Funktionen */
+
+ if (!strcmp(FName.str.p_str, "SYMTYPE"))
+ {
+ as_tempres_set_int(pErg, GetSymbolType(&FArg));
+ LEAVE;
+ }
+
+ else if (!strcmp(FName.str.p_str, "DEFINED"))
+ {
+ as_tempres_set_int(pErg, !!IsSymbolDefined(&FArg));
+ LEAVE;
+ }
+
+ else if (!strcmp(FName.str.p_str, "ASSUMEDVAL"))
+ {
+ unsigned IdxAssume;
+
+ for (IdxAssume = 0; IdxAssume < ASSUMERecCnt; IdxAssume++)
+ if (!as_strcasecmp(FArg.str.p_str, pASSUMERecs[IdxAssume].Name))
+ {
+ as_tempres_set_int(pErg, *(pASSUMERecs[IdxAssume].Dest));
+ LEAVE;
+ }
+ WrStrErrorPos(ErrNum_SymbolUndef, &FArg);
+ LEAVE;
+ }
+
+ /* Unterausdruck auswerten (interne Funktionen maxmimal mit drei Argumenten) */
+
+ cnt = 0;
+ PromotedFlags = eSymbolFlag_None;
+ PromotedAddrSpaceMask = 0;
+ PromotedDataSize = eSymbolSizeUnknown;
+ do
+ {
+ zp = QuotPos(FArg.str.p_str, ',');
+ if (zp)
+ StrCompSplitRef(&InArgs[cnt], &Remainder, &FArg, zp);
+ else
+ InArgs[cnt] = FArg;
+ if (cnt < 3)
+ {
+ EvalStrExpression(&InArgs[cnt], &InVals[cnt]);
+ if (InVals[cnt].Typ == TempNone)
+ LEAVE;
+ TReloc = InVals[cnt].Relocs;
+ }
+ else
+ {
+ WrError(ErrNum_InvFuncArgCnt);
+ LEAVE;
+ }
+ if (TReloc)
+ {
+ WrStrErrorPos(ErrNum_NoRelocs, &InArgs[cnt]);
+ FreeRelocs(&TReloc);
+ LEAVE;
+ }
+ if (zp)
+ FArg = Remainder;
+ PromotedFlags |= InVals[cnt].Flags & eSymbolFlags_Promotable;
+ PromotedAddrSpaceMask |= InVals[cnt].AddrSpaceMask;
+ if (PromotedDataSize == eSymbolSizeUnknown) PromotedDataSize = InVals[0].DataSize;
+ cnt++;
+ }
+ while (zp);
+
+ /* search function */
+
+ for (pFunction = Functions; pFunction->pName; pFunction++)
+ if (!strcmp(FName.str.p_str, pFunction->pName))
+ break;
+ if (!pFunction->pName)
+ {
+ WrStrErrorPos(ErrNum_UnknownFunc, &FName);
+ LEAVE;
+ }
+
+ /* argument checking */
+
+ if ((cnt < pFunction->MinNumArgs) || (cnt > pFunction->MaxNumArgs))
+ {
+ WrError(ErrNum_InvFuncArgCnt);
+ LEAVE;
+ }
+ for (z1 = 0; z1 < cnt; z1++)
+ {
+ if ((InVals[z1].Typ == TempInt) && (!(pFunction->ArgTypes[z1] & (1 << TempInt))))
+ TempResultToFloat(&InVals[z1]);
+ if (!(pFunction->ArgTypes[z1] & (1 << InVals[z1].Typ)))
+ {
+ WrStrErrorPos(DeduceExpectTypeErrMsgMask(pFunction->ArgTypes[z1], InVals[z1].Typ), &InArgs[z1]);
+ LEAVE;
+ }
+ }
+ pFunction->pFunc(pErg, InVals, cnt);
+ pErg->Flags |= PromotedFlags;
+ pErg->AddrSpaceMask |= PromotedAddrSpaceMask;
+ if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = PromotedDataSize;
+
+ LEAVE;
+ }
+
+ /* nichts dergleichen, dann einfaches Symbol: urspruenglichen Wert wieder
+ herstellen, dann Pruefung auf $$-temporaere Symbole */
+
+ StrCompCopy(&CopyComp, &STempComp);
+ KillPrefBlanksStrComp(&CopyComp);
+ KillPostBlanksStrComp(&CopyComp);
+
+ ChkTmp1(CopyComp.str.p_str, e_symbol_source_none);
+
+ /* interne Symbole ? */
+
+ if (!as_strcasecmp(CopyComp.str.p_str, "MOMFILE"))
+ {
+ as_tempres_set_c_str(pErg, CurrFileName);
+ LEAVE;
+ }
+
+ if (!as_strcasecmp(CopyComp.str.p_str, "MOMLINE"))
+ {
+ as_tempres_set_int(pErg, CurrLine);
+ LEAVE;
+ }
+
+ if (!as_strcasecmp(CopyComp.str.p_str, "MOMPASS"))
+ {
+ as_tempres_set_int(pErg, PassNo);
+ LEAVE;
+ }
+
+ if (!as_strcasecmp(CopyComp.str.p_str, "MOMSECTION"))
+ {
+ as_tempres_set_c_str(pErg, GetSectionName(MomSectionHandle));
+ LEAVE;
+ }
+
+ if (!as_strcasecmp(CopyComp.str.p_str, "MOMSEGMENT"))
+ {
+ as_tempres_set_c_str(pErg, SegNames[ActPC]);
+ LEAVE;
+ }
+
+ /* plain symbol */
+
+ LookupSymbol(&CopyComp, pErg, True, TempAll);
+
+func_exit:
+
+ StrCompFree(&CopyComp);
+ StrCompFree(&STempComp);
+
+ for (z1 = 0; z1 < 3; z1++)
+ {
+ if (InVals[z1].Relocs)
+ FreeRelocs(&InVals[z1].Relocs);
+ as_tempres_free(&InVals[z1]);
+ }
+}
+
+void EvalExpression(const char *pExpr, TempResult *pErg)
+{
+ tStrComp Expr;
+
+ StrCompMkTemp(&Expr, (char*)pExpr, 0);
+ EvalStrExpression(&Expr, pErg);
+}
+
+LargeInt EvalStrIntExpressionWithResult(const tStrComp *pComp, IntType Type, tEvalResult *pResult)
+{
+ TempResult t;
+ LargeInt Result = -1;
+
+ as_tempres_ini(&t);
+ EvalResultClear(pResult);
+
+ EvalStrExpression(pComp, &t);
+ SetRelocs(t.Relocs);
+
+ switch (t.Typ)
+ {
+ case TempInt:
+ Result = t.Contents.Int;
+ pResult->Flags = t.Flags;
+ pResult->AddrSpaceMask = t.AddrSpaceMask;
+ pResult->DataSize = t.DataSize;
+ break;
+ case TempString:
+ {
+ int l = t.Contents.str.len;
+
+ if ((l > 0) && (l <= 4))
+ {
+ char *pRun;
+ Byte Digit;
+
+ Result = 0;
+ for (pRun = t.Contents.str.p_str;
+ pRun < t.Contents.str.p_str + l;
+ pRun++)
+ {
+ Digit = (usint) *pRun;
+ Result = (Result << 8) | CharTransTable[Digit & 0xff];
+ }
+ pResult->Flags = t.Flags;
+ pResult->AddrSpaceMask = t.AddrSpaceMask;
+ pResult->DataSize = t.DataSize;
+ break;
+ }
+ else
+ {
+ WrStrErrorPos(ErrNum_IntButString, pComp);
+ FreeRelocs(&LastRelocs);
+ LEAVE;
+ }
+ }
+ /* else fall-through */
+ default:
+ if (t.Typ != TempNone)
+ WrStrErrorPos(DeduceExpectTypeErrMsgMask(TempInt | TempString, t.Typ), pComp);
+ FreeRelocs(&LastRelocs);
+ LEAVE;
+ }
+
+ if (mFirstPassUnknown(t.Flags))
+ Result &= IntTypeDefs[(int)Type].Mask;
+
+ pResult->OK = HardRanges ? ChkRangeByType(Result, Type, pComp) : ChkRangeWarnByType(Result, Type, pComp);
+ if (!pResult->OK)
+ {
+ if (HardRanges)
+ {
+ FreeRelocs(&LastRelocs);
+ Result = -1;
+ LEAVE;
+ }
+ else
+ {
+ pResult->OK = True;
+ Result &= IntTypeDefs[(int)Type].Mask;
+ }
+ }
+
+func_exit:
+ as_tempres_free(&t);
+ return Result;
+}
+
+LargeInt EvalStrIntExpressionWithFlags(const tStrComp *pComp, IntType Type, Boolean *pResult, tSymbolFlags *pFlags)
+{
+ tEvalResult EvalResult;
+ LargeInt Result = EvalStrIntExpressionWithResult(pComp, Type, &EvalResult);
+
+ *pResult = EvalResult.OK;
+ if (pFlags)
+ *pFlags = EvalResult.Flags;
+ return Result;
+}
+
+LargeInt EvalStrIntExpression(const tStrComp *pComp, IntType Type, Boolean *pResult)
+{
+ tEvalResult EvalResult;
+ LargeInt Result = EvalStrIntExpressionWithResult(pComp, Type, &EvalResult);
+
+ *pResult = EvalResult.OK;
+ return Result;
+}
+
+LargeInt EvalStrIntExpressionOffsWithResult(const tStrComp *pExpr, int Offset, IntType Type, tEvalResult *pResult)
+{
+ if (Offset)
+ {
+ tStrComp Comp;
+
+ StrCompRefRight(&Comp, pExpr, Offset);
+ return EvalStrIntExpressionWithResult(&Comp, Type, pResult);
+ }
+ else
+ return EvalStrIntExpressionWithResult(pExpr, Type, pResult);
+}
+
+LargeInt EvalStrIntExpressionOffsWithFlags(const tStrComp *pComp, int Offset, IntType Type, Boolean *pResult, tSymbolFlags *pFlags)
+{
+ tEvalResult EvalResult;
+ LargeInt Result = EvalStrIntExpressionOffsWithResult(pComp, Offset, Type, &EvalResult);
+
+ *pResult = EvalResult.OK;
+ if (pFlags)
+ *pFlags = EvalResult.Flags;
+ return Result;
+}
+
+LargeInt EvalStrIntExpressionOffs(const tStrComp *pComp, int Offset, IntType Type, Boolean *pResult)
+{
+ tEvalResult EvalResult;
+ LargeInt Result = EvalStrIntExpressionOffsWithResult(pComp, Offset, Type, &EvalResult);
+
+ *pResult = EvalResult.OK;
+ return Result;
+}
+
+Double EvalStrFloatExpressionWithResult(const tStrComp *pExpr, FloatType Type, tEvalResult *pResult)
+{
+ TempResult t;
+ Double Result = -1;
+
+ as_tempres_ini(&t);
+ EvalResultClear(pResult);
+
+ EvalStrExpression(pExpr, &t);
+ switch (t.Typ)
+ {
+ case TempNone:
+ LEAVE;
+ case TempInt:
+ Result = t.Contents.Int;
+ pResult->Flags = t.Flags;
+ pResult->AddrSpaceMask = t.AddrSpaceMask;
+ pResult->DataSize = t.DataSize;
+ break;
+ case TempString:
+ {
+ WrStrErrorPos(ErrNum_FloatButString, pExpr);
+ LEAVE;
+ }
+ default:
+ Result = t.Contents.Float;
+ }
+
+ if (!FloatRangeCheck(Result, Type))
+ {
+ WrStrErrorPos(ErrNum_OverRange, pExpr);
+ LEAVE;
+ }
+
+ pResult->OK = True;
+func_exit:
+ as_tempres_free(&t);
+ return Result;
+}
+
+Double EvalStrFloatExpression(const tStrComp *pExpr, FloatType Type, Boolean *pResult)
+{
+ Double Ret;
+ tEvalResult Result;
+
+ Ret = EvalStrFloatExpressionWithResult(pExpr, Type, &Result);
+ *pResult = Result.OK;
+ return Ret;
+}
+
+void EvalStrStringExpressionWithResult(const tStrComp *pExpr, tEvalResult *pResult, char *pEvalResult)
+{
+ TempResult t;
+
+ as_tempres_ini(&t);
+ EvalResultClear(pResult);
+
+ EvalStrExpression(pExpr, &t);
+ if (t.Typ != TempString)
+ {
+ *pEvalResult = '\0';
+ if (t.Typ != TempNone)
+ {
+ if (mFirstPassUnknown(t.Flags))
+ {
+ *pEvalResult = '\0';
+ pResult->Flags = t.Flags;
+ pResult->AddrSpaceMask = t.AddrSpaceMask;
+ pResult->DataSize = t.DataSize;
+ pResult->OK = True;
+ }
+ else
+ WrStrErrorPos(DeduceExpectTypeErrMsgMask(TempString, t.Typ), pExpr);
+ }
+ }
+ else
+ {
+ as_nonz_dynstr_to_c_str(pEvalResult, &t.Contents.str, STRINGSIZE);
+ pResult->Flags = t.Flags;
+ pResult->AddrSpaceMask = t.AddrSpaceMask;
+ pResult->DataSize = t.DataSize;
+ pResult->OK = True;
+ }
+ as_tempres_free(&t);
+}
+
+void EvalStrStringExpression(const tStrComp *pExpr, Boolean *pResult, char *pEvalResult)
+{
+ tEvalResult Result;
+
+ EvalStrStringExpressionWithResult(pExpr, &Result, pEvalResult);
+ *pResult = Result.OK;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EvalStrRegExpressionWithResult(const struct sStrComp *pExpr, struct sRegDescr *pResult, struct sEvalResult *pEvalResult, Boolean IssueErrors)
+ * \brief retrieve/evaluate register expression
+ * \param pExpr source code expression
+ * \param pResult retrieved register
+ * \param pEvalResult success flag, symbol size & flags
+ * \param IssueErrors print errors at all?
+ * \return occured error
+ * ------------------------------------------------------------------------ */
+
+PSymbolEntry ExpandAndFindNode(const struct sStrComp *pComp, TempType SearchType)
+{
+ PSymbolEntry pEntry;
+ String ExpName;
+ const char *pKlPos;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pComp))
+ return NULL;
+
+ /* just [...] without symbol name itself is not valid */
+
+ pKlPos = strchr(ExpName, '[');
+ if ((pKlPos == ExpName) || (ChkSymbNameUpTo(ExpName, pKlPos) != pKlPos))
+ return NULL;
+
+ pEntry = FindLocNode(ExpName, SearchType);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, SearchType);
+ return pEntry;
+}
+
+tErrorNum EvalStrRegExpressionWithResult(const struct sStrComp *pExpr, tRegDescr *pResult, tEvalResult *pEvalResult)
+{
+ PSymbolEntry pEntry;
+
+ EvalResultClear(pEvalResult);
+
+ pEntry = ExpandAndFindNode(pExpr, TempReg);
+ if (!pEntry)
+ return ErrNum_SymbolUndef;
+
+ pEntry->Used = True;
+ pEvalResult->DataSize = pEntry->SymWert.DataSize;
+
+ if (pEntry->SymWert.Typ != TempReg)
+ return ErrNum_ExpectReg;
+ *pResult = pEntry->SymWert.Contents.RegDescr;
+
+ if (pEntry->SymWert.Contents.RegDescr.Dissect != DissectReg)
+ return ErrNum_RegWrongTarget;
+
+ pEvalResult->OK = True;
+ return ErrNum_None;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EvalStrRegExpressionAsOperand(const tStrComp *pArg, struct sRegDescr *pResult, struct sEvalResult *pEvalResult, tSymbolSize ReqSize, Boolean MustBeReg)
+ * \brief check for possible register in instruction operand
+ * \param pArg source argument
+ * \param ReqSize possible fixed operand size
+ * \param MustBeReg operand cannot be anything else but register
+ * \return eIsReg: argument is a register
+ eIsNoReg: argument is no register
+ eRegAbort: argument is faulty, abort anyway (only if !MustBeReg)
+ * ------------------------------------------------------------------------ */
+
+tRegEvalResult EvalStrRegExpressionAsOperand(const tStrComp *pArg, struct sRegDescr *pResult, struct sEvalResult *pEvalResult, tSymbolSize ReqSize, Boolean MustBeReg)
+{
+ tErrorNum ErrorNum;
+
+ ErrorNum = EvalStrRegExpressionWithResult(pArg, pResult, pEvalResult);
+ if (pEvalResult->OK && (ReqSize != eSymbolSizeUnknown) && (pEvalResult->DataSize != ReqSize))
+ {
+ pEvalResult->OK = False;
+ ErrorNum = ErrNum_InvOpSize;
+ }
+ switch (ErrorNum)
+ {
+ case ErrNum_None:
+ return eIsReg;
+ case ErrNum_SymbolUndef:
+ if (MustBeReg)
+ {
+ if (PassNo <= MaxSymPass)
+ {
+ pResult->Reg = 0;
+ pResult->Dissect = NULL;
+ Repass = True;
+ return eIsReg;
+ }
+ else
+ {
+ WrStrErrorPos(ErrNum_InvReg, pArg);
+ return eIsNoReg;
+ }
+ }
+ else
+ return eIsNoReg;
+ case ErrNum_ExpectReg:
+ if (MustBeReg)
+ WrStrErrorPos(ErrorNum, pArg);
+ return eIsNoReg;
+ default:
+ WrStrErrorPos(ErrorNum, pArg);
+ return MustBeReg ? eIsNoReg : eRegAbort;
+ }
+}
+
+static void FreeSymbolEntry(PSymbolEntry *Node, Boolean Destroy)
+{
+ PCrossRef Lauf;
+
+ if ((*Node)->Tree.Name)
+ {
+ free((*Node)->Tree.Name);
+ (*Node)->Tree.Name = NULL;
+ }
+
+ as_tempres_free(&(*Node)->SymWert);
+
+ while ((*Node)->RefList)
+ {
+ Lauf = (*Node)->RefList->Next;
+ free((*Node)->RefList);
+ (*Node)->RefList = Lauf;
+ }
+
+ FreeRelocs(&((*Node)->SymWert.Relocs));
+
+ if (Destroy)
+ {
+ free(*Node);
+ Node = NULL;
+ }
+}
+
+static char *serr, *snum;
+typedef struct
+{
+ Boolean MayChange, DoCross;
+} TEnterStruct, *PEnterStruct;
+
+static Boolean SymbolAdder(PTree *PDest, PTree Neu, void *pData)
+{
+ PSymbolEntry NewEntry = (PSymbolEntry)Neu, *Node;
+ PEnterStruct EnterStruct = (PEnterStruct) pData;
+
+ /* added to an empty leaf ? */
+
+ if (!PDest)
+ {
+ NewEntry->Defined = True;
+ NewEntry->Used = False;
+ NewEntry->Changeable = EnterStruct->MayChange;
+ NewEntry->RefList = NULL;
+ if (EnterStruct->DoCross)
+ {
+ NewEntry->FileNum = GetFileNum(CurrFileName);
+ NewEntry->LineNum = CurrLine;
+ }
+ return True;
+ }
+
+ /* replace en entry: check for validity */
+
+ Node = (PSymbolEntry*)PDest;
+
+ /* tried to redefine a symbol with EQU ? */
+
+ if (((*Node)->Defined) && (!(*Node)->Changeable) && (!EnterStruct->MayChange))
+ {
+ strmaxcpy(serr, (*Node)->Tree.Name, STRINGSIZE);
+ if (EnterStruct->DoCross)
+ as_snprcatf(serr, STRINGSIZE, ",%s %s:%ld",
+ getmessage(Num_PrevDefMsg),
+ GetFileName((*Node)->FileNum), (long)((*Node)->LineNum));
+ WrXError(ErrNum_DoubleDef, serr);
+ FreeSymbolEntry(&NewEntry, TRUE);
+ return False;
+ }
+
+ /* tried to reassign a constant (EQU) a value with SET and vice versa ? */
+
+ else if ( ((*Node)->Defined) && (EnterStruct->MayChange != (*Node)->Changeable) )
+ {
+ strmaxcpy(serr, (*Node)->Tree.Name, STRINGSIZE);
+ if (EnterStruct->DoCross)
+ as_snprcatf(serr, STRINGSIZE, ",%s %s:%ld",
+ getmessage(Num_PrevDefMsg),
+ GetFileName((*Node)->FileNum), (long)((*Node)->LineNum));
+ WrXError((*Node)->Changeable ? ErrNum_VariableRedefinedAsConstant : ErrNum_ConstantRedefinedAsVariable, serr);
+ FreeSymbolEntry(&NewEntry, TRUE);
+ return False;
+ }
+
+ else
+ {
+ if (!EnterStruct->MayChange)
+ {
+ Boolean value_changed;
+
+#if 0
+ if (NewEntry->SymWert.Typ == TempInt)
+ fprintf(stderr, "NewEntry 0x%lx Node 0x%lx Node changed %d\n",
+ NewEntry->SymWert.Contents.Int, (*Node)->SymWert.Contents.Int, (*Node)->changed);
+#endif
+
+ /* If the symbol value was changed after entry (padding of label),
+ compare to the originally set value, because this is what we get
+ here as initial value to set (before padding) in the next pass: */
+
+ if (NewEntry->SymWert.Typ != (*Node)->SymWert.Typ)
+ value_changed = True;
+ else switch (NewEntry->SymWert.Typ)
+ {
+ case TempInt:
+ value_changed = NewEntry->SymWert.Contents.Int != ((*Node)->changed ? (*Node)->unchanged_value : (*Node)->SymWert.Contents.Int);
+ break;
+ default:
+ value_changed = !!as_tempres_cmp(&NewEntry->SymWert, &(*Node)->SymWert);
+ }
+ if (value_changed)
+ {
+ if (!Repass && (JmpErrors > 0))
+ {
+ if (ThrowErrors)
+ ErrorCount -= JmpErrors;
+ JmpErrors = 0;
+ }
+ Repass = True;
+ if (MsgIfRepass && (PassNo >= PassNoForMessage))
+ {
+ strmaxcpy(serr, Neu->Name, STRINGSIZE);
+ if (Neu->Attribute != -1)
+ {
+ strmaxcat(serr, "[", STRINGSIZE);
+ strmaxcat(serr, GetSectionName(Neu->Attribute), STRINGSIZE);
+ strmaxcat(serr, "]", STRINGSIZE);
+ }
+ WrXError(ErrNum_PhaseErr, serr);
+ }
+ }
+ }
+ if (EnterStruct->DoCross)
+ {
+ NewEntry->LineNum = (*Node)->LineNum;
+ NewEntry->FileNum = (*Node)->FileNum;
+ }
+
+ /* take over values from existing node that shall be kept */
+
+ NewEntry->RefList = (*Node)->RefList;
+ (*Node)->RefList = NULL;
+ NewEntry->Defined = True;
+ NewEntry->Used = (*Node)->Used;
+ NewEntry->Changeable = EnterStruct->MayChange;
+
+ /* since NewEntry will be copied over Node, free the latter's dynamic data: */
+
+ FreeSymbolEntry(Node, False);
+ return True;
+ }
+}
+
+static void EnterLocSymbol(PSymbolEntry Neu)
+{
+ TEnterStruct EnterStruct;
+ PTree TreeRoot;
+
+ Neu->Tree.Attribute = MomLocHandle;
+ if (!CaseSensitive)
+ NLS_UpString(Neu->Tree.Name);
+ EnterStruct.MayChange = EnterStruct.DoCross = FALSE;
+ TreeRoot = &FirstLocSymbol->Tree;
+ EnterTree(&TreeRoot, (&Neu->Tree), SymbolAdder, &EnterStruct);
+ FirstLocSymbol = (PSymbolEntry)TreeRoot;
+}
+
+static void EnterSymbol_Search(PForwardSymbol *Lauf, PForwardSymbol *Prev,
+ PForwardSymbol **RRoot, PSymbolEntry Neu,
+ PForwardSymbol *Root, Byte ResCode, Byte *SearchErg)
+{
+ *Lauf = (*Root);
+ *Prev = NULL;
+ *RRoot = Root;
+ while ((*Lauf) && (strcmp((*Lauf)->Name, Neu->Tree.Name)))
+ {
+ *Prev = (*Lauf);
+ *Lauf = (*Lauf)->Next;
+ }
+ if (*Lauf)
+ *SearchErg = ResCode;
+}
+
+static void EnterSymbol(PSymbolEntry Neu, Boolean MayChange, LongInt ResHandle)
+{
+ PForwardSymbol Lauf, Prev;
+ PForwardSymbol *RRoot;
+ Byte SearchErg;
+ String CombName;
+ PSaveSection RunSect;
+ LongInt MSect;
+ PSymbolEntry Copy;
+ TEnterStruct EnterStruct;
+ PTree TreeRoot = &(FirstSymbol->Tree);
+
+ if (!CaseSensitive)
+ NLS_UpString(Neu->Tree.Name);
+
+ SearchErg = 0;
+ EnterStruct.MayChange = MayChange;
+ EnterStruct.DoCross = MakeCrossList;
+ Neu->Tree.Attribute = (ResHandle == -2) ? MomSectionHandle : ResHandle;
+ if ((SectionStack) && (Neu->Tree.Attribute == MomSectionHandle))
+ {
+ EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu, &(SectionStack->LocSyms),
+ 1, &SearchErg);
+ if (!Lauf)
+ EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu,
+ &(SectionStack->GlobSyms), 2, &SearchErg);
+ if (!Lauf)
+ EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu,
+ &(SectionStack->ExportSyms), 3, &SearchErg);
+ if (SearchErg == 2)
+ Neu->Tree.Attribute = Lauf->DestSection;
+ if (SearchErg == 3)
+ {
+ strmaxcpy(CombName, Neu->Tree.Name, STRINGSIZE);
+ RunSect = SectionStack;
+ MSect = MomSectionHandle;
+ while ((MSect != Lauf->DestSection) && (RunSect))
+ {
+ strmaxprep(CombName, "_", STRINGSIZE);
+ strmaxprep(CombName, GetSectionName(MSect), STRINGSIZE);
+ MSect = RunSect->Handle;
+ RunSect = RunSect->Next;
+ }
+ Copy = (PSymbolEntry) calloc(1, sizeof(TSymbolEntry));
+ *Copy = (*Neu);
+ Copy->Tree.Name = as_strdup(CombName);
+ Copy->Tree.Attribute = Lauf->DestSection;
+ Copy->SymWert.Relocs = DupRelocs(Neu->SymWert.Relocs);
+ if (Copy->SymWert.Typ == TempString)
+ {
+ size_t l = Neu->SymWert.Contents.str.len;
+ Copy->SymWert.Contents.str.p_str = (char*)malloc(l);
+ memcpy(Copy->SymWert.Contents.str.p_str, Neu->SymWert.Contents.str.p_str,
+ Copy->SymWert.Contents.str.len = Copy->SymWert.Contents.str.capacity = l);
+ }
+ EnterTree(&TreeRoot, &(Copy->Tree), SymbolAdder, &EnterStruct);
+ }
+ if (Lauf)
+ {
+ free(Lauf->Name);
+ free(Lauf->pErrorPos);
+ if (!Prev)
+ *RRoot = Lauf->Next;
+ else
+ Prev->Next = Lauf->Next;
+ free(Lauf);
+ }
+ }
+ EnterTree(&TreeRoot, &(Neu->Tree), SymbolAdder, &EnterStruct);
+ FirstSymbol = (PSymbolEntry)TreeRoot;
+}
+
+void PrintSymTree(char *Name)
+{
+ fprintf(Debug, "---------------------\n");
+ fprintf(Debug, "Enter Symbol %s\n\n", Name);
+ PrintSymbolTree();
+ PrintSymbolDepth();
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChangeSymbol(PSymbolEntry pEntry, LargeInt Value)
+ * \brief change value of symbol in symbol table (use with caution)
+ * \param pEntry symbol entry to modify
+ * \param Value new (integer)value
+ * ------------------------------------------------------------------------ */
+
+void ChangeSymbol(PSymbolEntry pEntry, LargeInt Value)
+{
+ if (!pEntry->changed)
+ {
+ pEntry->unchanged_value = (pEntry->SymWert.Typ == TempInt) ? pEntry->SymWert.Contents.Int : 0;
+ pEntry->changed = True;
+ }
+ as_tempres_set_int(&pEntry->SymWert, Value);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn CreateSymbolEntry(const tStrComp *pName, LongInt *pDestHandle, tSymbolFlags symbol_flags)
+ * \brief create empty container for symbol tabl eentry
+ * \param pName unexpanded symbol name
+ * \param pDestHandle section handle (out)
+ * \param symbol_flags symbol flags
+ * \return * to container or NULL
+ * ------------------------------------------------------------------------ */
+
+PSymbolEntry CreateSymbolEntry(const tStrComp *pName, LongInt *pDestHandle, tSymbolFlags symbol_flags)
+{
+ PSymbolEntry pNeu;
+ String ExtName;
+
+ if (!ExpandStrSymbol(ExtName, sizeof(ExtName), pName))
+ return NULL;
+ if (!GetSymSection(ExtName, pDestHandle, pName))
+ return NULL;
+ (void)ChkTmp(ExtName, (symbol_flags & eSymbolFlag_Label) ? e_symbol_source_label : e_symbol_source_define);
+ if (!ChkSymbName(ExtName))
+ {
+ WrStrErrorPos(ErrNum_InvSymName, pName);
+ return NULL;
+ }
+ pNeu = (PSymbolEntry) calloc(1, sizeof(TSymbolEntry));
+ pNeu->Tree.Name = as_strdup(ExtName);
+ as_tempres_ini(&pNeu->SymWert);
+ return pNeu;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EnterIntSymbolWithFlags(const tStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange, tSymbolFlags Flags)
+ * \brief add integer symbol to symbol table
+ * \param pName unexpanded name
+ * \param Wert integer value
+ * \param addrspace symbol's address space
+ * \param MayChange constant or variable?
+ * \param Flags additional flags
+ * \return * to newly created entry in tree
+ * ------------------------------------------------------------------------ */
+
+PSymbolEntry EnterIntSymbolWithFlags(const tStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange, tSymbolFlags Flags)
+{
+ LongInt DestHandle;
+ PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle, Flags);
+
+ if (!pNeu)
+ return NULL;
+
+ as_tempres_set_int(&pNeu->SymWert, Wert);
+ pNeu->SymWert.AddrSpaceMask = (addrspace != SegNone) ? 1 << addrspace : 0;
+ pNeu->SymWert.Flags = Flags;
+ pNeu->SymWert.DataSize = eSymbolSizeUnknown;
+ pNeu->RefList = NULL;
+ pNeu->SymWert.Relocs = NULL;
+
+ if ((MomLocHandle == -1) || (DestHandle != -2))
+ {
+ EnterSymbol(pNeu, MayChange, DestHandle);
+ if (MakeDebug)
+ PrintSymTree(pNeu->Tree.Name);
+ }
+ else
+ EnterLocSymbol(pNeu);
+ return pNeu;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EnterExtSymbol(const tStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange)
+ * \brief create extended symbol
+ * \param pName unexpanded name
+ * \param Wert symbol value
+ * \param AddrSpace symbol's address space
+ * \param MayChange variable or constant?
+ * ------------------------------------------------------------------------ */
+
+void EnterExtSymbol(const tStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange)
+{
+ LongInt DestHandle;
+ PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle, eSymbolFlag_None);
+
+ if (!pNeu)
+ return;
+
+ as_tempres_set_int(&pNeu->SymWert, Wert);
+ pNeu->SymWert.AddrSpaceMask = (addrspace != SegNone) ? 1 << addrspace : 0;
+ pNeu->SymWert.Flags = eSymbolFlag_None;
+ pNeu->SymWert.DataSize = eSymbolSizeUnknown;
+ pNeu->RefList = NULL;
+ pNeu->SymWert.Relocs = (PRelocEntry) malloc(sizeof(TRelocEntry));
+ pNeu->SymWert.Relocs->Next = NULL;
+ pNeu->SymWert.Relocs->Ref = as_strdup(pNeu->Tree.Name);
+ pNeu->SymWert.Relocs->Add = True;
+
+ if ((MomLocHandle == -1) || (DestHandle != -2))
+ {
+ EnterSymbol(pNeu, MayChange, DestHandle);
+ if (MakeDebug)
+ PrintSymTree(pNeu->Tree.Name);
+ }
+ else
+ EnterLocSymbol(pNeu);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EnterRelSymbol(const tStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange)
+ * \brief enter relocatable symbol
+ * \param pName unexpanded name
+ * \param Wert symbol value
+ * \param addrspace symbol's address space
+ * \param MayChange variable or constant?
+ * \return * to created entry in tree
+ * ------------------------------------------------------------------------ */
+
+PSymbolEntry EnterRelSymbol(const tStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange)
+{
+ LongInt DestHandle;
+ PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle, eSymbolFlag_None);
+
+ if (!pNeu)
+ return NULL;
+
+ as_tempres_set_int(&pNeu->SymWert, Wert);
+ pNeu->SymWert.AddrSpaceMask = (addrspace != SegNone) ? 1 << addrspace : 0;
+ pNeu->SymWert.Flags = eSymbolFlag_None;
+ pNeu->SymWert.DataSize = eSymbolSizeUnknown;
+ pNeu->RefList = NULL;
+ pNeu->SymWert.Relocs = (PRelocEntry) malloc(sizeof(TRelocEntry));
+ pNeu->SymWert.Relocs->Next = NULL;
+ pNeu->SymWert.Relocs->Ref = as_strdup(RelName_SegStart);
+ pNeu->SymWert.Relocs->Add = True;
+
+ if ((MomLocHandle == -1) || (DestHandle != -2))
+ {
+ EnterSymbol(pNeu, MayChange, DestHandle);
+ if (MakeDebug)
+ PrintSymTree(pNeu->Tree.Name);
+ }
+ else
+ EnterLocSymbol(pNeu);
+
+ return pNeu;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EnterFloatSymbol(const tStrComp *pName, Double Wert, Boolean MayChange)
+ * \brief enter floating point symbol
+ * \param pName unexpanded name
+ * \param Wert symbol value
+ * \param MayChange variable or constant?
+ * ------------------------------------------------------------------------ */
+
+void EnterFloatSymbol(const tStrComp *pName, Double Wert, Boolean MayChange)
+{
+ LongInt DestHandle;
+ PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle, eSymbolFlag_None);
+
+ if (!pNeu)
+ return;
+
+ as_tempres_set_float(&pNeu->SymWert, Wert);
+ pNeu->SymWert.AddrSpaceMask = 0;
+ pNeu->SymWert.Flags = eSymbolFlag_None;
+ pNeu->SymWert.DataSize = eSymbolSizeUnknown;
+ pNeu->RefList = NULL;
+ pNeu->SymWert.Relocs = NULL;
+
+ if ((MomLocHandle == -1) || (DestHandle != -2))
+ {
+ EnterSymbol(pNeu, MayChange, DestHandle);
+ if (MakeDebug)
+ PrintSymTree(pNeu->Tree.Name);
+ }
+ else
+ EnterLocSymbol(pNeu);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EnterNonZStringSymbolWithFlags(const tStrComp *pName, const as_nonz_dynstr_t *p_value, Boolean MayChange, tSymbolFlags Flags)
+ * \brief enter string symbol
+ * \param pName unexpanded name
+ * \param pValue symbol value
+ * \param MayChange variable or constant?
+ * \param Flags special symbol flags to store
+ * ------------------------------------------------------------------------ */
+
+void EnterNonZStringSymbolWithFlags(const tStrComp *pName, const as_nonz_dynstr_t *p_value, Boolean MayChange, tSymbolFlags Flags)
+{
+ LongInt DestHandle;
+ PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle, Flags);
+
+ if (!pNeu)
+ return;
+
+ /* TODO: TempRes alloc exact len */
+ pNeu->SymWert.Contents.str.p_str = (char*)malloc(p_value->len);
+ memcpy(pNeu->SymWert.Contents.str.p_str, p_value->p_str, p_value->len);
+ pNeu->SymWert.Contents.str.len =
+ pNeu->SymWert.Contents.str.capacity = p_value->len;
+ pNeu->SymWert.Typ = TempString;
+ pNeu->SymWert.AddrSpaceMask = 0;
+ pNeu->SymWert.Flags = Flags;
+ pNeu->SymWert.DataSize = eSymbolSizeUnknown;
+ pNeu->RefList = NULL;
+ pNeu->SymWert.Relocs = NULL;
+
+ if ((MomLocHandle == -1) || (DestHandle != -2))
+ {
+ EnterSymbol(pNeu, MayChange, DestHandle);
+ if (MakeDebug)
+ PrintSymTree(pNeu->Tree.Name);
+ }
+ else
+ EnterLocSymbol(pNeu);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EnterStringSymbol(const tStrComp *pName, const char *pValue, Boolean MayChange)
+ * \brief enter string symbol
+ * \param pName unexpanded name
+ * \param pValue symbol value
+ * \param MayChange variable or constant?
+ * ------------------------------------------------------------------------ */
+
+void EnterStringSymbol(const tStrComp *pName, const char *pValue, Boolean MayChange)
+{
+ as_nonz_dynstr_t NonZString;
+
+ as_nonz_dynstr_ini_c_str(&NonZString, pValue);
+ EnterNonZStringSymbol(pName, &NonZString, MayChange);
+ as_nonz_dynstr_free(&NonZString);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn EnterRegSymbol(const struct sStrComp *pName, const tRegDescr *pDescr, tSymbolSize Size, Boolean MayChange, Boolean AddList)
+ * \brief enter register symbol
+ * \param pName unexpanded name
+ * \param pDescr register's numeric value & associated dissector
+ * \param Size register's data size
+ * \param MayChange variable or constant?
+ * \param AddList add value to listing?
+ * ------------------------------------------------------------------------ */
+
+void EnterRegSymbol(const struct sStrComp *pName, const tRegDescr *pDescr, tSymbolSize Size, Boolean MayChange, Boolean AddList)
+{
+ LongInt DestHandle;
+ PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle, eSymbolFlag_None);
+
+ if (!pNeu)
+ return;
+
+ as_tempres_set_reg(&pNeu->SymWert, pDescr);
+ pNeu->SymWert.AddrSpaceMask = 0;
+ pNeu->SymWert.Flags = eSymbolFlag_None;
+ pNeu->SymWert.DataSize = Size;
+ pNeu->RefList = NULL;
+ pNeu->SymWert.Relocs = NULL;
+
+ if ((MomLocHandle == -1) || (DestHandle != -2))
+ {
+ EnterSymbol(pNeu, MayChange, DestHandle);
+ if (MakeDebug)
+ PrintSymTree(pNeu->Tree.Name);
+ RegistersDefined = True;
+ }
+ else
+ EnterLocSymbol(pNeu);
+
+ if (AddList)
+ {
+ *ListLine = '=';
+ pDescr->Dissect(&ListLine[1], STRINGSIZE - 1, pDescr->Reg, Size);
+ }
+}
+
+static void AddReference(PSymbolEntry Node)
+{
+ PCrossRef Lauf, Neu;
+
+ /* Speicher belegen */
+
+ Neu = (PCrossRef) malloc(sizeof(TCrossRef));
+ Neu->LineNum = CurrLine;
+ Neu->OccNum = 1;
+ Neu->Next = NULL;
+
+ /* passende Datei heraussuchen */
+
+ Neu->FileNum = GetFileNum(CurrFileName);
+
+ /* suchen, ob Eintrag schon existiert */
+
+ Lauf = Node->RefList;
+ while ((Lauf)
+ && ((Lauf->FileNum != Neu->FileNum) || (Lauf->LineNum != Neu->LineNum)))
+ Lauf = Lauf->Next;
+
+ /* schon einmal in dieser Datei in dieser Zeile aufgetaucht: nur Zaehler
+ rauf: */
+
+ if (Lauf)
+ {
+ Lauf->OccNum++;
+ free(Neu);
+ }
+
+ /* ansonsten an Kettenende anhaengen */
+
+ else if (!Node->RefList) Node->RefList = Neu;
+
+ else
+ {
+ Lauf = Node->RefList;
+ while (Lauf->Next)
+ Lauf = Lauf->Next;
+ Lauf->Next = Neu;
+ }
+}
+
+static PSymbolEntry FindNode_FNode(char *Name, TempType SearchType, LongInt Handle)
+{
+ PSymbolEntry Lauf;
+
+ Lauf = (PSymbolEntry) SearchTree((PTree)FirstSymbol, Name, Handle);
+
+ if (Lauf)
+ {
+ if (Lauf->SymWert.Typ & SearchType)
+ {
+ if (MakeCrossList && DoRefs)
+ AddReference(Lauf);
+ }
+ else
+ Lauf = NULL;
+ }
+
+ return Lauf;
+}
+
+static Boolean FindNode_FSpec(char *Name, PForwardSymbol Root)
+{
+ while ((Root) && (strcmp(Root->Name, Name)))
+ Root = Root->Next;
+ return (Root != NULL);
+}
+
+static PSymbolEntry FindNode(const char *Name_O, TempType SearchType)
+{
+ PSaveSection Lauf;
+ LongInt DestSection;
+ PSymbolEntry Result = NULL;
+ String Name;
+
+ strmaxcpy(Name, Name_O, STRINGSIZE);
+ ChkTmp3(Name, e_symbol_source_none);
+
+ /* TODO: pass StrComp */
+ if (!GetSymSection(Name, &DestSection, NULL))
+ return NULL;
+
+ if (!CaseSensitive)
+ NLS_UpString(Name);
+
+ if (SectionStack)
+ if (PassNo <= MaxSymPass)
+ if (FindNode_FSpec(Name, SectionStack->LocSyms)) DestSection = MomSectionHandle;
+
+ if (DestSection == -2)
+ {
+ Result = FindNode_FNode(Name, SearchType, MomSectionHandle);
+ if (Result)
+ return Result;
+ Lauf = SectionStack;
+ while (Lauf)
+ {
+ Result = FindNode_FNode(Name, SearchType, Lauf->Handle);
+ if (Result)
+ break;
+ Lauf = Lauf->Next;
+ }
+ }
+ else
+ Result = FindNode_FNode(Name, SearchType, DestSection);
+
+ return Result;
+}
+
+static PSymbolEntry FindLocNode_FNode(char *Name, TempType SearchType, LongInt Handle)
+{
+ PSymbolEntry Lauf;
+
+ Lauf = (PSymbolEntry) SearchTree((PTree)FirstLocSymbol, Name, Handle);
+
+ if (Lauf)
+ {
+ if (!(Lauf->SymWert.Typ & SearchType))
+ Lauf = NULL;
+ }
+
+ return Lauf;
+}
+
+static PSymbolEntry FindLocNode(const char *Name_O, TempType SearchType)
+{
+ PLocHandle RunLocHandle;
+ PSymbolEntry Result = NULL;
+ String Name;
+
+ strmaxcpy(Name, Name_O, STRINGSIZE);
+ ChkTmp3(Name, e_symbol_source_none);
+ if (!CaseSensitive)
+ NLS_UpString(Name);
+
+ if (MomLocHandle == -1)
+ return NULL;
+
+ Result = FindLocNode_FNode(Name, SearchType, MomLocHandle);
+ if (Result)
+ return Result;
+
+ RunLocHandle = FirstLocHandle;
+ while ((RunLocHandle) && (RunLocHandle->Cont != -1))
+ {
+ Result = FindLocNode_FNode(Name, SearchType, RunLocHandle->Cont);
+ if (Result)
+ break;
+ RunLocHandle = RunLocHandle->Next;
+ }
+
+ return Result;
+}
+/**
+void SetSymbolType(const tStrComp *pName, Byte NTyp)
+{
+ PSymbolEntry Lauf;
+ Boolean HRef;
+ String ExpName;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return;
+ HRef = DoRefs;
+ DoRefs = False;
+ Lauf = FindLocNode(ExpName, TempInt);
+ if (!Lauf)
+ Lauf = FindNode(ExpName, TempInt);
+ if (Lauf)
+ Lauf->SymType = NTyp;
+ DoRefs = HRef;
+}
+**/
+
+void LookupSymbol(const struct sStrComp *pComp, TempResult *pValue, Boolean WantRelocs, TempType ReqType)
+{
+ PSymbolEntry pEntry;
+ String ExpName;
+ const char *pKlPos;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pComp))
+ {
+ pValue->Typ = TempNone;
+ return;
+ }
+
+ pKlPos = strchr(ExpName, '[');
+ if (ChkSymbNameUpTo(ExpName, pKlPos) != pKlPos)
+ {
+ WrStrErrorPos(ErrNum_InvSymName, pComp);
+ pValue->Typ = TempNone;
+ return;
+ }
+
+ pEntry = FindLocNode(ExpName, ReqType);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, ReqType);
+ if (pEntry)
+ {
+ as_tempres_copy_value(pValue, &pEntry->SymWert);
+ if (pValue->Typ != TempNone)
+ {
+ if (WantRelocs)
+ pValue->Relocs = DupRelocs(pEntry->SymWert.Relocs);
+ pValue->Flags = pEntry->SymWert.Flags;
+ }
+ pValue->AddrSpaceMask = pEntry->SymWert.AddrSpaceMask;
+ if ((pEntry->SymWert.DataSize != eSymbolSizeUnknown) && (pValue->DataSize == eSymbolSizeUnknown))
+ pValue->DataSize = pEntry->SymWert.DataSize;
+ if (!pEntry->Defined)
+ {
+ if (Repass)
+ pValue->Flags |= eSymbolFlag_Questionable;
+ pValue->Flags |= eSymbolFlag_UsesForwards;
+ }
+ pEntry->Used = True;
+ }
+
+ /* Symbol evtl. im ersten Pass unbekannt */
+
+ else if (PassNo <= MaxSymPass) /* !pEntry */
+ {
+ as_tempres_set_int(pValue, EProgCounter());
+ Repass = True;
+ if ((MsgIfRepass) && (PassNo >= PassNoForMessage))
+ WrStrErrorPos(ErrNum_RepassUnknown, pComp);
+ pValue->Flags |= eSymbolFlag_FirstPassUnknown;
+ }
+ else
+ WrStrErrorPos(ErrNum_SymbolUndef, pComp);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn SetSymbolOrStructElemSize(const struct sStrComp *pName, tSymbolSize Size)
+ * \brief set (integer) data size associated with a symbol
+ * \param pName unexpanded name of symbol
+ * \param Size operand size to set
+ * ------------------------------------------------------------------------ */
+
+void SetSymbolOrStructElemSize(const struct sStrComp *pName, tSymbolSize Size)
+{
+ if (pInnermostNamedStruct)
+ SetStructElemSize(pInnermostNamedStruct->StructRec, pName->str.p_str, Size);
+ else
+ {
+ PSymbolEntry pEntry;
+ Boolean HRef;
+ String ExpName;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return;
+ HRef = DoRefs;
+ DoRefs = False;
+ pEntry = FindLocNode(ExpName, TempInt);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, TempInt);
+ if (pEntry)
+ pEntry->SymWert.DataSize = Size;
+ DoRefs = HRef;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GetSymbolSize(const struct sStrComp *pName)
+ * \brief get symbol's integer size
+ * \param pName unexpanded symbol name
+ * \return symbol size or -1 if symbol does not exist
+ * ------------------------------------------------------------------------ */
+
+ShortInt GetSymbolSize(const struct sStrComp *pName)
+{
+ PSymbolEntry pEntry;
+ String ExpName;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return -1;
+ pEntry = FindLocNode(ExpName, TempInt);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, TempInt);
+ return pEntry ? pEntry->SymWert.DataSize : eSymbolSizeUnknown;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn IsSymbolDefined(const struct sStrComp *pName)
+ * \brief check whether symbol nas been used so far
+ * \param pName unexpanded symbol name
+ * \return true if symbol exists and has been defined so far
+ * ------------------------------------------------------------------------ */
+
+Boolean IsSymbolDefined(const struct sStrComp *pName)
+{
+ PSymbolEntry pEntry;
+ String ExpName;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return False;
+
+ pEntry = FindLocNode(ExpName, TempAll);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, TempAll);
+ return pEntry && pEntry->Defined;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn IsSymbolUsed(const struct sStrComp *pName)
+ * \brief check whether symbol nas been used so far
+ * \param pName unexpanded symbol name
+ * \return true if symbol exists and has been used
+ * ------------------------------------------------------------------------ */
+
+Boolean IsSymbolUsed(const struct sStrComp *pName)
+{
+ PSymbolEntry pEntry;
+ String ExpName;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return False;
+
+ pEntry = FindLocNode(ExpName, TempAll);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, TempAll);
+ return pEntry && pEntry->Used;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn IsSymbolChangeable(const struct sStrComp *pName)
+ * \brief check whether symbol's value may be changed or is constant
+ * \param pName unexpanded symbol name
+ * \return true if symbol exists and is changeable
+ * ------------------------------------------------------------------------ */
+
+Boolean IsSymbolChangeable(const struct sStrComp *pName)
+{
+ PSymbolEntry pEntry;
+ String ExpName;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return False;
+
+ pEntry = FindLocNode(ExpName, TempAll);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, TempAll);
+ return pEntry && pEntry->Changeable;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GetSymbolType(const struct sStrComp *pName)
+ * \brief retrieve type (int/float/string) of symbol
+ * \param pName unexpanded name
+ * \return type or -1 if non-existent
+ * ------------------------------------------------------------------------ */
+
+as_addrspace_t addrspace_from_mask(unsigned mask)
+{
+ as_addrspace_t space;
+
+ for (space = SegCode; space < SegCount; space++)
+ if (mask & (1 << space))
+ return space;
+ return SegNone;
+}
+
+Integer GetSymbolType(const struct sStrComp *pName)
+{
+ PSymbolEntry pEntry;
+ String ExpName;
+
+ if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
+ return -1;
+
+ pEntry = FindLocNode(ExpName, TempAll);
+ if (!pEntry)
+ pEntry = FindNode(ExpName, TempAll);
+
+ if (!pEntry)
+ return -1;
+ else if (pEntry->SymWert.Typ == TempReg)
+ return 0x80;
+ else
+ return addrspace_from_mask(pEntry->SymWert.AddrSpaceMask);
+}
+
+typedef struct
+{
+ int Width, cwidth;
+ LongInt Sum, USum;
+ as_dynstr_t Zeilenrest;
+ int ZeilenrestLen,
+ ZeilenrestVisibleLen;
+ as_dynstr_t s1, sh;
+} TListContext;
+
+static void PrintSymbolList_AddOut(char *s, TListContext *pContext)
+{
+ int AddVisibleLen = visible_strlen(s),
+ AddLen = strlen(s);
+
+ if (AddVisibleLen + pContext->ZeilenrestVisibleLen > pContext->Width)
+ {
+ pContext->Zeilenrest.p_str[pContext->ZeilenrestLen - 1] = '\0';
+ WrLstLine(pContext->Zeilenrest.p_str);
+ as_dynstr_copy_c_str(&pContext->Zeilenrest, s);
+ pContext->ZeilenrestLen = AddLen;
+ pContext->ZeilenrestVisibleLen = AddVisibleLen;
+ }
+ else
+ {
+ as_dynstr_append_c_str(&pContext->Zeilenrest, s);
+ pContext->ZeilenrestLen += AddLen;
+ pContext->ZeilenrestVisibleLen += AddVisibleLen;
+ }
+}
+
+static void PrintSymbolList_PNode(PTree Tree, void *pData)
+{
+ PSymbolEntry Node = (PSymbolEntry) Tree;
+
+ if (Node->SymWert.Typ != TempReg)
+ {
+ TListContext *pContext = (TListContext*) pData;
+ int l1, nBlanks;
+ const TempResult *pValue = &Node->SymWert;
+
+ if ((pValue->Typ == TempInt) && DissectBit && (pValue->AddrSpaceMask & (1 << SegBData)))
+ DissectBit(pContext->s1.p_str, pContext->s1.capacity, pValue->Contents.Int);
+ else
+ StrSym(pValue, False, &pContext->s1, ListRadixBase);
+
+ as_sdprintf(&pContext->sh, "%c%s : ", Node->Used ? ' ' : '*', Tree->Name);
+ if (Tree->Attribute != -1)
+ as_sdprcatf(&pContext->sh, " [%s]", GetSectionName(Tree->Attribute));
+ l1 = (strlen(pContext->s1.p_str) + visible_strlen(pContext->sh.p_str) + 4);
+ for (nBlanks = pContext->cwidth - 1 - l1; nBlanks < 0; nBlanks += pContext->cwidth);
+ as_sdprcatf(&pContext->sh, "%s%s %c | ", Blanks(nBlanks), pContext->s1.p_str, SegShorts[addrspace_from_mask(pValue->AddrSpaceMask)]);
+ PrintSymbolList_AddOut(pContext->sh.p_str, pContext);
+ pContext->Sum++;
+ if (!Node->Used)
+ pContext->USum++;
+ }
+}
+
+void PrintSymbolList(void)
+{
+ int ActPageWidth;
+ TListContext Context;
+
+ as_dynstr_ini(&Context.Zeilenrest, STRINGSIZE);
+ as_dynstr_ini(&Context.s1, STRINGSIZE);
+ as_dynstr_ini(&Context.sh, STRINGSIZE);
+ Context.Width = (PageWidth == 0) ? 80 : PageWidth;
+ NewPage(ChapDepth, True);
+ WrLstLine(getmessage(Num_ListSymListHead1));
+ WrLstLine(getmessage(Num_ListSymListHead2));
+ WrLstLine("");
+
+ Context.ZeilenrestLen =
+ Context.ZeilenrestVisibleLen = 0;
+ Context.Sum = Context.USum = 0;
+ ActPageWidth = (PageWidth == 0) ? 80 : PageWidth;
+ Context.cwidth = ActPageWidth >> 1;
+ IterTree((PTree)FirstSymbol, PrintSymbolList_PNode, &Context);
+ if (Context.Zeilenrest.p_str[0] != '\0')
+ {
+ Context.Zeilenrest.p_str[strlen(Context.Zeilenrest.p_str) - 1] = '\0';
+ WrLstLine(Context.Zeilenrest.p_str);
+ }
+ WrLstLine("");
+ as_sdprintf(&Context.Zeilenrest, "%7lu%s",
+ (unsigned long)Context.Sum,
+ getmessage((Context.Sum == 1) ? Num_ListSymSumMsg : Num_ListSymSumsMsg));
+ WrLstLine(Context.Zeilenrest.p_str);
+ as_sdprintf(&Context.Zeilenrest, "%7lu%s",
+ (unsigned long)Context.USum,
+ getmessage((Context.USum == 1) ? Num_ListUSymSumMsg : Num_ListUSymSumsMsg));
+ WrLstLine(Context.Zeilenrest.p_str);
+ WrLstLine("");
+ as_dynstr_free(&Context.s1);
+ as_dynstr_free(&Context.sh);
+ as_dynstr_free(&Context.Zeilenrest);
+}
+
+typedef struct
+{
+ FILE *f;
+ Boolean HWritten;
+ as_addrspace_t Space;
+ as_dynstr_t s;
+} TDebContext;
+
+static Boolean match_space_mask(unsigned mask, as_addrspace_t space)
+{
+ if (SegNone == space)
+ return !mask;
+ else
+ return !!((mask >> space) & 1);
+}
+
+static void PrintDebSymbols_PNode(PTree Tree, void *pData)
+{
+ PSymbolEntry Node = (PSymbolEntry) Tree;
+ TDebContext *DebContext = (TDebContext*) pData;
+ int l1;
+
+ if (!match_space_mask(Node->SymWert.AddrSpaceMask, DebContext->Space))
+ return;
+
+ if (!DebContext->HWritten)
+ {
+ fprintf(DebContext->f, "\n"); ChkIO(ErrNum_FileWriteError);
+ fprintf(DebContext->f, "Symbols in Segment %s\n", SegNames[DebContext->Space]); ChkIO(ErrNum_FileWriteError);
+ DebContext->HWritten = True;
+ }
+
+ fprintf(DebContext->f, "%s", Node->Tree.Name); ChkIO(ErrNum_FileWriteError);
+ l1 = strlen(Node->Tree.Name);
+ if (Node->Tree.Attribute != -1)
+ {
+ as_sdprintf(&DebContext->s, "[%d]", (int)Node->Tree.Attribute);
+ fprintf(DebContext->f, "%s", DebContext->s.p_str); ChkIO(ErrNum_FileWriteError);
+ l1 += strlen(DebContext->s.p_str);
+ }
+ fprintf(DebContext->f, "%s ", Blanks(37 - l1)); ChkIO(ErrNum_FileWriteError);
+ switch (Node->SymWert.Typ)
+ {
+ case TempInt:
+ fprintf(DebContext->f, "Int ");
+ break;
+ case TempFloat:
+ fprintf(DebContext->f, "Float ");
+ break;
+ case TempString:
+ fprintf(DebContext->f, "String ");
+ break;
+ default:
+ break;
+ }
+ ChkIO(ErrNum_FileWriteError);
+ if (Node->SymWert.Typ == TempString)
+ {
+ errno = 0;
+ l1 = fstrlenprint(DebContext->f, Node->SymWert.Contents.str.p_str, Node->SymWert.Contents.str.len);
+ ChkIO(ErrNum_FileWriteError);
+ }
+ else
+ {
+ StrSym(&Node->SymWert, False, &DebContext->s, 16);
+ l1 = strlen(DebContext->s.p_str);
+ fprintf(DebContext->f, "%s", DebContext->s.p_str); ChkIO(ErrNum_FileWriteError);
+ }
+ fprintf(DebContext->f, "%s %-3d %d %d\n", Blanks(25 - l1), Node->SymWert.DataSize, (int)Node->Used, (int)Node->Changeable);
+ ChkIO(ErrNum_FileWriteError);
+}
+
+void PrintDebSymbols(FILE *f)
+{
+ TDebContext DebContext;
+
+ as_dynstr_ini(&DebContext.s, 256);
+ DebContext.f = f;
+ for (DebContext.Space = SegNone; DebContext.Space < SegCount; DebContext.Space++)
+ {
+ DebContext.HWritten = False;
+ IterTree((PTree)FirstSymbol, PrintDebSymbols_PNode, &DebContext);
+ }
+ as_dynstr_free(&DebContext.s);
+}
+
+typedef struct
+{
+ FILE *f;
+ LongInt Handle;
+} TNoISymContext;
+
+static void PrNoISection(PTree Tree, void *pData)
+{
+ PSymbolEntry Node = (PSymbolEntry)Tree;
+ TNoISymContext *pContext = (TNoISymContext*) pData;
+
+ if ((Node->SymWert.AddrSpaceMask & NoICEMask) && (Node->Tree.Attribute == pContext->Handle) && (Node->SymWert.Typ == TempInt))
+ {
+ errno = 0; fprintf(pContext->f, "DEFINE %s 0x", Node->Tree.Name); ChkIO(ErrNum_FileWriteError);
+ errno = 0; fprintf(pContext->f, LargeHIntFormat, Node->SymWert.Contents.Int); ChkIO(ErrNum_FileWriteError);
+ errno = 0; fprintf(pContext->f, "\n"); ChkIO(ErrNum_FileWriteError);
+ }
+}
+
+void PrintNoISymbols(FILE *f)
+{
+ PCToken CurrSection;
+ TNoISymContext Context;
+
+ Context.f = f;
+ Context.Handle = -1;
+ IterTree((PTree)FirstSymbol, PrNoISection, &Context);
+ Context.Handle++;
+ for (CurrSection = FirstSection; CurrSection; CurrSection = CurrSection->Next)
+ if (ChunkSum(&CurrSection->Usage)>0)
+ {
+ fprintf(f, "FUNCTION %s ", CurrSection->Name); ChkIO(ErrNum_FileWriteError);
+ fprintf(f, LargeIntFormat, ChunkMin(&CurrSection->Usage)); ChkIO(ErrNum_FileWriteError);
+ fprintf(f, "\n"); ChkIO(ErrNum_FileWriteError);
+ IterTree((PTree)FirstSymbol, PrNoISection, &Context);
+ Context.Handle++;
+ fprintf(f, "}FUNC "); ChkIO(ErrNum_FileWriteError);
+ fprintf(f, LargeIntFormat, ChunkMax(&CurrSection->Usage)); ChkIO(ErrNum_FileWriteError);
+ fprintf(f, "\n"); ChkIO(ErrNum_FileWriteError);
+ }
+}
+
+void PrintSymbolTree(void)
+{
+ DumpTree((PTree)FirstSymbol);
+}
+
+static void ClearSymbolList_ClearNode(PTree Node, void *pData)
+{
+ PSymbolEntry SymbolEntry = (PSymbolEntry) Node;
+ UNUSED(pData);
+
+ FreeSymbolEntry(&SymbolEntry, FALSE);
+}
+
+void ClearSymbolList(void)
+{
+ PTree TreeRoot;
+
+ TreeRoot = &(FirstSymbol->Tree);
+ FirstSymbol = NULL;
+ DestroyTree(&TreeRoot, ClearSymbolList_ClearNode, NULL);
+ TreeRoot = &(FirstLocSymbol->Tree);
+ FirstLocSymbol = NULL;
+ DestroyTree(&TreeRoot, ClearSymbolList_ClearNode, NULL);
+}
+
+/*-------------------------------------------------------------------------*/
+/* Stack-Verwaltung */
+
+Boolean PushSymbol(const tStrComp *pSymName, const tStrComp *pStackName)
+{
+ PSymbolEntry pSrc;
+ PSymbolStack LStack, NStack, PStack;
+ PSymbolStackEntry Elem;
+ String ExpSymName, ExpStackName;
+
+ if (!ExpandStrSymbol(ExpSymName, sizeof(ExpSymName), pSymName))
+ return False;
+
+ pSrc = FindNode(ExpSymName, TempAll);
+ if (!pSrc)
+ {
+ WrStrErrorPos(ErrNum_SymbolUndef, pSymName);
+ return False;
+ }
+
+ if (*pStackName->str.p_str)
+ {
+ if (!ExpandStrSymbol(ExpStackName, sizeof(ExpStackName), pStackName))
+ return False;
+ }
+ else
+ strmaxcpy(ExpStackName, DefStackName, STRINGSIZE);
+ if (!ChkSymbName(ExpStackName))
+ {
+ WrStrErrorPos(ErrNum_InvSymName, pStackName);
+ return False;
+ }
+
+ LStack = FirstStack;
+ PStack = NULL;
+ while ((LStack) && (strcmp(LStack->Name, ExpStackName) < 0))
+ {
+ PStack = LStack;
+ LStack = LStack->Next;
+ }
+
+ if ((!LStack) || (strcmp(LStack->Name, ExpStackName) > 0))
+ {
+ NStack = (PSymbolStack) malloc(sizeof(TSymbolStack));
+ NStack->Name = as_strdup(ExpStackName);
+ NStack->Contents = NULL;
+ NStack->Next = LStack;
+ if (!PStack)
+ FirstStack = NStack;
+ else
+ PStack->Next = NStack;
+ LStack = NStack;
+ }
+
+ Elem = (PSymbolStackEntry) malloc(sizeof(TSymbolStackEntry));
+ Elem->Next = LStack->Contents;
+ Elem->Contents = pSrc->SymWert;
+ LStack->Contents = Elem;
+
+ return True;
+}
+
+Boolean PopSymbol(const tStrComp *pSymName, const tStrComp *pStackName)
+{
+ PSymbolEntry pDest;
+ PSymbolStack LStack, PStack;
+ PSymbolStackEntry Elem;
+ String ExpSymName, ExpStackName;
+
+ if (!ExpandStrSymbol(ExpSymName, sizeof(ExpSymName), pSymName))
+ return False;
+
+ pDest = FindNode(ExpSymName, TempAll);
+ if (!pDest)
+ {
+ WrStrErrorPos(ErrNum_SymbolUndef, pSymName);
+ return False;
+ }
+
+ if (*pStackName->str.p_str)
+ {
+ if (!ExpandStrSymbol(ExpStackName, sizeof(ExpStackName), pStackName))
+ return False;
+ }
+ else
+ strmaxcpy(ExpStackName, DefStackName, STRINGSIZE);
+ if (!ChkSymbName(ExpStackName))
+ {
+ WrStrErrorPos(ErrNum_InvSymName, pStackName);
+ return False;
+ }
+
+ LStack = FirstStack;
+ PStack = NULL;
+ while ((LStack) && (strcmp(LStack->Name, ExpStackName) < 0))
+ {
+ PStack = LStack;
+ LStack = LStack->Next;
+ }
+
+ if ((!LStack) || (strcmp(LStack->Name, ExpStackName) > 0))
+ {
+ WrStrErrorPos(ErrNum_StackEmpty, pStackName);
+ return False;
+ }
+
+ Elem = LStack->Contents;
+ pDest->SymWert = Elem->Contents;
+ LStack->Contents = Elem->Next;
+ if (!LStack->Contents)
+ {
+ if (!PStack)
+ FirstStack = LStack->Next;
+ else
+ PStack->Next = LStack->Next;
+ free(LStack->Name);
+ free(LStack);
+ }
+ free(Elem);
+
+ return True;
+}
+
+void ClearStacks(void)
+{
+ PSymbolStack Act;
+ PSymbolStackEntry Elem;
+ int z;
+ String s;
+
+ while (FirstStack)
+ {
+ z = 0;
+ Act = FirstStack;
+ while (Act->Contents)
+ {
+ Elem = Act->Contents;
+ Act->Contents = Elem->Next;
+ free(Elem);
+ z++;
+ }
+ as_snprintf(s, sizeof(s), "%s(%d)", Act->Name, z);
+ WrXError(ErrNum_StackNotEmpty, s);
+ free(Act->Name);
+ FirstStack = Act->Next;
+ free(Act);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+/* Funktionsverwaltung */
+
+void EnterFunction(const tStrComp *pComp, char *FDefinition, Byte NewCnt)
+{
+ PFunction Neu;
+ String FName_N;
+ const char *pFName;
+
+ if (!CaseSensitive)
+ {
+ strmaxcpy(FName_N, pComp->str.p_str, STRINGSIZE);
+ NLS_UpString(FName_N);
+ pFName = FName_N;
+ }
+ else
+ pFName = pComp->str.p_str;
+
+ if (!ChkSymbName(pFName))
+ {
+ WrStrErrorPos(ErrNum_InvSymName, pComp);
+ return;
+ }
+
+ if (FindFunction(pFName))
+ {
+ if (PassNo == 1)
+ WrStrErrorPos(ErrNum_DoubleDef, pComp);
+ return;
+ }
+
+ Neu = (PFunction) malloc(sizeof(TFunction));
+ Neu->Next = FirstFunction;
+ Neu->ArguCnt = NewCnt;
+ Neu->Name = as_strdup(pFName);
+ Neu->Definition = as_strdup(FDefinition);
+ FirstFunction = Neu;
+}
+
+PFunction FindFunction(const char *Name)
+{
+ PFunction Lauf = FirstFunction;
+ String Name_N;
+
+ if (!CaseSensitive)
+ {
+ strmaxcpy(Name_N, Name, STRINGSIZE);
+ NLS_UpString(Name_N);
+ Name = Name_N;
+ }
+
+ while ((Lauf) && (strcmp(Lauf->Name, Name)))
+ Lauf = Lauf->Next;
+ return Lauf;
+}
+
+void PrintFunctionList(void)
+{
+ PFunction Lauf;
+ String OneS;
+ Boolean cnt;
+
+ if (!FirstFunction)
+ return;
+
+ NewPage(ChapDepth, True);
+ WrLstLine(getmessage(Num_ListFuncListHead1));
+ WrLstLine(getmessage(Num_ListFuncListHead2));
+ WrLstLine("");
+
+ OneS[0] = '\0';
+ Lauf = FirstFunction;
+ cnt = False;
+ while (Lauf)
+ {
+ strmaxcat(OneS, Lauf->Name, STRINGSIZE);
+ if (strlen(Lauf->Name) < 37)
+ strmaxcat(OneS, Blanks(37-strlen(Lauf->Name)), STRINGSIZE);
+ if (!cnt) strmaxcat(OneS, " | ", STRINGSIZE);
+ else
+ {
+ WrLstLine(OneS);
+ OneS[0] = '\0';
+ }
+ cnt = !cnt;
+ Lauf = Lauf->Next;
+ }
+ if (cnt)
+ {
+ OneS[strlen(OneS)-1] = '\0';
+ WrLstLine(OneS);
+ }
+ WrLstLine("");
+}
+
+void ClearFunctionList(void)
+{
+ PFunction Lauf;
+
+ while (FirstFunction)
+ {
+ Lauf = FirstFunction->Next;
+ free(FirstFunction->Name);
+ free(FirstFunction->Definition);
+ free(FirstFunction);
+ FirstFunction = Lauf;
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void ResetSymbolDefines_ResetNode(PTree Node, void *pData)
+{
+ PSymbolEntry SymbolEntry = (PSymbolEntry) Node;
+ UNUSED(pData);
+
+ SymbolEntry->Defined = False;
+ SymbolEntry->Used = False;
+}
+
+void ResetSymbolDefines(void)
+{
+ IterTree(&(FirstSymbol->Tree), ResetSymbolDefines_ResetNode, NULL);
+ IterTree(&(FirstLocSymbol->Tree), ResetSymbolDefines_ResetNode, NULL);
+}
+
+void SetFlag(Boolean *Flag, const char *Name, Boolean Wert)
+{
+ tStrComp TmpComp;
+
+ *Flag = Wert;
+ StrCompMkTemp(&TmpComp, (char*)Name, 0);
+ EnterIntSymbol(&TmpComp, *Flag ? 1 : 0, SegNone, True);
+}
+
+void AddDefSymbol(char *Name, TempResult *Value)
+{
+ PDefSymbol Neu;
+
+ Neu = FirstDefSymbol;
+ while (Neu)
+ {
+ if (!strcmp(Neu->SymName, Name))
+ return;
+ Neu = Neu->Next;
+ }
+
+ Neu = (PDefSymbol) malloc(sizeof(TDefSymbol));
+ Neu->Next = FirstDefSymbol;
+ Neu->SymName = as_strdup(Name);
+ Neu->Wert = (*Value);
+ FirstDefSymbol = Neu;
+}
+
+void RemoveDefSymbol(char *Name)
+{
+ PDefSymbol Save, Lauf;
+
+ if (!FirstDefSymbol)
+ return;
+
+ if (!strcmp(FirstDefSymbol->SymName, Name))
+ {
+ Save = FirstDefSymbol;
+ FirstDefSymbol = FirstDefSymbol->Next;
+ }
+ else
+ {
+ Lauf = FirstDefSymbol;
+ while ((Lauf->Next) && (strcmp(Lauf->Next->SymName, Name)))
+ Lauf = Lauf->Next;
+ if (!Lauf->Next)
+ return;
+ Save = Lauf->Next;
+ Lauf->Next = Lauf->Next->Next;
+ }
+ free(Save->SymName);
+ free(Save);
+}
+
+void CopyDefSymbols(void)
+{
+ PDefSymbol Lauf;
+ tStrComp TmpComp;
+
+ Lauf = FirstDefSymbol;
+ while (Lauf)
+ {
+ StrCompMkTemp(&TmpComp, Lauf->SymName, 0);
+ switch (Lauf->Wert.Typ)
+ {
+ case TempInt:
+ EnterIntSymbol(&TmpComp, Lauf->Wert.Contents.Int, SegNone, True);
+ break;
+ case TempFloat:
+ EnterFloatSymbol(&TmpComp, Lauf->Wert.Contents.Float, True);
+ break;
+ case TempString:
+ {
+ EnterNonZStringSymbol(&TmpComp, &Lauf->Wert.Contents.str, True);
+ break;
+ }
+ default:
+ break;
+ }
+ Lauf = Lauf->Next;
+ }
+}
+
+const TempResult *FindDefSymbol(const char *pName)
+{
+ PDefSymbol pRun;
+
+ for (pRun = FirstDefSymbol; pRun; pRun = pRun->Next)
+ if (!strcmp(pName, pRun->SymName))
+ return &pRun->Wert;
+ return NULL;
+}
+
+void PrintSymbolDepth(void)
+{
+ LongInt TreeMin, TreeMax;
+
+ GetTreeDepth(&(FirstSymbol->Tree), &TreeMin, &TreeMax);
+ fprintf(Debug, " MinTree %ld\n", (long)TreeMin);
+ fprintf(Debug, " MaxTree %ld\n", (long)TreeMax);
+}
+
+LongInt GetSectionHandle(char *SName_O, Boolean AddEmpt, LongInt Parent)
+{
+ PCToken Lauf, Prev;
+ LongInt z;
+ String SName;
+
+ strmaxcpy(SName, SName_O, STRINGSIZE);
+ if (!CaseSensitive)
+ NLS_UpString(SName);
+
+ Lauf = FirstSection;
+ Prev = NULL;
+ z = 0;
+ while ((Lauf) && ((strcmp(Lauf->Name, SName)) || (Lauf->Parent != Parent)))
+ {
+ z++;
+ Prev = Lauf;
+ Lauf = Lauf->Next;
+ }
+
+ if (!Lauf)
+ {
+ if (AddEmpt)
+ {
+ Lauf = (PCToken) malloc(sizeof(TCToken));
+ Lauf->Parent = MomSectionHandle;
+ Lauf->Name = as_strdup(SName);
+ Lauf->Next = NULL;
+ InitChunk(&(Lauf->Usage));
+ if (!Prev)
+ FirstSection = Lauf;
+ else
+ Prev->Next = Lauf;
+ }
+ else
+ z = -2;
+ }
+ return z;
+}
+
+const char *GetSectionName(LongInt Handle)
+{
+ PCToken Lauf = FirstSection;
+ static const char *Dummy = "";
+
+ if (Handle == -1)
+ return Dummy;
+ while ((Handle > 0) && (Lauf))
+ {
+ Lauf = Lauf->Next;
+ Handle--;
+ }
+ return Lauf ? Lauf->Name : Dummy;
+}
+
+void SetMomSection(LongInt Handle)
+{
+ LongInt z;
+
+ MomSectionHandle = Handle;
+ if (Handle < 0)
+ MomSection = NULL;
+ else
+ {
+ MomSection = FirstSection;
+ for (z = 1; z <= Handle; z++)
+ if (MomSection)
+ MomSection = MomSection->Next;
+ }
+}
+
+void AddSectionUsage(LongInt Start, LongInt Length)
+{
+ if ((ActPC != SegCode) || (!MomSection))
+ return;
+ AddChunk(&(MomSection->Usage), Start, Length, False);
+}
+
+void ClearSectionUsage(void)
+{
+ PCToken Tmp;
+
+ for (Tmp = FirstSection; Tmp; Tmp = Tmp->Next)
+ ClearChunk(&(Tmp->Usage));
+}
+
+static void PrintSectionList_PSection(LongInt Handle, int Indent)
+{
+ PCToken Lauf;
+ LongInt Cnt;
+ String h;
+
+ ChkStack();
+ if (Handle != -1)
+ {
+ strmaxcpy(h, Blanks(Indent << 1), STRINGSIZE);
+ strmaxcat(h, GetSectionName(Handle), STRINGSIZE);
+ WrLstLine(h);
+ }
+ Lauf = FirstSection;
+ Cnt = 0;
+ while (Lauf)
+ {
+ if (Lauf->Parent == Handle)
+ PrintSectionList_PSection(Cnt, Indent + 1);
+ Lauf = Lauf->Next;
+ Cnt++;
+ }
+}
+
+void PrintSectionList(void)
+{
+ if (!FirstSection)
+ return;
+
+ NewPage(ChapDepth, True);
+ WrLstLine(getmessage(Num_ListSectionListHead1));
+ WrLstLine(getmessage(Num_ListSectionListHead2));
+ WrLstLine("");
+ PrintSectionList_PSection(-1, 0);
+}
+
+void PrintDebSections(FILE *f)
+{
+ PCToken Lauf;
+ LongInt Cnt, z, l, s;
+ char Str[30];
+
+ Lauf = FirstSection; Cnt = 0;
+ while (Lauf)
+ {
+ fputs("\nInfo for Section ", f); ChkIO(ErrNum_FileWriteError);
+ fprintf(f, LongIntFormat, Cnt); ChkIO(ErrNum_FileWriteError);
+ fputc(' ', f); ChkIO(ErrNum_FileWriteError);
+ fputs(GetSectionName(Cnt), f); ChkIO(ErrNum_FileWriteError);
+ fputc(' ', f); ChkIO(ErrNum_FileWriteError);
+ fprintf(f, LongIntFormat, Lauf->Parent); ChkIO(ErrNum_FileWriteError);
+ fputc('\n', f); ChkIO(ErrNum_FileWriteError);
+ for (z = 0; z < Lauf->Usage.RealLen; z++)
+ {
+ l = Lauf->Usage.Chunks[z].Length;
+ s = Lauf->Usage.Chunks[z].Start;
+ HexString(Str, sizeof(Str), s, 0);
+ fputs(Str, f);
+ ChkIO(ErrNum_FileWriteError);
+ if (l == 1)
+ fprintf(f, "\n");
+ else
+ {
+ HexString(Str, sizeof(Str), s + l - 1, 0);
+ fprintf(f, "-%s\n", Str);
+ }
+ ChkIO(ErrNum_FileWriteError);
+ }
+ Lauf = Lauf->Next;
+ Cnt++;
+ }
+}
+
+void ClearSectionList(void)
+{
+ PCToken Tmp;
+
+ while (FirstSection)
+ {
+ Tmp = FirstSection;
+ free(Tmp->Name);
+ ClearChunk(&(Tmp->Usage));
+ FirstSection = Tmp->Next; free(Tmp);
+ }
+}
+
+/*---------------------------------------------------------------------------------*/
+
+/*!------------------------------------------------------------------------
+ * \fn PrintCrossList_PNode(PTree Node, void *pData)
+ * \brief printf cross refence list of a single symbol table entry
+ * \param Node node base object
+ * \param pData actual symbol entry
+ * \return
+ * ------------------------------------------------------------------------ */
+
+static void PrintCrossList_PNode(PTree Node, void *pData)
+{
+ int FileZ;
+ PCrossRef pCross;
+ String LineAcc;
+ String h;
+ char LineStr[30];
+ PSymbolEntry SymbolEntry = (PSymbolEntry) Node;
+ as_dynstr_t *p_val_str = (as_dynstr_t*)pData;
+ Boolean First;
+
+ if (!SymbolEntry->RefList)
+ return;
+
+ StrSym(&SymbolEntry->SymWert, False, p_val_str, ListRadixBase);
+ as_snprintf(LineStr, sizeof(LineStr), LongIntFormat, SymbolEntry->LineNum);
+
+ as_snprintf(h, sizeof(h), "%s%s",
+ getmessage(Num_ListCrossSymName), Node->Name);
+ if (Node->Attribute != -1)
+ as_snprcatf(h, sizeof(h), "[%s]", GetSectionName(Node->Attribute));
+ as_snprcatf(h, sizeof(h), " (=%s, %s:%s):",
+ p_val_str->p_str, GetFileName(SymbolEntry->FileNum), LineStr);
+
+ WrLstLine(h);
+
+ for (FileZ = 0; FileZ < GetFileCount(); FileZ++)
+ {
+ First = True;
+ strcpy(LineAcc, " ");
+ for (pCross = SymbolEntry->RefList; pCross; pCross = pCross->Next)
+ if (pCross->FileNum == FileZ)
+ {
+ if (First)
+ {
+ strcpy(h, " ");
+ strmaxcat(h, getmessage(Num_ListCrossFileName), STRINGSIZE);
+ strmaxcat(h, GetFileName(FileZ), STRINGSIZE);
+ strmaxcat(h, " :", STRINGSIZE);
+ WrLstLine(h);
+ First = False;
+ }
+ as_snprcatf(LineAcc, sizeof(LineAcc), "%5ld", (long)pCross->LineNum);
+ if (pCross->OccNum != 1)
+ as_snprcatf(LineAcc, sizeof(LineAcc), "(%2ld)", (long)pCross->OccNum);
+ else
+ strmaxcat(LineAcc, " ", STRINGSIZE);
+ if (strlen(LineAcc) >= 72)
+ {
+ WrLstLine(LineAcc);
+ strcpy(LineAcc, " ");
+ }
+ }
+ if (strcmp(LineAcc, " "))
+ WrLstLine(LineAcc);
+ }
+ WrLstLine("");
+}
+
+void PrintCrossList(void)
+{
+ as_dynstr_t val_str;
+
+ as_dynstr_ini(&val_str, 256);
+ WrLstLine("");
+ WrLstLine(getmessage(Num_ListCrossListHead1));
+ WrLstLine(getmessage(Num_ListCrossListHead2));
+ WrLstLine("");
+ IterTree(&(FirstSymbol->Tree), PrintCrossList_PNode, &val_str);
+ WrLstLine("");
+ as_dynstr_free(&val_str);
+}
+
+static void ClearCrossList_CNode(PTree Tree, void *pData)
+{
+ PCrossRef Lauf;
+ PSymbolEntry SymbolEntry = (PSymbolEntry) Tree;
+ UNUSED(pData);
+
+ while (SymbolEntry->RefList)
+ {
+ Lauf = SymbolEntry->RefList->Next;
+ free(SymbolEntry->RefList);
+ SymbolEntry->RefList = Lauf;
+ }
+}
+
+void ClearCrossList(void)
+{
+ IterTree(&(FirstSymbol->Tree), ClearCrossList_CNode, NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+
+LongInt GetLocHandle(void)
+{
+ return LocHandleCnt++;
+}
+
+void PushLocHandle(LongInt NewLoc)
+{
+ PLocHandle NewLocHandle;
+
+ NewLocHandle = (PLocHandle) malloc(sizeof(TLocHeap));
+ NewLocHandle->Cont = MomLocHandle;
+ NewLocHandle->Next = FirstLocHandle;
+ FirstLocHandle = NewLocHandle; MomLocHandle = NewLoc;
+}
+
+void PopLocHandle(void)
+{
+ PLocHandle OldLocHandle;
+
+ OldLocHandle = FirstLocHandle;
+ if (!OldLocHandle) return;
+ MomLocHandle = OldLocHandle->Cont;
+ FirstLocHandle = OldLocHandle->Next;
+ free(OldLocHandle);
+}
+
+void ClearLocStack()
+{
+ while (MomLocHandle != -1)
+ PopLocHandle();
+}
+
+/*--------------------------------------------------------------------------*/
+
+static void PrintRegList_PNode(PTree Tree, void *pData)
+{
+ PSymbolEntry Node = (PSymbolEntry) Tree;
+
+ if (Node->SymWert.Typ == TempReg)
+ {
+ TListContext *pContext = (TListContext*) pData;
+ String tmp, tmp2;
+
+ if (Node->SymWert.Contents.RegDescr.Dissect)
+ Node->SymWert.Contents.RegDescr.Dissect(tmp2, sizeof(tmp2), Node->SymWert.Contents.RegDescr.Reg, Node->SymWert.DataSize);
+ else
+ *tmp2 = '\0';
+ *tmp = '\0';
+ if (Tree->Attribute != -1)
+ as_snprcatf(tmp, sizeof(tmp), "[%s]", GetSectionName(Tree->Attribute));
+ as_snprcatf(tmp, sizeof(tmp), "%c%s --> %s", Node->Used ? ' ' : '*', Tree->Name, tmp2);
+ if ((int)strlen(tmp) > pContext->cwidth - 3)
+ {
+ if (*pContext->Zeilenrest.p_str)
+ WrLstLine(pContext->Zeilenrest.p_str);
+ *pContext->Zeilenrest.p_str = '\0';
+ WrLstLine(tmp);
+ }
+ else
+ {
+ strmaxcat(tmp, Blanks(pContext->cwidth - 3 - strlen(tmp)), STRINGSIZE);
+ if (!*pContext->Zeilenrest.p_str)
+ as_dynstr_copy_c_str(&pContext->Zeilenrest, tmp);
+ else
+ {
+ as_sdprcatf(&pContext->Zeilenrest, " | %s", tmp);
+ WrLstLine(pContext->Zeilenrest.p_str);
+ *pContext->Zeilenrest.p_str = '\0';
+ }
+ }
+ pContext->Sum++;
+ if (!Node->Used)
+ pContext->USum++;
+ }
+}
+
+void PrintRegDefs(void)
+{
+ String buf;
+ LongInt ActPageWidth;
+ TListContext Context;
+
+ if (!RegistersDefined)
+ return;
+
+ NewPage(ChapDepth, True);
+ WrLstLine(getmessage(Num_ListRegDefListHead1));
+ WrLstLine(getmessage(Num_ListRegDefListHead2));
+ WrLstLine("");
+
+ as_dynstr_ini(&Context.Zeilenrest, STRINGSIZE);
+ as_dynstr_ini(&Context.s1, 1);
+ as_dynstr_ini(&Context.sh, 1);
+ Context.Sum = Context.USum = 0;
+ ActPageWidth = (PageWidth == 0) ? 80 : PageWidth;
+ Context.cwidth = ActPageWidth >> 1;
+ IterTree((PTree)FirstSymbol, PrintRegList_PNode, &Context);
+
+ if (*Context.Zeilenrest.p_str)
+ WrLstLine(Context.Zeilenrest.p_str);
+ WrLstLine("");
+ as_snprintf(buf, sizeof(buf), "%7ld%s",
+ (long) Context.Sum,
+ getmessage((Context.Sum == 1) ? Num_ListRegDefSumMsg : Num_ListRegDefSumsMsg));
+ WrLstLine(buf);
+ as_snprintf(buf, sizeof(buf), "%7ld%s",
+ (long)Context.USum,
+ getmessage((Context.USum == 1) ? Num_ListRegDefUSumMsg : Num_ListRegDefUSumsMsg));
+ WrLstLine("");
+ as_dynstr_free(&Context.Zeilenrest);
+ as_dynstr_free(&Context.s1);
+ as_dynstr_free(&Context.sh);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void ClearCodepages(void)
+{
+ PTransTable Old;
+
+ while (TransTables)
+ {
+ Old = TransTables;
+ TransTables = Old->Next;
+ free(Old->Name);
+ free(Old->Table);
+ free(Old);
+ }
+}
+
+void PrintCodepages(void)
+{
+ char buf[500];
+ PTransTable Table;
+ int z, cnt, cnt2;
+
+ NewPage(ChapDepth, True);
+ WrLstLine(getmessage(Num_ListCodepageListHead1));
+ WrLstLine(getmessage(Num_ListCodepageListHead2));
+ WrLstLine("");
+
+ cnt2 = 0;
+ for (Table = TransTables; Table; Table = Table->Next)
+ {
+ for (z = cnt = 0; z < 256; z++)
+ if (Table->Table[z] != z)
+ cnt++;
+ as_snprintf(buf, sizeof(buf), "%s (%d%s)", Table->Name, cnt,
+ getmessage((cnt == 1) ? Num_ListCodepageChange : Num_ListCodepagePChange));
+ WrLstLine(buf);
+ cnt2++;
+ }
+ WrLstLine("");
+ as_snprintf(buf, sizeof(buf), "%d%s", cnt2,
+ getmessage((cnt2 == 1) ? Num_ListCodepageSumMsg : Num_ListCodepageSumsMsg));
+ WrLstLine(buf);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void asmpars_init(void)
+{
+ tIntTypeDef *pCurr;
+
+ serr = (char*)malloc(sizeof(char) * STRINGSIZE);
+ snum = (char*)malloc(sizeof(char) * STRINGSIZE);
+ FirstDefSymbol = NULL;
+ FirstFunction = NULL;
+ BalanceTrees = False;
+
+ for (pCurr = IntTypeDefs; pCurr < IntTypeDefs + (sizeof(IntTypeDefs) / sizeof(*IntTypeDefs)); pCurr++)
+ {
+ unsigned SignType = Hi(pCurr->SignAndWidth);
+ unsigned Bits, Cnt;
+
+ Bits = Lo(pCurr->SignAndWidth) - ((SignType == 0x80) ? 1 : 0);
+ for (Cnt = 0, pCurr->Mask = 0; Cnt < Bits; Cnt++)
+ pCurr->Mask = (pCurr->Mask << 1) | 1;
+
+ pCurr->Max = (LargeInt)pCurr->Mask;
+
+ switch (SignType & 0xc0)
+ {
+ case 0x80:
+ pCurr->Min = -pCurr->Max - 1;
+ break;
+ case 0xc0:
+ pCurr->Min = (LargeInt)(pCurr->Mask / 2);
+ pCurr->Min = -pCurr->Min - 1;
+ break;
+ default:
+ pCurr->Min = 0;
+ break;
+ }
+ }
+
+ LastGlobSymbol = (char*)malloc(sizeof(char) * STRINGSIZE);
+}
--- /dev/null
+#ifndef _ASMPARS_H
+#define _ASMPARS_H
+/* asmpars.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Verwaltung von Symbolen und das ganze Drumherum... */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+
+#include "symbolsize.h"
+#include "symflags.h"
+#include "tempresult.h"
+#include "intformat.h"
+#include "lstmacroexp.h"
+#include "errmsg.h"
+#include "addrspace.h"
+
+typedef enum
+{
+ UInt1 ,
+ UInt2 ,
+ UInt3 ,
+ SInt4 , UInt4 , Int4 ,
+ SInt5 , UInt5 , Int5 ,
+ SInt6 , UInt6 ,
+ SInt7 , UInt7 ,
+ SInt8 , UInt8 , Int8 ,
+ SInt9 , UInt9 ,
+ UInt10 , Int10 ,
+ UInt11 ,
+ UInt12 , Int12 ,
+ UInt13 ,
+ UInt14 , Int14 ,
+ SInt15 , UInt15 ,
+ SInt16 , UInt16 , Int16 ,
+ UInt17 ,
+ UInt18 ,
+ UInt19 ,
+ SInt20 , UInt20 , Int20 ,
+ UInt21 ,
+ UInt22 ,
+ UInt23 ,
+ SInt24 , UInt24 , Int24 ,
+ SInt30 , UInt30 , Int30 ,
+ SInt32 , UInt32 , Int32 ,
+#ifdef HAS64
+ SInt64 , UInt64 , Int64 ,
+#endif
+ IntTypeCnt
+} IntType;
+
+#ifdef __cplusplus
+# include "cppops.h"
+DefCPPOps_Enum(IntType)
+#endif
+
+#ifdef HAS64
+#define LargeUIntType UInt64
+#define LargeSIntType SInt64
+#define LargeIntType Int64
+#else
+#define LargeUIntType UInt32
+#define LargeSIntType SInt32
+#define LargeIntType Int32
+#endif
+
+typedef struct
+{
+ Word SignAndWidth;
+ LargeWord Mask;
+ LargeInt Min, Max;
+} tIntTypeDef;
+
+typedef enum
+{
+ Float32,
+ Float64,
+ Float80,
+ FloatDec,
+ FloatCo,
+ Float16,
+ FloatTypeCnt
+} FloatType;
+
+typedef enum
+{
+ e_symbol_source_none,
+ e_symbol_source_label,
+ e_symbol_source_define
+} as_symbol_source_t;
+
+typedef struct _TFunction
+{
+ struct _TFunction *Next;
+ Byte ArguCnt;
+ StringPtr Name, Definition;
+} TFunction, *PFunction;
+
+typedef struct sEvalResult
+{
+ Boolean OK;
+ tSymbolFlags Flags;
+ unsigned AddrSpaceMask; /* Welche Adressraeume genutzt ? */
+ tSymbolSize DataSize;
+} tEvalResult;
+
+struct sStrComp;
+struct as_nonz_dynstr;
+struct sRelocEntry;
+struct sSymbolEntry;
+
+extern tIntTypeDef IntTypeDefs[IntTypeCnt];
+extern LongInt MomLocHandle;
+extern LongInt TmpSymCounter,
+ FwdSymCounter,
+ BackSymCounter;
+extern char TmpSymCounterVal[10];
+extern LongInt LocHandleCnt;
+extern LongInt MomLocHandle;
+
+
+extern void AsmParsInit(void);
+
+extern void InitTmpSymbols(void);
+
+extern Boolean SingleBit(LargeInt Inp, LargeInt *Erg);
+
+
+extern IntType GetSmallestUIntType(LargeWord MaxValue);
+
+extern IntType GetUIntTypeByBits(unsigned Bits);
+
+extern LargeInt NonZString2Int(const struct as_nonz_dynstr *p_str);
+
+extern Boolean Int2NonZString(struct as_nonz_dynstr *p_str, LargeInt Src);
+
+extern int TempResultToInt(TempResult *pResult);
+
+extern Boolean MultiCharToInt(TempResult *pResult, unsigned MaxLen);
+
+
+extern Boolean RangeCheck(LargeInt Wert, IntType Typ);
+
+extern Boolean ChkRangeByType(LargeInt value, IntType type, const struct sStrComp *p_comp);
+extern Boolean ChkRangeWarnByType(LargeInt value, IntType type, const struct sStrComp *p_comp);
+
+extern Boolean FloatRangeCheck(Double Wert, FloatType Typ);
+
+
+extern Boolean IdentifySection(const struct sStrComp *pName, LongInt *Erg);
+
+
+extern Boolean ExpandStrSymbol(char *pDest, size_t DestSize, const struct sStrComp *pSrc);
+
+extern void ChangeSymbol(struct sSymbolEntry *pEntry, LargeInt Value);
+
+extern struct sSymbolEntry *EnterIntSymbolWithFlags(const struct sStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange, tSymbolFlags Flags);
+
+#define EnterIntSymbol(pName, Wert, addrspace, MayChange) EnterIntSymbolWithFlags(pName, Wert, addrspace, MayChange, eSymbolFlag_None)
+
+extern void EnterExtSymbol(const struct sStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange);
+
+extern struct sSymbolEntry *EnterRelSymbol(const struct sStrComp *pName, LargeInt Wert, as_addrspace_t addrspace, Boolean MayChange);
+
+extern void EnterFloatSymbol(const struct sStrComp *pName, Double Wert, Boolean MayChange);
+
+extern void EnterStringSymbol(const struct sStrComp *pName, const char *pValue, Boolean MayChange);
+
+extern void EnterNonZStringSymbolWithFlags(const struct sStrComp *pName, const struct as_nonz_dynstr *p_value, Boolean MayChange, tSymbolFlags Flags);
+
+extern void EnterRegSymbol(const struct sStrComp *pName, const tRegDescr *Value, tSymbolSize Size, Boolean MayChange, Boolean AddList);
+
+#define EnterNonZStringSymbol(pName, pValue, MayChange) EnterNonZStringSymbolWithFlags(pName, pValue, MayChange, eSymbolFlag_None)
+
+extern void LookupSymbol(const struct sStrComp *pName, TempResult *pValue, Boolean WantRelocs, TempType ReqType);
+
+extern void PrintSymbolList(void);
+
+extern void PrintDebSymbols(FILE *f);
+
+extern void PrintNoISymbols(FILE *f);
+
+extern void PrintSymbolTree(void);
+
+extern void ClearSymbolList(void);
+
+extern void ResetSymbolDefines(void);
+
+extern void PrintSymbolDepth(void);
+
+
+extern void EvalResultClear(tEvalResult *pResult);
+
+
+extern void SetSymbolOrStructElemSize(const struct sStrComp *pName, tSymbolSize Size);
+
+extern ShortInt GetSymbolSize(const struct sStrComp *pName);
+
+extern Boolean IsSymbolDefined(const struct sStrComp *pName);
+
+extern Boolean IsSymbolUsed(const struct sStrComp *pName);
+
+extern Boolean IsSymbolChangeable(const struct sStrComp *pName);
+
+extern Integer GetSymbolType(const struct sStrComp *pName);
+
+extern void EvalExpression(const char *pExpr, TempResult *Erg);
+
+extern void EvalStrExpression(const struct sStrComp *pExpr, TempResult *pErg);
+
+extern void SetIntConstModeByMask(LongWord Mask);
+extern void SetIntConstMode(tIntConstMode Mode);
+extern void SetIntConstRelaxedMode(Boolean NewRelaxedMode);
+
+extern LargeInt EvalStrIntExpression(const struct sStrComp *pExpr, IntType Type, Boolean *pResult);
+extern LargeInt EvalStrIntExpressionWithFlags(const struct sStrComp *pExpr, IntType Type, Boolean *pResult, tSymbolFlags *pFlags);
+extern LargeInt EvalStrIntExpressionWithResult(const struct sStrComp *pExpr, IntType Type, struct sEvalResult *pResult);
+extern LargeInt EvalStrIntExpressionOffs(const struct sStrComp *pExpr, int Offset, IntType Type, Boolean *pResult);
+extern LargeInt EvalStrIntExpressionOffsWithFlags(const struct sStrComp *pExpr, int Offset, IntType Type, Boolean *pResult, tSymbolFlags *pFlags);
+extern LargeInt EvalStrIntExpressionOffsWithResult(const struct sStrComp *pExpr, int Offset, IntType Type, struct sEvalResult *pResult);
+
+extern Double EvalStrFloatExpressionWithResult(const struct sStrComp *pExpr, FloatType Typ, struct sEvalResult *pResult);
+extern Double EvalStrFloatExpression(const struct sStrComp *pExpr, FloatType Typ, Boolean *pResult);
+
+extern void EvalStrStringExpressionWithResult(const struct sStrComp *pExpr, struct sEvalResult *pResult, char *pEvalResult);
+extern void EvalStrStringExpression(const struct sStrComp *pExpr, Boolean *pResult, char *pEvalResult);
+
+extern tErrorNum EvalStrRegExpressionWithResult(const struct sStrComp *pExpr, struct sRegDescr *pResult, struct sEvalResult *pEvalResult);
+typedef enum { eIsNoReg, eIsReg, eRegAbort } tRegEvalResult;
+extern tRegEvalResult EvalStrRegExpressionAsOperand(const struct sStrComp *pArg, struct sRegDescr *pResult, struct sEvalResult *pEvalResult, tSymbolSize ReqSize, Boolean MustBeReg);
+
+
+extern Boolean PushSymbol(const struct sStrComp *pSymName, const struct sStrComp *pStackName);
+
+extern Boolean PopSymbol(const struct sStrComp *pSymName, const struct sStrComp *pStackName);
+
+extern void ClearStacks(void);
+
+
+extern void EnterFunction(const struct sStrComp *pComp, char *FDefinition, Byte NewCnt);
+
+extern PFunction FindFunction(const char *Name);
+
+extern void PrintFunctionList(void);
+
+extern void ClearFunctionList(void);
+
+
+extern void AddDefSymbol(char *Name, TempResult *Value);
+
+extern void RemoveDefSymbol(char *Name);
+
+extern void CopyDefSymbols(void);
+
+extern const TempResult *FindDefSymbol(const char *pName);
+
+extern void PrintCrossList(void);
+
+extern void ClearCrossList(void);
+
+
+extern LongInt GetSectionHandle(char *SName_O, Boolean AddEmpt, LongInt Parent);
+
+extern const char *GetSectionName(LongInt Handle);
+
+extern void SetMomSection(LongInt Handle);
+
+extern void AddSectionUsage(LongInt Start, LongInt Length);
+
+extern void ClearSectionUsage(void);
+
+extern void PrintSectionList(void);
+
+extern void PrintDebSections(FILE *f);
+
+extern void ClearSectionList(void);
+
+
+extern void SetFlag(Boolean *Flag, const char *Name, Boolean Wert);
+
+extern LongInt GetLocHandle(void);
+
+extern void PushLocHandle(LongInt NewLoc);
+
+extern void PopLocHandle(void);
+
+extern void ClearLocStack(void);
+
+
+extern void PrintRegDefs(void);
+
+
+extern void ClearCodepages(void);
+
+extern void PrintCodepages(void);
+
+
+extern void asmpars_init(void);
+
+#endif /* _ASMPARS_H */
--- /dev/null
+#ifndef _ASMRELOCS_H
+#define _ASMRELOCS_H
+/* asmrelocs.h */
+/****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Verwaltung von Relokationslisten */
+/* */
+/* Historie: 25. 7.1999 Grundsteinlegung */
+/* 8. 8.1999 Reloc-Liste gespeichert */
+/* 19. 1.2000 TransferRelocs begonnen */
+/* 26. 6.2000 added exports */
+/* */
+/****************************************************************************/
+
+struct sRelocEntry
+{
+ struct sRelocEntry *Next;
+ char *Ref;
+ Byte Add;
+};
+typedef struct sRelocEntry TRelocEntry, *PRelocEntry;
+
+
+extern PRelocEntry LastRelocs;
+
+extern PRelocEntry MergeRelocs(PRelocEntry *list1, PRelocEntry *list2,
+ Boolean Add);
+
+extern void InvertRelocs(PRelocEntry *erg, PRelocEntry *src);
+
+extern void FreeRelocs(PRelocEntry *list);
+
+extern PRelocEntry DupRelocs(PRelocEntry src);
+
+extern void SetRelocs(PRelocEntry List);
+
+extern void TransferRelocs(LargeWord Addr, LongWord Type);
+
+extern void TransferRelocs2(PRelocEntry RelocList, LargeWord Addr, LongWord Type);
+
+extern void SubPCRefReloc(void);
+
+extern void AddExport(char *Name, LargeInt Value, LongWord Flags);
+#endif /* _ASMRELOCS_H */
--- /dev/null
+#ifndef _ASMSTRUCTS_H
+#define _ASMSTRUCTS_H
+/* asmstructs.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* functions for structure handling */
+/* */
+/*****************************************************************************/
+
+
+#include "symbolsize.h"
+
+struct sStructElem;
+struct sStrComp;
+
+typedef void (*tStructElemExpandFnc)(const struct sStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base);
+
+typedef struct sStructElem
+{
+ struct sStructElem *Next;
+ char *pElemName, *pRefElemName;
+ Boolean IsStruct;
+ tStructElemExpandFnc ExpandFnc;
+ LongInt Offset;
+ ShortInt BitPos; /* -1 -> no bit position */
+ ShortInt BitWidthM1; /* -1 -> no bit field, otherwise actual width minus one */
+ tSymbolSize OpSize;
+} TStructElem, *PStructElem;
+
+typedef struct sStructRec
+{
+ LongInt TotLen;
+ PStructElem Elems;
+ char ExtChar;
+ Boolean DoExt;
+ Boolean IsUnion;
+} TStructRec, *PStructRec;
+
+typedef struct sStructStack
+{
+ struct sStructStack *Next;
+ char *Name, *pBaseName;
+ LargeWord SaveCurrPC, SaveOffsetToInnermost;
+ PStructRec StructRec;
+} TStructStack, *PStructStack;
+
+extern PStructStack StructStack, pInnermostNamedStruct;
+extern int StructSaveSeg;
+
+extern PStructRec CreateStructRec(void);
+
+extern void DestroyStructElem(PStructElem pStructElem);
+
+extern void DestroyStructRec(PStructRec StructRec);
+
+extern void BuildStructName(char *pResult, unsigned ResultLen, const char *pName);
+
+extern PStructElem CreateStructElem(const struct sStrComp *pElemName);
+
+extern PStructElem CloneStructElem(const struct sStrComp *pCloneElemName, const struct sStructElem *pSrc);
+
+extern Boolean AddStructElem(PStructRec pStructRec, PStructElem pElement);
+
+extern void SetStructElemSize(PStructRec pStructRec, const char *pElemName, tSymbolSize Size);
+
+extern void AddStructSymbol(const char *pName, LargeWord Value);
+
+extern void ResolveStructReferences(PStructRec pStructRec);
+
+extern void BumpStructLength(PStructRec StructRec, LongInt Length);
+
+extern void AddStruct(PStructRec StructRec, char *Name, Boolean Protest);
+
+extern Boolean FoundStruct(PStructRec *Erg, const char *pName);
+
+extern void ResetStructDefines(void);
+
+extern void PrintStructList(void);
+
+extern void ClearStructList(void);
+
+extern void ExpandStruct(PStructRec StructRec);
+
+extern void asmstruct_init(void);
+
+#endif /* _ASMSTRUCTS_H */
--- /dev/null
+/* asmsub.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Unterfunktionen, vermischtes */
+/* */
+/*****************************************************************************/
+
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include "version.h"
+#include "endian.h"
+#include "stdhandl.h"
+#include "console.h"
+#include "nls.h"
+#include "nlmessages.h"
+#include "as.rsc"
+#include "strutil.h"
+#include "stringlists.h"
+#include "chunks.h"
+#include "ioerrs.h"
+#include "intformat.h"
+#include "errmsg.h"
+#include "asmdef.h"
+#include "asmpars.h"
+#include "asmdebug.h"
+#include "as.h"
+
+#include "asmsub.h"
+
+
+#ifdef __TURBOC__
+#ifdef __DPMI16__
+#define STKSIZE 35072
+#else
+#define STKSIZE 49152
+#endif
+#endif
+
+#define VALID_S1 1
+#define VALID_SN 2
+#define VALID_M1 4
+#define VALID_MN 8
+
+static StringList CopyrightList, OutList, ShareOutList, ListOutList;
+
+static LongWord StartStack, MinStack, LowStack;
+
+static unsigned ValidSymCharLen;
+static Byte *ValidSymChar;
+
+/****************************************************************************/
+/* Modulinitialisierung */
+
+void AsmSubPassInit(void)
+{
+ PageLength = 60;
+ PageWidth = 0;
+}
+
+/****************************************************************************/
+/* Copyrightlistenverwaltung */
+
+void AddCopyright(const char *NewLine)
+{
+ AddStringListLast(&CopyrightList, NewLine);
+}
+
+void WriteCopyrights(TSwitchProc NxtProc)
+{
+ StringRecPtr Lauf;
+
+ if (!StringListEmpty(CopyrightList))
+ {
+ WrConsoleLine(GetStringListFirst(CopyrightList, &Lauf), True);
+ NxtProc();
+ while (Lauf)
+ {
+ WrConsoleLine(GetStringListNext(&Lauf), True);
+ NxtProc();
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* ermittelt das erste/letzte Auftauchen eines Zeichens ausserhalb */
+/* "geschuetzten" Bereichen */
+
+static char *QuotPosCore(const char *s, int (*SearchFnc)(const char*, const char*), const char *pSearch, tQualifyQuoteFnc QualifyQuoteFnc)
+{
+ register ShortInt Brack = 0, AngBrack = 0;
+ register const char *i;
+ Boolean InSglQuot = False, InDblQuot = False, ThisEscaped = False, NextEscaped = False;
+
+ for (i = s; *i; i++, ThisEscaped = NextEscaped)
+ {
+ NextEscaped = False;
+ if (!SearchFnc(i, pSearch))
+ {
+ if (!AngBrack && !Brack && !InSglQuot && !InDblQuot)
+ return (char*)i;
+ }
+ switch (*i)
+ {
+ case '"':
+ if (!InSglQuot && !ThisEscaped)
+ InDblQuot = !InDblQuot;
+ break;
+ case '\'':
+ if (!InDblQuot && !ThisEscaped)
+ {
+ if (InSglQuot || !QualifyQuoteFnc || QualifyQuoteFnc(s, i))
+ InSglQuot = !InSglQuot;
+ }
+ break;
+ case '\\':
+ if ((InSglQuot || InDblQuot) && !ThisEscaped)
+ NextEscaped = True;
+ break;
+ case '(':
+ if (!AngBrack && !InDblQuot && !InSglQuot)
+ Brack++;
+ break;
+ case ')':
+ if (!AngBrack && !InDblQuot && !InSglQuot)
+ Brack--;
+ break;
+ case '[':
+ if (!Brack && !InDblQuot && !InSglQuot)
+ AngBrack++;
+ break;
+ case ']':
+ if (!Brack && !InDblQuot && !InSglQuot)
+ AngBrack--;
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static int SearchSingleChar(const char *pPos, const char *pSearch)
+{
+ return ((int)*pSearch) - ((int)*pPos);
+}
+
+static int SearchMultChar(const char *pPos, const char *pSearch)
+{
+ return !strchr(pSearch, *pPos);
+}
+
+static int SearchMultString(const char *pPos, const char *pSearch)
+{
+ int len;
+
+ while (True)
+ {
+ if (!(len = strlen(pSearch)))
+ return 1;
+ if (!strncmp(pPos, pSearch, len))
+ return 0;
+ pSearch += len + 1;
+ }
+}
+
+char *QuotMultPosQualify(const char *s, const char *pSearch, tQualifyQuoteFnc QualifyQuoteFnc)
+{
+ return QuotPosCore(s, SearchMultChar, pSearch, QualifyQuoteFnc);
+}
+
+char *QuotPosQualify(const char *s, char Zeichen, tQualifyQuoteFnc QualifyQuoteFnc)
+{
+ return QuotPosCore(s, SearchSingleChar, &Zeichen, QualifyQuoteFnc);
+}
+
+char *QuotSMultPosQualify(const char *s, const char *pStrs, tQualifyQuoteFnc QualifyQuoteFnc)
+{
+ return QuotPosCore(s, SearchMultString, pStrs, QualifyQuoteFnc);
+}
+
+char *RQuotPos(char *s, char Zeichen)
+{
+ ShortInt Brack = 0, AngBrack = 0;
+ char *i;
+ Boolean Quot = False, Paren = False;
+
+ for (i = s + strlen(s) - 1; i >= s; i--)
+ if (*i == Zeichen)
+ {
+ if ((!AngBrack) && (!Brack) && (!Paren) && (!Quot))
+ return i;
+ }
+ else switch (*i)
+ {
+ case '"':
+ if ((!Brack) && (!AngBrack) && (!Quot))
+ Paren = !Paren;
+ break;
+ case '\'':
+ if ((!Brack) && (!AngBrack) && (!Paren))
+ Quot = !Quot;
+ break;
+ case ')':
+ if ((!AngBrack) && (!Paren) && (!Quot))
+ Brack++;
+ break;
+ case '(':
+ if ((!AngBrack) && (!Paren) && (!Quot))
+ Brack--;
+ break;
+ case ']':
+ if ((!Brack) && (!Paren) && (!Quot))
+ AngBrack++;
+ break;
+ case '[':
+ if ((!Brack) && (!Paren) && (!Quot))
+ AngBrack--;
+ break;
+ }
+
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* ermittelt das erste (nicht-) Leerzeichen in einem String */
+
+char *FirstBlank(const char *s)
+{
+ const char *h, *Min = NULL;
+
+ h = strchr(s, ' ');
+ if (h)
+ if ((!Min) || (h < Min))
+ Min = h;
+ h = strchr(s, Char_HT);
+ if (h)
+ if ((!Min) || (h < Min))
+ Min = h;
+ return (char*)Min;
+}
+
+/*--------------------------------------------------------------------------*/
+/* einen String in zwei Teile zerlegen */
+
+void SplitString(char *Source, char *Left, char *Right, char *Trenner)
+{
+ char Save;
+ LongInt slen = strlen(Source);
+
+ if ((!Trenner) || (Trenner >= Source + slen))
+ Trenner = Source + slen;
+ Save = (*Trenner);
+ *Trenner = '\0';
+ strmov(Left, Source);
+ *Trenner = Save;
+ if (Trenner >= Source + slen)
+ *Right = '\0';
+ else
+ strmov(Right, Trenner + 1);
+}
+
+/*--------------------------------------------------------------------------*/
+/* verbesserte Grossbuchstabenfunktion */
+
+/* einen String in Grossbuchstaben umwandeln. Dabei Stringkonstanten in Ruhe */
+/* lassen */
+
+void UpString(char *s)
+{
+ char *z;
+ int hypquot = 0;
+ Boolean LastBk = FALSE, ThisBk;
+
+ for (z = s; *z != '\0'; z++)
+ {
+ ThisBk = FALSE;
+ switch (*z)
+ {
+ case '\\':
+ ThisBk = TRUE;
+ break;
+ case '\'':
+ if ((!(hypquot & 2)) && (!LastBk))
+ hypquot ^= 1;
+ break;
+ case '"':
+ if ((!(hypquot & 1)) && (!LastBk))
+ hypquot ^= 2;
+ break;
+ default:
+ if (!hypquot)
+ *z = UpCaseTable[(int)*z];
+ }
+ LastBk = ThisBk;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn MatchChars(const char *pStr, const char *pPattern, ...)
+ * \brief see if beginning of string matches given pattern
+ * \param pStr string to check
+ * \param pPattern expected pattern
+ * \return * to character following match or NULL if no match
+ * ------------------------------------------------------------------------ */
+
+char *MatchChars(const char *pStr, const char *pPattern, ...)
+{
+ va_list ap;
+ char *pResult = NULL;
+
+ va_start(ap, pPattern);
+ for (; *pPattern; pPattern++)
+ switch (*pPattern)
+ {
+ /* single space in pattern matches arbitrary # of spaces in string */
+ case ' ':
+ for (; as_isspace(*pStr); pStr++);
+ break;
+ case '?':
+ {
+ const char *pPatternStr = va_arg(ap, const char*);
+ char *pSave = va_arg(ap, char*);
+
+ if (!strchr(pPatternStr, as_toupper(*pStr)))
+ goto func_exit;
+ if (pSave)
+ *pSave = *pStr;
+ pStr++;
+ break;
+ }
+ default:
+ if (as_toupper(*pStr) != as_toupper(*pPattern))
+ goto func_exit;
+ pStr++;
+ }
+ pResult = (char*)pStr;
+func_exit:
+ va_end(ap);
+ return pResult;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn MatchCharsRev(const char *pStr, const char *pPattern, ...)
+ * \brief see if end of string matches given pattern
+ * \param pStr string to check
+ * \param pPattern expected pattern
+ * \return * to trailing string matching pattern or NULL if no match
+ * ------------------------------------------------------------------------ */
+
+char *MatchCharsRev(const char *pStr, const char *pPattern, ...)
+{
+ va_list ap;
+ char *pResult = NULL;
+ const char *pPatternRun = pPattern + strlen(pPattern) - 1,
+ *pStrRun = pStr + strlen(pStr) - 1;
+
+ va_start(ap, pPattern);
+ for (; pPatternRun >= pPattern; pPatternRun--)
+ switch (*pPatternRun)
+ {
+ /* single space in pattern matches arbitrary # of spaces in string */
+ case ' ':
+ for (; (pStrRun >= pStr) && as_isspace(*pStrRun); pStrRun--);
+ break;
+ case '?':
+ {
+ const char *pPatternStr = va_arg(ap, const char*);
+ char *pSave = va_arg(ap, char*);
+
+ if (!strchr(pPatternStr, as_toupper(*pStrRun)))
+ goto func_exit;
+ if (pSave)
+ *pSave = *pStrRun;
+ pStrRun--;
+ break;
+ }
+ default:
+ if ((pStrRun < pStr) || (as_toupper(*pStrRun) != as_toupper(*pPatternRun)))
+ goto func_exit;
+ pStrRun--;
+ }
+ pResult = (char*)(pStrRun + 1);
+func_exit:
+ va_end(ap);
+ return pResult;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn FindClosingParenthese(const char *pStr)
+ * \brief find matching closing parenthese
+ * \param pStr * to string right after opening parenthese
+ * \return * to closing parenthese or NULL
+ * ------------------------------------------------------------------------ */
+
+char *FindClosingParenthese(const char *pStr)
+{
+ int Nest = 1;
+ Boolean InSgl = False, InDbl = False;
+
+ for (; *pStr; pStr++)
+ {
+ switch (*pStr)
+ {
+ case '\'':
+ if (!InDbl) InSgl = !InSgl;
+ break;
+ case '"':
+ if (!InSgl) InDbl = !InDbl;
+ break;
+ case '(':
+ if (!InSgl && !InDbl) Nest++;
+ break;
+ case ')':
+ if (!InSgl && !InDbl) Nest--;
+ if (!Nest)
+ return (char*)pStr;
+ break;
+ default:
+ break;
+ }
+ }
+ return NULL;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn FindOpeningParenthese(const char *pStrBegin, const char *pStrEnd, const char Bracks[2])
+ * \brief find matching opening parenthese in string
+ * \param pStrBegin start of string
+ * \param pStrEnd end of string, preceding closing parenthese in question
+ * \param Bracks opening & closing parenthese
+ * \return * to opening parenthese or NULL if not found
+ * ------------------------------------------------------------------------ */
+
+char *FindOpeningParenthese(const char *pStrBegin, const char *pStrEnd, const char Bracks[2])
+{
+ int Nest = 1;
+ Boolean InSgl = False, InDbl = False;
+
+ for (; pStrEnd >= pStrBegin; pStrEnd--)
+ {
+ if (*pStrEnd == Bracks[1])
+ {
+ if (!InSgl && !InDbl) Nest++;
+ }
+ else if (*pStrEnd == Bracks[0])
+ {
+ if (!InSgl && !InDbl) Nest--;
+ if (!Nest)
+ return (char*)pStrEnd;
+ }
+ else switch (*pStrEnd)
+ {
+ case '\'':
+ if (!InDbl) InSgl = !InSgl;
+ break;
+ case '"':
+ if (!InSgl) InDbl = !InDbl;
+ break;
+ default:
+ break;
+ }
+ }
+ return NULL;
+}
+
+/****************************************************************************/
+
+void TranslateString(char *s, int Length)
+{
+ char *pRun, *pEnd;
+
+ if (Length < 0)
+ Length = strlen(s);
+ for (pRun = s, pEnd = pRun + Length; pRun < pEnd; pRun++)
+ *pRun = CharTransTable[((usint)(*pRun)) & 0xff];
+}
+
+ShortInt StrCaseCmp(const char *s1, const char *s2, LongInt Hand1, LongInt Hand2)
+{
+ int tmp;
+
+ tmp = as_toupper(*s1) - as_toupper(*s2);
+ if (!tmp)
+ tmp = as_strcasecmp(s1, s2);
+ if (!tmp)
+ tmp = Hand1 - Hand2;
+ if (tmp < 0)
+ return -1;
+ if (tmp > 0)
+ return 1;
+ return 0;
+}
+
+/****************************************************************************/
+/* an einen Dateinamen eine Endung anhaengen */
+
+void AddSuffix(char *s, const char *Suff)
+{
+ char *p, *z, *Part;
+
+ p = NULL;
+ for (z = s; *z != '\0'; z++)
+ if (*z == '\\')
+ p = z;
+ Part = p ? p : s;
+ if (!strchr(Part, '.'))
+ strmaxcat(s, Suff, STRINGSIZE);
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* von einem Dateinamen die Endung loeschen */
+
+void KillSuffix(char *s)
+{
+ char *p, *z, *Part;
+
+ p = NULL;
+ for (z = s; *z != '\0'; z++)
+ if (*z == '\\')
+ p = z;
+ Part = p ? p : s;
+ Part = strchr(Part, '.');
+ if (Part)
+ *Part = '\0';
+}
+
+/*--------------------------------------------------------------------------*/
+/* Pfadanteil (Laufwerk+Verzeichnis) von einem Dateinamen abspalten */
+
+char *PathPart(char *Name)
+{
+ static String s;
+ char *p;
+
+ strmaxcpy(s, Name, STRINGSIZE);
+
+ p = strrchr(Name, PATHSEP);
+#ifdef DRSEP
+ if (!p)
+ p = strrchr(Name, DRSEP);
+#endif
+
+ if (!p)
+ *s = '\0';
+ else
+ s[1] = '\0';
+
+ return s;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Namensanteil von einem Dateinamen abspalten */
+
+const char *NamePart(const char *Name)
+{
+ const char *p = strrchr(Name, PATHSEP);
+
+#ifdef DRSEP
+ if (!p)
+ p = strrchr(Name, DRSEP);
+#endif
+
+ return p ? p + 1 : Name;
+}
+
+/****************************************************************************/
+/* eine Gleitkommazahl in einen String umwandeln */
+
+void FloatString(char *pDest, size_t DestSize, Double f)
+{
+#define MaxLen 18
+ char *p, *d, ExpChar = HexStartCharacter + ('E' - 'A');
+ sint n, ExpVal, nzeroes;
+ Boolean WithE, OK;
+
+ /* 1. mit Maximallaenge wandeln, fuehrendes Vorzeichen weg */
+
+ (void)DestSize;
+ as_snprintf(pDest, DestSize, "%27.15e", f);
+ for (p = pDest; (*p == ' ') || (*p == '+'); p++);
+ if (p != pDest)
+ strmov(pDest, p);
+
+ /* 2. Exponenten soweit als moeglich kuerzen, evtl. ganz streichen */
+
+ p = strchr(pDest, ExpChar);
+ if (!p)
+ return;
+ switch (*(++p))
+ {
+ case '+':
+ strmov(p, p + 1);
+ break;
+ case '-':
+ p++;
+ break;
+ }
+
+ while (*p == '0')
+ strmov(p, p + 1);
+ WithE = (*p != '\0');
+ if (!WithE)
+ pDest[strlen(pDest) - 1] = '\0';
+
+ /* 3. Nullen am Ende der Mantisse entfernen, Komma bleibt noch */
+
+ p = WithE ? strchr(pDest, ExpChar) : pDest + strlen(pDest);
+ p--;
+ while (*p == '0')
+ {
+ strmov(p, p + 1);
+ p--;
+ }
+
+ /* 4. auf die gewuenschte Maximalstellenzahl begrenzen */
+
+ p = WithE ? strchr(pDest, ExpChar) : pDest + strlen(pDest);
+ d = strchr(pDest, '.');
+ n = p - d - 1;
+
+ /* 5. Maximallaenge ueberschritten ? */
+
+ if (strlen(pDest) > MaxLen)
+ strmov(d + (n - (strlen(pDest) - MaxLen)), d + n);
+
+ /* 6. Exponentenwert berechnen */
+
+ if (WithE)
+ {
+ p = strchr(pDest, ExpChar);
+ ExpVal = ConstLongInt(p + 1, &OK, 10);
+ }
+ else
+ {
+ p = pDest + strlen(pDest);
+ ExpVal = 0;
+ }
+
+ /* 7. soviel Platz, dass wir den Exponenten weglassen und evtl. Nullen
+ anhaengen koennen ? */
+
+ if (ExpVal > 0)
+ {
+ nzeroes = ExpVal - (p - strchr(pDest, '.') - 1); /* = Zahl von Nullen, die anzuhaengen waere */
+
+ /* 7a. nur Kommaverschiebung erforderlich. Exponenten loeschen und
+ evtl. auch Komma */
+
+ if (nzeroes <= 0)
+ {
+ *p = '\0';
+ d = strchr(pDest, '.');
+ strmov(d, d + 1);
+ if (nzeroes != 0)
+ {
+ memmove(pDest + strlen(pDest) + nzeroes + 1, pDest + strlen(pDest) + nzeroes, -nzeroes);
+ pDest[strlen(pDest) - 1 + nzeroes] = '.';
+ }
+ }
+
+ /* 7b. Es muessen Nullen angehaengt werden. Schauen, ob nach Loeschen von
+ Punkt und E-Teil genuegend Platz ist */
+
+ else
+ {
+ n = strlen(p) + 1 + (MaxLen - strlen(pDest)); /* = Anzahl freizubekommender Zeichen+Gutschrift */
+ if (n >= nzeroes)
+ {
+ *p = '\0';
+ d = strchr(pDest, '.');
+ strmov(d, d + 1);
+ d = pDest + strlen(pDest);
+ for (n = 0; n < nzeroes; n++)
+ *(d++) = '0';
+ *d = '\0';
+ }
+ }
+ }
+
+ /* 8. soviel Platz, dass Exponent wegkann und die Zahl mit vielen Nullen
+ vorne geschrieben werden kann ? */
+
+ else if (ExpVal < 0)
+ {
+ n = (-ExpVal) - (strlen(p)); /* = Verlaengerung nach Operation */
+ if (strlen(pDest) + n <= MaxLen)
+ {
+ *p = '\0';
+ d = strchr(pDest, '.');
+ strmov(d, d + 1);
+ d = (pDest[0] == '-') ? pDest + 1 : pDest;
+ memmove(d - ExpVal + 1, d, strlen(pDest) + 1);
+ *(d++) = '0';
+ *(d++) = '.';
+ for (n = 0; n < -ExpVal - 1; n++)
+ *(d++) = '0';
+ }
+ }
+
+
+ /* 9. Ueberfluessiges Komma entfernen */
+
+ if (WithE)
+ p = strchr(pDest, ExpChar);
+ else
+ p = pDest + strlen(pDest);
+ if (p && (*(p - 1) == '.'))
+ strmov(p - 1, p);
+}
+
+/****************************************************************************/
+/* Symbol in String wandeln */
+
+void StrSym(const TempResult *t, Boolean WithSystem, as_dynstr_t *p_dest, unsigned Radix)
+{
+ LargeInt IntVal;
+
+ if (p_dest->capacity)
+ p_dest->p_str[0] = '\0';
+ switch (t->Typ)
+ {
+ case TempInt:
+ IntVal = t->Contents.Int;
+ IsInt:
+ {
+ String Buf;
+
+ if (WithSystem)
+ {
+ switch (IntConstMode)
+ {
+ case eIntConstModeMoto:
+ as_sdprcatf(p_dest, "%s", GetIntConstMotoPrefix(Radix));
+ break;
+ case eIntConstModeC:
+ as_sdprcatf(p_dest, "%s", GetIntConstCPrefix(Radix));
+ break;
+ case eIntConstModeIBM:
+ as_sdprcatf(p_dest, "%s", GetIntConstIBMPrefix(Radix));
+ break;
+ default:
+ break;
+ }
+ }
+ SysString(Buf, sizeof(Buf), IntVal, Radix,
+ 1, (16 == Radix) && (IntConstMode == eIntConstModeIntel),
+ HexStartCharacter, SplitByteCharacter);
+ as_sdprcatf(p_dest, "%s", Buf);
+ if (WithSystem)
+ {
+ switch (IntConstMode)
+ {
+ case eIntConstModeIntel:
+ as_sdprcatf(p_dest, GetIntConstIntelSuffix(Radix));
+ break;
+ case eIntConstModeIBM:
+ as_sdprcatf(p_dest, GetIntConstIBMSuffix(Radix));
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ case TempFloat:
+ FloatString(p_dest->p_str, p_dest->capacity, t->Contents.Float);
+ break;
+ case TempString:
+ as_tempres_append_dynstr(p_dest, t);
+ break;
+ case TempReg:
+ if (t->Contents.RegDescr.Dissect)
+ t->Contents.RegDescr.Dissect(p_dest->p_str, p_dest->capacity, t->Contents.RegDescr.Reg, t->DataSize);
+ else
+ {
+ IntVal = t->Contents.RegDescr.Reg;
+ goto IsInt;
+ }
+ break;
+ default:
+ as_sdprintf(p_dest, "???");
+ }
+}
+
+/****************************************************************************/
+/* Listingzaehler zuruecksetzen */
+
+void ResetPageCounter(void)
+{
+ int z;
+
+ for (z = 0; z <= ChapMax; z++)
+ PageCounter[z] = 0;
+ LstCounter = 0;
+ ChapDepth = 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/* eine neue Seite im Listing beginnen */
+
+void NewPage(ShortInt Level, Boolean WithFF)
+{
+ ShortInt z;
+ String Header, s;
+ char Save;
+
+ if (ListOn == 0)
+ return;
+
+ LstCounter = 0;
+
+ if (ChapDepth < (Byte) Level)
+ {
+ memmove(PageCounter + (Level - ChapDepth), PageCounter, (ChapDepth + 1) * sizeof(Word));
+ for (z = 0; z <= Level - ChapDepth; PageCounter[z++] = 1);
+ ChapDepth = Level;
+ }
+ for (z = 0; z <= Level - 1; PageCounter[z++] = 1);
+ PageCounter[Level]++;
+
+ if ((WithFF) && (!ListToNull))
+ {
+ errno = 0;
+ fprintf(LstFile, "%c", Char_FF);
+ ChkIO(ErrNum_ListWrError);
+ }
+
+ as_snprintf(Header, sizeof(Header), " AS V%s%s%s",
+ Version,
+ getmessage(Num_HeadingFileNameLab),
+ NamePart(SourceFile));
+ if (strcmp(CurrFileName, "INTERNAL")
+ && *CurrFileName
+ && strcmp(NamePart(CurrFileName), NamePart(SourceFile)))
+ {
+ strmaxcat(Header, "(", STRINGSIZE);
+ strmaxcat(Header, NamePart(CurrFileName), STRINGSIZE);
+ strmaxcat(Header, ")", STRINGSIZE);
+ }
+ strmaxcat(Header, getmessage(Num_HeadingPageLab), STRINGSIZE);
+
+ for (z = ChapDepth; z >= 0; z--)
+ {
+ as_snprintf(s, sizeof(s), IntegerFormat, PageCounter[z]);
+ strmaxcat(Header, s, STRINGSIZE);
+ if (z != 0)
+ strmaxcat(Header, ".", STRINGSIZE);
+ }
+
+ strmaxcat(Header, " - ", STRINGSIZE);
+ NLS_CurrDateString(s, sizeof(s));
+ strmaxcat(Header, s, STRINGSIZE);
+ strmaxcat(Header, " ", STRINGSIZE);
+ NLS_CurrTimeString(False, s, sizeof(s));
+ strmaxcat(Header, s, STRINGSIZE);
+
+ if (PageWidth != 0)
+ while (strlen(Header) > PageWidth)
+ {
+ Save = Header[PageWidth];
+ Header[PageWidth] = '\0';
+ if (!ListToNull)
+ {
+ errno = 0;
+ fprintf(LstFile, "%s\n", Header);
+ ChkIO(ErrNum_ListWrError);
+ }
+ Header[PageWidth] = Save;
+ strmov(Header, Header + PageWidth);
+ }
+
+ if (!ListToNull)
+ {
+ errno = 0;
+ fprintf(LstFile, "%s\n", Header);
+ ChkIO(ErrNum_ListWrError);
+
+ if (PrtTitleString[0])
+ {
+ errno = 0;
+ fprintf(LstFile, "%s\n", PrtTitleString);
+ ChkIO(ErrNum_ListWrError);
+ }
+
+ errno = 0;
+ fprintf(LstFile, "\n\n");
+ ChkIO(ErrNum_ListWrError);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* eine Zeile ins Listing schieben */
+
+void WrLstLine(const char *Line)
+{
+ int LLength;
+ char bbuf[2500];
+ String LLine;
+ int blen = 0, hlen, z, Start;
+
+ if ((ListOn == 0) || (ListToNull))
+ return;
+
+ if (PageLength == 0)
+ {
+ errno = 0;
+ fprintf(LstFile, "%s\n", Line);
+ ChkIO(ErrNum_ListWrError);
+ }
+ else
+ {
+ if ((PageWidth == 0) || ((strlen(Line) << 3) < PageWidth))
+ LLength = 1;
+ else
+ {
+ blen = 0;
+ for (z = 0; z < (int)strlen(Line); z++)
+ if (Line[z] == Char_HT)
+ {
+ memset(bbuf + blen, ' ', 8 - (blen & 7));
+ blen += 8 - (blen&7);
+ }
+ else
+ bbuf[blen++] = Line[z];
+ LLength = blen / PageWidth;
+ if (blen % PageWidth)
+ LLength++;
+ }
+ if (LLength == 1)
+ {
+ errno = 0;
+ fprintf(LstFile, "%s\n", Line);
+ ChkIO(ErrNum_ListWrError);
+ if ((++LstCounter) == PageLength)
+ NewPage(0, True);
+ }
+ else
+ {
+ Start = 0;
+ for (z = 1; z <= LLength; z++)
+ {
+ hlen = PageWidth;
+ if (blen - Start < hlen)
+ hlen = blen - Start;
+ memcpy(LLine, bbuf + Start, hlen);
+ LLine[hlen] = '\0';
+ errno = 0;
+ fprintf(LstFile, "%s\n", LLine);
+ if ((++LstCounter) == PageLength)
+ NewPage(0, True);
+ Start += hlen;
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Ausdruck in Spalte vor Listing */
+
+void SetListLineVal(TempResult *t)
+{
+ as_dynstr_t str;
+
+ as_dynstr_ini(&str, STRINGSIZE);
+ StrSym(t, True, &str, ListRadixBase);
+ as_snprintf(ListLine, STRINGSIZE, "=%s", str.p_str);
+ LimitListLine();
+ as_dynstr_free(&str);
+}
+
+void LimitListLine(void)
+{
+ if (strlen(ListLine) + 1 > LISTLINESPACE)
+ {
+ ListLine[LISTLINESPACE - 4] = '\0';
+ strmaxcat(ListLine, "..", STRINGSIZE);
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn PrintOneLineMuted(FILE *pFile, const char *pLine,
+ const struct sLineComp *pMuteComponent,
+ const struct sLineComp *pMuteComponent2)
+ * \brief print a line, with a certain component muted out (i.e. replaced by spaces)
+ * \param pFile where to write
+ * \param pLine line to print
+ * \param pMuteComponent component to mute in printout
+ * ------------------------------------------------------------------------ */
+
+static Boolean CompMatch(int Col, const struct sLineComp *pComp)
+{
+ return (pComp
+ && (pComp->StartCol >= 0)
+ && (Col >= pComp->StartCol)
+ && (Col < pComp->StartCol + (int)pComp->Len));
+}
+
+void PrintOneLineMuted(FILE *pFile, const char *pLine,
+ const struct sLineComp *pMuteComponent,
+ const struct sLineComp *pMuteComponent2)
+{
+ int z, Len = strlen(pLine);
+ Boolean Match;
+
+ errno = 0;
+ for (z = 0; z < Len; z++)
+ {
+ Match = CompMatch(z, pMuteComponent) || CompMatch(z, pMuteComponent2);
+ fputc(Match ? ' ' : pLine[z], pFile);
+ }
+ fputc('\n', pFile);
+ ChkIO(ErrNum_ListWrError);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn PrLineMarker(FILE *pFile, const char *pLine, const char *pPrefix, const char *pTrailer,
+ char Marker, const struct sLineComp *pLineComp)
+ * \brief print a line, optionally with a marking of a component below
+ * \param pFile where to write
+ * \param pLine line to print/underline
+ * \param pPrefix what to print before (under)line
+ * \param pTrailer what to print after (under)line
+ * \param Marker character to use for marking
+ * \param pLineComp position and length of optional marker
+ * ------------------------------------------------------------------------ */
+
+void PrLineMarker(FILE *pFile, const char *pLine, const char *pPrefix, const char *pTrailer,
+ char Marker, const struct sLineComp *pLineComp)
+{
+ const char *pRun;
+ int z;
+
+ fputs(pPrefix, pFile);
+ for (pRun = pLine; *pRun; pRun++)
+ fputc(TabCompressed(*pRun), pFile);
+ fprintf(pFile, "%s\n", pTrailer);
+
+ if (pLineComp && (pLineComp->StartCol >= 0) && (pLineComp->Len > 0))
+ {
+ fputs(pPrefix, pFile);
+ if (pLineComp->StartCol > 0)
+ fprintf(pFile, "%*s", pLineComp->StartCol, "");
+ for (z = 0; z < (int)pLineComp->Len; z++)
+ fputc(Marker, pFile);
+ fprintf(pFile, "%s\n", pTrailer);
+ }
+}
+
+/****************************************************************************/
+/* einen Symbolnamen auf Gueltigkeit ueberpruefen */
+
+static Byte GetValidSymChar(unsigned Ch)
+{
+ return (Ch < ValidSymCharLen) ? ValidSymChar[Ch] : 0;
+}
+
+static char *ChkNameUpTo(const char *pSym, const char *pUpTo, Byte _Mask)
+{
+ Byte Mask = _Mask;
+ unsigned Ch;
+ const char *pPrev;
+
+ if (!*pSym)
+ return (char*)pSym;
+
+ while (*pSym && (pSym != pUpTo))
+ {
+ pPrev = pSym;
+ if (ValidSymCharLen > 256)
+ Ch = UTF8ToUnicode(&pSym);
+ else
+ Ch = ((unsigned int)*pSym++) & 0xff;
+
+ if (!(GetValidSymChar(Ch) & Mask))
+ return (char*)pPrev;
+ Mask = _Mask << 1;
+ }
+ return (char*)pSym;
+}
+
+char *ChkSymbNameUpTo(const char *pSym, const char *pUpTo)
+{
+ char *pResult = ChkNameUpTo(pSym, pUpTo, VALID_S1);
+
+ /* If NULL as UpTo was given, and all is fine up to end of string,
+ also return NULL as result. So Equation 'Result==UpTo' is fulfilled: */
+
+ if (!pUpTo && !*pResult)
+ pResult= NULL;
+ return pResult;
+}
+
+Boolean ChkSymbName(const char *pSym)
+{
+ const char *pEnd = ChkSymbNameUpTo(pSym, NULL);
+ return *pSym && !pEnd;
+}
+
+char *ChkMacSymbNameUpTo(const char *pSym, const char *pUpTo)
+{
+ char *pResult = ChkNameUpTo(pSym, pUpTo, VALID_M1);
+
+ /* If NULL as UpTo was given, and all is fine up to end of string,
+ also return NULL as result. So Equation 'Result==UpTo' is fulfilled: */
+
+ if (!pUpTo && !*pResult)
+ pResult= NULL;
+ return pResult;
+}
+
+Boolean ChkMacSymbName(const char *pSym)
+{
+ const char *pEnd = ChkMacSymbNameUpTo(pSym, NULL);
+ return *pSym && !pEnd;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn visible_strlen(const char *pSym)
+ * \brief retrieve 'visible' length of string, regarding multi-by sequences for UTF-8
+ * \param pSym symbol name
+ * \return visible length in characters
+ * ------------------------------------------------------------------------ */
+
+unsigned visible_strlen(const char *pSym)
+{
+ if (ValidSymCharLen > 256)
+ {
+ unsigned Result = 0;
+
+ while (*pSym)
+ {
+ (void)UTF8ToUnicode(&pSym);
+ Result++;
+ }
+ return Result;
+ }
+ else
+ return strlen(pSym);
+}
+
+/****************************************************************************/
+
+LargeWord ProgCounter(void)
+{
+ return PCs[ActPC];
+}
+
+/*--------------------------------------------------------------------------*/
+/* aktuellen Programmzaehler mit Phasenverschiebung holen */
+
+LargeWord EProgCounter(void)
+{
+ return PCs[ActPC] + Phases[ActPC];
+}
+
+/*--------------------------------------------------------------------------*/
+/* Granularitaet des aktuellen Segments holen */
+
+Word Granularity(void)
+{
+ return Grans[ActPC];
+}
+
+/*--------------------------------------------------------------------------*/
+/* Linstingbreite des aktuellen Segments holen */
+
+Word ListGran(void)
+{
+ return ListGrans[ActPC];
+}
+
+/*--------------------------------------------------------------------------*/
+/* pruefen, ob alle Symbole einer Formel im korrekten Adressraum lagen */
+
+void ChkSpace(Byte AddrSpace, unsigned AddrSpaceMask)
+{
+ AddrSpaceMask &= ~(1 << AddrSpace);
+
+ if (AddrSpaceMask) WrError(ErrNum_WrongSegment);
+}
+
+/****************************************************************************/
+/* eine Chunkliste im Listing ausgeben & Speicher loeschen */
+
+void PrintChunk(ChunkList *NChunk, DissectBitProc Dissect, int ItemsPerLine)
+{
+ LargeWord NewMin, FMin;
+ Boolean Found;
+ Word p = 0, z;
+ int BufferZ;
+ String BufferS;
+ int MaxItemLen = 79 / ItemsPerLine;
+
+ NewMin = 0;
+ BufferZ = 0;
+ *BufferS = '\0';
+
+ do
+ {
+ /* niedrigsten Start finden, der ueberhalb des letzten Endes liegt */
+
+ Found = False;
+ FMin = IntTypeDefs[LargeUIntType].Max;
+ for (z = 0; z < NChunk->RealLen; z++)
+ if (NChunk->Chunks[z].Start >= NewMin)
+ if (FMin > NChunk->Chunks[z].Start)
+ {
+ Found = True;
+ FMin = NChunk->Chunks[z].Start;
+ p = z;
+ }
+
+ if (Found)
+ {
+ char Num[30];
+
+ Dissect(Num, sizeof(Num), NChunk->Chunks[p].Start);
+ strmaxcat(BufferS, Num, STRINGSIZE);
+ if (NChunk->Chunks[p].Length != 1)
+ {
+ strmaxcat(BufferS, "-", STRINGSIZE);
+ Dissect(Num, sizeof(Num), NChunk->Chunks[p].Start + NChunk->Chunks[p].Length - 1);
+ strmaxcat(BufferS, Num, STRINGSIZE);
+ }
+ strmaxcat(BufferS, Blanks(MaxItemLen - strlen(BufferS) % MaxItemLen), STRINGSIZE);
+ if (++BufferZ == ItemsPerLine)
+ {
+ WrLstLine(BufferS);
+ *BufferS = '\0';
+ BufferZ = 0;
+ }
+ NewMin = NChunk->Chunks[p].Start + NChunk->Chunks[p].Length;
+ }
+ }
+ while (Found);
+
+ if (BufferZ != 0)
+ WrLstLine(BufferS);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Listen ausgeben */
+
+void PrintUseList(void)
+{
+ int z, z2, l;
+ String s;
+
+ for (z = 1; z < SegCount; z++)
+ if (SegChunks[z].Chunks)
+ {
+ as_snprintf(s, sizeof(s), " %s%s%s",
+ getmessage(Num_ListSegListHead1), SegNames[z],
+ getmessage(Num_ListSegListHead2));
+ WrLstLine(s);
+ strcpy(s, " ");
+ l = strlen(SegNames[z]) + strlen(getmessage(Num_ListSegListHead1)) + strlen(getmessage(Num_ListSegListHead2));
+ for (z2 = 0; z2 < l; z2++)
+ strmaxcat(s, "-", STRINGSIZE);
+ WrLstLine(s);
+ WrLstLine("");
+ PrintChunk(SegChunks + z,
+ (z == SegBData) ? DissectBit : Default_DissectBit,
+ (z == SegBData) ? 3 : 4);
+ WrLstLine("");
+ }
+}
+
+void ClearUseList(void)
+{
+ int z;
+
+ for (z = 1; z < SegCount; z++)
+ ClearChunk(SegChunks + z);
+}
+
+/****************************************************************************/
+/* Include-Pfadlistenverarbeitung */
+
+static char *GetPath(char *Acc)
+{
+ char *p;
+ static String tmp;
+
+ p = strchr(Acc, DIRSEP);
+ if (!p)
+ {
+ strmaxcpy(tmp, Acc, STRINGSIZE);
+ Acc[0] = '\0';
+ }
+ else
+ {
+ *p = '\0';
+ strmaxcpy(tmp, Acc, STRINGSIZE);
+ strmov(Acc, p + 1);
+ }
+ return tmp;
+}
+
+void AddIncludeList(char *NewPath)
+{
+ String Test;
+
+ strmaxcpy(Test, IncludeList, STRINGSIZE);
+ while (*Test != '\0')
+ if (!strcmp(GetPath(Test), NewPath))
+ return;
+ if (*IncludeList != '\0')
+ strmaxprep(IncludeList, SDIRSEP, STRINGSIZE);
+ strmaxprep(IncludeList, NewPath, STRINGSIZE);
+}
+
+
+void RemoveIncludeList(char *RemPath)
+{
+ String Save;
+ char *Part;
+
+ strmaxcpy(IncludeList, Save, STRINGSIZE);
+ IncludeList[0] = '\0';
+ while (Save[0] != '\0')
+ {
+ Part = GetPath(Save);
+ if (strcmp(Part, RemPath))
+ {
+ if (IncludeList[0] != '\0')
+ strmaxcat(IncludeList, SDIRSEP, STRINGSIZE);
+ strmaxcat(IncludeList, Part, STRINGSIZE);
+ }
+ }
+}
+
+/****************************************************************************/
+/* Listen mit Ausgabedateien */
+
+void ClearOutList(void)
+{
+ ClearStringList(&OutList);
+}
+
+void AddToOutList(const char *NewName)
+{
+ AddStringListLast(&OutList, NewName);
+}
+
+void RemoveFromOutList(const char *OldName)
+{
+ RemoveStringList(&OutList, OldName);
+}
+
+char *GetFromOutList(void)
+{
+ return GetAndCutStringList(&OutList);
+}
+
+void ClearShareOutList(void)
+{
+ ClearStringList(&ShareOutList);
+}
+
+void AddToShareOutList(const char *NewName)
+{
+ AddStringListLast(&ShareOutList, NewName);
+}
+
+void RemoveFromShareOutList(const char *OldName)
+{
+ RemoveStringList(&ShareOutList, OldName);
+}
+
+char *GetFromShareOutList(void)
+{
+ return GetAndCutStringList(&ShareOutList);
+}
+
+void ClearListOutList(void)
+{
+ ClearStringList(&ListOutList);
+}
+
+void AddToListOutList(const char *NewName)
+{
+ AddStringListLast(&ListOutList, NewName);
+}
+
+void RemoveFromListOutList(const char *OldName)
+{
+ RemoveStringList(&ListOutList, OldName);
+}
+
+char *GetFromListOutList(void)
+{
+ return GetAndCutStringList(&ListOutList);
+}
+
+/****************************************************************************/
+/* Tokenverarbeitung */
+
+static Boolean CompressLine_NErl(char ch)
+{
+ return (((ch >= 'A') && (ch <= 'Z'))
+ || ((ch >= 'a') && (ch <= 'z'))
+ || ((ch >= '0') && (ch <= '9')));
+}
+
+typedef int (*tCompareFnc)(const char *s1, const char *s2, size_t n);
+
+int ReplaceLine(as_dynstr_t *p_str, const char *pSearch, const char *pReplace, Boolean CaseSensitive)
+{
+ int SearchLen = strlen(pSearch), ReplaceLen = strlen(pReplace), StrLen = strlen(p_str->p_str), DeltaLen = ReplaceLen - SearchLen;
+ int NumReplace = 0, Pos, End, CmpRes, Avail, nCopy, nMove;
+ tCompareFnc Compare = CaseSensitive ? strncmp : as_strncasecmp;
+
+ Pos = 0;
+ while (Pos <= StrLen - SearchLen)
+ {
+ End = Pos + SearchLen;
+ CmpRes = Compare(&p_str->p_str[Pos], pSearch, SearchLen);
+ if ((!CmpRes)
+ && ((Pos == 0) || (!CompressLine_NErl(p_str->p_str[Pos - 1])))
+ && ((End >= StrLen) || (!CompressLine_NErl(p_str->p_str[End]))))
+ {
+ if (StrLen + DeltaLen + 1 > (int)p_str->capacity)
+ as_dynstr_realloc(p_str, as_dynstr_roundup_len(p_str->capacity + DeltaLen));
+ Avail = p_str->capacity - 1 - Pos;
+ nCopy = ReplaceLen; if (nCopy > Avail) nCopy = Avail;
+ Avail -= nCopy;
+ nMove = StrLen - (Pos + SearchLen); if (nMove > Avail) nMove = Avail;
+ memmove(&p_str->p_str[Pos + nCopy], &p_str->p_str[Pos + SearchLen], nMove);
+ memcpy(&p_str->p_str[Pos], pReplace, nCopy);
+ p_str->p_str[Pos + nCopy + nMove] = '\0';
+ Pos += nCopy;
+ StrLen += DeltaLen;
+ NumReplace++;
+ }
+ else
+ Pos++;
+ }
+ return NumReplace;
+}
+
+static void SetToken(char *Token, unsigned TokenNum)
+{
+ Token[0] = (TokenNum >> 4) + 1;
+ Token[1] = (TokenNum & 15) + 1;
+ Token[2] = 0;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn CompressLine(const char *TokNam, unsigned TokenNum, as_dynstr_t *p_str, Boolean ThisCaseSensitive)
+ * \brief compress tokens in line
+ * \param TokNam name to compress into token
+ * \param TokenNum token #
+ * \param p_str string to work on
+ * \param ThisCaseSensitive operate case sensitive?
+ * ------------------------------------------------------------------------ */
+
+int CompressLine(const char *TokNam, unsigned TokenNum, as_dynstr_t *p_str, Boolean ThisCaseSensitive)
+{
+ char Token[3];
+ SetToken(Token, TokenNum);
+ return ReplaceLine(p_str, TokNam, Token, ThisCaseSensitive);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ExpandLine(const char *TokNam, unsigned TokenNum, as_dynstr_t *p_str)
+ * \brief expand tokens in line
+ * \param TokNam name to expand token to
+ * \param TokenNum token #
+ * \param p_str string to work on
+ * ------------------------------------------------------------------------ */
+
+void ExpandLine(const char *TokNam, unsigned TokenNum, as_dynstr_t *p_str)
+{
+ char Token[3];
+ SetToken(Token, TokenNum);
+ (void)ReplaceLine(p_str, Token, TokNam, True);
+}
+
+void KillCtrl(char *Line)
+{
+ char *z;
+
+ if (*(z = Line) == '\0')
+ return;
+ do
+ {
+ if (*z == '\0');
+ else if (*z == Char_HT)
+ {
+ strmov(z, z + 1);
+ strprep(z, Blanks(8 - ((z - Line) % 8)));
+ }
+ else if ((*z & 0xe0) == 0)
+ *z = ' ';
+ z++;
+ }
+ while (*z != '\0');
+}
+
+/****************************************************************************/
+/* Buchhaltung */
+
+void BookKeeping(void)
+{
+ if (MakeUseList)
+ if (AddChunk(SegChunks + ActPC, ProgCounter(), CodeLen, ActPC == SegCode))
+ WrError(ErrNum_Overlap);
+ if (DebugMode != DebugNone)
+ {
+ AddSectionUsage(ProgCounter(), CodeLen);
+ AddLineInfo(InMacroFlag, CurrLine, CurrFileName, ActPC, PCs[ActPC], CodeLen);
+ }
+}
+
+/****************************************************************************/
+/* Differenz zwischen zwei Zeiten mit Tagesueberlauf berechnen */
+
+long DTime(long t1, long t2)
+{
+ LongInt d;
+
+ d = t2 - t1;
+ if (d < 0) d += (24*360000);
+ return (d > 0) ? d : -d;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Init/Deinit passes */
+
+typedef struct sProcStore
+{
+ struct sProcStore *pNext;
+ SimpProc Proc;
+} tProcStore;
+
+static tProcStore *pInitPassProcStore = NULL,
+ *pClearUpProcStore = NULL;
+
+void InitPass(void)
+{
+ tProcStore *pStore;
+
+ for (pStore = pInitPassProcStore; pStore; pStore = pStore->pNext)
+ pStore->Proc();
+}
+
+void ClearUp(void)
+{
+ tProcStore *pStore;
+
+ for (pStore = pClearUpProcStore; pStore; pStore = pStore->pNext)
+ pStore->Proc();
+}
+
+void AddInitPassProc(SimpProc NewProc)
+{
+ tProcStore *pNewStore = (tProcStore*)calloc(1, sizeof(*pNewStore));
+
+ pNewStore->pNext = pInitPassProcStore;
+ pNewStore->Proc = NewProc;
+ pInitPassProcStore = pNewStore;
+}
+
+void AddClearUpProc(SimpProc NewProc)
+{
+ tProcStore *pNewStore = (tProcStore*)calloc(1, sizeof(*pNewStore));
+
+ pNewStore->pNext = pClearUpProcStore;
+ pNewStore->Proc = NewProc;
+ pClearUpProcStore = pNewStore;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Zeit holen */
+
+#ifdef __MSDOS__
+
+#include <dos.h>
+
+long GTime(void)
+{
+ struct time tbuf;
+ long result;
+
+ gettime(&tbuf);
+ result = tbuf.ti_hour;
+ result = (result * 60) + tbuf.ti_min;
+ result = (result * 60) + tbuf.ti_sec;
+ result = (result * 100) + tbuf.ti_hund;
+ return result;
+}
+
+#elif __IBMC__
+
+#include <time.h>
+#define INCL_DOSDATETIME
+#include <os2.h>
+
+long GTime(void)
+{
+ DATETIME dt;
+ struct tm ts;
+ DosGetDateTime(&dt);
+ memset(&ts, 0, sizeof(ts));
+ ts.tm_year = dt.year - 1900;
+ ts.tm_mon = dt.month - 1;
+ ts.tm_mday = dt.day;
+ ts.tm_hour = dt.hours;
+ ts.tm_min = dt.minutes;
+ ts.tm_sec = dt.seconds;
+ return (mktime(&ts) * 100) + (dt.hundredths);
+}
+
+#elif __MINGW32__
+
+/* distribution by Gunnar Wallmann */
+
+#include <sys/time.h>
+#include "math64.h"
+
+/*time from 1 Jan 1601 to 1 Jan 1970 in 100ns units */
+
+typedef struct _FILETIME
+{
+ unsigned long dwLowDateTime;
+ unsigned long dwHighDateTime;
+} FILETIME;
+
+void __stdcall GetSystemTimeAsFileTime(FILETIME*);
+
+long GTime(void)
+{
+ union
+ {
+#ifndef NOLONGLONG
+ long long ns100; /*time since 1 Jan 1601 in 100ns units */
+#endif
+ FILETIME ft;
+ } _now;
+
+ GetSystemTimeAsFileTime(&(_now.ft));
+#ifdef NOLONGLONG
+ {
+ static const t64 offs = { 0xd53e8000, 0x019db1de },
+ div = { 100000, 0 };
+ t64 acc;
+
+ acc.low = _now.ft.dwLowDateTime;
+ acc.high = _now.ft.dwHighDateTime;
+ sub64(&acc, &acc, &offs);
+ div64(&acc, &acc, &div);
+ return acc.low;
+ }
+#else
+# define _W32_FT_OFFSET (116444736000000000LL)
+ return (_now.ns100 - _W32_FT_OFFSET) / 100000LL;
+#endif
+}
+
+#else
+
+#include <sys/time.h>
+
+long GTime(void)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return (tv.tv_sec*100) + (tv.tv_usec/10000);
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+/* Stackfehler abfangen - bis auf DOS nur Dummies */
+
+#ifdef __TURBOC__
+
+#ifdef __DPMI16__
+#else
+unsigned _stklen = STKSIZE;
+unsigned _ovrbuffer = 64*48;
+#endif
+#include <malloc.h>
+
+void ChkStack(void)
+{
+ LongWord avail = stackavail();
+ if (avail < MinStack)
+ WrError(ErrNum_StackOvfl);
+ if (avail < LowStack)
+ LowStack = avail;
+}
+
+void ResetStack(void)
+{
+ LowStack = stackavail();
+}
+
+LongWord StackRes(void)
+{
+ return LowStack - MinStack;
+}
+#endif /* __TURBOC__ */
+
+#ifdef CKMALLOC
+#undef malloc
+#undef realloc
+
+void *ckmalloc(size_t s)
+{
+ void *tmp;
+
+#ifdef __TURBOC__
+ if (coreleft() < HEAPRESERVE + s)
+ WrError(ErrNum_HeapOvfl);
+#endif
+
+ tmp = malloc(s);
+ if (!tmp && (s > 0))
+ WrError(ErrNum_HeapOvfl);
+ return tmp;
+}
+
+void *ckrealloc(void *p, size_t s)
+{
+ void *tmp;
+
+#ifdef __TURBOC__
+ if (coreleft() < HEAPRESERVE + s)
+ WrError(ErrNum_HeapOvfl);
+#endif
+
+ tmp = realloc(p, s);
+ if (!tmp)
+ WrError(ErrNum_HeapOvfl);
+ return tmp;
+}
+#endif
+
+static void SetValidSymChar(unsigned Ch, Byte Value)
+{
+ ValidSymChar[Ch] = Value;
+}
+
+static void SetValidSymChars(unsigned Start, unsigned Stop, Byte Value)
+{
+ for (; Start <= Stop; Start++)
+ SetValidSymChar(Start, Value);
+}
+
+void asmsub_init(void)
+{
+#ifdef __TURBOC__
+#ifdef __MSDOS__
+#ifdef __DPMI16__
+ char *MemFlag, *p;
+ String MemVal, TempName;
+ unsigned long FileLen;
+#else
+ char *envval;
+ int ovrerg;
+#endif
+#endif
+#endif
+
+ InitStringList(&CopyrightList);
+ InitStringList(&OutList);
+ InitStringList(&ShareOutList);
+ InitStringList(&ListOutList);
+
+#ifdef __TURBOC__
+#ifdef __MSDOS__
+#ifdef __DPMI16__
+ /* Fuer DPMI evtl. Swapfile anlegen */
+
+ MemFlag = getenv("ASXSWAP");
+ if (MemFlag)
+ {
+ strmaxcpy(MemVal, MemFlag, STRINGSIZE);
+ p = strchr(MemVal, ',');
+ if (!p)
+ strcpy(TempName, "ASX.TMP");
+ else
+ {
+ *p = NULL;
+ strcpy(TempName, MemVal);
+ strmov(MemVal, p + 1);
+ };
+ KillBlanks(TempName);
+ KillBlanks(MemVal);
+ FileLen = strtol(MemFlag, &p, 0);
+ if (*p != '\0')
+ {
+ fputs(getmessage(Num_ErrMsgInvSwapSize), stderr);
+ exit(4);
+ }
+ if (MEMinitSwapFile(TempName, FileLen << 20) != RTM_OK)
+ {
+ fputs(getmessage(Num_ErrMsgSwapTooBig), stderr);
+ exit(4);
+ }
+ }
+#else
+ /* Bei DOS Auslagerung Overlays in XMS/EMS versuchen */
+
+ envval = getenv("USEXMS");
+ if ((envval) && (as_toupper(*envval) == 'N'))
+ ovrerg = -1;
+ else
+ ovrerg = _OvrInitExt(0, 0);
+ if (ovrerg != 0)
+ {
+ envval = getenv("USEEMS");
+ if ((!envval) || (as_toupper(*envval) != 'N'))
+ _OvrInitEms(0, 0, 0);
+ }
+#endif
+#endif
+#endif
+
+#ifdef __TURBOC__
+ StartStack = stackavail();
+ LowStack = stackavail();
+ MinStack = StartStack - STKSIZE + 0x800;
+#else
+ StartStack = LowStack = MinStack = 0;
+#endif
+
+ /* initialize array of valid characters */
+
+ ValidSymCharLen = (NLS_GetCodepage() == eCodepageUTF8) ? 1280 : 256;
+ ValidSymChar = (Byte*) calloc(ValidSymCharLen, sizeof(Byte));
+
+ /* The basic ASCII stuff: letters, dot and underbar are allowed
+ anwhere, numbers not at beginning: */
+
+ SetValidSymChars('a', 'z', VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars('A', 'Z', VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars('0', '9', VALID_SN | VALID_MN);
+ SetValidSymChar ('.' , VALID_S1 | VALID_SN );
+ SetValidSymChar ('_' , VALID_S1 | VALID_SN );
+
+ /* Extensions, depending on character set: */
+
+ switch (NLS_GetCodepage())
+ {
+ case eCodepage1251:
+ SetValidSymChar (0xa3 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xb3 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xa8 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xb8 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xaa , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xba , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xaf , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xbf , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xbd , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xbe , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ goto iso8859_1;
+ case eCodepage1252:
+ SetValidSymChar (0x8a , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0x9a , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0x8c , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0x9c , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0x8e , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0x9e , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0x9f , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ goto iso8859_1;
+ case eCodepage850:
+ SetValidSymChars(0xb5, 0xb7, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars(0xc6, 0xc7, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars(0xd0, 0xd9, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xde , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars(0xe0, 0xed, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ /* fall-through */
+ case eCodepage437:
+ SetValidSymChars(128, 165, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (225 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ break;
+ case eCodepage866:
+ SetValidSymChars(0x80, 0xaf, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars(0xe0, 0xf7, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ break;
+ case eCodepageISO8859_15:
+ SetValidSymChar (0xa6 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xa8 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xb4 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xb8 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xbc , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xbd , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xbe , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ /* fall-through */
+ case eCodepageISO8859_1:
+ iso8859_1:
+ SetValidSymChar (0xa1 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xa2 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars(0xc0, 0xff, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ break;
+ case eCodepageKOI8_R:
+ SetValidSymChar (0xa3 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (0xb3 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars(0xc0, 0xff, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ break;
+ case eCodepageUTF8:
+ {
+ const tNLSCharacterTab *pTab = GetCharacterTab(eCodepageUTF8);
+ tNLSCharacter ch;
+ unsigned Unicode;
+ const char *pCh;
+
+ for (ch = (tNLSCharacter)0; ch < eCH_cnt; ch++)
+ {
+ if ((ch == eCH_e2) || (ch == eCH_mu) || (ch == eCH_iquest) || (ch == eCH_iexcl))
+ continue;
+ pCh = &((*pTab)[ch][0]);
+ Unicode = UTF8ToUnicode(&pCh);
+ if (Unicode < ValidSymCharLen)
+ SetValidSymChar (Unicode, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ }
+
+ /* Greek */
+
+ SetValidSymChar ( 895 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar ( 902 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (1011 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (1016 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (1018 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChar (1019 , VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars( 904, 974, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars( 984, 1007, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+
+ /* Cyrillic */
+
+ SetValidSymChars(0x400, 0x481, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ SetValidSymChars(0x48a, 0x4ff, VALID_S1 | VALID_SN | VALID_M1 | VALID_MN);
+ }
+ default:
+ break;
+ }
+
+#if 0
+ for (z = 0; z < ValidSymCharLen; z++)
+ {
+ if (!(z & 15))
+ fprintf(stderr, "%02x:", z);
+ fprintf(stderr, " %x", ValidSymChar[z]);
+ if ((z & 15) == 15)
+ fprintf(stderr, "\n");
+ }
+#endif
+
+ version_init();
+}
--- /dev/null
+#ifndef _ASMSUB_H
+#define _ASMSUB_H
+/* asmsub.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Unterfunktionen, vermischtes */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+
+#define LISTLINESPACE 20
+
+struct sLineComp;
+struct sStrComp;
+struct as_dynstr;
+
+typedef void (*TSwitchProc)(
+#ifdef __PROTOS__
+void
+#endif
+);
+
+
+extern void AsmSubPassInit(void);
+
+
+extern long GTime(void);
+
+
+extern void UpString(char *s);
+
+extern char *QuotPosQualify(const char *s, char Zeichen, tQualifyQuoteFnc QualifyQuoteFnc);
+#define QuotPos(s, Zeichen) QuotPosQualify(s, Zeichen, NULL)
+extern char *QuotMultPosQualify(const char *s, const char *pSearch, tQualifyQuoteFnc QualifyQuoteFnc);
+#define QuotMultPos(s, pSearch) QuotMultPosQualify(s, pSearch, NULL)
+extern char *QuotSMultPosQualify(const char *s, const char *pStrs, tQualifyQuoteFnc QualifyQuoteFnc);
+#define QuotSMultPos(s, pStrs) QuotSMultPosQualify(s, pStrs, NULL)
+
+extern char *RQuotPos(char *s, char Zeichen);
+
+extern char *FirstBlank(const char *s);
+
+extern void SplitString(char *Source, char *Left, char *Right, char *Trenner);
+
+extern void TranslateString(char *s, int Length);
+
+extern ShortInt StrCaseCmp(const char *s1, const char *s2, LongInt Hand1, LongInt Hand2);
+
+extern char *MatchChars(const char *pStr, const char *pPattern, ...);
+extern char *MatchCharsRev(const char *pStr, const char *pPattern, ...);
+
+extern char *FindClosingParenthese(const char *pStr);
+
+extern char *FindOpeningParenthese(const char *pStrBegin, const char *pStrEnd, const char Bracks[2]);
+
+#ifdef PROFILE_MEMO
+static inline Boolean Memo(const char *s)
+{
+ NumMemo++;
+ return !strcmp(OpPart.str.p_str, s);
+}
+#else
+# define Memo(s) (!strcmp(OpPart.str.p_str, (s)))
+#endif
+
+
+extern void AddSuffix(char *s, const char *Suff);
+
+extern void KillSuffix(char *s);
+
+extern const char *NamePart(const char *Name);
+
+extern char *PathPart(char *Name);
+
+
+extern void FloatString(char *pDest, size_t DestSize, Double f);
+
+extern void StrSym(const TempResult *t, Boolean WithSystem, struct as_dynstr *p_dest, unsigned Radix);
+
+
+extern void ResetPageCounter(void);
+
+extern void NewPage(ShortInt Level, Boolean WithFF);
+
+extern void WrLstLine(const char *Line);
+
+extern void SetListLineVal(TempResult *t);
+
+extern void LimitListLine(void);
+
+extern void PrintOneLineMuted(FILE *pFile, const char *pLine,
+ const struct sLineComp *pMuteComponent,
+ const struct sLineComp *pMuteComponent2);
+extern void PrLineMarker(FILE *pFile, const char *pLine, const char *pPrefix, const char *pTrailer,
+ char Marker, const struct sLineComp *pLineComp);
+
+extern LargeWord ProgCounter(void);
+
+extern LargeWord EProgCounter(void);
+
+extern Word Granularity(void);
+
+extern Word ListGran(void);
+
+extern void ChkSpace(Byte AddrSpace, unsigned AddrSpaceMask);
+
+
+extern void PrintUseList(void);
+
+extern void ClearUseList(void);
+
+
+extern int CompressLine(const char *TokNam, unsigned TokenNum, struct as_dynstr *p_str, Boolean CaseSensitive);
+
+extern void ExpandLine(const char *TokNam, unsigned TokenNum, struct as_dynstr *p_str);
+
+extern void KillCtrl(char *Line);
+
+#ifdef __TURBOC__
+extern void ChkStack(void);
+
+extern void ResetStack(void);
+
+extern LongWord StackRes(void);
+#else
+#define ChkStack() {}
+#define ResetStack() {}
+#define StackRes() 0
+#endif
+
+
+extern void AddCopyright(const char *NewLine);
+
+extern void WriteCopyrights(TSwitchProc NxtProc);
+
+
+extern char *ChkSymbNameUpTo(const char *pSym, const char *pUpTo);
+extern Boolean ChkSymbName(const char *pSym);
+
+extern char *ChkMacSymbNameUpTo(const char *pSym, const char *pUpTo);
+extern Boolean ChkMacSymbName(const char *pSym);
+
+extern unsigned visible_strlen(const char *pSym);
+
+
+extern void AddIncludeList(char *NewPath);
+
+extern void RemoveIncludeList(char *RemPath);
+
+
+extern void ClearOutList(void);
+
+extern void AddToOutList(const char *NewName);
+
+extern void RemoveFromOutList(const char *OldName);
+
+extern char *GetFromOutList(void);
+
+
+extern void ClearShareOutList(void);
+
+extern void AddToShareOutList(const char *NewName);
+
+extern void RemoveFromShareOutList(const char *OldName);
+
+extern char *GetFromShareOutList(void);
+
+
+extern void ClearListOutList(void);
+
+extern void AddToListOutList(const char *NewName);
+
+extern void RemoveFromListOutList(const char *OldName);
+
+extern char *GetFromListOutList(void);
+
+
+extern void BookKeeping(void);
+
+
+extern long DTime(long t1, long t2);
+
+
+extern void InitPass(void);
+extern void AddInitPassProc(SimpProc NewProc);
+
+extern void ClearUp(void);
+extern void AddClearUpProc(SimpProc NewProc);
+
+extern void asmsub_init(void);
+
+#include "asmerr.h"
+
+#endif /* _ASMSUB_H */
--- /dev/null
+/* bpemu.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Emulation einiger Borland-Pascal-Funktionen */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+
+#include "strutil.h"
+#include "bpemu.h"
+
+#ifdef __MSDOS__
+#include <dos.h>
+#include <dir.h>
+#endif
+
+#if defined( __EMX__ ) || defined( __IBMC__ )
+#include <os2.h>
+#endif
+
+#ifdef __MINGW32__
+#include <direct.h>
+#endif
+
+char *FExpand(char *Src)
+{
+ static String CurrentDir;
+ String Copy;
+#ifdef DRSEP
+ String DrvPart;
+#endif /* DRSEP */
+ char *p, *p2;
+
+ strmaxcpy(Copy, Src, STRINGSIZE);
+
+#ifdef DRSEP
+ p = strchr(Copy,DRSEP);
+ if (p)
+ {
+ memcpy(DrvPart, Copy, p - Copy);
+ DrvPart[p - Copy] = '\0';
+ strmov(Copy, p + 1);
+ }
+ else
+ *DrvPart = '\0';
+#endif
+
+#if (defined __MSDOS__)
+ {
+ int DrvNum;
+
+ if (*DrvPart == '\0')
+ {
+ DrvNum = getdisk();
+ *DrvPart = DrvNum + 'A';
+ DrvPart[1] = '\0';
+ DrvNum++;
+ }
+ else
+ DrvNum = toupper(*DrvPart) - '@';
+ getcurdir(DrvNum, CurrentDir);
+ }
+#elif (defined __EMX__) || (defined __IBMC__)
+ {
+ ULONG DrvNum, Dummy;
+
+ if (*DrvPart == '\0')
+ {
+ DosQueryCurrentDisk(&DrvNum, &Dummy);
+ *DrvPart = DrvNum + '@';
+ DrvPart[1] = '\0';
+ }
+ else
+ DrvNum = toupper(*DrvPart) - '@';
+ Dummy = 255;
+ DosQueryCurrentDir(DrvNum, (PBYTE) CurrentDir, &Dummy);
+ }
+#elif (defined __MINGW32__)
+ {
+ int DrvNum;
+
+ if (!*DrvPart)
+ {
+ DrvNum = _getdrive();
+ *DrvPart = DrvNum + '@';
+ DrvPart[1] = '\0';
+ }
+ else
+ DrvNum = toupper(*DrvPart) - '@';
+ _getdcwd(DrvNum, CurrentDir, STRINGSIZE);
+ if (CurrentDir[1] == ':')
+ strmov(CurrentDir, CurrentDir + 2);
+ }
+#elif (defined _WIN32) /* CygWIN */
+ if (!getcwd(CurrentDir, STRINGSIZE))
+ 0[CurrentDir] = '\0';
+ for (p = CurrentDir; *p; p++)
+ if (*p == '/') *p = '\\';
+#else /* UNIX */
+ if (!getcwd(CurrentDir, STRINGSIZE))
+ 0[CurrentDir] = '\0';
+#endif
+
+ if ((*CurrentDir) && (CurrentDir[strlen(CurrentDir) - 1] != PATHSEP))
+ strmaxcat(CurrentDir, SPATHSEP, STRINGSIZE);
+ if (*CurrentDir!=PATHSEP)
+ strmaxprep(CurrentDir, SPATHSEP, STRINGSIZE);
+
+ if (*Copy == PATHSEP)
+ {
+ strmaxcpy(CurrentDir, SPATHSEP, STRINGSIZE);
+ strmov(Copy, Copy + 1);
+ }
+
+#ifdef DRSEP
+#ifdef __CYGWIN32__
+ /* win32 getcwd() does not deliver current drive letter, therefore only prepend a drive letter
+ if there was one before. */
+ if (*DrvPart)
+#endif
+ {
+ strmaxprep(CurrentDir, SDRSEP, STRINGSIZE);
+ strmaxprep(CurrentDir, DrvPart, STRINGSIZE);
+ }
+#endif
+
+ while (True)
+ {
+ p = strchr(Copy, PATHSEP);
+ if (!p)
+ break;
+ *p = '\0';
+ if (!strcmp(Copy, "."));
+ else if ((!strcmp(Copy, "..")) && (strlen(CurrentDir) > 1))
+ {
+ CurrentDir[strlen(CurrentDir) - 1] = '\0';
+ p2 = strrchr(CurrentDir, PATHSEP); p2[1] = '\0';
+ }
+ else
+ {
+ strmaxcat(CurrentDir, Copy, STRINGSIZE);
+ strmaxcat(CurrentDir, SPATHSEP, STRINGSIZE);
+ }
+ strmov(Copy, p + 1);
+ }
+
+ strmaxcat(CurrentDir, Copy, STRINGSIZE);
+
+ return CurrentDir;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn FSearch(char *pDest, size_t DestSize, const char *pFileToSearch, const char *pCurrFileName, const char *pSearchPath)
+ * \brief search for file in given path(s)
+ * \param pDest where to put result
+ * \param DestSize size of result buffer
+ * \param pFileToSearch file to search for
+ * \param pCurrFileName file this file was referenced from
+ * \param pSearchPath list of directories to search
+ * \return 0 if found or error code
+ * ------------------------------------------------------------------------ */
+
+static int AssembleAndCheck(char *pDest, size_t DestSize, const char *pPath, unsigned PathLen, const char *pFileToSearch)
+{
+ FILE *pDummy;
+
+ if (PathLen > DestSize - 1)
+ PathLen = DestSize - 1;
+ memcpy(pDest, pPath, PathLen);
+ pDest[PathLen] = '\0';
+#ifdef __CYGWIN32__
+ DeCygwinPath(pDest);
+#endif
+ if (PathLen > 0)
+ strmaxcat(pDest, SPATHSEP, DestSize);
+ strmaxcat(pDest, pFileToSearch, DestSize);
+ pDummy = fopen(pDest, "r");
+ if (pDummy)
+ {
+ fclose(pDummy);
+ return 0;
+ }
+ else
+ return 2;
+}
+
+int FSearch(char *pDest, size_t DestSize, const char *pFileToSearch, const char *pCurrFileName, const char *pSearchPath)
+{
+ /* If the file has an absolute path ('/....', '\....', 'X:....'), do not search relative
+ to current file's directory: */
+
+ Boolean Absolute = (*pFileToSearch == '/');
+ const char *pPos, *pStart;
+
+#if (defined _WIN32) || (defined __EMX__) || (defined __IBMC__) || (defined __MSDOS__)
+ if (*pFileToSearch == PATHSEP)
+ Absolute = True;
+#endif
+#ifdef DRSEP
+ if ((as_islower(*pFileToSearch) || as_isupper(*pFileToSearch))
+ && (pFileToSearch[1] == DRSEP))
+ Absolute = True;
+#endif
+
+ if (pCurrFileName && !Absolute)
+ {
+#if (defined _WIN32) || (defined __EMX__) || (defined __IBMC__) || (defined __MSDOS__)
+ /* On systems with \ as path separator, we may get a mixture of / and \ in the path.
+ Assure we find the last one of either: */
+
+ pPos = strrmultchr(pCurrFileName, SPATHSEP "/");
+#else
+ pPos = strrchr(pCurrFileName, PATHSEP);
+#endif
+ if (!AssembleAndCheck(pDest, DestSize, pCurrFileName, pPos ? pPos - pCurrFileName : 0, pFileToSearch))
+ return 0;
+ }
+ else
+ {
+ if (!AssembleAndCheck(pDest, DestSize, NULL, 0, pFileToSearch))
+ return 0;
+ }
+
+ /* TODO: if the file has an absolute path, searching the include path should be pointless: */
+
+ pStart = pSearchPath;
+ while (True)
+ {
+ pPos = strchr(pStart, DIRSEP);
+
+ if (!AssembleAndCheck(pDest, DestSize, pStart, pPos ? pPos - pStart : (int)strlen(pStart), pFileToSearch))
+ return 0;
+ if (pPos)
+ pStart = pPos+ 1;
+ else
+ break;
+ }
+
+ *pDest = '\0';
+ return 2;
+}
+
+long FileSize(FILE *file)
+{
+ long Save = ftell(file), Size;
+
+ fseek(file, 0, SEEK_END);
+ Size=ftell(file);
+ fseek(file, Save, SEEK_SET);
+ return Size;
+}
+
+Byte Lo(Word inp)
+{
+ return (inp & 0xff);
+}
+
+Byte Hi(Word inp)
+{
+ return ((inp >> 8) & 0xff);
+}
+
+unsigned LoWord(LongWord Src)
+{
+ return (Src & 0xffff);
+}
+
+unsigned HiWord(LongWord Src)
+{
+ return ((Src >> 16) & 0xffff);
+}
+
+unsigned long LoDWord(LargeWord Src)
+{
+ return Src & 0xfffffffful;
+}
+
+Boolean Odd(int inp)
+{
+ return ((inp & 1) == 1);
+}
+
+Boolean DirScan(char *Mask, charcallback callback)
+{
+ char Name[1024];
+
+#ifdef __MSDOS__
+ struct ffblk blk;
+ int res;
+ char *pos;
+
+ res = findfirst(Mask, &blk, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_LABEL | FA_DIREC | FA_ARCH);
+ if (res < 0)
+ return False;
+ pos = strrchr(Mask, PATHSEP);
+ if (!pos)
+ pos = strrchr(Mask, DRSEP);
+ pos = pos ? pos + 1 : Mask;
+ memcpy(Name, Mask, pos - Mask);
+ while (res==0)
+ {
+ if ((blk.ff_attrib & (FA_LABEL|FA_DIREC)) == 0)
+ {
+ strcpy(Name + (pos - Mask), blk.ff_name);
+ callback(Name);
+ }
+ res = findnext(&blk);
+ }
+ return True;
+#else
+#if defined ( __EMX__ ) || defined ( __IBMC__ )
+ HDIR hdir = 1;
+ FILEFINDBUF3 buf;
+ ULONG rescnt;
+ USHORT res;
+ char *pos;
+
+ rescnt = 1;
+ res = DosFindFirst(Mask, &hdir, 0x16, &buf, sizeof(buf), &rescnt, 1);
+ if (res)
+ return False;
+ pos = strrchr(Mask, PATHSEP);
+ if (!pos)
+ pos = strrchr(Mask, DRSEP);
+ pos = pos ? pos + 1 : Mask;
+ memcpy(Name, Mask, pos - Mask);
+ while (res == 0)
+ {
+ strcpy(Name + (pos - Mask), buf.achName);
+ callback(Name);
+ res = DosFindNext(hdir, &buf, sizeof(buf), &rescnt);
+ }
+ return True;
+#else
+ strmaxcpy(Name, Mask, sizeof(Name));
+ callback(Name);
+ return True;
+#endif
+#endif
+}
+
+LongInt MyGetFileTime(char *Name)
+{
+ struct stat st;
+
+ if (stat(Name, &st) == -1)
+ return 0;
+ else
+ return st.st_mtime;
+}
+
+#ifdef __CYGWIN32__
+
+/* convert CygWin-style paths back to something usable by other Win32 apps */
+
+char *DeCygWinDirList(char *pStr)
+{
+ char *pRun;
+
+ for (pRun = pStr; *pRun; pRun++)
+ if (*pRun == ':')
+ *pRun = ';';
+
+ return pStr;
+}
+
+char *DeCygwinPath(char *pStr)
+{
+ char *pRun;
+
+ if ((strlen(pStr) >= 4)
+ && (pStr[0] =='/') && (pStr[1] == '/') && (pStr[3] == '/')
+ && (isalpha(pStr[2])))
+ {
+ strmov(pStr, pStr + 1);
+ pStr[0] = pStr[1];
+ pStr[1] = ':';
+ }
+
+ if ((strlen(pStr) >= 4)
+ && (pStr[0] =='\\') && (pStr[1] == '\\') && (pStr[3] == '\\')
+ && (isalpha(pStr[2])))
+ {
+ strmov(pStr, pStr + 1);
+ pStr[0] = pStr[1];
+ pStr[1] = ':';
+ }
+
+ for (pRun = pStr; *pRun; pRun++)
+ if (*pRun == '/')
+ *pRun = '\\';
+
+ return pStr;
+}
+#endif /* __CYGWIN32__ */
+
+void bpemu_init(void)
+{
+}
--- /dev/null
+#ifndef _BPEMU_H
+#define _BPEMU_H
+/* bpemu.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Emulation einiger Borland-Pascal-Funktionen */
+/* */
+/* Historie: 20. 5.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+typedef void (*charcallback)(
+#ifdef __PROTOS__
+char *Name
+#endif
+);
+
+extern char *FExpand(char *Src);
+
+extern int FSearch(char *pDest, size_t DestSize, const char *FileToSearch, const char *pCurrFileName, const char *SearchPath);
+
+extern long FileSize(FILE *file);
+
+extern Byte Lo(Word inp);
+
+extern Byte Hi(Word inp);
+
+extern unsigned LoWord(LongWord Src);
+
+extern unsigned HiWord(LongWord Src);
+
+extern unsigned long LoDWord(LargeWord Src);
+
+extern Boolean Odd (int inp);
+
+extern Boolean DirScan(char *Mask, charcallback callback);
+
+extern LongInt MyGetFileTime(char *Name);
+
+#ifdef __CYGWIN32__
+extern char *DeCygWinDirList(char *pStr);
+
+extern char *DeCygwinPath(char *pStr);
+#endif
+
+extern void bpemu_init(void);
+#endif /* _BPEMU_H */
--- /dev/null
+#ifndef _CHARDEFS_H
+#define _CHARDEFS_H
+/* chardefs.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* system-dependant definition of national-specific characters */
+/* */
+/* History: 2001-10-13 /AArnold - created this header */
+/* */
+/*****************************************************************************/
+
+typedef enum
+{
+ eCH_ae,
+ eCH_ee,
+ eCH_ie,
+ eCH_oe,
+ eCH_ue,
+ eCH_Ae,
+ eCH_Ee,
+ eCH_Ie,
+ eCH_Oe,
+ eCH_Ue,
+ eCH_sz,
+ eCH_e2,
+ eCH_mu,
+ eCH_agrave,
+ eCH_Agrave,
+ eCH_egrave,
+ eCH_Egrave,
+ eCH_igrave,
+ eCH_Igrave,
+ eCH_ograve,
+ eCH_Ograve,
+ eCH_ugrave,
+ eCH_Ugrave,
+ eCH_aacute,
+ eCH_Aacute,
+ eCH_eacute,
+ eCH_Eacute,
+ eCH_iacute,
+ eCH_Iacute,
+ eCH_oacute,
+ eCH_Oacute,
+ eCH_uacute,
+ eCH_Uacute,
+ eCH_acirc,
+ eCH_Acirc,
+ eCH_ecirc,
+ eCH_Ecirc,
+ eCH_icirc,
+ eCH_Icirc,
+ eCH_ocirc,
+ eCH_Ocirc,
+ eCH_ucirc,
+ eCH_Ucirc,
+ eCH_ccedil,
+ eCH_Ccedil,
+ eCH_ntilde,
+ eCH_Ntilde,
+ eCH_aring,
+ eCH_Aring,
+ eCH_aelig,
+ eCH_Aelig,
+ eCH_oslash,
+ eCH_Oslash,
+ eCH_iquest,
+ eCH_iexcl,
+ eCH_cnt
+} tNLSCharacter;
+
+#ifdef __cplusplus
+# include "cppops.h"
+DefCPPOps_Enum(tNLSCharacter)
+#endif
+
+typedef char tNLSCharacterTab[eCH_cnt][2];
+
+typedef enum
+{
+ eCodepageASCII,
+ eCodepageISO8859_1,
+ eCodepageISO8859_15,
+ eCodepageKOI8_R,
+ eCodepage437,
+ eCodepage850,
+ eCodepage866,
+ eCodepage1251,
+ eCodepage1252,
+ eCodepageUTF8,
+ eCodepageCnt
+} tCodepage;
+
+#ifdef __cplusplus
+# include "cppops.h"
+DefCPPOps_Enum(tCodepage)
+#endif
+
+#include "datatypes.h"
+
+extern const tNLSCharacterTab *GetCharacterTab(tCodepage Codepage);
+
+extern const char NLS_HtmlCharacterTab[eCH_cnt][9];
+
+extern int CharTab_GetLength(const tNLSCharacterTab *pTab, tNLSCharacter Character);
+
+extern const char *CharTab_GetNULTermString(const tNLSCharacterTab *pTab, tNLSCharacter Character, char *pBuffer);
+
+extern LongWord UTF8ToUnicode(const char* *ppChr);
+
+extern void UnicodeToUTF8(char* *ppChr, LongWord Unicode);
+
+#endif /* _CHARDEFS_H */
--- /dev/null
+#ifndef _CHUNKS_H
+#define _CHUNKS_H
+/* chunks.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Verwaltung von Adressbereichslisten */
+/* */
+/* Historie: 16. 5.1996 Grundsteinlegung */
+/* 16. 8.1998 Min/Max-Ausgabe */
+/* */
+/*****************************************************************************/
+
+typedef struct
+{
+ LargeWord Start, Length;
+} OneChunk;
+
+typedef struct
+{
+ Word RealLen,AllocLen;
+ OneChunk *Chunks;
+} ChunkList;
+
+
+extern Boolean AddChunk(ChunkList *NChunk, LargeWord NewStart, LargeWord NewLen, Boolean Warn);
+
+extern void DeleteChunk(ChunkList *NChunk, LargeWord DelStart, LargeWord DelLen);
+
+extern Boolean AddressInChunk(ChunkList *NChunk, LargeWord Address);
+
+extern void SortChunks(ChunkList *NChunk);
+
+extern void InitChunk(ChunkList *NChunk);
+
+extern void ClearChunk(ChunkList *NChunk);
+
+extern LargeWord ChunkMin(ChunkList *NChunk);
+
+extern LargeWord ChunkMax(ChunkList *NChunk);
+
+extern LargeWord ChunkSum(ChunkList *NChunk);
+
+
+extern void chunks_init(void);
+#endif /* _CHUNKS_H */
--- /dev/null
+#ifndef _CODEPSEUDO_H
+#define _CODEPSEUDO_H
+/* codepseudo.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Haeufiger benutzte Pseudo-Befehle */
+/* */
+/*****************************************************************************/
+
+#include "addrspace.h"
+
+struct _ASSUMERec;
+
+extern int FindInst(void *Field, int Size, int Count);
+
+extern Boolean IsIndirectGen(const char *Asc, const char *pBeginEnd);
+extern Boolean IsIndirect(const char *Asc);
+
+typedef int (*tDispBaseSplitQualifier)(const char *pArg, int StartPos, int SplitPos);
+extern int FindDispBaseSplitWithQualifier(const char *pArg, int *pArgLen, tDispBaseSplitQualifier Qualifier);
+#define FindDispBaseSplit(pArg, pArgLen) FindDispBaseSplitWithQualifier(pArg, pArgLen, NULL)
+
+extern void CodeEquate(as_addrspace_t DestSeg, LargeInt Min, LargeInt Max);
+
+extern Boolean QualifyQuote_SingleQuoteConstant(const char *pStart, const char *pQuotePos);
+
+#endif /* _CODEPSEUDO_H */
--- /dev/null
+/* codevars.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Gemeinsame Variablen aller Codegeneratoren */
+/* */
+/* Historie: 26.5.1997 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+
+#include "asmitree.h"
+
+int InstrZ;
+int AdrCnt;
+PInstTable InstTable;
--- /dev/null
+#ifndef _CODEVARS_H
+#define _CODEVARS_H
+/* codevars.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Gemeinsame Variablen aller Codegeneratoren */
+/* */
+/* Historie: 26.5.1997 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+extern int InstrZ;
+extern int AdrCnt;
+
+extern PInstTable InstTable;
+
+#endif /* _CODEVARS_H */
--- /dev/null
+#ifndef _CONSOLE_H
+#define _CONSOLE_H
+/* console.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS Port */
+/* */
+/* Console Output Handling */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+
+extern void WrConsoleLine(const char *pLine, Boolean NewLine);
+
+#endif /* _CONSOLE_H */
--- /dev/null
+#ifndef _CPPOPS_H
+#define _CPPOPS_H
+
+#define DefCPPOps_Mask(datatype)\
+\
+static inline datatype operator|=(datatype &lhs, datatype rhs)\
+{\
+ lhs = (datatype)(((int)lhs) | ((int)rhs));\
+ return lhs;\
+}\
+\
+static inline datatype operator&=(datatype &lhs, datatype rhs)\
+{\
+ lhs = (datatype)(((int)lhs) & ((int)rhs));\
+ return lhs;\
+}\
+\
+static inline datatype operator|(datatype lhs, datatype rhs)\
+{\
+ return (datatype)(((int)lhs) | ((int)rhs));\
+}\
+\
+static inline datatype operator&(datatype lhs, datatype rhs)\
+{\
+ return (datatype)(((int)lhs) & ((int)rhs));\
+}\
+\
+static inline datatype operator~(datatype rhs)\
+{\
+ return (datatype)(~((int)rhs));\
+}\
+
+#define DefCPPOps_Enum(datatype)\
+\
+static inline datatype operator++(datatype &rhs, int)\
+{\
+ datatype old = rhs;\
+ rhs = (datatype)((int)rhs + 1);\
+ return old;\
+}\
+\
+static inline datatype operator--(datatype &rhs, int)\
+{\
+ datatype old = rhs;\
+ rhs = (datatype)((int)rhs - 1);\
+ return old;\
+}\
+\
+static inline datatype operator+(datatype lhs, int rhs)\
+{\
+ return (datatype)((int)lhs + rhs);\
+}\
+\
+static inline datatype operator-(datatype lhs, int rhs)\
+{\
+ return (datatype)((int)lhs - rhs);\
+}\
+
+#endif /* _CPPOPS_H */
--- /dev/null
+/* cpulist.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* Manages CPU List */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+#include "strutil.h"
+
+#include "cpulist.h"
+
+static tpCPUDef FirstCPUDef; /* Liste mit Prozessordefinitionen */
+static CPUVar CPUCnt; /* Gesamtzahl Prozessoren */
+static int MaxNameLen = 0;
+
+/****************************************************************************/
+/* neuen Prozessor definieren */
+
+CPUVar AddCPUUserWithArgs(const char *NewName, tCPUSwitchUserProc Switcher, void *pUserData, tCPUFreeUserDataProc Freeer, const tCPUArg *pArgs)
+{
+ tpCPUDef Lauf, Neu;
+ char *p;
+ int l;
+
+ Neu = (tpCPUDef) malloc(sizeof(tCPUDef));
+ Neu->Name = as_strdup(NewName);
+ Neu->pArgs = pArgs;
+ /* kein UpString, weil noch nicht initialisiert ! */
+ for (p = Neu->Name; *p != '\0'; p++)
+ *p = as_toupper(*p);
+ Neu->SwitchProc = Switcher;
+ Neu->FreeProc = Freeer;
+ Neu->pUserData = pUserData;
+ Neu->Next = NULL;
+ Neu->Number = Neu->Orig = CPUCnt;
+
+ l = strlen(NewName);
+ if (l > MaxNameLen)
+ MaxNameLen = l;
+
+ Lauf = FirstCPUDef;
+ if (!Lauf)
+ FirstCPUDef = Neu;
+ else
+ {
+ while (Lauf->Next)
+ Lauf = Lauf->Next;
+ Lauf->Next = Neu;
+ }
+
+ return CPUCnt++;
+}
+
+typedef struct
+{
+ tCPUSwitchProc Switcher;
+} tNoUserData;
+
+static void SwitchNoUserProc(void *pUserData)
+{
+ ((tNoUserData*)pUserData)->Switcher();
+}
+
+static void FreeNoUserProc(void *pUserData)
+{
+ free(pUserData);
+}
+
+CPUVar AddCPUWithArgs(const char *NewName, tCPUSwitchProc Switcher, const tCPUArg *pArgs)
+{
+ tNoUserData *pData = (tNoUserData*)malloc(sizeof(*pData));
+
+ pData->Switcher = Switcher;
+ return AddCPUUserWithArgs(NewName, SwitchNoUserProc, pData, FreeNoUserProc, pArgs);
+}
+
+Boolean AddCPUAlias(char *OrigName, char *AliasName)
+{
+ tpCPUDef Lauf = FirstCPUDef, Neu;
+
+ while ((Lauf) && (strcmp(Lauf->Name, OrigName)))
+ Lauf = Lauf->Next;
+
+ if (!Lauf)
+ return False;
+ else
+ {
+ Neu = (tpCPUDef) malloc(sizeof(tCPUDef));
+ Neu->Next = NULL;
+ Neu->Name = as_strdup(AliasName);
+ Neu->Number = CPUCnt++;
+ Neu->Orig = Lauf->Orig;
+ Neu->SwitchProc = Lauf->SwitchProc;
+ Neu->FreeProc = Lauf->FreeProc;
+ Neu->pUserData = Lauf->pUserData;
+ Neu->pArgs = Lauf->pArgs;
+ while (Lauf->Next)
+ Lauf = Lauf->Next;
+ Lauf->Next = Neu;
+ return True;
+ }
+}
+
+void IterateCPUList(tCPUListIterator Iterator, void *pUser)
+{
+ tpCPUDef pRun;
+
+ for (pRun= FirstCPUDef; pRun; pRun = pRun->Next)
+ Iterator(pRun, pUser);
+}
+
+typedef struct
+{
+ int cnt, perline;
+ tCPUSwitchUserProc Proc;
+ tCPUSwitchProc NoUserProc;
+ tPrintNextCPUProc NxtProc;
+} tPrintContext;
+
+static void PrintIterator(const tCPUDef *pCPUDef, void *pUser)
+{
+ tPrintContext *pContext = (tPrintContext*)pUser;
+
+ /* ignore aliases */
+
+ if (pCPUDef->Number == pCPUDef->Orig)
+ {
+ tCPUSwitchProc ThisNoUserProc = (pCPUDef->SwitchProc == SwitchNoUserProc) ? ((tNoUserData*)pCPUDef->pUserData)->Switcher : NULL;
+ Boolean Unequal;
+
+ if (pCPUDef->SwitchProc != pContext->Proc)
+ Unequal = True;
+ else if (pCPUDef->SwitchProc == SwitchNoUserProc)
+ Unequal = (pContext->NoUserProc != ThisNoUserProc);
+ else
+ Unequal = False;
+ if (Unequal || (pContext->cnt == pContext->perline))
+ {
+ pContext->Proc = pCPUDef->SwitchProc;
+ pContext->NoUserProc = ThisNoUserProc;
+ printf("\n");
+ pContext->NxtProc();
+ pContext->cnt = 0;
+ }
+ printf("%-*s", MaxNameLen + 1, pCPUDef->Name);
+ pContext->cnt++;
+ }
+}
+
+void PrintCPUList(tPrintNextCPUProc NxtProc)
+{
+ tPrintContext Context;
+
+ Context.Proc = NULL;
+ Context.NoUserProc = NULL;
+ Context.cnt = 0;
+ Context.NxtProc = NxtProc;
+ Context.perline = 79 / (MaxNameLen + 1);
+ IterateCPUList(PrintIterator, &Context);
+ printf("\n");
+ NxtProc();
+}
+
+void ClearCPUList(void)
+{
+ tpCPUDef Save;
+
+ while (FirstCPUDef)
+ {
+ Save = FirstCPUDef;
+ FirstCPUDef = Save->Next;
+ free(Save->Name);
+ if (Save->FreeProc)
+ Save->FreeProc(Save->pUserData);
+ free(Save);
+ }
+}
+
+const tCPUDef *LookupCPUDefByVar(CPUVar Var)
+{
+ tpCPUDef pRun;
+
+ for (pRun = FirstCPUDef; pRun; pRun = pRun->Next)
+ if (pRun->Number == Var)
+ break;
+ return pRun;
+}
+
+const tCPUDef *LookupCPUDefByName(const char *pName)
+{
+ tpCPUDef pRun;
+
+ for (pRun = FirstCPUDef; pRun; pRun = pRun->Next)
+ {
+ int l = strlen(pRun->Name);
+
+ if (strncmp(pRun->Name, pName, l))
+ continue;
+ if ((pName[l] == '\0') || (pName[l] == ':'))
+ break;
+ }
+ return pRun;
+}
+
+void cpulist_init(void)
+{
+ FirstCPUDef = NULL;
+ CPUCnt = 0;
+}
--- /dev/null
+#ifndef _CPULIST_H
+#define _CPULIST_H
+/* cpulist.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* Manages CPU List */
+/* */
+/*****************************************************************************/
+
+typedef void (*tCPUSwitchProc)(
+#ifdef __PROTOS__
+void
+#endif
+);
+
+typedef void (*tCPUSwitchUserProc)(
+#ifdef __PROTOS__
+void *pUserData
+#endif
+);
+
+typedef void (*tPrintNextCPUProc)(
+#ifdef __PROTOS__
+void
+#endif
+);
+
+typedef void (*tCPUFreeUserDataProc)(void *pUserData);
+
+typedef unsigned CPUVar;
+#define CPUNone ((CPUVar)-1)
+
+typedef struct sCPUArg
+{
+ const char *pName;
+ const LongInt Min, Max, DefValue;
+ LongInt *pValue;
+} tCPUArg;
+
+typedef struct sCPUDef
+{
+ struct sCPUDef *Next;
+ char *Name;
+ CPUVar Number, Orig;
+ tCPUSwitchUserProc SwitchProc;
+ tCPUFreeUserDataProc FreeProc;
+ void *pUserData;
+ const tCPUArg *pArgs;
+} tCPUDef, *tpCPUDef;
+
+typedef void (*tCPUListIterator)(const tCPUDef *pRun, void *pUser);
+
+extern CPUVar AddCPUWithArgs(const char *NewName, tCPUSwitchProc Switcher, const tCPUArg *pArgs);
+#define AddCPU(NewName, Switcher) AddCPUWithArgs(NewName, Switcher, NULL)
+extern CPUVar AddCPUUserWithArgs(const char *NewName, tCPUSwitchUserProc Switcher, void *pUserData, tCPUFreeUserDataProc Freeer, const tCPUArg *pArgs);
+#define AddCPUUser(NewName, Switcher, pUserData, Freeer) AddCPUUserWithArgs(NewName, Switcher, pUserData, Freeer, NULL)
+
+extern Boolean AddCPUAlias(char *OrigName, char *AliasName);
+
+extern const tCPUDef *LookupCPUDefByVar(CPUVar Var);
+
+extern const tCPUDef *LookupCPUDefByName(const char *pName);
+
+extern void IterateCPUList(tCPUListIterator Iterator, void *pUser);
+
+extern void PrintCPUList(tPrintNextCPUProc NxtProc);
+
+extern void ClearCPUList(void);
+
+extern void cpulist_init(void);
+
+#endif /* _CPULIST_H */
--- /dev/null
+#ifndef _DATATYPES_H
+#define _DATATYPES_H
+/* datatypes.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* define some handy types & constants */
+/* */
+/* History: 2001-10-13 /AArnold - created this comment */
+/* */
+/*****************************************************************************/
+
+#include "sysdefs.h"
+
+typedef Card8 Byte; /* Integertypen */
+typedef Integ8 ShortInt;
+
+#ifdef HAS16
+typedef Card16 Word;
+typedef Integ16 Integer;
+#endif
+
+typedef Card32 LongWord;
+typedef Integ32 LongInt;
+#define PRILongInt PRIInteg32
+
+#ifdef HAS64
+typedef Card64 QuadWord;
+typedef Integ64 QuadInt;
+#endif
+
+#ifdef HAS64
+typedef QuadInt LargeInt;
+typedef QuadWord LargeWord;
+#define LARGEBITS 64
+#else
+typedef LongInt LargeInt;
+typedef LongWord LargeWord;
+#define LARGEBITS 32
+#endif
+
+typedef signed int sint;
+typedef unsigned int usint;
+
+typedef char Char;
+
+typedef double Double;
+typedef float Single;
+
+typedef Byte Boolean;
+
+#ifndef STRINGSIZE
+# define STRINGSIZE 256
+#endif
+#define SHORTSTRINGSIZE 65
+
+typedef char String[STRINGSIZE];
+typedef char ShortString[SHORTSTRINGSIZE];
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef True
+#define True 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef False
+#define False 0
+#endif
+
+#endif /* _DATATYPES_H */
--- /dev/null
+/* dynstr.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* Handling of strings with dynamic allocation */
+/* */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "dynstr.h"
+
+static void check_dynamic(const as_dynstr_t *p_str)
+{
+ if (!p_str->dynamic)
+ {
+ fprintf(stderr, "attemt to resize non-dynamic string\n");
+ abort();
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_ini(as_dynstr_t *p_str, size_t AllocLen)
+ * \brief initialize empty string with given capacity
+ * \param p_str string to initialize
+ * \param AllocLen initial alloc length
+ * ------------------------------------------------------------------------ */
+
+void as_dynstr_ini(as_dynstr_t *p_str, size_t ini_capacity)
+{
+ p_str->p_str = (char*)malloc(ini_capacity);
+ p_str->capacity = p_str->p_str ? ini_capacity : 0;
+ p_str->dynamic = !!p_str->p_str;
+ memset(p_str->p_str, 0, p_str->capacity);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_ini_clone(as_dynstr_t *p_str, const as_dynstr_t *p_src)
+ * \brief initialize empty string from other string
+ * \param p_str string to initialize
+ * \param p_src string to clone
+ * ------------------------------------------------------------------------ */
+
+void as_dynstr_ini_clone(as_dynstr_t *p_str, const as_dynstr_t *p_src)
+{
+ p_str->p_str = (char*)malloc(p_src->capacity);
+ if (p_str->p_str)
+ {
+ strcpy(p_str->p_str, p_src->p_str);
+ p_str->capacity = p_src->capacity;
+ p_str->dynamic = 1;
+ }
+ else
+ {
+ p_str->capacity = 0;
+ p_str->dynamic = 0;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_ini_c_str(as_dynstr_t *p_str, const char *p_src)
+ * \brief initialize string from C string
+ * \param p_str string to initialize
+ * \param p_src init source
+ * ------------------------------------------------------------------------ */
+
+void as_dynstr_ini_c_str(as_dynstr_t *p_str, const char *p_src)
+{
+ size_t capacity = as_dynstr_roundup_len(strlen(p_src));
+
+ p_str->p_str = (char*)malloc(capacity);
+ if (p_str->p_str)
+ {
+ strcpy(p_str->p_str, p_src);
+ p_str->capacity = capacity;
+ p_str->dynamic = 1;
+ }
+ else
+ {
+ p_str->capacity = 0;
+ p_str->dynamic = 0;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_realloc(as_dynstr_t *p_str, size_t new_capacity)
+ * \brief shrink/grow string's capacity
+ * \param p_str string to adapt
+ * \param new_capacity new capacity
+ * \return 0 if success or error code
+ * ------------------------------------------------------------------------ */
+
+int as_dynstr_realloc(as_dynstr_t *p_str, size_t new_capacity)
+{
+ char *p_new;
+ size_t old_capacity;
+
+ check_dynamic(p_str);
+ p_new = (char*)realloc(p_str->p_str, new_capacity);
+ old_capacity = p_str->capacity;
+ if (p_new)
+ {
+ p_str->p_str = p_new;
+ p_str->capacity = new_capacity;
+ if (new_capacity > old_capacity)
+ memset(p_str->p_str + old_capacity, 0, new_capacity - old_capacity);
+ else if (new_capacity > 0)
+ p_str->p_str[new_capacity - 1] = '\0';
+ return 0;
+ }
+ else
+ return ENOMEM;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_free(as_dynstr_t *p_str)
+ * \brief free/destroy string
+ * \param p_str string to handle
+ * ------------------------------------------------------------------------ */
+
+void as_dynstr_free(as_dynstr_t *p_str)
+{
+ if (p_str->dynamic && p_str->p_str)
+ free(p_str->p_str);
+ p_str->p_str = NULL;
+ p_str->capacity = 0;
+ p_str->dynamic = 0;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_copy(as_dynstr_t *p_dest, const as_dynstr_t *p_src)
+ * \brief set string from other string
+ * \param p_str string to set
+ * \param p_src init source
+ * \return actual # of characters copied
+ * ------------------------------------------------------------------------ */
+
+size_t as_dynstr_copy(as_dynstr_t *p_dest, const as_dynstr_t *p_src)
+{
+ return as_dynstr_copy_c_str(p_dest, p_src->p_str);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_copy_c_str(as_dynstr_t *p_dest, const char *p_src)
+ * \brief set string from C string
+ * \param p_str string to set
+ * \param p_src init source
+ * \return actual # of characters copied
+ * ------------------------------------------------------------------------ */
+
+size_t as_dynstr_copy_c_str(as_dynstr_t *p_dest, const char *p_src)
+{
+ size_t len = strlen(p_src);
+
+ if ((len >= p_dest->capacity) && p_dest->dynamic)
+ as_dynstr_realloc(p_dest, as_dynstr_roundup_len(len));
+
+ if (len >= p_dest->capacity)
+ len = p_dest->capacity - 1;
+ memcpy(p_dest->p_str, p_src, len);
+ p_dest->p_str[len] = '\0';
+ return len;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_append_c_str(as_dynstr_t *p_dest, const char *p_src)
+ * \brief extend string
+ * \param p_dest string to extend
+ * \param p_src what to append
+ * \return actual # of bytes transferred
+ * ------------------------------------------------------------------------ */
+
+size_t as_dynstr_append_c_str(as_dynstr_t *p_dest, const char *p_src)
+{
+ size_t src_len = strlen(p_src),
+ dest_len = strlen(p_dest->p_str);
+
+ if (dest_len + src_len + 1 > p_dest->capacity)
+ as_dynstr_realloc(p_dest, as_dynstr_roundup_len(dest_len + src_len));
+ if (src_len >= p_dest->capacity - dest_len)
+ src_len = p_dest->capacity - dest_len - 1;
+ memcpy(p_dest->p_str + dest_len, p_src, src_len);
+ p_dest->p_str[dest_len + src_len] = '\0';
+ return src_len;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_dynstr_dump_hex(FILE *p_file, const as_dynstr_t *p_str)
+ * \brief debug helper
+ * \param p_file where to dump
+ * \param p_str string to dump
+ * ------------------------------------------------------------------------ */
+
+void as_dynstr_dump_hex(FILE *p_file, const as_dynstr_t *p_str)
+{
+ const char *p_run;
+
+ fprintf(p_file, "[%u]", (unsigned)p_str->capacity);
+ for (p_run = p_str->p_str; *p_run; p_run++) fprintf(p_file, " %02x", *p_run & 0xff);
+ fprintf(p_file, "\n");
+}
--- /dev/null
+#ifndef _DYNSTR_H
+#define _DYNSTR_H
+/* dynstr.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* Handling of strings with dynamic allocation */
+/* */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stddef.h>
+
+typedef struct as_dynstr
+{
+ size_t capacity;
+ char *p_str;
+ int dynamic;
+} as_dynstr_t;
+
+/* add one character more for terminating NUL */
+
+#define as_dynstr_roundup_len(len) \
+ (((len) + 128) & ~127)
+
+extern void as_dynstr_ini(as_dynstr_t *p_str, size_t ini_alloc_len);
+
+extern void as_dynstr_ini_clone(as_dynstr_t *p_str, const as_dynstr_t *p_src);
+
+extern void as_dynstr_ini_c_str(as_dynstr_t *p_str, const char *p_src);
+
+extern int as_dynstr_realloc(as_dynstr_t *p_str, size_t new_alloc_len);
+
+extern void as_dynstr_free(as_dynstr_t *p_str);
+
+extern size_t as_dynstr_copy(as_dynstr_t *p_dest, const as_dynstr_t *p_src);
+
+extern size_t as_dynstr_copy_c_str(as_dynstr_t *p_dest, const char *p_src);
+
+extern size_t as_dynstr_append_c_str(as_dynstr_t *p_dest, const char *p_src);
+
+extern void as_dynstr_dump_hex(FILE *p_file, const as_dynstr_t *p_str);
+
+#endif /* _DYNSTR_H */
--- /dev/null
+#ifndef _MYENDIAN_H
+#define _MYENDIAN_H
+/* endian.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Little/Big-Endian-Routinen */
+/* */
+/* Historie: 30. 5.1996 Grundsteinlegung */
+/* 6. 7.1997 Dec32BlankString dazu */
+/* 1. 6.2000 added LargeHIntFormat */
+/* 7. 7.2000 added memory read/write functions */
+/* */
+/*****************************************************************************/
+
+#include <stdio.h> // Nick
+#include "datatypes.h"
+
+extern Boolean HostBigEndian;
+
+extern const char *Integ16Format, *Integ32Format, *Integ64Format;
+extern const char *IntegerFormat, *LongIntFormat, *QuadIntFormat;
+extern const char *LargeIntFormat, *LargeHIntFormat;
+
+
+extern void WSwap(void *Field, int Cnt);
+
+extern void DSwap(void *Field, int Cnt);
+
+extern void QSwap(void *Field, int Cnt);
+
+extern void TSwap(void *Field, int Cnt);
+
+extern void DWSwap(void *Field, int Cnt);
+
+extern void QWSwap(void *Field, int Cnt);
+
+extern void TWSwap(void *Field, int Cnt);
+
+
+extern Boolean Read2(FILE *file, void *Ptr);
+
+extern Boolean Read4(FILE *file, void *Ptr);
+
+extern Boolean Read8(FILE *file, void *Ptr);
+
+
+extern Boolean Write2(FILE *file, void *Ptr);
+
+extern Boolean Write4(FILE *file, void *Ptr);
+
+extern Boolean Write8(FILE *file, void *Ptr);
+
+#define MRead1L(Buffer) (*((Byte *)(Buffer)))
+
+#define MRead1B(Buffer) (*((Byte *)(Buffer)))
+
+extern Word MRead2L(Byte *Buffer);
+
+extern Word MRead2B(Byte *Buffer);
+
+#define MWrite1L(Buffer, Value) (*((Byte*) (Buffer))) = Value;
+
+#define MWrite1B(Buffer, Value) (*((Byte*) (Buffer))) = Value;
+
+extern void MWrite2L(Byte *Buffer, Word Value);
+
+extern void MWrite2B(Byte *Buffer, Word Value);
+
+extern LongWord MRead4L(Byte *Buffer);
+
+extern LongWord MRead4B(Byte *Buffer);
+
+extern void MWrite4L(Byte *Buffer, LongWord Value);
+
+extern void MWrite4B(Byte *Buffer, LongWord Value);
+
+#ifdef HAS64
+extern QuadWord MRead8L(Byte *Buffer);
+
+extern QuadWord MRead8B(Byte *Buffer);
+
+extern void MWrite8L(Byte *Buffer, QuadWord Value);
+
+extern void MWrite8B(Byte *Buffer, QuadWord Value);
+#endif
+
+extern void endian_init(void);
+#endif /* _MYENDIAN_H */
--- /dev/null
+/* errmsg.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* Cross Assembler */
+/* */
+/* Error message definition & associated checking */
+/* */
+/*****************************************************************************/
+
+#include <string.h>
+#include <stdarg.h>
+#include "strutil.h"
+
+#include "datatypes.h"
+#include "asmdef.h"
+#include "asmpars.h"
+#include "strutil.h"
+#include "asmsub.h"
+#include "nlmessages.h"
+#include "cpulist.h"
+#include "as.rsc"
+#include "errmsg.h"
+
+static tErrorNum GetDefaultCPUErrorNum(tErrorNum ThisNum)
+{
+ return ThisNum ? ThisNum : ErrNum_InstructionNotSupported;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn report_error_range(LargeInt value, LargeInt ref, char comp_op, tErrorNum error_num, const tStrComp *p_comp)
+ * \brief core routine to emit range error message
+ * \param value offending value
+ * \param ref reference value was checked against
+ * \param comp_op comparison op that failed
+ * \param error_num error message to emit
+ * \param p_comp source argument (may be NULL)
+ * \return constant False
+ * ------------------------------------------------------------------------ */
+
+static Boolean report_error_range(LargeInt value, LargeInt ref, char comp_op, tErrorNum error_num, const tStrComp *p_comp)
+{
+ char s[100];
+
+ as_snprintf(s, sizeof(s), "%llld %c %llld", value, comp_op, ref);
+ if (p_comp)
+ WrXErrorPos(error_num, s, &p_comp->Pos);
+ else
+ WrXError(error_num, s);
+ return False;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkRangePos(LargeInt Value, LargeInt Min, LargeInt Max, const tStrComp *p_comp)
+ * \brief check whether integer is in range and issue error if not
+ * \param Value value to check
+ * \param Min minimum of range
+ * \param Max maximum of range
+ * \param p_comp corresponding source argument (may be NULL)
+ * \return TRUE if in-range and no error
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkRangePos(LargeInt Value, LargeInt Min, LargeInt Max, const tStrComp *p_comp)
+{
+ if (Value < Min)
+ return report_error_range(Value, Min, '<', ErrNum_UnderRange, p_comp);
+ else if (Value > Max)
+ return report_error_range(Value, Max, '>', ErrNum_OverRange, p_comp);
+ else
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkRangeWarnPos(LargeInt Value, LargeInt Min, LargeInt Max, const tStrComp *p_comp)
+ * \brief check whether integer is in range and issue error if not
+ * \param Value value to check
+ * \param Min minimum of range
+ * \param Max maximum of range
+ * \param p_comp corresponding source argument (may be NULL)
+ * \return TRUE if in-range and no error
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkRangeWarnPos(LargeInt Value, LargeInt Min, LargeInt Max, const tStrComp *p_comp)
+{
+ if (Value < Min)
+ return report_error_range(Value, Min, '<', ErrNum_WUnderRange, p_comp);
+ else if (Value > Max)
+ return report_error_range(Value, Max, '>', ErrNum_WOverRange, p_comp);
+ else
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkArgCntExtPos(int ThisCnt, int MinCnt, int MaxCnt, const struct sLineComp *pComp)
+ * \brief check whether argument count is within given range and issue error if not
+ * \param ThisCnt count to check
+ * \param MinCnt minimum allowed count
+ * \param MaxCnt maximum allowed count
+ * \param pComp position in source line (optional)
+ * \return TRUE if in-range and no error
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkArgCntExtPos(int ThisCnt, int MinCnt, int MaxCnt, const struct sLineComp *pComp)
+{
+ if ((ThisCnt < MinCnt) || (ThisCnt > MaxCnt))
+ {
+ char Str[100];
+
+ if (MinCnt != MaxCnt)
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgArgCntFromTo), MinCnt, MaxCnt, ThisCnt);
+ else switch (MinCnt)
+ {
+ case 0:
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgArgCntZero), ThisCnt);
+ break;
+ case 1:
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgArgCntOne), ThisCnt);
+ break;
+ default:
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgArgCntMulti), MinCnt, ThisCnt);
+ }
+ if (pComp)
+ WrXErrorPos(ErrNum_WrongArgCnt, Str, pComp);
+ else
+ WrXError(ErrNum_WrongArgCnt, Str);
+ return False;
+ }
+ else
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkArgCntExtEitherOr(int ThisCnt, int EitherCnt, int OrCnt)
+ * \brief check whether argument count is according to given values and issue error if not
+ * \param ThisCnt count to check
+ * \param EitherCnt allowed count
+ * \param OrCnt other allowed count
+ * \return TRUE if count OK and no error
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkArgCntExtEitherOr(int ThisCnt, int EitherCnt, int OrCnt)
+{
+ if ((ThisCnt != EitherCnt) && (ThisCnt != OrCnt))
+ {
+ char Str[100];
+
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgArgCntEitherOr), EitherCnt, OrCnt, ThisCnt);
+ WrXError(ErrNum_WrongArgCnt, Str);
+ return False;
+ }
+ else
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkMinCPUExt(CPUVar MinCPU, tErrorNum ErrorNum)
+ * \brief check whether currently selected CPU is at least given one and issue error if not
+ * \param MinCPU minimum required CPU
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \return TRUE if currently selected CPU is OK and no error
+ * ------------------------------------------------------------------------ */
+
+extern Boolean ChkMinCPUExt(CPUVar MinCPU, tErrorNum ErrorNum)
+{
+ if (MomCPU < MinCPU)
+ {
+ const tCPUDef *pCPUDef;
+ ErrorNum = GetDefaultCPUErrorNum(ErrorNum);
+
+ pCPUDef = LookupCPUDefByVar(MinCPU);
+ if (pCPUDef)
+ {
+ char Str[100];
+
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgMinCPUSupported), pCPUDef->Name);
+ WrXError(ErrorNum, Str);
+ }
+ else
+ WrError(ErrorNum);
+ return False;
+ }
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn AChkMinCPUExtPos(CPUVar MinCPU, tErrorNum ErrorNum, const struct sStrComp *pComp)
+ * \brief check for minimum CPU of this addressing mode
+ * \param MinCPU min. CPU required
+ * \param ErrorNum error message to print
+ * \param pComp argument to complain about
+ * \return True if CPU is OK
+ * ------------------------------------------------------------------------ */
+
+Boolean AChkMinCPUExtPos(CPUVar MinCPU, tErrorNum ErrorNum, const struct sStrComp *pComp)
+{
+ if (MomCPU < MinCPU)
+ {
+ WrStrErrorPos(ErrorNum, pComp);
+ return False;
+ }
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkMaxCPUExt(CPUVar MaxCPU, tErrorNum ErrorNum)
+ * \brief check whether currently selected CPU is at most given one and issue error if not
+ * \param MaxCPU maximum required CPU
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \return TRUE if currently selected CPU is OK and no error
+ * ------------------------------------------------------------------------ */
+
+extern Boolean ChkMaxCPUExt(CPUVar MaxCPU, tErrorNum ErrorNum)
+{
+ if (MomCPU > MaxCPU)
+ {
+ const tCPUDef *pCPUDef;
+ ErrorNum = GetDefaultCPUErrorNum(ErrorNum);
+
+ pCPUDef = LookupCPUDefByVar(MaxCPU);
+ if (pCPUDef)
+ {
+ char Str[100];
+
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgMaxCPUSupported), pCPUDef->Name);
+ WrXError(ErrorNum, Str);
+ }
+ else
+ WrError(ErrorNum);
+ return False;
+ }
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkRangeCPUExt(CPUVar MinCPU, CPUVar MaxCPU, tErrorNum ErrorNum)
+ * \brief check whether currently selected CPU is within given range
+ * \param MinCPU minimum required CPU
+ * \param MaxCPU maximum required CPU
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \return TRUE if currently selected CPU is OK and no error
+ * ------------------------------------------------------------------------ */
+
+extern Boolean ChkRangeCPUExt(CPUVar MinCPU, CPUVar MaxCPU, tErrorNum ErrorNum)
+{
+ if ((MomCPU < MinCPU) || (MomCPU > MaxCPU))
+ {
+ const tCPUDef *pCPUDefMin, *pCPUDefMax;
+ ErrorNum = GetDefaultCPUErrorNum(ErrorNum);
+
+ pCPUDefMin = LookupCPUDefByVar(MinCPU);
+ pCPUDefMax = LookupCPUDefByVar(MaxCPU);
+ if (pCPUDefMin && pCPUDefMax)
+ {
+ char Str[100];
+
+ as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgRangeCPUSupported), pCPUDefMin->Name, pCPUDefMax->Name);
+ WrXError(ErrorNum, Str);
+ }
+ else
+ WrError(ErrorNum);
+ return False;
+ }
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkMinCPUExt(CPUVar MatchCPU, tErrorNum ErrorNum)
+ * \brief check whether currently selected CPU is given one and issue error if not
+ * \param MatchCPU required CPU
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \return TRUE if currently selected CPU is OK and no error
+ * ------------------------------------------------------------------------ */
+
+extern Boolean ChkExactCPUExt(CPUVar MatchCPU, tErrorNum ErrorNum)
+{
+ if (MomCPU != MatchCPU)
+ {
+ const tCPUDef *pCPUDef;
+ ErrorNum = GetDefaultCPUErrorNum(ErrorNum);
+
+ pCPUDef = LookupCPUDefByVar(MatchCPU);
+ if (pCPUDef)
+ {
+ char Str[100];
+
+ as_snprintf(Str, sizeof(Str), "%s%s%s", getmessage(Num_ErrMsgOnlyCPUSupported1), pCPUDef->Name, getmessage(Num_ErrMsgOnlyCPUSupported2));
+ WrXError(ErrorNum, Str);
+ }
+ else
+ WrError(ErrorNum);
+ return False;
+ }
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkExcludeCPUExt(CPUVar MatchCPU, tErrorNum ErrorNum)
+ * \brief check whether currently selected CPU is NOT given one and issue error if not
+ * \param MatchCPU disallowed CPU
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \return TRUE if currently selected CPU is OK and no error
+ * ------------------------------------------------------------------------ */
+
+typedef struct
+{
+ const tCPUDef *pExcludeCPUDef;
+ const tCPUDef *pLastCPUDef;
+ String Str;
+ Boolean First;
+ Word ExcludeMask;
+ CPUVar ExcludeCPUFirst;
+} tExcludeContext;
+
+static void IterateExclude(const tCPUDef *pThisCPUDef, void *pUser)
+{
+ tExcludeContext *pContext = (tExcludeContext*)pUser;
+
+ /* ignore other families or aliases */
+
+ if (pThisCPUDef)
+ {
+ if ((pThisCPUDef->SwitchProc != pContext->pExcludeCPUDef->SwitchProc)
+ || ((1 << (pThisCPUDef->Number - pContext->ExcludeCPUFirst)) & pContext->ExcludeMask)
+ || (pThisCPUDef->Number != pThisCPUDef->Orig))
+ return;
+ }
+
+ if (pContext->pLastCPUDef)
+ {
+ if (!pContext->First)
+ strmaxcat(pContext->Str, pThisCPUDef ? ", " : getmessage(Num_ErrMsgOnlyCPUSupportedOr), sizeof(pContext->Str));
+ strmaxcat(pContext->Str, pContext->pLastCPUDef->Name, sizeof(pContext->Str));
+ pContext->First = False;
+ }
+ pContext->pLastCPUDef = pThisCPUDef;
+}
+
+extern Boolean ChkExcludeCPUExt(CPUVar MatchCPU, tErrorNum ErrorNum)
+{
+ tExcludeContext Context;
+
+ if (MomCPU != MatchCPU)
+ return True;
+
+ Context.pExcludeCPUDef = LookupCPUDefByVar(MatchCPU);
+
+ if (Context.pExcludeCPUDef)
+ {
+ *Context.Str = '\0';
+ Context.First = True;
+ Context.pLastCPUDef = NULL;
+ Context.ExcludeMask = 1;
+ Context.ExcludeCPUFirst = MatchCPU;
+ strmaxcat(Context.Str, getmessage(Num_ErrMsgOnlyCPUSupported1), sizeof(Context.Str));
+ IterateCPUList(IterateExclude, &Context);
+ IterateExclude(NULL, &Context);
+ WrXError(GetDefaultCPUErrorNum(ErrorNum), Context.Str);
+ }
+ else
+ WrError(GetDefaultCPUErrorNum(ErrorNum));
+ return False;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkExcludeCPUList(int ErrorNum, ...)
+ * \brief check whether currently selected CPU is one of the given ones and issue error if it is
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \param ... List of CPUs terminated by CPUNone
+ * \return Index (-1...-n) of matching CPU or 0 if current CPU does not match any
+ * ------------------------------------------------------------------------ */
+
+int ChkExcludeCPUList(int ErrorNum, ...)
+{
+ va_list ap;
+ int Index = -1, FoundIndex = 0;
+ CPUVar ThisCPU;
+
+ va_start(ap, ErrorNum);
+ while (True)
+ {
+ ThisCPU = va_arg(ap, CPUVar);
+ if (ThisCPU == CPUNone)
+ break;
+ if (MomCPU == ThisCPU)
+ {
+ FoundIndex = Index;
+ break;
+ }
+ }
+ va_end(ap);
+
+ if (FoundIndex < 0)
+ {
+ tExcludeContext Context;
+
+ *Context.Str = '\0';
+ Context.First = True;
+ Context.pExcludeCPUDef =
+ Context.pLastCPUDef = NULL;
+ strmaxcat(Context.Str, getmessage(Num_ErrMsgOnlyCPUSupported1), sizeof(Context.Str));
+
+ /* convert vararg list to bitmap */
+
+ Context.ExcludeMask = 0;
+ Context.ExcludeCPUFirst = CPUNone;
+ va_start(ap, ErrorNum);
+ while (TRUE)
+ {
+ ThisCPU = va_arg(ap, CPUVar);
+ if (ThisCPU == CPUNone)
+ break;
+ if (!Context.pExcludeCPUDef)
+ Context.pExcludeCPUDef = LookupCPUDefByVar(ThisCPU);
+ if (Context.ExcludeCPUFirst == CPUNone)
+ {
+ Context.ExcludeCPUFirst = ThisCPU;
+ Context.ExcludeMask = 1;
+ }
+ else if (ThisCPU > Context.ExcludeCPUFirst)
+ Context.ExcludeMask |= 1 << (ThisCPU - Context.ExcludeCPUFirst);
+ else if (ThisCPU < Context.ExcludeCPUFirst)
+ {
+ Context.ExcludeMask <<= Context.ExcludeCPUFirst - ThisCPU;
+ Context.ExcludeMask |= 1;
+ Context.ExcludeCPUFirst = ThisCPU;
+ }
+ }
+ va_end(ap);
+ IterateCPUList(IterateExclude, &Context);
+ IterateExclude(NULL, &Context);
+ WrXError(GetDefaultCPUErrorNum((tErrorNum)ErrorNum), Context.Str);
+ }
+
+ return FoundIndex;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkExactCPUList(int ErrorNum)
+ * \brief check whether currently selected CPU is one of the given ones and issue error if not
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \param ... List of CPUs terminated by CPUNone
+ * \return Index (0...) of matching CPU or -1 if current CPU does not match
+ * ------------------------------------------------------------------------ */
+
+extern int ChkExactCPUList(int ErrorNum, ...)
+{
+ va_list ap;
+ String Str;
+ CPUVar ThisCPU, NextCPU;
+ const tCPUDef *pCPUDef;
+ Boolean First = True;
+ int FoundIndex = 0;
+
+ va_start(ap, ErrorNum);
+ while (True)
+ {
+ ThisCPU = va_arg(ap, CPUVar);
+ if ((ThisCPU == CPUNone) || (MomCPU == ThisCPU))
+ break;
+ FoundIndex++;
+ }
+ va_end(ap);
+ if (ThisCPU != CPUNone)
+ return FoundIndex;
+
+ va_start(ap, ErrorNum);
+ *Str = '\0';
+ strmaxcat(Str, getmessage(Num_ErrMsgOnlyCPUSupported1), sizeof(Str));
+ ThisCPU = CPUNone;
+ while (True)
+ {
+ NextCPU = va_arg(ap, CPUVar);
+ pCPUDef = (ThisCPU != CPUNone) ? LookupCPUDefByVar(ThisCPU) : NULL;
+ if (pCPUDef)
+ {
+ if (!First)
+ strmaxcat(Str, (NextCPU == CPUNone) ? getmessage(Num_ErrMsgOnlyCPUSupportedOr) : ", ", sizeof(Str));
+ strmaxcat(Str, pCPUDef->Name, sizeof(Str));
+ First = False;
+ }
+ if (NextCPU == CPUNone)
+ break;
+ ThisCPU = NextCPU;
+ }
+ va_end(ap);
+ strmaxcat(Str, getmessage(Num_ErrMsgOnlyCPUSupported2), sizeof(Str));
+ WrXError(GetDefaultCPUErrorNum((tErrorNum)ErrorNum), Str);
+ return -1;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkExactCPUMaskExt(Word CPUMask, CPUVar FirstCPU, tErrorNum ErrorNum)
+ * \brief check whether currently selected CPU is one of the given ones and issue error if not
+ * \param CPUMask bit mask of allowed CPUs
+ * \param CPUVar CPU corresponding to bit 0 in mask
+ * \param ErrorNum error to issue if not OK (0 = default message)
+ * \param ... List of CPUs terminated by CPUNone
+ * \return Index (0...) of matching CPU or -1 if current CPU does not match
+ * ------------------------------------------------------------------------ */
+
+int ChkExactCPUMaskExt(Word CPUMask, CPUVar FirstCPU, tErrorNum ErrorNum)
+{
+ int Bit = MomCPU - FirstCPU;
+ String Str;
+ const tCPUDef *pCPUDef;
+ Boolean First = True;
+ CPUVar ThisCPU;
+
+ if (CPUMask & (1 << Bit))
+ return Bit;
+
+ *Str = '\0';
+ strmaxcat(Str, getmessage(Num_ErrMsgOnlyCPUSupported1), sizeof(Str));
+ for (Bit = 0, ThisCPU = FirstCPU; Bit < 16; Bit++, ThisCPU++)
+ {
+ if (!(CPUMask & (1 << Bit)))
+ continue;
+ CPUMask &= ~(1 << Bit);
+ pCPUDef = LookupCPUDefByVar(ThisCPU);
+ if (pCPUDef)
+ {
+ if (!First)
+ strmaxcat(Str, CPUMask ? ", " : getmessage(Num_ErrMsgOnlyCPUSupportedOr), sizeof(Str));
+ strmaxcat(Str, pCPUDef->Name, sizeof(Str));
+ First = False;
+ }
+ }
+ strmaxcat(Str, getmessage(Num_ErrMsgOnlyCPUSupported2), sizeof(Str));
+ WrXError(ErrorNum ? ErrorNum : ErrNum_InstructionNotSupported, Str);
+ return -1;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkSamePage(LargeWord Addr1, LargeWord Addr2, unsigned PageBits)
+ * \brief check whether two addresses are of same page
+ * \param CurrAddr, DestAddr addresses to check
+ * \param PageBits page size in bits
+ * \param DestFlags symbol flags of DestAddr
+ * \return TRUE if OK
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkSamePage(LargeWord CurrAddr, LargeWord DestAddr, unsigned PageBits, tSymbolFlags DestFlags)
+{
+ LargeWord Mask = ~((1ul << PageBits) - 1);
+ Boolean Result = ((CurrAddr & Mask) == (DestAddr & Mask))
+ || mFirstPassUnknownOrQuestionable(DestFlags);
+ if (!Result)
+ WrError(ErrNum_TargOnDiffPage);
+ return Result;
+}
--- /dev/null
+#ifndef _ERRMSG_H
+#define _ERRMSG_H
+/* errmsg.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* Cross Assembler */
+/* */
+/* Error message definition & associated checking */
+/* */
+/*****************************************************************************/
+
+#include "cpulist.h"
+#include "symflags.h"
+#include "datatypes.h"
+
+typedef enum
+{
+ ErrNum_None = 0,
+ ErrNum_UselessDisp = 5,
+ ErrNum_ShortAddrPossible = 10,
+ ErrNum_ShortJumpPossible = 20,
+ ErrNum_NoShareFile = 30,
+ ErrNum_BigDecFloat = 40,
+ ErrNum_PrivOrder = 50,
+ ErrNum_DistNull = 60,
+ ErrNum_WrongSegment = 70,
+ ErrNum_InAccSegment = 75,
+ ErrNum_PhaseErr = 80,
+ ErrNum_Overlap = 90,
+ ErrNum_OverlapReg = 95,
+ ErrNum_NoCaseHit = 100,
+ ErrNum_InAccPage = 110,
+ ErrNum_RMustBeEven = 120,
+ ErrNum_Obsolete = 130,
+ ErrNum_Unpredictable = 140,
+ ErrNum_AlphaNoSense = 150,
+ ErrNum_Senseless = 160,
+ ErrNum_RepassUnknown = 170,
+ ErrNum_AddrNotAligned = 180,
+ ErrNum_IOAddrNotAllowed = 190,
+ ErrNum_Pipeline = 200,
+ ErrNum_DoubleAdrRegUse = 210,
+ ErrNum_NotBitAddressable = 220,
+ ErrNum_StackNotEmpty = 230,
+ ErrNum_NULCharacter = 240,
+ ErrNum_PageCrossing = 250,
+ ErrNum_WUnderRange = 255,
+ ErrNum_WOverRange = 260,
+ ErrNum_NegDUP = 270,
+ ErrNum_ConvIndX = 280,
+ ErrNum_NullResMem = 290,
+ ErrNum_BitNumberTruncated = 300,
+ ErrNum_InvRegisterPointer = 310,
+ ErrNum_MacArgRedef = 320,
+ ErrNum_Deprecated = 330,
+ ErrNum_SrcLEThanDest = 340,
+ ErrNum_TrapValidInstruction = 350,
+ ErrNum_PaddingAdded = 360,
+ ErrNum_RegNumWraparound = 370,
+ ErrNum_IndexedForIndirect = 380,
+ ErrNum_DoubleDef = 1000,
+ ErrNum_SymbolUndef = 1010,
+ ErrNum_InvSymName = 1020,
+ ErrNum_InvFormat = 1090,
+ ErrNum_UseLessAttr = 1100,
+ ErrNum_TooLongAttr = 1105,
+ ErrNum_UndefAttr = 1107,
+ ErrNum_WrongArgCnt = 1110,
+ ErrNum_CannotSplitArg = 1112,
+ ErrNum_WrongOptCnt = 1115,
+ ErrNum_OnlyImmAddr = 1120,
+ ErrNum_InvOpSize = 1130,
+ ErrNum_ConfOpSizes = 1131,
+ ErrNum_UndefOpSizes = 1132,
+ ErrNum_StringOrIntButFloat = 1133,
+ ErrNum_IntButFloat = 1134,
+ /* ErrNum_InvOpType = 1135, */
+ ErrNum_FloatButString = 1136,
+ ErrNum_OpTypeMismatch = 1137,
+ ErrNum_StringButInt = 1138,
+ ErrNum_StringButFloat = 1139,
+ ErrNum_TooManyArgs = 1140,
+ ErrNum_IntButString = 1141,
+ ErrNum_IntOrFloatButString = 1142,
+ ErrNum_ExpectString = 1143,
+ ErrNum_ExpectInt = 1144,
+ ErrNum_StringOrIntOrFloatButReg = 1145,
+ ErrNum_ExpectIntOrString = 1146,
+ ErrNum_ExpectReg = 1147,
+ ErrNum_RegWrongTarget = 1148,
+ ErrNum_NoRelocs = 1150,
+ ErrNum_UnresRelocs = 1155,
+ ErrNum_Unexportable = 1156,
+ ErrNum_UnknownInstruction = 1200,
+ ErrNum_BrackErr = 1300,
+ ErrNum_DivByZero = 1310,
+ ErrNum_UnderRange = 1315,
+ ErrNum_OverRange = 1320,
+ ErrNum_NotPwr2 = 1322,
+ ErrNum_NotAligned = 1325,
+ ErrNum_DistTooBig = 1330,
+ ErrNum_InAccReg = 1335,
+ ErrNum_NoShortAddr = 1340,
+ ErrNum_InvAddrMode = 1350,
+ ErrNum_AddrMustBeEven = 1351,
+ ErrNum_AddrMustBeAligned = 1352,
+ ErrNum_InvParAddrMode = 1355,
+ ErrNum_UndefCond = 1360,
+ ErrNum_IncompCond = 1365,
+ ErrNum_UnknownFlag = 1366,
+ ErrNum_DuplicateFlag = 1367,
+ ErrNum_UnknownInt = 1368,
+ ErrNum_DuplicateInt = 1369,
+ ErrNum_JmpDistTooBig = 1370,
+ ErrNum_DistIsOdd = 1375,
+ ErrNum_SkipTargetMismatch = 1376,
+ ErrNum_InvShiftArg = 1380,
+ ErrNum_Range18 = 1390,
+ ErrNum_Only1 = 1391,
+ ErrNum_ShiftCntTooBig = 1400,
+ ErrNum_InvRegList = 1410,
+ ErrNum_InvCmpMode = 1420,
+ ErrNum_InvCPUType = 1430,
+ ErrNum_InvFPUType = 1431,
+ ErrNum_InvPMMUType = 1432,
+ ErrNum_InvCtrlReg = 1440,
+ ErrNum_InvPMMUReg = 1444,
+ ErrNum_InvReg = 1445,
+ ErrNum_DoubleReg = 1446,
+ ErrNum_RegBankMismatch = 1447,
+ ErrNum_UndefRegSize = 1448,
+ ErrNum_InvOpOnReg = 1449,
+ ErrNum_NoSaveFrame = 1450,
+ ErrNum_NoRestoreFrame = 1460,
+ ErrNum_UnknownMacArg = 1465,
+ ErrNum_MissEndif = 1470,
+ ErrNum_InvIfConst = 1480,
+ ErrNum_DoubleSection = 1483,
+ ErrNum_InvSection = 1484,
+ ErrNum_MissingEndSect = 1485,
+ ErrNum_WrongEndSect = 1486,
+ ErrNum_NotInSection = 1487,
+ ErrNum_UndefdForward = 1488,
+ ErrNum_ContForward = 1489,
+ ErrNum_InvFuncArgCnt = 1490,
+ ErrNum_MsgMissingLTORG = 1495,
+ ErrNum_InstructionNotSupported = 1500,
+ ErrNum_FPUNotEnabled = 1501,
+ ErrNum_PMMUNotEnabled = 1502,
+ ErrNum_FullPMMUNotEnabled = 1503,
+ ErrNum_Z80SyntaxNotEnabled = 1504,
+ ErrNum_AddrModeNotSupported = 1505,
+ ErrNum_Z80SyntaxExclusive = 1506,
+ ErrNum_FPUInstructionNotSupported = 1507,
+ ErrNum_CustomNotEnabled = 1508,
+ ErrNum_InvBitPos = 1510,
+ ErrNum_OnlyOnOff = 1520,
+ ErrNum_StackEmpty = 1530,
+ ErrNum_NotOneBit = 1540,
+ ErrNum_MissingStruct = 1550,
+ ErrNum_OpenStruct = 1551,
+ ErrNum_WrongStruct = 1552,
+ ErrNum_PhaseDisallowed = 1553,
+ ErrNum_InvStructDir = 1554,
+ ErrNum_DoubleStruct = 1555,
+ ErrNum_UnresolvedStructRef = 1556,
+ ErrNum_DuplicateStructElem = 1557,
+ ErrNum_NotRepeatable = 1560,
+ ErrNum_ShortRead = 1600,
+ ErrNum_UnknownCodepage = 1610,
+ ErrNum_RomOffs063 = 1700,
+ ErrNum_InvFCode = 1710,
+ ErrNum_InvFMask = 1720,
+ ErrNum_InvMMUReg = 1730,
+ ErrNum_Level07 = 1740,
+ ErrNum_InvBitMask = 1750,
+ ErrNum_InvRegPair = 1760,
+ ErrNum_OpenMacro = 1800,
+ ErrNum_OpenIRP = 1801,
+ ErrNum_OpenIRPC = 1802,
+ ErrNum_OpenREPT = 1803,
+ ErrNum_OpenWHILE = 1804,
+ ErrNum_EXITMOutsideMacro = 1805,
+ ErrNum_TooManyMacParams = 1810,
+ ErrNum_UndefKeyArg = 1811,
+ ErrNum_NoPosArg = 1812,
+ ErrNum_DoubleMacro = 1815,
+ ErrNum_FirstPassCalc = 1820,
+ ErrNum_TooManyNestedIfs = 1830,
+ ErrNum_MissingIf = 1840,
+ ErrNum_RekMacro = 1850,
+ ErrNum_UnknownFunc = 1860,
+ ErrNum_InvFuncArg = 1870,
+ ErrNum_FloatOverflow = 1880,
+ ErrNum_InvArgPair = 1890,
+ ErrNum_NotOnThisAddress = 1900,
+ ErrNum_NotFromThisAddress = 1905,
+ ErrNum_TargOnDiffPage = 1910,
+ ErrNum_TargOnDiffSection = 1911,
+ ErrNum_CodeOverflow = 1920,
+ ErrNum_AdrOverflow = 1925,
+ ErrNum_MixDBDS = 1930,
+ ErrNum_NotInStruct = 1940,
+ ErrNum_ParNotPossible = 1950,
+ ErrNum_InvSegment = 1960,
+ ErrNum_UnknownSegment = 1961,
+ ErrNum_UnknownSegReg = 1962,
+ ErrNum_InvString = 1970,
+ ErrNum_InvRegName = 1980,
+ ErrNum_InvArg = 1985,
+ ErrNum_NoIndir = 1990,
+ ErrNum_NotInThisSegment = 1995,
+ ErrNum_NotInMaxmode = 1996,
+ ErrNum_OnlyInMaxmode = 1997,
+ ErrNum_PackCrossBoundary = 2000,
+ ErrNum_UnitMultipleUsed = 2001,
+ ErrNum_MultipleLongRead = 2002,
+ ErrNum_MultipleLongWrite = 2003,
+ ErrNum_LongReadWithStore = 2004,
+ ErrNum_TooManyRegisterReads = 2005,
+ ErrNum_OverlapDests = 2006,
+ ErrNum_TooManyBranchesInExPacket = 2008,
+ ErrNum_CannotUseUnit = 2009,
+ ErrNum_InvEscSequence = 2010,
+ ErrNum_InvPrefixCombination = 2020,
+ ErrNum_ConstantRedefinedAsVariable = 2030,
+ ErrNum_VariableRedefinedAsConstant = 2035,
+ ErrNum_StructNameMissing = 2040,
+ ErrNum_EmptyArgument = 2050,
+ ErrNum_Unimplemented = 2060,
+ ErrNum_FreestandingUnnamedStruct = 2070,
+ ErrNum_STRUCTEndedByENDUNION = 2080,
+ ErrNum_AddrOnDifferentPage = 2090,
+ ErrNum_UnknownMacExpMod = 2100,
+ ErrNum_TooManyMacExpMod = 2105,
+ ErrNum_ConflictingMacExpMod = 2110,
+ ErrNum_InvalidPrepDir = 2120,
+ ErrNum_ExpectedError = 2130,
+ ErrNum_NoNestExpect = 2140,
+ ErrNum_MissingENDEXPECT = 2150,
+ ErrNum_MissingEXPECT = 2160,
+ ErrNum_NoDefCkptReg = 2170,
+ ErrNum_InvBitField = 2180,
+ ErrNum_ArgValueMissing = 2190,
+ ErrNum_UnknownArg = 2200,
+ ErrNum_IndexRegMustBe16Bit = 2210,
+ ErrNum_IOAddrRegMustBe16Bit = 2211,
+ ErrNum_SegAddrRegMustBe32Bit = 2212,
+ ErrNum_NonSegAddrRegMustBe16Bit = 2213,
+ ErrNum_InvStructArgument = 2220,
+ ErrNum_TooManyArrayDimensions = 2221,
+ ErrNum_InvIntFormat = 2230,
+ ErrNum_InvIntFormatList = 2231,
+ ErrNum_InvScale = 2240,
+ ErrNum_ConfStringOpt = 2250,
+ ErrNum_UnknownStringOpt = 2251,
+ ErrNum_InvCacheInvMode = 2252,
+ ErrNum_InvCfgList = 2253,
+ ErrNum_ConfBitBltOpt = 2254,
+ ErrNum_UnknownBitBltOpt = 2255,
+ ErrNum_InternalError = 10000,
+ ErrNum_OpeningFile = 10001,
+ ErrNum_ListWrError = 10002,
+ ErrNum_FileReadError = 10003,
+ ErrNum_FileWriteError = 10004,
+ ErrNum_HeapOvfl = 10006,
+ ErrNum_StackOvfl = 10007,
+ ErrNum_MaxIncLevelExceeded = 10008
+} tErrorNum;
+
+struct sLineComp;
+struct sStrComp;
+
+extern Boolean ChkRangePos(LargeInt Value, LargeInt Min, LargeInt Max, const struct sStrComp *p_comp);
+#define ChkRange(Value, Min, Max) ChkRangePos(Value, Min, Max, NULL)
+extern Boolean ChkRangeWarnPos(LargeInt Value, LargeInt Min, LargeInt Max, const struct sStrComp *p_comp);
+#define ChkRangeWarn(Value, Min, Max) ChkRangeWarnPos(Value, Min, Max, NULL)
+
+extern Boolean ChkArgCntExtPos(int ThisCnt, int MinCnt, int MaxCnt, const struct sLineComp *pComp);
+#define ChkArgCnt(MinCnt, MaxCnt) ChkArgCntExtPos(ArgCnt, MinCnt, MaxCnt, NULL)
+#define ChkArgCntExt(ThisCnt, MinCnt, MaxCnt) ChkArgCntExtPos(ThisCnt, MinCnt, MaxCnt, NULL)
+extern Boolean ChkArgCntExtEitherOr(int ThisCnt, int EitherCnt, int OrCnt);
+
+extern Boolean ChkMinCPUExt(CPUVar MinCPU, tErrorNum ErrorNum);
+#define ChkMinCPU(MinCPU) ChkMinCPUExt(MinCPU, ErrNum_InstructionNotSupported)
+
+extern Boolean AChkMinCPUExtPos(CPUVar MinCPU, tErrorNum ErrorNum, const struct sStrComp *pComp);
+#define AChkMinCPUPos(MinCPU, pComp) AChkMinCPUExtPos(MinCPU, ErrNum_AddrModeNotSupported, pComp)
+
+extern Boolean ChkMaxCPUExt(CPUVar MaxCPU, tErrorNum ErrorNum);
+#define ChkMaxCPU(MaxCPU) ChkMaxCPUExt(MaxCPU, ErrNum_InstructionNotSupported)
+
+extern Boolean ChkExactCPUExt(CPUVar CheckCPU, tErrorNum ErrorNum);
+#define ChkExactCPU(CheckCPU) ChkExactCPUExt(CheckCPU, ErrNum_InstructionNotSupported)
+
+extern Boolean ChkRangeCPUExt(CPUVar MinCPU, CPUVar MaxCPU, tErrorNum ErrorNum);
+#define ChkRangeCPU(MinCPU, MaxCPU) ChkRangeCPUExt(MinCPU, MaxCPU, ErrNum_InstructionNotSupported)
+
+extern Boolean ChkExcludeCPUExt(CPUVar CheckCPU, tErrorNum ErrorNum);
+#define ChkExcludeCPU(CheckCPU) ChkExcludeCPUExt(CheckCPU, ErrNum_InstructionNotSupported)
+
+extern int ChkExactCPUList(int ErrorNum, ...);
+extern int ChkExcludeCPUList(int ErrorNum, ...);
+
+extern int ChkExactCPUMaskExt(Word CPUMask, CPUVar FirstCPU, tErrorNum ErrorNum);
+#define ChkExactCPUMask(CPUMask, FirstCPU) ChkExactCPUMaskExt(CPUMask, FirstCPU, ErrNum_InstructionNotSupported)
+
+extern Boolean ChkSamePage(LargeWord CurrAddr, LargeWord DestAddr, unsigned PageBits, tSymbolFlags DestFlags);
+
+#endif /* _ERRMSG_H */
--- /dev/null
+#ifndef _FILEFORMAT_H
+#define _FILEFORMAT_H
+/* fileformat.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Definition von Konstanten fuer das P-Format */
+/* */
+/* Historie: 3.12.1996 Grundsteinlegung */
+/* 11. 9.1998 ROMDATA-Segment hinzugenommen */
+/* 12. 7.1999 RelocRec-Typ hinzugenommen */
+/* 19. 1.2000 Patch-Typen definiert */
+/* */
+/*****************************************************************************/
+
+#include "addrspace.h"
+
+#define FileMagic 0x1489
+
+#define FileHeaderEnd 0x00 /* Dateiende */
+#define FileHeaderStartAdr 0x80 /* Einsprungadresse absolut */
+#define FileHeaderDataRec 0x81 /* normaler Datenrecord */
+#define FileHeaderRDataRec 0x82 /* Datenrecord mit Symbolen */
+#define FileHeaderRelocRec 0x83 /* relokatibler Datenrecord */
+#define FileHeaderRRelocRec 0x84 /* relokatibler Datenrecord mit Symbolen */
+#define FileHeaderRelocInfo 0x85 /* Relokationsinformationen */
+
+/* Definition der im Code liegenden, zu patchenden Typen:
+
+ Dazu wird ein 32-Bit-Wert verwendet. Das oberste Byte gibt den Basistyp
+ an, hier ist momentan nur 0 fuer binaere Integers definiert. Fuer diesen
+ Fall steht in Bit 0..7 die Laenge des Integers in Bits, in Bit 20 die
+ Information, ob es sich um einen Big(1)- oder Little-Endian(0)-Typ handelt.
+ Bits 8..11 geben die Startposition bzw. Bits 12..15 die Laenge der ersten
+ Komponente im ersten Byte an, danach folgen so viele ganze Bytes wie
+ moeglich. Bits 16 bis 19 geben die Lage der verbleibenden Bits im letzten
+ Byte an. Bit 21 zeigt an, ob bei der Relokation addiert oder subtrahiert
+ werden soll. Bit 22 spezifiziert 'Seitenintegers', d.h. die Adresse,
+ die an einer bestimmten Stelle eingepatcht wird, muss in den oberen (nicht
+ gespeicherten) Bits identisch zur Adresse der Patchstelle selber sein.
+ Ist Bit22=0, ist es ein normaler vorzeichenloser Int von 0...(2^n)-1
+
+ Daraus ergeben sich z. B. folgende einfachen Typen: */
+
+#define RelocTypeL8 0x00008008l
+#define RelocTypeB8 RelocTypeL8 /* :-) was wunder */
+#define RelocTypeL16 0x00008010l
+#define RelocTypeB16 0x00108010l
+#define RelocTypeL24 0x00008018l
+#define RelocTypeB24 0x00108018l
+#define RelocTypeL32 0x00008020l
+#define RelocTypeB32 0x00108020l
+#define RelocTypeL64 0x00008040l
+#define RelocTypeB64 0x00108040l
+
+#define RelocFlagBig 0x00100000l
+#define RelocFlagSUB 0x00200000l
+#define RelocBitCnt(Type) (Type & 0xff)
+#define RelocFlagPage 0x00400000l
+
+/* this is an internal symbol name used to signify the start address
+ of a segment */
+
+#define RelName_SegStart "$$$"
+
+#define RelFlag_Relative 1
+
+#endif /* _FILEFORMAT_H */
--- /dev/null
+#ifndef _FUNCTION_H
+#define _FUNCTION_H
+/* function.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* internal holder for int/float/string */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+#include "tempresult.h"
+
+typedef struct
+{
+ const char *pName;
+ Byte MinNumArgs, MaxNumArgs;
+ Byte ArgTypes[3];
+ void (*pFunc)(TempResult *pErg, const TempResult *pArgs, unsigned ArgCnt);
+} tFunction;
+
+extern const tFunction Functions[];
+
+#endif /* _FUNCTION_H */
--- /dev/null
+#ifndef _IEEEFLOAT_H
+#define _IEEEFLOAT_H
+/* ieeefloat.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS */
+/* */
+/* IEEE Floating Point Handling */
+/* */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+
+enum
+{
+ AS_FP_NORMAL,
+ AS_FP_SUBNORMAL,
+ AS_FP_NAN,
+ AS_FP_INFINITE
+};
+
+extern int as_fpclassify(Double inp);
+
+extern Boolean Double_2_ieee2(Double inp, Byte *pDest, Boolean NeedsBig);
+
+extern void Double_2_ieee4(Double inp, Byte *pDest, Boolean NeedsBig);
+
+extern void Double_2_ieee8(Double inp, Byte *pDest, Boolean NeedsBig);
+
+extern void Double_2_ieee10(Double inp, Byte *pDest, Boolean NeedsBig);
+
+#endif /* _IEEEFLOAT_H */
--- /dev/null
+/* intformat.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS */
+/* */
+/* enums regarding integer constant notations */
+/* */
+/*****************************************************************************/
+
+#include "strutil.h"
+#include "datatypes.h"
+#include <stdlib.h>
+#include <string.h>
+
+#include "intformat.h"
+
+static const Byte BaseVals[3] =
+{
+ 2, 8, 16
+};
+
+LongWord NativeIntConstModeMask, OtherIntConstModeMask;
+tIntFormatList *IntFormatList = NULL;
+tIntConstMode IntConstMode;
+Boolean IntConstModeIBMNoTerm, RelaxedMode;
+int RadixBase;
+
+static Boolean ChkIntFormatCHex(tIntCheckCtx *pCtx, char Ch)
+{
+ if ((pCtx->ExprLen > 2)
+ && (*pCtx->pExpr == '0')
+ && (RadixBase <= Ch - 'A' + 10)
+ && (as_toupper(pCtx->pExpr[1]) == Ch))
+ {
+ pCtx->pExpr += 2;
+ pCtx->ExprLen -= 2;
+ return True;
+ }
+ return False;
+}
+
+static Boolean ChkIntFormatCBin(tIntCheckCtx *pCtx, char Ch)
+{
+ if ((pCtx->ExprLen > 2)
+ && (*pCtx->pExpr == '0')
+ && (RadixBase <= Ch - 'A' + 10)
+ && (as_toupper(pCtx->pExpr[1]) == Ch))
+ {
+ const char *pRun;
+
+ for (pRun = pCtx->pExpr + 2; pRun < pCtx->pExpr + pCtx->ExprLen; pRun++)
+ if (DigitVal(*pRun, 2) < 0)
+ return False;
+ pCtx->pExpr += 2;
+ pCtx->ExprLen -= 2;
+ return True;
+ }
+ return False;
+}
+
+static Boolean ChkIntFormatMot(tIntCheckCtx *pCtx, char Ch)
+{
+ if ((pCtx->ExprLen > 1)
+ && (*pCtx->pExpr == Ch))
+ {
+ pCtx->pExpr++;
+ pCtx->ExprLen--;
+ return True;
+ }
+ return False;
+}
+
+static Boolean ChkIntFormatInt(tIntCheckCtx *pCtx, char Ch)
+{
+ if ((pCtx->ExprLen < 2) || !as_isdigit(*pCtx->pExpr))
+ return False;
+ if ((RadixBase <= Ch - 'A' + 10)
+ && (as_toupper(pCtx->pExpr[pCtx->ExprLen - 1]) == Ch))
+ {
+ pCtx->ExprLen--;
+ return True;
+ }
+ return False;
+}
+
+static Boolean ChkIntFormatIBM(tIntCheckCtx *pCtx, char Ch)
+{
+ if ((pCtx->ExprLen < 3)
+ || (as_toupper(*pCtx->pExpr) != Ch)
+ || (pCtx->pExpr[1] != '\''))
+ return False;
+ if ((pCtx->ExprLen > 3) && (pCtx->pExpr[pCtx->ExprLen - 1] == '\''))
+ {
+ pCtx->pExpr += 2;
+ pCtx->ExprLen -= 3;
+ return True;
+ }
+ else if (IntConstModeIBMNoTerm)
+ {
+ pCtx->pExpr += 2;
+ pCtx->ExprLen -= 2;
+ return True;
+ }
+ return False;
+}
+
+static Boolean ChkIntFormatCOct(tIntCheckCtx *pCtx, char Ch)
+{
+ const char *pRun;
+ UNUSED(Ch);
+
+ if ((pCtx->ExprLen < 2)
+ || (*pCtx->pExpr != '0'))
+ return False;
+ for (pRun = pCtx->pExpr + 1; pRun < pCtx->pExpr + pCtx->ExprLen; pRun++)
+ if (DigitVal(*pRun, 8) < 0)
+ return False;
+ return True;
+}
+
+static Boolean ChkIntFormatNatHex(tIntCheckCtx *pCtx, char Ch)
+{
+ const char *pRun;
+ UNUSED(Ch);
+
+ if ((pCtx->ExprLen < 2)
+ || (*pCtx->pExpr != '0'))
+ return False;
+ for (pRun = pCtx->pExpr + 1; pRun < pCtx->pExpr + pCtx->ExprLen; pRun++)
+ if (!as_isxdigit(*pRun))
+ return False;
+ return True;
+}
+
+static Boolean ChkIntFormatDef(tIntCheckCtx *pCtx, char Ch)
+{
+ UNUSED(pCtx);
+ UNUSED(Ch);
+ return True;
+}
+
+static const tIntFormatList IntFormatList_All[] =
+{
+ { ChkIntFormatCHex , eIntFormatCHex, 16, 'X', "0xhex" },
+ { ChkIntFormatCBin , eIntFormatCBin, 2, 'B', "0bbin" },
+ { ChkIntFormatMot , eIntFormatMotHex, 16, '$', "$hex" },
+ { ChkIntFormatMot , eIntFormatMotBin, 2, '%', "%bin" },
+ { ChkIntFormatMot , eIntFormatMotOct, 8, '@', "@oct" },
+ { ChkIntFormatInt , eIntFormatIntHex, 16, 'H', "hexh" },
+ { ChkIntFormatInt , eIntFormatIntBin, 2, 'B', "binb" },
+ { ChkIntFormatInt , eIntFormatIntOOct, 8, 'O', "octo" },
+ { ChkIntFormatInt , eIntFormatIntQOct, 8, 'Q', "octq" },
+ { ChkIntFormatIBM , eIntFormatIBMHHex, 16, 'H', "h'hex'" },
+ { ChkIntFormatIBM , eIntFormatIBMXHex, 16, 'X', "x'hex'" },
+ { ChkIntFormatIBM , eIntFormatIBMBin, 2, 'B', "b'bin'" },
+ { ChkIntFormatIBM , eIntFormatIBMOct, 8, 'O', "o'oct'" },
+ { ChkIntFormatCOct , eIntFormatCOct, 8, '0', "0oct" },
+ { ChkIntFormatNatHex, eIntFormatNatHex, 16, '0', "0hex" },
+ { ChkIntFormatDef , eIntFormatDefRadix,-1, '\0', "dec" }, /* -1 -> RadixBase */
+ { NULL , (tIntFormatId)0, 0, '\0', "" }
+};
+
+/*!------------------------------------------------------------------------
+ * \fn GetIntConstIntelSuffix(unsigned Radix)
+ * \brief return Intel-style suffix letter fitting to number system
+ * \param Radix req'd number system
+ * \return * to suffix string (may be empty)
+ * ------------------------------------------------------------------------ */
+
+const char *GetIntConstIntelSuffix(unsigned Radix)
+{
+ static const char BaseLetters[3] =
+ {
+ 'B', 'O', 'H'
+ };
+ unsigned BaseIdx;
+
+ for (BaseIdx = 0; BaseIdx < sizeof(BaseVals) / sizeof(*BaseVals); BaseIdx++)
+ if (Radix == BaseVals[BaseIdx])
+ {
+ static char Result[2] = { '\0', '\0' };
+
+ Result[0] = BaseLetters[BaseIdx] + (HexStartCharacter - 'A');
+ return Result;
+ }
+ return "";
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GetIntConstMotoPrefix(unsigned Radix)
+ * \brief return Motorola-style prefix letter fitting to number system
+ * \param Radix req'd number system
+ * \return * to prefix string (may be empty)
+ * ------------------------------------------------------------------------ */
+
+const char *GetIntConstMotoPrefix(unsigned Radix)
+{
+ static const char BaseIds[3] =
+ {
+ '%', '@', '$'
+ };
+ unsigned BaseIdx;
+
+ for (BaseIdx = 0; BaseIdx < sizeof(BaseVals) / sizeof(*BaseVals); BaseIdx++)
+ if (Radix == BaseVals[BaseIdx])
+ {
+ static char Result[2] = { '\0', '\0' };
+
+ Result[0] = BaseIds[BaseIdx];
+ return Result;
+ }
+ return "";
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GetIntConstCPrefix(unsigned Radix)
+ * \brief return C-style prefix letter fitting to number system
+ * \param Radix req'd number system
+ * \return * to prefix string (may be empty)
+ * ------------------------------------------------------------------------ */
+
+const char *GetIntConstCPrefix(unsigned Radix)
+{
+ static const char BaseIds[3][3] =
+ {
+ "0b", "0", "0x"
+ };
+ unsigned BaseIdx;
+
+ for (BaseIdx = 0; BaseIdx < sizeof(BaseVals) / sizeof(*BaseVals); BaseIdx++)
+ if (Radix == BaseVals[BaseIdx])
+ return BaseIds[BaseIdx];;
+ return "";
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GetIntConstIBMPrefix(unsigned Radix)
+ * \brief return IBM-style prefix letter fitting to number system
+ * \param Radix req'd number system
+ * \return * to prefix string (may be empty)
+ * ------------------------------------------------------------------------ */
+
+const char *GetIntConstIBMPrefix(unsigned Radix)
+{
+ static const char BaseIds[3] =
+ {
+ 'B', 'O', 'X'
+ };
+ unsigned BaseIdx;
+
+ for (BaseIdx = 0; BaseIdx < sizeof(BaseVals) / sizeof(*BaseVals); BaseIdx++)
+ if (Radix == BaseVals[BaseIdx])
+ {
+ static char Result[3] = { '\0', '\'', '\0' };
+
+ Result[0] = BaseIds[BaseIdx] + (HexStartCharacter - 'A');
+ return Result;
+ }
+ return "";
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GetIntConstIBMSuffix(unsigned Radix)
+ * \brief return IBM-style suffix fitting to number system
+ * \param Radix req'd number system
+ * \return * to prefix string (may be empty)
+ * ------------------------------------------------------------------------ */
+
+const char *GetIntConstIBMSuffix(unsigned Radix)
+{
+ unsigned BaseIdx;
+
+ for (BaseIdx = 0; BaseIdx < sizeof(BaseVals) / sizeof(*BaseVals); BaseIdx++)
+ if (Radix == BaseVals[BaseIdx])
+ return "\'";
+ return "";
+}
+
+/*!------------------------------------------------------------------------
+ * \fn SetIntConstModeByMask(LongWord Mask)
+ * \brief set new (non-relaxed) integer constant mode by bit mask
+ * \param Mask modes to set
+ * ------------------------------------------------------------------------ */
+
+void SetIntConstModeByMask(LongWord Mask)
+{
+ const tIntFormatList *pSrc;
+ tIntFormatList *pDest;
+
+ if (!IntFormatList)
+ IntFormatList = (tIntFormatList*)malloc(sizeof(IntFormatList_All));
+ for (pDest = IntFormatList, pSrc = IntFormatList_All; pSrc->Check; pSrc++)
+ {
+ if (!((Mask >> pSrc->Id) & 1))
+ continue;
+ *pDest++ = *pSrc;
+ }
+ memset(pDest, 0, sizeof(*pDest));
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ModifyIntConstModeByMask(LongWord ANDMask, LongWord ORMask)
+ * \brief add or remove integer notations to/from native list
+ * \param ANDMask notations to remove
+ * \param ORMask notations to add
+ * \return True if mask was set up successfully
+ * ------------------------------------------------------------------------ */
+
+#define BadMask ((1ul << eIntFormatCOct) | (1ul << eIntFormatNatHex))
+
+Boolean ModifyIntConstModeByMask(LongWord ANDMask, LongWord ORMask)
+{
+ LongWord NewMask = (NativeIntConstModeMask & ~ANDMask) | ORMask;
+
+ if ((NewMask & BadMask) == BadMask)
+ return False;
+ else
+ {
+ NativeIntConstModeMask = NewMask;
+ SetIntConstModeByMask(NativeIntConstModeMask | (RelaxedMode ? OtherIntConstModeMask : 0));
+ return True;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn SetIntConstMode(tIntConstMode Mode)
+ * \brief set new (non-relaxed) integer constant mode
+ * \param Mode mode to set
+ * ------------------------------------------------------------------------ */
+
+void SetIntConstMode(tIntConstMode Mode)
+{
+ IntConstMode = Mode;
+ switch (Mode)
+ {
+ case eIntConstModeC:
+ NativeIntConstModeMask = eIntFormatMaskC;
+ OtherIntConstModeMask = eIntFormatMaskIntel | eIntFormatMaskMoto | eIntFormatMaskIBM;
+ break;
+ case eIntConstModeIntel:
+ NativeIntConstModeMask = eIntFormatMaskIntel;
+ OtherIntConstModeMask = eIntFormatMaskC | eIntFormatMaskMoto | eIntFormatMaskIBM;
+ break;
+ case eIntConstModeMoto:
+ NativeIntConstModeMask = eIntFormatMaskMoto;
+ OtherIntConstModeMask = eIntFormatMaskC | eIntFormatMaskIntel | eIntFormatMaskIBM;
+ break;
+ case eIntConstModeIBM:
+ NativeIntConstModeMask = eIntFormatMaskIBM;
+ OtherIntConstModeMask = eIntFormatMaskC | eIntFormatMaskIntel | eIntFormatMaskMoto;
+ break;
+ default:
+ NativeIntConstModeMask = 0;
+ }
+ NativeIntConstModeMask |= (1ul << eIntFormatDefRadix);
+ SetIntConstModeByMask(NativeIntConstModeMask | (RelaxedMode ? OtherIntConstModeMask : 0));
+}
+
+/*!------------------------------------------------------------------------
+ * \fn SetIntConstRelaxedMode(Boolean NewRelaxedMode)
+ * \brief update relaxed mode - parser list
+ * \param NewRelaxedMode mode to set
+ * ------------------------------------------------------------------------ */
+
+void SetIntConstRelaxedMode(Boolean NewRelaxedMode)
+{
+ SetIntConstModeByMask(NativeIntConstModeMask | (NewRelaxedMode ? OtherIntConstModeMask : 0));
+}
+
+/*!------------------------------------------------------------------------
+ * \fn GetIntFormatId(const char *pIdent)
+ * \brief transform identifier to id
+ * \param pIdent textual identifier
+ * \return resulting Id or None if not found
+ * ------------------------------------------------------------------------ */
+
+tIntFormatId GetIntFormatId(const char *pIdent)
+{
+ const tIntFormatList *pList;
+ for (pList = IntFormatList_All; pList->Check; pList++)
+ if (!as_strcasecmp(pIdent, pList->Ident))
+ return (tIntFormatId)pList->Id;
+ return eIntFormatNone;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn intformat_init(void)
+ * \brief module initialization
+ * ------------------------------------------------------------------------ */
+
+void intformat_init(void)
+{
+ /* Allow all int const modes for handling possible -D options: */
+
+ RelaxedMode = True;
+ SetIntConstMode(eIntConstModeC);
+}
--- /dev/null
+/* intformat.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS */
+/* */
+/* enums regarding integer constant notations */
+/* */
+/*****************************************************************************/
+
+#ifndef _INTFORMAT_H
+#define _INTFORMAT_H
+
+typedef enum
+{
+ eIntFormatNone,
+ eIntFormatDefRadix, /* ... */
+ eIntFormatMotBin, /* %... */
+ eIntFormatMotOct, /* @... */
+ eIntFormatMotHex, /* $... */
+ eIntFormatIntBin, /* ...b */
+ eIntFormatIntOOct, /* ...o */
+ eIntFormatIntQOct, /* ...q */
+ eIntFormatIntHex, /* ...h */
+ eIntFormatIBMBin, /* b'...' */
+ eIntFormatIBMOct, /* o'...' */
+ eIntFormatIBMXHex, /* x'...' */
+ eIntFormatIBMHHex, /* h'...' */
+ eIntFormatCBin, /* 0b... */
+ eIntFormatCOct, /* 0... */
+ eIntFormatCHex, /* 0x... */
+ eIntFormatNatHex /* 0..., incompatible with eIntFormatCOct */
+} tIntFormatId;
+
+#define eIntFormatMaskC ((1ul << eIntFormatCHex) | (1ul << eIntFormatCBin) | (1ul << eIntFormatCOct))
+#define eIntFormatMaskIntel ((1ul << eIntFormatIntHex) | (1ul << eIntFormatIntBin) | (1ul << eIntFormatIntOOct) | (1ul << eIntFormatIntQOct))
+#define eIntFormatMaskMoto ((1ul << eIntFormatMotHex) | (1ul << eIntFormatMotBin) | (1ul << eIntFormatMotOct))
+#define eIntFormatMaskIBM ((1ul << eIntFormatIBMXHex) | (1ul << eIntFormatIBMHHex) | (1ul << eIntFormatIBMBin) | (1ul << eIntFormatIBMOct))
+
+typedef enum eIntConstMode
+{
+ eIntConstModeIntel, /* Hex xxxxh, Oct xxxxo, Bin xxxxb */
+ eIntConstModeMoto, /* Hex $xxxx, Oct @xxxx, Bin %xxxx */
+ eIntConstModeC, /* Hex 0x..., Oct 0...., Bin 0b... */
+ eIntConstModeIBM /* Hex 'xxxx['], Oct o'xxxx['], Bin b'xxxx['] */
+} tIntConstMode;
+
+typedef struct
+{
+ const char *pExpr;
+ size_t ExprLen;
+ int Base;
+} tIntCheckCtx;
+
+typedef Boolean (*tIntFormatCheck)(tIntCheckCtx *pCtx, char Ch);
+
+typedef struct
+{
+ tIntFormatCheck Check;
+ Byte Id;
+ ShortInt Base;
+ char Ch;
+ char Ident[7];
+} tIntFormatList;
+
+extern LongWord NativeIntConstModeMask, OtherIntConstModeMask;
+extern tIntFormatList *IntFormatList;
+extern Boolean RelaxedMode;
+extern int RadixBase;
+
+extern const char *GetIntConstMotoPrefix(unsigned Radix);
+extern const char *GetIntConstIntelSuffix(unsigned Radix);
+extern const char *GetIntConstIBMPrefix(unsigned Radix);
+extern const char *GetIntConstIBMSuffix(unsigned Radix);
+extern const char *GetIntConstCPrefix(unsigned Radix);
+
+extern void SetIntConstModeByMask(LongWord Mask);
+extern Boolean ModifyIntConstModeByMask(LongWord ANDMask, LongWord ORMask);
+
+extern void SetIntConstMode(tIntConstMode Mode);
+
+extern void SetIntConstRelaxedMode(Boolean NewRelaxedMode);
+
+extern tIntFormatId GetIntFormatId(const char *pIdent);
+
+extern void intformat_init(void);
+
+#endif /* _INTFORMAT_H */
--- /dev/null
+/* intpseudo.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS */
+/* */
+/* Commonly Used Intel-Style Pseudo Instructions */
+/* */
+/*****************************************************************************/
+
+/*****************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "stdinc.h"
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+
+#include "bpemu.h"
+#include "endian.h"
+#include "strutil.h"
+#include "nls.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmitree.h"
+#include "onoff_common.h"
+#include "errmsg.h"
+#include "ieeefloat.h"
+
+#include "intpseudo.h"
+
+#define LEAVE goto func_exit
+
+/*****************************************************************************
+ * Local Types
+ *****************************************************************************/
+
+struct sLayoutCtx;
+
+typedef Boolean (*TLayoutFunc)(
+#ifdef __PROTOS__
+ const tStrComp *pArg, struct sLayoutCtx *pCtx
+#endif
+ );
+
+typedef enum
+{
+ DSNone, DSConstant, DSSpace
+} tDSFlag;
+
+struct sCurrCodeFill
+{
+ LongInt FullWordCnt;
+ int LastWordFill;
+};
+typedef struct sCurrCodeFill tCurrCodeFill;
+
+struct sLayoutCtx
+{
+ tDSFlag DSFlag;
+ TLayoutFunc LayoutFunc;
+ int BaseElemLenBits, FullWordSize, ElemsPerFullWord;
+ Boolean (*Put4I)(Byte b, struct sLayoutCtx *pCtx);
+ Boolean (*Put8I)(Byte b, struct sLayoutCtx *pCtx);
+ Boolean (*Put16I)(Word w, struct sLayoutCtx *pCtx);
+ Boolean (*Put16F)(Double f, struct sLayoutCtx *pCtx);
+ Boolean (*Put32I)(LongWord l, struct sLayoutCtx *pCtx);
+ Boolean (*Put32F)(Double f, struct sLayoutCtx *pCtx);
+ Boolean (*Put64I)(LargeWord q, struct sLayoutCtx *pCtx);
+ Boolean (*Put64F)(Double f, struct sLayoutCtx *pCtx);
+ Boolean (*Put80F)(Double t, struct sLayoutCtx *pCtx);
+ Boolean (*Replicate)(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx);
+ tCurrCodeFill CurrCodeFill, FillIncPerElem;
+ const tStrComp *pCurrComp;
+ int LoHiMap;
+};
+typedef struct sLayoutCtx tLayoutCtx;
+
+/*****************************************************************************
+ * Global Variables
+ *****************************************************************************/
+
+static char Z80SyntaxName[] = "Z80SYNTAX";
+tZ80Syntax CurrZ80Syntax;
+
+/*****************************************************************************
+ * Local Functions
+ *****************************************************************************/
+
+void _DumpCodeFill(const char *pTitle, const tCurrCodeFill *pFill)
+{
+ fprintf(stderr, "%s %u %d\n", pTitle, (unsigned)pFill->FullWordCnt, pFill->LastWordFill);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn Boolean SetDSFlag(struct sLayoutCtx *pCtx, tDSFlag Flag)
+ * \brief check set data disposition/reservation flag in context
+ * \param pCtx context
+ * \param Flag operation to be set
+ * \return True if operation could be set or was alreday set
+ * ------------------------------------------------------------------------ */
+
+static Boolean SetDSFlag(struct sLayoutCtx *pCtx, tDSFlag Flag)
+{
+ if ((pCtx->DSFlag != DSNone) && (pCtx->DSFlag != Flag))
+ {
+ WrStrErrorPos(ErrNum_MixDBDS, pCtx->pCurrComp);
+ return False;
+ }
+ pCtx->DSFlag = Flag;
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn IncMaxCodeLen(struct sLayoutCtx *pCtx, LongWord NumFullWords)
+ * \brief assure xAsmCode has space for at moleast n more full words
+ * \param pCtxcontext
+ * \param NumFullWords # of additional words intended to write
+ * \return True if success
+ * ------------------------------------------------------------------------ */
+
+static Boolean IncMaxCodeLen(struct sLayoutCtx *pCtx, LongWord NumFullWords)
+{
+ if (SetMaxCodeLen((pCtx->CurrCodeFill.FullWordCnt + NumFullWords) * pCtx->FullWordSize))
+ {
+ WrStrErrorPos(ErrNum_CodeOverflow, pCtx->pCurrComp);
+ return False;
+ }
+ else
+ return True;
+}
+
+static LargeWord ByteInWord(Byte b, int Pos)
+{
+ return ((LargeWord)b) << (Pos << 3);
+}
+
+static Byte NibbleInByte(Byte n, int Pos)
+{
+ return (n & 15) << (Pos << 2);
+}
+
+static Word NibbleInWord(Byte n, int Pos)
+{
+ return ((Word)(n & 15)) << (Pos << 2);
+}
+
+static Byte ByteFromWord(LargeWord w, int Pos)
+{
+ return (w >> (Pos << 3)) & 0xff;
+}
+
+static Byte NibbleFromByte(Byte b, int Pos)
+{
+ return (b >> (Pos << 2)) & 0x0f;
+}
+
+static Byte NibbleFromWord(Word w, int Pos)
+{
+ return (w >> (Pos << 2)) & 0x0f;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn SubCodeFill
+ * \brief perform 'c = a - b' on tCurrCodeFill structures
+ * \param c result
+ * \param b, c arguments
+ * ------------------------------------------------------------------------ */
+
+static void SubCodeFill(tCurrCodeFill *c, const tCurrCodeFill *a, const tCurrCodeFill *b, struct sLayoutCtx *pCtx)
+{
+ c->FullWordCnt = a->FullWordCnt - b->FullWordCnt;
+ if ((c->LastWordFill = a->LastWordFill - b->LastWordFill) < 0)
+ {
+ c->LastWordFill += pCtx->ElemsPerFullWord;
+ c->FullWordCnt--;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn MultCodeFill(tCurrCodeFill *b, LongWord a, struct sLayoutCtx *pCtx)
+ * \brief perform 'b *= a' on tCurrCodeFill structures
+ * \param b what to multiply
+ * \param a scaling factor
+ * ------------------------------------------------------------------------ */
+
+static void MultCodeFill(tCurrCodeFill *b, LongWord a, struct sLayoutCtx *pCtx)
+{
+ b->FullWordCnt *= a;
+ b->LastWordFill *= a;
+ if (pCtx->ElemsPerFullWord > 1)
+ {
+ LongWord div = b->LastWordFill / pCtx->ElemsPerFullWord,
+ mod = b->LastWordFill % pCtx->ElemsPerFullWord;
+ b->FullWordCnt += div;
+ b->LastWordFill = mod;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn IncCodeFill(tCurrCodeFill *a, struct sLayoutCtx *pCtx)
+ * \brief advance tCurrCodeFill pointer by one base element
+ * \param a pointer to increment
+ * \param pCtx context
+ * ------------------------------------------------------------------------ */
+
+static void IncCodeFill(tCurrCodeFill *a, struct sLayoutCtx *pCtx)
+{
+ if (++a->LastWordFill >= pCtx->ElemsPerFullWord)
+ {
+ a->LastWordFill -= pCtx->ElemsPerFullWord;
+ a->FullWordCnt++;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn IncCurrCodeFill(struct sLayoutCtx *pCtx)
+ * \brief advance CodeFill pointer in context and reserve memory
+ * \param pCtx context
+ * \return True if success
+ * ------------------------------------------------------------------------ */
+
+static Boolean IncCurrCodeFill(struct sLayoutCtx *pCtx)
+{
+ LongInt OldFullWordCnt = pCtx->CurrCodeFill.FullWordCnt;
+
+ IncCodeFill(&pCtx->CurrCodeFill, pCtx);
+ if (OldFullWordCnt == pCtx->CurrCodeFill.FullWordCnt)
+ return True;
+ else if (!IncMaxCodeLen(pCtx, 1))
+ return False;
+ else
+ {
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt] = 0;
+ return True;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn IncCodeFillBy(tCurrCodeFill *a, const tCurrCodeFill *inc, struct sLayoutCtx *pCtx)
+ * \brief perform 'a += inc' on tCurrCodeFill structures
+ * \param a what to advance
+ * \param inc by what to advance
+ * \param pCtx context
+ * ------------------------------------------------------------------------ */
+
+static void IncCodeFillBy(tCurrCodeFill *a, const tCurrCodeFill *inc, struct sLayoutCtx *pCtx)
+{
+ a->LastWordFill += inc->LastWordFill;
+ if ((pCtx->ElemsPerFullWord > 1) && (a->LastWordFill >= pCtx->ElemsPerFullWord))
+ {
+ a->LastWordFill -= pCtx->ElemsPerFullWord;
+ a->FullWordCnt++;
+ }
+ a->FullWordCnt += inc->FullWordCnt;
+}
+
+/*****************************************************************************
+ * Function: LayoutNibble
+ * Purpose: parse argument, interprete as nibble,
+ * and put into result buffer
+ * Result: TRUE if no errors occured
+ *****************************************************************************/
+
+static Boolean Put4I_To_8(Byte b, struct sLayoutCtx *pCtx)
+{
+ tCurrCodeFill Pos = pCtx->CurrCodeFill;
+ if (!IncCurrCodeFill(pCtx))
+ return False;
+ if (!Pos.LastWordFill)
+ BAsmCode[Pos.FullWordCnt] = NibbleInByte(b, Pos.LastWordFill ^ pCtx->LoHiMap);
+ else
+ BAsmCode[Pos.FullWordCnt] |= NibbleInByte(b, Pos.LastWordFill ^ pCtx->LoHiMap);
+ return True;
+}
+
+static Boolean Replicate4_To_8(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
+{
+ Byte b;
+ tCurrCodeFill CurrPos;
+
+ CurrPos = *pStartPos;
+ while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
+ {
+ b = NibbleFromByte(BAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
+ if (!Put4I_To_8(b, pCtx))
+ return False;
+ IncCodeFill(&CurrPos, pCtx);
+ }
+
+ return True;
+}
+
+static Boolean Put4I_To_16(Byte b, struct sLayoutCtx *pCtx)
+{
+ tCurrCodeFill Pos = pCtx->CurrCodeFill;
+ if (!IncCurrCodeFill(pCtx))
+ return False;
+ if (!Pos.LastWordFill)
+ WAsmCode[Pos.FullWordCnt] = NibbleInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
+ else
+ WAsmCode[Pos.FullWordCnt] |= NibbleInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
+ return True;
+}
+
+static Boolean Replicate4_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
+{
+ Byte b;
+ tCurrCodeFill CurrPos;
+
+ CurrPos = *pStartPos;
+ while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
+ {
+ b = NibbleFromWord(WAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
+ if (!Put4I_To_16(b, pCtx))
+ return False;
+ IncCodeFill(&CurrPos, pCtx);
+ }
+
+ return True;
+}
+
+static Boolean LayoutNibble(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
+{
+ Boolean Result = False;
+ TempResult t;
+
+ as_tempres_ini(&t);
+ EvalStrExpression(pExpr, &t);
+ switch (t.Typ)
+ {
+ case TempInt:
+ if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xf;
+ if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int4)) WrStrErrorPos(ErrNum_OverRange, pExpr);
+ else
+ {
+ if (!pCtx->Put4I(t.Contents.Int, pCtx))
+ LEAVE;
+ Result = True;
+ }
+ break;
+ case TempFloat:
+ WrStrErrorPos(ErrNum_IntButFloat, pExpr);
+ break;
+ case TempString:
+ WrStrErrorPos(ErrNum_IntButString, pExpr);
+ break;
+ default:
+ break;
+ }
+
+func_exit:
+ as_tempres_free(&t);
+ return Result;
+}
+
+/*****************************************************************************
+ * Function: LayoutByte
+ * Purpose: parse argument, interprete as byte,
+ * and put into result buffer
+ * Result: TRUE if no errors occured
+ *****************************************************************************/
+
+static Boolean Put8I_To_8(Byte b, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 1))
+ return False;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt++] = b;
+ return True;
+}
+
+static Boolean Put8I_To_16(Byte b, struct sLayoutCtx *pCtx)
+{
+ tCurrCodeFill Pos = pCtx->CurrCodeFill;
+ if (!IncCurrCodeFill(pCtx))
+ return False;
+ if (!Pos.LastWordFill)
+ WAsmCode[Pos.FullWordCnt] = ByteInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
+ else
+ WAsmCode[Pos.FullWordCnt] |= ByteInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
+ return True;
+}
+
+static Boolean Replicate8ToN_To_8(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
+{
+ tCurrCodeFill Pos;
+
+ if (!IncMaxCodeLen(pCtx, pEndPos->FullWordCnt - pStartPos->FullWordCnt))
+ return False;
+
+ for (Pos = *pStartPos; Pos.FullWordCnt < pEndPos->FullWordCnt; Pos.FullWordCnt += pCtx->BaseElemLenBits / 8)
+ {
+ memcpy(&BAsmCode[pCtx->CurrCodeFill.FullWordCnt], &BAsmCode[Pos.FullWordCnt], pCtx->BaseElemLenBits / 8);
+ pCtx->CurrCodeFill.FullWordCnt += pCtx->BaseElemLenBits / 8;
+ }
+ if (Pos.FullWordCnt != pEndPos->FullWordCnt)
+ {
+ WrXError(ErrNum_InternalError, "DUP replication inconsistency");
+ return False;
+ }
+
+ return True;
+}
+
+static Boolean Replicate8_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
+{
+ Byte b;
+ tCurrCodeFill CurrPos;
+
+ CurrPos = *pStartPos;
+ while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
+ {
+ b = ByteFromWord(WAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
+ if (!Put8I_To_16(b, pCtx))
+ return False;
+ IncCodeFill(&CurrPos, pCtx);
+ }
+
+ return True;
+}
+
+static Boolean LayoutByte(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
+{
+ Boolean Result = False;
+ TempResult t;
+
+ as_tempres_ini(&t);
+ EvalStrExpression(pExpr, &t);
+ switch (t.Typ)
+ {
+ case TempInt:
+ ToInt:
+ if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xff;
+ if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int8)) WrStrErrorPos(ErrNum_OverRange, pExpr);
+ else
+ {
+ if (!pCtx->Put8I(t.Contents.Int, pCtx))
+ LEAVE;
+ Result = True;
+ }
+ break;
+ case TempFloat:
+ WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
+ break;
+ case TempString:
+ {
+ unsigned z;
+
+ if (MultiCharToInt(&t, 1))
+ goto ToInt;
+
+ TranslateString(t.Contents.str.p_str, t.Contents.str.len);
+
+ for (z = 0; z < t.Contents.str.len; z++)
+ if (!pCtx->Put8I(t.Contents.str.p_str[z], pCtx))
+ LEAVE;
+
+ Result = True;
+ break;
+ }
+ default:
+ break;
+ }
+
+func_exit:
+ as_tempres_free(&t);
+ return Result;
+}
+
+/*****************************************************************************
+ * Function: LayoutWord
+ * Purpose: parse argument, interprete as 16-bit word,
+ * and put into result buffer
+ * Result: TRUE if no errors occured
+ *****************************************************************************/
+
+static Boolean Put16I_To_8(Word w, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 2))
+ return False;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = Lo(w);
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = Hi(w);
+ pCtx->CurrCodeFill.FullWordCnt += 2;
+ return True;
+}
+
+static Boolean Put16F_To_8(Double t, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 2))
+ return False;
+ if (!Double_2_ieee2(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap))
+ {
+ WrError(ErrNum_OverRange);
+ return False;
+ }
+ pCtx->CurrCodeFill.FullWordCnt += 2;
+ return True;
+}
+
+static Boolean Put16I_To_16(Word w, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 1))
+ return False;
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt++] = w;
+ return True;
+}
+
+static Boolean Put16F_To_16(Double t, struct sLayoutCtx *pCtx)
+{
+ Byte Tmp[2];
+
+ if (!IncMaxCodeLen(pCtx, 1))
+ return False;
+
+ Double_2_ieee2(t, Tmp, !!pCtx->LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[1], 1 ^ pCtx->LoHiMap);
+ pCtx->CurrCodeFill.FullWordCnt += 1;
+ return True;
+}
+
+static Boolean Replicate16ToN_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
+{
+ tCurrCodeFill Pos;
+
+ if (!IncMaxCodeLen(pCtx, pEndPos->FullWordCnt - pStartPos->FullWordCnt))
+ return False;
+
+ for (Pos = *pStartPos; Pos.FullWordCnt < pEndPos->FullWordCnt; Pos.FullWordCnt += pCtx->BaseElemLenBits / 16)
+ {
+ memcpy(&WAsmCode[pCtx->CurrCodeFill.FullWordCnt], &WAsmCode[Pos.FullWordCnt], pCtx->BaseElemLenBits / 8);
+ pCtx->CurrCodeFill.FullWordCnt += pCtx->BaseElemLenBits / 16;
+ }
+ if (Pos.FullWordCnt != pEndPos->FullWordCnt)
+ {
+ WrXError(ErrNum_InternalError, "DUP replication inconsistency");
+ return False;
+ }
+
+ return True;
+}
+
+static Boolean LayoutWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
+{
+ Boolean Result = False;
+ TempResult t;
+
+ as_tempres_ini(&t);
+ EvalStrExpression(pExpr, &t);
+ Result = True;
+ switch (t.Typ)
+ {
+ case TempInt:
+ ToInt:
+ if (pCtx->Put16I)
+ {
+ if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xffff;
+ if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int16)) WrStrErrorPos(ErrNum_OverRange, pExpr);
+ else
+ {
+ if (!pCtx->Put16I(t.Contents.Int, pCtx))
+ LEAVE;
+ Result = True;
+ }
+ break;
+ }
+ else
+ TempResultToFloat(&t);
+ /* fall-through */
+ case TempFloat:
+ if (!pCtx->Put16F) WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
+ else if (!FloatRangeCheck(t.Contents.Float, Float16)) WrStrErrorPos(ErrNum_OverRange, pExpr);
+ else
+ {
+ if (!pCtx->Put16F(t.Contents.Float, pCtx))
+ LEAVE;
+ Result = True;
+ }
+ break;
+ case TempString:
+ {
+ unsigned z;
+
+ if (MultiCharToInt(&t, 2))
+ goto ToInt;
+
+ TranslateString(t.Contents.str.p_str, t.Contents.str.len);
+
+ for (z = 0; z < t.Contents.str.len; z++)
+ if (!pCtx->Put16I(t.Contents.str.p_str[z], pCtx))
+ LEAVE;
+
+ Result = True;
+ break;
+ }
+ default:
+ break;
+ }
+
+func_exit:
+ as_tempres_free(&t);
+ return Result;
+}
+
+/*****************************************************************************
+ * Function: LayoutDoubleWord
+ * Purpose: parse argument, interprete as 32-bit word or
+ single precision float, and put into result buffer
+ * Result: TRUE if no errors occured
+ *****************************************************************************/
+
+static Boolean Put32I_To_8(LongWord l, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 4))
+ return False;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l ) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >> 8) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 16) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 24) & 0xff;
+ pCtx->CurrCodeFill.FullWordCnt += 4;
+ return True;
+}
+
+static Boolean Put32F_To_8(Double t, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 4))
+ return False;
+ Double_2_ieee4(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
+ pCtx->CurrCodeFill.FullWordCnt += 4;
+ return True;
+}
+
+static Boolean Put32I_To_16(LongWord l, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 2))
+ return False;
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = LoWord(l);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = HiWord(l);
+ pCtx->CurrCodeFill.FullWordCnt += 2;
+ return True;
+}
+
+static Boolean Put32F_To_16(Double t, struct sLayoutCtx *pCtx)
+{
+ Byte Tmp[4];
+
+ if (!IncMaxCodeLen(pCtx, 2))
+ return False;
+ Double_2_ieee4(t, Tmp, !!pCtx->LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[1], 1 ^ pCtx->LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[3], 1 ^ pCtx->LoHiMap);
+ pCtx->CurrCodeFill.FullWordCnt += 2;
+ return True;
+}
+
+static Boolean LayoutDoubleWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
+{
+ TempResult erg;
+ Boolean Result = False;
+ Word Cnt = 0;
+
+ as_tempres_ini(&erg);
+ EvalStrExpression(pExpr, &erg);
+ Result = False;
+ switch (erg.Typ)
+ {
+ case TempNone:
+ break;
+ case TempInt:
+ ToInt:
+ if (pCtx->Put32I)
+ {
+ if (mFirstPassUnknown(erg.Flags)) erg.Contents.Int &= 0xfffffffful;
+ if (!mSymbolQuestionable(erg.Flags) && !RangeCheck(erg.Contents.Int, Int32)) WrStrErrorPos(ErrNum_OverRange, pExpr);
+ else
+ {
+ if (!pCtx->Put32I(erg.Contents.Int, pCtx))
+ LEAVE;
+ Cnt = 4;
+ Result = True;
+ }
+ break;
+ }
+ else
+ TempResultToFloat(&erg);
+ /* fall-through */
+ case TempFloat:
+ if (!pCtx->Put32F) WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
+ else if (!FloatRangeCheck(erg.Contents.Float, Float32)) WrStrErrorPos(ErrNum_OverRange, pExpr);
+ else
+ {
+ if (!pCtx->Put32F(erg.Contents.Float, pCtx))
+ LEAVE;
+ Cnt = 4;
+ Result = True;
+ }
+ break;
+ case TempString:
+ {
+ unsigned z;
+
+ if (MultiCharToInt(&erg, 4))
+ goto ToInt;
+
+ TranslateString(erg.Contents.str.p_str, erg.Contents.str.len);
+
+ for (z = 0; z < erg.Contents.str.len; z++)
+ if (!pCtx->Put32I(erg.Contents.str.p_str[z], pCtx))
+ LEAVE;
+
+ Cnt = erg.Contents.str.len * 4;
+ Result = True;
+ break;
+ }
+ case TempReg:
+ WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
+ break;
+ case TempAll:
+ assert(0);
+ }
+ (void)Cnt;
+
+func_exit:
+ as_tempres_free(&erg);
+ return Result;
+}
+
+
+/*****************************************************************************
+ * Function: LayoutQuadWord
+ * Purpose: parse argument, interprete as 64-bit word or
+ double precision float, and put into result buffer
+ * Result: TRUE if no errors occured
+ *****************************************************************************/
+
+static Boolean Put64I_To_8(LargeWord l, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 8))
+ return False;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l ) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >> 8) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 16) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 24) & 0xff;
+#ifdef HAS64
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)] = (l >> 32) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)] = (l >> 40) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (6 ^ pCtx->LoHiMap)] = (l >> 48) & 0xff;
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (7 ^ pCtx->LoHiMap)] = (l >> 56) & 0xff;
+#else
+ /* TempResult is TempInt, so sign-extend */
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)] =
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)] =
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (6 ^ pCtx->LoHiMap)] =
+ BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (7 ^ pCtx->LoHiMap)] = (l & 0x80000000ul) ? 0xff : 0x00;
+#endif
+ pCtx->CurrCodeFill.FullWordCnt += 8;
+ return True;
+}
+
+static Boolean Put64F_To_8(Double t, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 8))
+ return False;
+ Double_2_ieee8(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
+ pCtx->CurrCodeFill.FullWordCnt += 8;
+ return True;
+}
+
+static Boolean Put64I_To_16(LargeWord l, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 4))
+ return False;
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l ) & 0xffff;
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >> 16) & 0xffff;
+#ifdef HAS64
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 32) & 0xffff;
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 48) & 0xffff;
+#else
+ /* TempResult is TempInt, so sign-extend */
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] =
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l & 0x80000000ul) ? 0xffff : 0x0000;
+#endif
+ pCtx->CurrCodeFill.FullWordCnt += 4;
+ return True;
+}
+
+static Boolean Put64F_To_16(Double t, struct sLayoutCtx *pCtx)
+{
+ Byte Tmp[8];
+ int LoHiMap = pCtx->LoHiMap & 1;
+
+ if (!IncMaxCodeLen(pCtx, 4))
+ return False;
+ Double_2_ieee8(t, Tmp, !!pCtx->LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ LoHiMap) | ByteInWord(Tmp[1], 1 ^ LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ LoHiMap) | ByteInWord(Tmp[3], 1 ^ LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 2] = ByteInWord(Tmp[4], 0 ^ LoHiMap) | ByteInWord(Tmp[5], 1 ^ LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 3] = ByteInWord(Tmp[6], 0 ^ LoHiMap) | ByteInWord(Tmp[7], 1 ^ LoHiMap);
+ pCtx->CurrCodeFill.FullWordCnt += 4;
+ return True;
+}
+
+static Boolean LayoutQuadWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
+{
+ Boolean Result = False;
+ TempResult erg;
+ Word Cnt = 0;
+
+ as_tempres_ini(&erg);
+ EvalStrExpression(pExpr, &erg);
+ Result = False;
+ switch(erg.Typ)
+ {
+ case TempNone:
+ break;
+ case TempInt:
+ ToInt:
+ if (pCtx->Put64I)
+ {
+ if (!pCtx->Put64I(erg.Contents.Int, pCtx))
+ LEAVE;
+ Cnt = 8;
+ Result = True;
+ break;
+ }
+ else
+ TempResultToFloat(&erg);
+ /* fall-through */
+ case TempFloat:
+ if (!pCtx->Put64F) WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
+ else if (!pCtx->Put64F(erg.Contents.Float, pCtx))
+ LEAVE;
+ Cnt = 8;
+ Result = True;
+ break;
+ case TempString:
+ {
+ unsigned z;
+
+ if (MultiCharToInt(&erg, 8))
+ goto ToInt;
+
+ TranslateString(erg.Contents.str.p_str, erg.Contents.str.len);
+
+ for (z = 0; z < erg.Contents.str.len; z++)
+ if (!pCtx->Put64I(erg.Contents.str.p_str[z], pCtx))
+ LEAVE;
+
+ Cnt = erg.Contents.str.len * 8;
+ Result = True;
+ break;
+ }
+ case TempReg:
+ WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
+ break;
+ case TempAll:
+ assert(0);
+ }
+ (void)Cnt;
+
+func_exit:
+ as_tempres_free(&erg);
+ return Result;
+}
+
+/*****************************************************************************
+ * Function: LayoutTenBytes
+ * Purpose: parse argument, interprete extended precision float,
+ * and put into result buffer
+ * Result: TRUE if no errors occured
+ *****************************************************************************/
+
+static Boolean Put80F_To_8(Double t, struct sLayoutCtx *pCtx)
+{
+ if (!IncMaxCodeLen(pCtx, 10))
+ return False;
+ Double_2_ieee10(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
+ pCtx->CurrCodeFill.FullWordCnt += 10;
+ return True;
+}
+
+static Boolean Put80F_To_16(Double t, struct sLayoutCtx *pCtx)
+{
+ Byte Tmp[10];
+ int LoHiMap = pCtx->LoHiMap & 1;
+
+ if (!IncMaxCodeLen(pCtx, 5))
+ return False;
+ Double_2_ieee10(t, Tmp, !!pCtx->LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ LoHiMap) | ByteInWord(Tmp[1], 1 ^ LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ LoHiMap) | ByteInWord(Tmp[3], 1 ^ LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 2] = ByteInWord(Tmp[4], 0 ^ LoHiMap) | ByteInWord(Tmp[5], 1 ^ LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 3] = ByteInWord(Tmp[6], 0 ^ LoHiMap) | ByteInWord(Tmp[7], 1 ^ LoHiMap);
+ WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 4] = ByteInWord(Tmp[8], 0 ^ LoHiMap) | ByteInWord(Tmp[9], 1 ^ LoHiMap);
+ pCtx->CurrCodeFill.FullWordCnt += 5;
+ return True;
+}
+
+static Boolean LayoutTenBytes(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
+{
+ Boolean Result = False;
+ TempResult erg;
+ Word Cnt;
+
+ as_tempres_ini(&erg);
+ EvalStrExpression(pExpr, &erg);
+ Result = False;
+ switch(erg.Typ)
+ {
+ case TempNone:
+ break;
+ case TempInt:
+ ToInt:
+ TempResultToFloat(&erg);
+ /* fall-through */
+ case TempFloat:
+ if (!pCtx->Put80F(erg.Contents.Float, pCtx))
+ LEAVE;
+ Cnt = 10;
+ Result = True;
+ break;
+ case TempString:
+ {
+ unsigned z;
+
+ if (MultiCharToInt(&erg, 4))
+ goto ToInt;
+
+ TranslateString(erg.Contents.str.p_str, erg.Contents.str.len);
+
+ for (z = 0; z < erg.Contents.str.len; z++)
+ if (!pCtx->Put80F(erg.Contents.str.p_str[z], pCtx))
+ LEAVE;
+
+ Cnt = erg.Contents.str.len * 10;
+ Result = True;
+ break;
+ }
+ case TempReg:
+ WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
+ break;
+ case TempAll:
+ assert(0);
+ }
+ (void)Cnt;
+
+func_exit:
+ as_tempres_free(&erg);
+ return Result;
+}
+
+/*****************************************************************************
+ * Global Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Function: DecodeIntelPseudo
+ * Purpose: handle Intel-style pseudo instructions
+ * Result: TRUE if mnemonic was handled
+ *****************************************************************************/
+
+static Boolean DecodeIntelPseudo_ValidSymChar(char ch)
+{
+ ch = as_toupper(ch);
+
+ return (((ch >= 'A') && (ch <= 'Z'))
+ || ((ch >= '0') && (ch <= '9'))
+ || (ch == '_')
+ || (ch == '.'));
+}
+
+static void DecodeIntelPseudo_HandleQuote(int *pDepth, Byte *pQuote, char Ch)
+{
+ switch (Ch)
+ {
+ case '(':
+ if (!(*pQuote))
+ (*pDepth)++;
+ break;
+ case ')':
+ if (!(*pQuote))
+ (*pDepth)--;
+ break;
+ case '\'':
+ if (!((*pQuote) & 2))
+ (*pQuote) ^= 1;
+ break;
+ case '"':
+ if (!((*pQuote) & 1))
+ (*pQuote) ^= 2;
+ break;
+ }
+}
+
+static Boolean DecodeIntelPseudo_LayoutMult(const tStrComp *pArg, struct sLayoutCtx *pCtx)
+{
+ int z, Depth, Len, LastNonBlank;
+ Boolean OK, LastValid, Result;
+ Byte Quote;
+ const char *pDupFnd, *pRun;
+ const tStrComp *pSaveComp;
+
+ pSaveComp = pCtx->pCurrComp;
+ pCtx->pCurrComp = pArg;
+
+ /* search for DUP:
+ - Exclude parts in parentheses, and parts in quotation marks.
+ - Assure there is some (non-blank) token before DUP, so if there
+ is e.g. a plain DUP as argument, it will not be interpreted as
+ DUP operator. */
+
+ Depth = Quote = 0;
+ LastValid = FALSE;
+ LastNonBlank = -1;
+ pDupFnd = NULL; Len = strlen(pArg->str.p_str);
+ for (pRun = pArg->str.p_str; pRun < pArg->str.p_str + Len - 2; pRun++)
+ {
+ DecodeIntelPseudo_HandleQuote(&Depth, &Quote, *pRun);
+ if (!Depth && !Quote)
+ {
+ if (!LastValid
+ && (LastNonBlank >= 0)
+ && !DecodeIntelPseudo_ValidSymChar(pRun[3])
+ && !as_strncasecmp(pRun, "DUP", 3))
+ {
+ pDupFnd = pRun;
+ break;
+ }
+ if (!as_isspace(*pRun))
+ LastNonBlank = pRun - pArg->str.p_str;
+ }
+ LastValid = DecodeIntelPseudo_ValidSymChar(*pRun);
+ }
+
+ /* found DUP: */
+
+ if (pDupFnd)
+ {
+ LongInt DupCnt;
+ char *pSep, *pRun;
+ String CopyStr;
+ tStrComp Copy, DupArg, RemArg, ThisRemArg;
+ tCurrCodeFill DUPStartFill, DUPEndFill;
+ tSymbolFlags Flags;
+
+ /* operate on copy */
+
+ StrCompMkTemp(&Copy, CopyStr, sizeof(CopyStr));
+ StrCompCopy(&Copy, pArg);
+ pSep = Copy.str.p_str + (pDupFnd - pArg->str.p_str);
+
+ /* evaluate count */
+
+ StrCompSplitRef(&DupArg, &RemArg, &Copy, pSep);
+ DupCnt = EvalStrIntExpressionWithFlags(&DupArg, Int32, &OK, &Flags);
+ if (mFirstPassUnknown(Flags))
+ {
+ WrStrErrorPos(ErrNum_FirstPassCalc, &DupArg); return False;
+ }
+ if (!OK)
+ {
+ Result = False;
+ goto func_exit;
+ }
+
+ /* catch invalid counts */
+
+ if (DupCnt <= 0)
+ {
+ if (DupCnt < 0)
+ WrStrErrorPos(ErrNum_NegDUP, &DupArg);
+ Result = True;
+ goto func_exit;
+ }
+
+ /* split into parts and evaluate */
+
+ StrCompIncRefLeft(&RemArg, 2);
+ KillPrefBlanksStrCompRef(&RemArg);
+ Len = strlen(RemArg.str.p_str);
+ if ((Len >= 2) && (*RemArg.str.p_str == '(') && (RemArg.str.p_str[Len - 1] == ')'))
+ {
+ StrCompIncRefLeft(&RemArg, 1);
+ StrCompShorten(&RemArg, 1);
+ Len -= 2;
+ }
+ DUPStartFill = pCtx->CurrCodeFill;
+ do
+ {
+ pSep = NULL; Quote = Depth = 0;
+ for (pRun = RemArg.str.p_str; *pRun; pRun++)
+ {
+ DecodeIntelPseudo_HandleQuote(&Depth, &Quote, *pRun);
+ if ((!Depth) && (!Quote) && (*pRun == ','))
+ {
+ pSep = pRun;
+ break;
+ }
+ }
+ if (pSep)
+ StrCompSplitRef(&RemArg, &ThisRemArg, &RemArg, pSep);
+ KillPrefBlanksStrCompRef(&RemArg);
+ KillPostBlanksStrComp(&RemArg);
+ if (!DecodeIntelPseudo_LayoutMult(&RemArg, pCtx))
+ {
+ Result = False;
+ goto func_exit;
+ }
+ if (pSep)
+ RemArg = ThisRemArg;
+ }
+ while (pSep);
+ DUPEndFill = pCtx->CurrCodeFill;
+
+ /* replicate result (data or reserve) */
+
+ switch (pCtx->DSFlag)
+ {
+ case DSConstant:
+ for (z = 1; z <= DupCnt - 1; z++)
+ if (!pCtx->Replicate(&DUPStartFill, &DUPEndFill, pCtx))
+ {
+ Result = False;
+ goto func_exit;
+ }
+ break;
+ case DSSpace:
+ {
+ tCurrCodeFill Diff;
+
+ SubCodeFill(&Diff, &DUPEndFill, &DUPStartFill, pCtx);
+ MultCodeFill(&Diff, DupCnt - 1, pCtx);
+ IncCodeFillBy(&pCtx->CurrCodeFill, &Diff, pCtx);
+ break;
+ }
+ default:
+ Result = False;
+ goto func_exit;
+ }
+
+ Result = True;
+ }
+
+ /* no DUP: simple expression. Differentiate space reservation & data disposition */
+
+ else if (!strcmp(pArg->str.p_str, "?"))
+ {
+ Result = SetDSFlag(pCtx, DSSpace);
+ if (Result)
+ IncCodeFillBy(&pCtx->CurrCodeFill, &pCtx->FillIncPerElem, pCtx);
+ }
+
+ else
+ Result = SetDSFlag(pCtx, DSConstant) && pCtx->LayoutFunc(pArg, pCtx);
+
+func_exit:
+ pCtx->pCurrComp = pSaveComp;
+ return Result;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDx(tLayoutCtx *pLayoutCtx)
+ * \brief Intel-style constant disposition
+ * \param pLayoutCtx layout infos & context
+ * ------------------------------------------------------------------------ */
+
+static void DecodeIntelDx(tLayoutCtx *pLayoutCtx)
+{
+ tStrComp *pArg;
+ Boolean OK;
+
+ pLayoutCtx->DSFlag = DSNone;
+ pLayoutCtx->FullWordSize = Grans[ActPC];
+ pLayoutCtx->ElemsPerFullWord = (8 * pLayoutCtx->FullWordSize) / pLayoutCtx->BaseElemLenBits;
+ if (pLayoutCtx->ElemsPerFullWord > 1)
+ {
+ pLayoutCtx->FillIncPerElem.FullWordCnt = 0;
+ pLayoutCtx->FillIncPerElem.LastWordFill = 1;
+ }
+ else
+ {
+ pLayoutCtx->FillIncPerElem.FullWordCnt = pLayoutCtx->BaseElemLenBits / (8 * pLayoutCtx->FullWordSize);
+ pLayoutCtx->FillIncPerElem.LastWordFill = 0;
+ }
+
+ OK = True;
+ forallargs(pArg, OK)
+ {
+ if (!*pArg->str.p_str)
+ {
+ OK = FALSE;
+ WrStrErrorPos(ErrNum_EmptyArgument, pArg);
+ }
+ else
+ OK = DecodeIntelPseudo_LayoutMult(pArg, pLayoutCtx);
+ }
+
+ /* Finalize: add optional padding if fractions of full words
+ remain unused & set code length */
+
+ if (OK)
+ {
+ if (pLayoutCtx->CurrCodeFill.LastWordFill)
+ {
+ WrError(ErrNum_PaddingAdded);
+ pLayoutCtx->CurrCodeFill.LastWordFill = 0;
+ pLayoutCtx->CurrCodeFill.FullWordCnt++;
+ }
+ CodeLen = pLayoutCtx->CurrCodeFill.FullWordCnt;
+ }
+
+ DontPrint = (pLayoutCtx->DSFlag == DSSpace);
+ if (DontPrint)
+ {
+ BookKeeping();
+ if (!CodeLen && OK) WrError(ErrNum_NullResMem);
+ }
+ if (OK && (pLayoutCtx->FullWordSize == 1))
+ ActListGran = 1;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDN(Word Flags)
+ * \brief Intel-style constant disposition - nibbles
+ * \param Flags Data Type & Endianess Flags
+ * ------------------------------------------------------------------------ */
+
+void DecodeIntelDN(Word Flags)
+{
+ tLayoutCtx LayoutCtx;
+
+ memset(&LayoutCtx, 0, sizeof(LayoutCtx));
+ LayoutCtx.LayoutFunc = LayoutNibble;
+ LayoutCtx.BaseElemLenBits = 4;
+ switch (Grans[ActPC])
+ {
+ case 1:
+ LayoutCtx.Put4I = Put4I_To_8;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
+ LayoutCtx.Replicate = Replicate4_To_8;
+ break;
+ case 2:
+ LayoutCtx.Put4I = Put4I_To_16;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 3 : 0;
+ LayoutCtx.Replicate = Replicate4_To_16;
+ break;
+ }
+ DecodeIntelDx(&LayoutCtx);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDB(Word BigEndian)
+ * \brief Intel-style constant disposition - bytes
+ * \param Flags Data Type & Endianess Flags
+ * ------------------------------------------------------------------------ */
+
+void DecodeIntelDB(Word Flags)
+{
+ tLayoutCtx LayoutCtx;
+
+ memset(&LayoutCtx, 0, sizeof(LayoutCtx));
+ LayoutCtx.LayoutFunc = LayoutByte;
+ LayoutCtx.BaseElemLenBits = 8;
+ switch (Grans[ActPC])
+ {
+ case 1:
+ LayoutCtx.Put8I = Put8I_To_8;
+ LayoutCtx.Replicate = Replicate8ToN_To_8;
+ break;
+ case 2:
+ LayoutCtx.Put8I = Put8I_To_16;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
+ LayoutCtx.Replicate = Replicate8_To_16;
+ break;
+ }
+ if (*LabPart.str.p_str)
+ SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
+ DecodeIntelDx(&LayoutCtx);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDW(Word Flags)
+ * \brief Intel-style constant disposition - words
+ * \param Flags Data Type & Endianess Flags
+ * ------------------------------------------------------------------------ */
+
+void DecodeIntelDW(Word Flags)
+{
+ tLayoutCtx LayoutCtx;
+
+ memset(&LayoutCtx, 0, sizeof(LayoutCtx));
+ LayoutCtx.LayoutFunc = LayoutWord;
+ LayoutCtx.BaseElemLenBits = 16;
+ switch (Grans[ActPC])
+ {
+ case 1:
+ LayoutCtx.Put16I = (Flags & eIntPseudoFlag_AllowInt) ? Put16I_To_8 : NULL;
+ LayoutCtx.Put16F = (Flags & eIntPseudoFlag_AllowFloat) ? Put16F_To_8 : NULL;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
+ LayoutCtx.Replicate = Replicate8ToN_To_8;
+ break;
+ case 2:
+ LayoutCtx.Put16I = (Flags & eIntPseudoFlag_AllowInt) ? Put16I_To_16 : NULL;
+ LayoutCtx.Put16F = (Flags & eIntPseudoFlag_AllowFloat) ? Put16F_To_16 : NULL;
+ LayoutCtx.Replicate = Replicate16ToN_To_16;
+ break;
+ }
+ if (*LabPart.str.p_str)
+ SetSymbolOrStructElemSize(&LabPart, eSymbolSize16Bit);
+ DecodeIntelDx(&LayoutCtx);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDD(Word Flags)
+ * \brief Intel-style constant disposition - 32-bit words
+ * \param Flags Data Type & Endianess Flags
+ * ------------------------------------------------------------------------ */
+
+void DecodeIntelDD(Word Flags)
+{
+ tLayoutCtx LayoutCtx;
+
+ memset(&LayoutCtx, 0, sizeof(LayoutCtx));
+ LayoutCtx.LayoutFunc = LayoutDoubleWord;
+ LayoutCtx.BaseElemLenBits = 32;
+ switch (Grans[ActPC])
+ {
+ case 1:
+ LayoutCtx.Put32I = (Flags & eIntPseudoFlag_AllowInt) ? Put32I_To_8 : NULL;
+ LayoutCtx.Put32F = (Flags & eIntPseudoFlag_AllowFloat) ? Put32F_To_8 : NULL;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 3 : 0;
+ LayoutCtx.Replicate = Replicate8ToN_To_8;
+ break;
+ case 2:
+ LayoutCtx.Put32I = (Flags & eIntPseudoFlag_AllowInt) ? Put32I_To_16 : NULL;
+ LayoutCtx.Put32F = (Flags & eIntPseudoFlag_AllowFloat) ? Put32F_To_16 : NULL;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
+ LayoutCtx.Replicate = Replicate16ToN_To_16;
+ break;
+ }
+ if (*LabPart.str.p_str)
+ SetSymbolOrStructElemSize(&LabPart, eSymbolSize32Bit);
+ DecodeIntelDx(&LayoutCtx);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDQ(Word Flags)
+ * \brief Intel-style constant disposition - 64-bit words
+ * \param Flags Data Type & Endianess Flags
+ * ------------------------------------------------------------------------ */
+
+void DecodeIntelDQ(Word Flags)
+{
+ tLayoutCtx LayoutCtx;
+
+ memset(&LayoutCtx, 0, sizeof(LayoutCtx));
+ LayoutCtx.LayoutFunc = LayoutQuadWord;
+ LayoutCtx.BaseElemLenBits = 64;
+ switch (Grans[ActPC])
+ {
+ case 1:
+ LayoutCtx.Put64I = (Flags & eIntPseudoFlag_AllowInt) ? Put64I_To_8 : NULL;
+ LayoutCtx.Put64F = (Flags & eIntPseudoFlag_AllowFloat) ? Put64F_To_8 : NULL;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 7 : 0;
+ LayoutCtx.Replicate = Replicate8ToN_To_8;
+ break;
+ case 2:
+ LayoutCtx.Put64I = (Flags & eIntPseudoFlag_AllowInt) ? Put64I_To_16 : NULL;
+ LayoutCtx.Put64F = (Flags & eIntPseudoFlag_AllowFloat) ? Put64F_To_16 : NULL;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 3 : 0;
+ LayoutCtx.Replicate = Replicate16ToN_To_16;
+ break;
+ }
+ if (*LabPart.str.p_str)
+ SetSymbolOrStructElemSize(&LabPart, eSymbolSize64Bit);
+ DecodeIntelDx(&LayoutCtx);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDT(Word Flags)
+ * \brief Intel-style constant disposition - 80-bit words
+ * \param Flags Data Type & Endianess Flags
+ * ------------------------------------------------------------------------ */
+
+void DecodeIntelDT(Word Flags)
+{
+ tLayoutCtx LayoutCtx;
+
+ memset(&LayoutCtx, 0, sizeof(LayoutCtx));
+ LayoutCtx.LayoutFunc = LayoutTenBytes;
+ LayoutCtx.BaseElemLenBits = 80;
+ switch (Grans[ActPC])
+ {
+ case 1:
+ LayoutCtx.Put80F = Put80F_To_8;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
+ LayoutCtx.Replicate = Replicate8ToN_To_8;
+ break;
+ case 2:
+ LayoutCtx.Put80F = Put80F_To_16;
+ LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
+ LayoutCtx.Replicate = Replicate16ToN_To_16;
+ break;
+ }
+ if (*LabPart.str.p_str)
+ SetSymbolOrStructElemSize(&LabPart, eSymbolSize80Bit);
+ DecodeIntelDx(&LayoutCtx);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelDS(Word Code)
+ * \brief Intel-style memory reservation
+ * ------------------------------------------------------------------------ */
+
+void DecodeIntelDS(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(1, 1))
+ {
+ tSymbolFlags Flags;
+ Boolean OK;
+ LongInt HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
+
+ if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
+ else if (OK)
+ {
+ DontPrint = True;
+ CodeLen = HVal;
+ if (!HVal)
+ WrError(ErrNum_NullResMem);
+ BookKeeping();
+ }
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeIntelPseudo(Boolean BigEndian)
+ * \brief decode Intel-style pseudo instructions
+ * \param BigEndian target endianess
+ * \return True if instruction found
+ * ------------------------------------------------------------------------ */
+
+Boolean DecodeIntelPseudo(Boolean BigEndian)
+{
+ static PInstTable InstTables[2] = { NULL, NULL };
+ int Idx = !!BigEndian;
+
+ if (!InstTables[Idx])
+ {
+ PInstTable InstTable = CreateInstTable(17);
+ Word Flag = BigEndian ? eIntPseudoFlag_BigEndian : eIntPseudoFlag_None;
+
+ AddInstTable(InstTable, "DN", Flag | eIntPseudoFlag_AllowInt, DecodeIntelDN);
+ AddInstTable(InstTable, "DB", Flag | eIntPseudoFlag_AllowInt, DecodeIntelDB);
+ AddInstTable(InstTable, "DW", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowFloat, DecodeIntelDW);
+ AddInstTable(InstTable, "DD", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowFloat, DecodeIntelDD);
+ AddInstTable(InstTable, "DQ", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowFloat, DecodeIntelDQ);
+ AddInstTable(InstTable, "DT", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowFloat, DecodeIntelDT);
+ AddInstTable(InstTable, "DS", 0, DecodeIntelDS);
+ InstTables[Idx] = InstTable;
+ }
+ return LookupInstTable(InstTables[Idx], OpPart.str.p_str);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DecodeZ80SYNTAX(Word Code)
+ * \brief change Z80 syntax support for target
+ * ------------------------------------------------------------------------ */
+
+static void DecodeZ80SYNTAX(Word Code)
+{
+ UNUSED(Code);
+
+ if (ChkArgCnt(1, 1))
+ {
+ tStrComp TmpComp;
+
+ StrCompMkTemp(&TmpComp, Z80SyntaxName, 0);
+ NLS_UpString(ArgStr[1].str.p_str);
+ if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
+ {
+ CurrZ80Syntax = eSyntax808x;
+ EnterIntSymbol(&TmpComp, 0, SegNone, True);
+ }
+ else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
+ {
+ CurrZ80Syntax = eSyntaxBoth;
+ EnterIntSymbol(&TmpComp, 1, SegNone, True);
+ }
+ else if (!as_strcasecmp(ArgStr[1].str.p_str, "EXCLUSIVE"))
+ {
+ CurrZ80Syntax = eSyntaxZ80;
+ EnterIntSymbol(&TmpComp, 2, SegNone, True);
+ }
+ else
+ WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn ChkZ80Syntax(tZ80Syntax InstrSyntax)
+ * \brief check whether instruction's syntax (808x/Z80) fits to selected one
+ * \param InstrSyntax instruction syntax
+ * \return True if all fine
+ * ------------------------------------------------------------------------ */
+
+Boolean ChkZ80Syntax(tZ80Syntax InstrSyntax)
+{
+ if ((InstrSyntax == eSyntax808x) && (!(CurrZ80Syntax & eSyntax808x)))
+ {
+ WrStrErrorPos(ErrNum_Z80SyntaxExclusive, &OpPart);
+ return False;
+ }
+ else if ((InstrSyntax == eSyntaxZ80) && (!(CurrZ80Syntax & eSyntaxZ80)))
+ {
+ WrStrErrorPos(ErrNum_Z80SyntaxNotEnabled, &OpPart);
+ return False;
+ }
+ else
+ return True;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn AddZ80Syntax(struct sInstTable *InstTable)
+ * \brief add Z80SYNTAX instruction to list & possibly set default
+ * \param InstTable table to add to
+ * ------------------------------------------------------------------------ */
+
+void AddZ80Syntax(struct sInstTable *InstTable)
+{
+ if (!onoff_test_and_set(e_onoff_reg_z80syntax))
+ {
+ tStrComp TmpComp;
+
+ CurrZ80Syntax = eSyntax808x;
+ StrCompMkTemp(&TmpComp, Z80SyntaxName, 0);
+ EnterIntSymbol(&TmpComp, 0, SegNone, True);
+ }
+ AddInstTable(InstTable, "Z80SYNTAX", 0, DecodeZ80SYNTAX);
+}
--- /dev/null
+#ifndef _INTPSEUDO_H
+#define _INTPSEUDO_H
+/* intpseudo.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Commonly used 'Intel Style' Pseudo Instructions */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+
+typedef enum
+{
+ eSyntaxNeither = 0,
+ eSyntax808x = 1,
+ eSyntaxZ80 = 2,
+ eSyntaxBoth = 3
+} tZ80Syntax;
+
+extern tZ80Syntax CurrZ80Syntax;
+
+/*****************************************************************************
+ * Global Functions
+ *****************************************************************************/
+
+enum
+{
+ eIntPseudoFlag_None = 0,
+ eIntPseudoFlag_BigEndian = 1 << 0,
+ eIntPseudoFlag_AllowInt = 1 << 1,
+ eIntPseudoFlag_AllowFloat = 1 << 2
+};
+
+extern void DecodeIntelDN(Word Flags);
+extern void DecodeIntelDB(Word Flags);
+extern void DecodeIntelDW(Word Flags);
+extern void DecodeIntelDD(Word Flags);
+extern void DecodeIntelDQ(Word Flags);
+extern void DecodeIntelDT(Word Flags);
+
+extern Boolean DecodeIntelPseudo(Boolean BigEndian);
+
+struct sInstTable;
+extern void AddZ80Syntax(struct sInstTable *InstTable);
+
+extern Boolean ChkZ80Syntax(tZ80Syntax InstrSyntax);
+
+#endif /* _INTPSEUDO_H */
--- /dev/null
+#ifndef _IOERRS_H
+#define _IOERRS_H
+/* ioerrs.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Abliefern der I/O-Fehlermeldungen */
+/* */
+/* Historie: 11.10.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+extern char *GetErrorMsg(int number);
+
+extern void ioerrs_init(char *ProgPath);
+#endif /* _IOERRS_H */
--- /dev/null
+#ifndef LSTMACROEXP_H
+#define LSTMACROEXP_H
+/* lstmacroexp.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Functions & variables regarding macro expansion in listing */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+
+typedef enum
+{
+ eLstMacroExpNone = 0,
+ eLstMacroExpRest = 1,
+ eLstMacroExpIf = 2,
+ eLstMacroExpMacro = 4,
+ eLstMacroExpAll = eLstMacroExpRest | eLstMacroExpIf | eLstMacroExpMacro
+} tLstMacroExp;
+
+#ifdef __cplusplus
+#include "cppops.h"
+DefCPPOps_Mask(tLstMacroExp)
+#endif
+
+#define LSTMACROEXPMOD_MAX 8
+
+typedef struct
+{
+ unsigned Count;
+ Byte Modifiers[LSTMACROEXPMOD_MAX];
+} tLstMacroExpMod;
+
+extern void SetLstMacroExp(tLstMacroExp NewMacroExp);
+extern tLstMacroExp GetLstMacroExp(void);
+
+extern void InitLstMacroExpMod(tLstMacroExpMod *pLstMacroExpMod);
+
+extern Boolean AddLstMacroExpMod(tLstMacroExpMod *pLstMacroExpMod, Boolean Set, tLstMacroExp Mod);
+
+extern Boolean ChkLstMacroExpMod(const tLstMacroExpMod *pLstMacroExpMod);
+
+extern void DumpLstMacroExpMod(const tLstMacroExpMod *pLstMacroExpMod, char *pDest, int DestLen);
+
+extern tLstMacroExp ApplyLstMacroExpMod(tLstMacroExp Src, const tLstMacroExpMod *pLstMacroExpMod);
+
+#endif /* LSTMACROEXP_H */
--- /dev/null
+#ifndef _MATH64_H
+#define _MATH64_H
+/* math64.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* 64 bit arithmetic for platforms not having a 64 bit integer */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+
+typedef struct
+{
+ LongWord low;
+ LongWord high;
+} t64;
+
+extern void add64(t64 *pRes, const t64 *pA, const t64 *pB);
+
+extern void sub64(t64 *pRes, const t64 *pA, const t64 *pB);
+
+extern void mul64(t64 *pRes, const t64 *pA, const t64 *pB);
+
+extern void div64(t64 *pRes, const t64 *pA, const t64 *pB);
+
+#endif /* _MATH64_H */
--- /dev/null
+/* natpseudo.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* Pseudo Instructions used for National Semiconductor CPUs */
+/* */
+/*****************************************************************************/
+
+/*****************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include "bpemu.h"
+
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmitree.h"
+#include "codepseudo.h"
+#include "intpseudo.h"
+#include "errmsg.h"
+
+#include "natpseudo.h"
+
+/*****************************************************************************
+ * Global Functions
+ *****************************************************************************/
+
+static void DecodeSFR(Word Code)
+{
+ UNUSED(Code);
+ CodeEquate(SegData, 0, 0xff);
+}
+
+static void DecodeDSx(Word Shift)
+{
+ if (ChkArgCnt(1, 1))
+ {
+ tSymbolFlags Flags;
+ Boolean ValOK;
+ Word Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &ValOK, &Flags) << Shift;
+
+ if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
+ else if (ValOK)
+ {
+ DontPrint = True;
+ if (!Size) WrError(ErrNum_NullResMem);
+ CodeLen = Size;
+ BookKeeping();
+ }
+ }
+}
+
+static void DecodeFx(Word Shift)
+{
+ if (ChkArgCnt(2, 2))
+ {
+ tSymbolFlags Flags;
+ Boolean ValOK;
+ Word Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &ValOK, &Flags);
+
+ if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
+ else if (ValOK)
+ {
+ if (SetMaxCodeLen(Size << Shift)) WrError(ErrNum_CodeOverflow);
+ else
+ {
+ Word Value = EvalStrIntExpression(&ArgStr[2], Shift ? Int16 : Int8, &ValOK);
+
+ if (ValOK)
+ {
+ Word z;
+
+ for (z = 0; z < Size; z++)
+ {
+ BAsmCode[CodeLen++] = Lo(Value);
+ if (Shift)
+ BAsmCode[CodeLen++] = Hi(Value);
+ }
+ }
+ }
+ }
+ }
+}
+
+Boolean DecodeNatPseudo(void)
+{
+ static PInstTable InstTable = NULL;
+
+ if (!InstTable)
+ {
+ InstTable = CreateInstTable(31);
+
+ AddInstTable(InstTable, "SFR" , 0 , DecodeSFR);
+ AddInstTable(InstTable, "ADDR" , eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt , DecodeIntelDB);
+ AddInstTable(InstTable, "ADDRW", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt , DecodeIntelDW);
+ AddInstTable(InstTable, "BYTE" , eIntPseudoFlag_AllowInt , DecodeIntelDB);
+ AddInstTable(InstTable, "WORD" , eIntPseudoFlag_AllowInt , DecodeIntelDW);
+ AddInstTable(InstTable, "DSB" , 0 , DecodeDSx);
+ AddInstTable(InstTable, "DSW" , 1 , DecodeDSx);
+ AddInstTable(InstTable, "FB" , 0 , DecodeFx);
+ AddInstTable(InstTable, "FW" , 1 , DecodeFx);
+ }
+
+ return LookupInstTable(InstTable, OpPart.str.p_str);
+}
--- /dev/null
+#ifndef _NATPSEUDO_H
+#define _NATPSEUDO_H
+/* natpseudo.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* Pseudo Instructions commonly used on National targets */
+/* */
+/*****************************************************************************/
+
+/*****************************************************************************
+ * Global Functions
+ *****************************************************************************/
+
+extern Boolean DecodeNatPseudo(void);
+
+#endif /* _NATPSEUDO_H */
--- /dev/null
+#ifndef _NLMESSAGES_H
+#define _NLMESSAGES_H
+/* nlmessages.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Einlesen und Verwalten von Meldungs-Strings */
+/* */
+/* Historie: 13. 8.1997 Grundsteinlegung */
+/* 17. 8.1997 Verallgemeinerung auf mehrere Kataloge */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+
+typedef struct
+{
+ char *MsgBlock;
+ LongInt *StrPosis, MsgCount;
+} TMsgCat, *PMsgCat;
+
+extern char *catgetmessage(PMsgCat Catalog, int Num);
+
+extern void opencatalog(PMsgCat Catalog, const char *File, const char *Path, LongInt File_MsgId1, LongInt File_MsgId2);
+
+extern char *getmessage(int Num);
+
+extern void nlmessages_init(const char *File, char *Path, LongInt File_MsgId1, LongInt File_MsgId2);
+#endif /* _NLMESSAGES_H */
--- /dev/null
+#ifndef _NLS_H
+#define _NLS_H
+/* nls.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Abhandlung landesspezifischer Unterschiede */
+/* */
+/* Historie: 16. 5.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+
+#include "chardefs.h"
+
+typedef enum
+{
+ TimeFormatUSA,
+ TimeFormatEurope,
+ TimeFormatJapan
+} TimeFormat;
+
+typedef enum
+{
+ DateFormatMTY,
+ DateFormatTMY,
+ DateFormatYMT
+} DateFormat;
+
+typedef enum
+{
+ CurrFormatPreNoBlank,
+ CurrFormatPostNoBlank,
+ CurrFormatPreBlank,
+ CurrFormatPostBlank
+} CurrFormat;
+
+typedef char CharTable[256];
+
+extern CharTable UpCaseTable, LowCaseTable;
+
+
+extern Boolean NLS_Initialize(int *argc, char **argv);
+
+extern Word NLS_GetCountryCode(void);
+
+extern tCodepage NLS_GetCodepage(void);
+
+extern void NLS_DateString(Word Year, Word Month, Word Day, char *Dest, size_t DestSize);
+
+extern void NLS_CurrDateString(char *Dest, size_t DestSize);
+
+extern void NLS_TimeString(Word Hour, Word Minute, Word Second, Word Sec100, char *Dest, size_t DestSize);
+
+extern void NLS_CurrTimeString(Boolean Use100, char *Dest, size_t DestSize);
+
+extern void NLS_CurrencyString(double inp, char *erg, size_t DestSize);
+
+extern char Upcase(char inp);
+
+extern void NLS_UpString(char *s);
+
+extern void NLS_LowString(char *s);
+
+extern int NLS_StrCmp(const char *s1, const char *s2);
+
+
+extern void nls_init(void);
+#endif /* _NLS_H */
--- /dev/null
+#ifndef _NONZSTRING_H
+#define _NONZSTRING_H
+/* nonzstring.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* Handling of strings without NUL termination */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+
+struct as_nonz_dynstr
+{
+ size_t len, capacity;
+ char *p_str;
+};
+typedef struct as_nonz_dynstr as_nonz_dynstr_t;
+
+#define as_nonz_dynstr_roundup_len(len) \
+ (((len) + 127) & ~127)
+
+extern void as_nonz_dynstr_ini(as_nonz_dynstr_t *p_str, size_t ini_capacity);
+
+extern void as_nonz_dynstr_ini_c_str(as_nonz_dynstr_t *p_str, const char *p_src);
+
+extern void as_nonz_dynstr_realloc(as_nonz_dynstr_t *p_str, size_t new_capacity);
+
+extern void as_nonz_dynstr_free(as_nonz_dynstr_t *p_str);
+
+extern size_t as_nonz_dynstr_to_c_str(char *p_dest, const as_nonz_dynstr_t *p_src, size_t dest_len);
+
+extern size_t as_nonz_dynstr_copy(as_nonz_dynstr_t *p_dest, const as_nonz_dynstr_t *p_src);
+
+extern size_t as_nonz_dynstr_append_raw(as_nonz_dynstr_t *p_dest, const char *p_src, int src_len); /* -1 -> strlen */
+
+extern size_t as_nonz_dynstr_copy_c_str(as_nonz_dynstr_t *p_dest, const char *p_src);
+
+extern size_t as_nonz_dynstr_append(as_nonz_dynstr_t *p_dest, const as_nonz_dynstr_t *p_src);
+
+extern int as_nonz_dynstr_cmp(const as_nonz_dynstr_t *p_str1, const as_nonz_dynstr_t *p_str2);
+
+extern int as_nonz_dynstr_find(const as_nonz_dynstr_t *p_haystack, const as_nonz_dynstr_t *p_needle);
+
+extern void as_nonz_dynstr_dump_hex(FILE *p_file, const as_nonz_dynstr_t *p_str);
+
+#endif /* _NONZSTRING_H */
--- /dev/null
+#ifndef _ONOFF_COMMON_H
+#define _ONOFF_COMMON_H
+/* onoff_common.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Port */
+/* */
+/* ON/OFF flags used by several targets */
+/* */
+/*****************************************************************************/
+
+#define FPUAvailName "HASFPU" /* FPU-Befehle erlaubt */
+#define PMMUAvailName "HASPMMU" /* PMMU-Befehle erlaubt */
+#define FullPMMUName "FULLPMMU"
+#define SupAllowedCmdName "SUPMODE" /* Privileged instructions allowed */
+#define SupAllowedSymName "INSUPMODE"
+#define MaxModeSymName "INMAXMODE" /* CPU in maximum mode */
+#define MaxModeCmdName "MAXMODE"
+#define SrcModeCmdName "SRCMODE"
+#define SrcModeSymName "INSRCMODE" /* CPU im Quellcode-kompatiblen Modus */
+#define ExtModeCmdName "EXTMODE"
+#define ExtModeSymName "INEXTMODE"
+#define LWordModeCmdName "LWORDMODE"
+#define LWordModeSymName "INLWORDMODE"
+#define DSPCmdName "DSP"
+#define DSPSymName "HASDSP"
+#define CustomAvailCmdName "CUSTOM"
+#define CustomAvailSymName "CUSTOM"
+#define PackingCmdName "PACKING"
+#define PackingSymName "PACKING"
+#define BigEndianCmdName "BIGENDIAN"
+#define BigEndianSymName "BIGENDIAN" /* Data storage MSB first */
+#define BranchExtCmdName "BRANCHEXT"
+#define BranchExtSymName "BRANCHEXT"
+
+extern Boolean FPUAvail,
+ PMMUAvail,
+ SupAllowed,
+ MaxMode,
+ TargetBigEndian,
+ DoPadding;
+
+/* NOTE: will have to switch this to #define as soon as
+ everything up to 2**15 is used up - 16 bit compilers
+ silently limit enums to int range */
+
+enum
+{
+ e_onoff_reg_fpu = 1 << 0,
+ e_onoff_reg_pmmu = 1 << 1,
+ e_onoff_reg_custom = 1 << 2,
+ e_onoff_reg_supmode = 1 << 3,
+ e_onoff_reg_maxmode = 1 << 4,
+ e_onoff_reg_extmode = 1 << 5,
+ e_onoff_reg_srcmode = 1 << 6,
+ e_onoff_reg_compmode = 1 << 7,
+ e_onoff_reg_lwordmode = 1 << 8,
+ e_onoff_reg_fullpmmu = 1 << 9,
+ e_onoff_reg_dsp = 1 << 10,
+ e_onoff_reg_packing = 1 << 11,
+ e_onoff_reg_bigendian = 1 << 12,
+ e_onoff_reg_branchext = 1 << 13,
+ e_onoff_reg_z80syntax = 1 << 14
+};
+
+extern unsigned onoff_test_and_set(unsigned mask);
+
+extern void onoff_fpu_add(void);
+extern void onoff_pmmu_add(void);
+extern void onoff_supmode_add(void);
+extern void onoff_maxmode_add(void);
+extern void onoff_bigendian_add(void);
+
+extern void onoff_common_init(void);
+
+#endif /* _ONOFF_COMMON_H */
--- /dev/null
+#ifndef _OPERATOR_H
+#define _OPERATOR_H
+/* operator.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* defintion of operators */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+#include "tempresult.h"
+
+#define OPERATOR_MAXCNT 30
+#define OPERATOR_MAXCOMB 5
+
+typedef struct
+{
+ const char *Id;
+ int IdLen;
+ Boolean Dyadic;
+ Byte Priority;
+ Byte TypeCombinations[OPERATOR_MAXCOMB];
+ void (*pFunc)(TempResult *pErg, TempResult *pLVal, TempResult *pRVal);
+} Operator;
+
+extern const Operator Operators[], MinusMonadicOperator, *pPotMonadicOperator;
+
+#endif /* _OPERATOR_H */
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+#ifndef _PASCSTYLE_H
+#define _PASCSTYLE_H
+
+#ifndef False
+#define False 0
+#define True 1
+#endif
+
+#define Ord(b) ((b) ? 1L : 0L)
+
+#define MaxLongInt 2147483647
+#endif /* _PASCSTYLE_H */
--- /dev/null
+#ifndef _STDHANDL_H
+#define _STDHANDL_H
+/* stdhandl.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Bereitstellung von fuer AS benoetigten Handle-Funktionen */
+/* */
+/* Historie: 5. 4.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+typedef enum {NoRedir,RedirToDevice,RedirToFile} TRedirected; /* Umleitung von Handles */
+
+#define NumStdIn 0
+#define NumStdOut 1
+#define NumStdErr 2
+
+extern TRedirected Redirected;
+
+extern void OpenWithStandard(FILE **ppFile, char *Path);
+
+extern void CloseIfOpen(FILE **ppFile);
+
+extern void stdhandl_init(void);
+#endif /* _STDHANDL_H */
--- /dev/null
+#ifndef _STDINC_H
+#define _STDINC_H
+/* stdinc.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* globaler Einzug immer benoetigter includes */
+/* */
+/* Historie: 21. 5.1996 min/max */
+/* 11. 5.1997 DOS-Anpassungen */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+#include <stdio.h>
+#ifndef __MUNIX__
+#include <stdlib.h>
+#endif
+#if !defined ( __MSDOS__ ) && !defined( __IBMC__ )
+#include <unistd.h>
+#endif
+#include <math.h>
+#include <errno.h>
+#include <sys/types.h>
+#ifdef __MSDOS__
+#include <alloc.h>
+#else
+#include <memory.h>
+#if !defined (__FreeBSD__) && !defined(__APPLE__)
+#include <malloc.h>
+#endif
+#endif
+
+#include "pascstyle.h"
+#include "datatypes.h"
+#include "chardefs.h"
+
+#ifndef min
+#define min(a,b) ((a<b)?(a):(b))
+#endif
+#ifndef max
+#define max(a,b) ((a>b)?(a):(b))
+#endif
+
+#ifndef M_PI
+#define M_PI 3.1415926535897932385E0
+#endif
+
+#endif /* _STDINC_H */
--- /dev/null
+/* strcomp.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* Macro Assembler AS */
+/* */
+/* Definition of a source line's component present after parsing */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+#include "datatypes.h"
+#include "strutil.h"
+#include "strcomp.h"
+
+static void check_capacity(const tStrComp *pComp)
+{
+ if (!pComp->str.capacity)
+ {
+ fprintf(stderr, "copy to zero-capacity StrComp\n");
+ abort();
+ }
+}
+
+static void check_no_capacity(const tStrComp *pComp)
+{
+ if (pComp->str.capacity)
+ {
+ fprintf(stderr, "ptr move on non-zero-capacity StrComp\n");
+ abort();
+ }
+}
+
+static size_t check_realloc(as_dynstr_t *p_str, size_t req_count)
+{
+ if ((req_count >= p_str->capacity) && p_str->dynamic)
+ as_dynstr_realloc(p_str, as_dynstr_roundup_len(req_count));
+ if (req_count >= p_str->capacity)
+ req_count = p_str->capacity - 1;
+ return req_count;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompAlloc(tStrComp *pComp, size_t capacity)
+ * \brief initialize string component with dynamic buffer
+ * \param pComp component to fill
+ * \param capacity requested capacity of buffer
+ * ------------------------------------------------------------------------ */
+
+void StrCompAlloc(tStrComp *pComp, size_t capacity)
+{
+ as_dynstr_ini(&pComp->str, capacity);
+ StrCompReset(pComp);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompReset(tStrComp *pComp)
+ * \brief reset string component to "empty" state
+ * \param pComp component to set
+ * ------------------------------------------------------------------------ */
+
+void StrCompReset(tStrComp *pComp)
+{
+ LineCompReset(&pComp->Pos);
+ *pComp->str.p_str = '\0';
+}
+
+/*!------------------------------------------------------------------------
+ * \fn LineCompReset(tLineComp *pComp)
+ * \brief reset line position to "empty" state
+ * \param pComp component to set
+ * ------------------------------------------------------------------------ */
+
+void LineCompReset(tLineComp *pComp)
+{
+ pComp->StartCol = -1;
+ pComp->Len = 0;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompFree(tStrComp *pComp)
+ * \brief free/clean string component
+ * \param pComp string component to be cleared
+ * ------------------------------------------------------------------------ */
+
+void StrCompFree(tStrComp *pComp)
+{
+ LineCompReset(&pComp->Pos);
+ as_dynstr_free(&pComp->str);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompMkTemp(tStrComp *pComp, char *pStr, size_t capacity)
+ * \brief create a dummy StrComp from plain string
+ * \param pComp comp to create
+ * \param pStr string to use
+ * \param capacity string's capacity
+ * ------------------------------------------------------------------------ */
+
+void StrCompMkTemp(tStrComp *pComp, char *pStr, size_t capacity)
+{
+ LineCompReset(&pComp->Pos);
+ pComp->str.p_str = pStr;
+ pComp->str.capacity = capacity;
+ pComp->str.dynamic = 0;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompRefRight(tStrComp *pDest, const tStrComp *pSrc, size_t StartOffs)
+ * \brief create a right-aligned substring component of string component (no copy)
+ * \param pDest destination component
+ * \param pSrc source component
+ * \param StartOffs how many characters to omit at the left
+ * ------------------------------------------------------------------------ */
+
+void StrCompRefRight(tStrComp *pDest, const tStrComp *pSrc, size_t StartOffs)
+{
+ pDest->str.p_str = pSrc->str.p_str + StartOffs;
+ pDest->str.capacity = 0;
+ pDest->str.dynamic = 0;
+ pDest->Pos.StartCol = pSrc->Pos.StartCol + StartOffs;
+ pDest->Pos.Len = pSrc->Pos.Len - StartOffs;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompCopy(tStrComp *pDest, tStrComp *pSrc)
+ * \brief copy string component
+ * \param pDest destination component
+ * \param pSrc source component
+ * ------------------------------------------------------------------------ */
+
+void StrCompCopy(tStrComp *pDest, const tStrComp *pSrc)
+{
+ pDest->Pos = pSrc->Pos;
+ pDest->Pos.Len = as_dynstr_copy(&pDest->str, &pSrc->str);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompCopySub(tStrComp *pDest, const tStrComp *pSrc, size_t Start, size_t Count)
+ * \brief copy substring
+ * \param pDest destination
+ * \param pSrc source
+ * \param Start start index to copy from
+ * \param Count # of characters to copy
+ * ------------------------------------------------------------------------ */
+
+void StrCompCopySub(tStrComp *pDest, const tStrComp *pSrc, size_t Start, size_t Count)
+{
+ unsigned l = strlen(pSrc->str.p_str);
+
+ if (Start >= l)
+ Count = 0;
+ else if (Start + Count > l)
+ Count = l - Start;
+ check_capacity(pDest);
+ Count = check_realloc(&pDest->str, Count);
+ memcpy(pDest->str.p_str, pSrc->str.p_str + Start, Count);
+ pDest->str.p_str[Count] = '\0';
+ pDest->Pos.StartCol = pSrc->Pos.StartCol + Start;
+ pDest->Pos.Len = Count;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompSplitRight(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
+ * \brief split off another component at the right of the source
+ * \param pSrc source to split off
+ * \param pDest where to put part splitted off
+ * \param pSrcSplitPos split position (not included in source or dest any more)
+ * ------------------------------------------------------------------------ */
+
+void StrCompSplitRight(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
+{
+ size_t SrcLen = strlen(pSrcSplitPos + 1);
+
+ check_capacity(pDest);
+ SrcLen = check_realloc(&pDest->str, SrcLen);
+ memcpy(pDest->str.p_str, pSrcSplitPos + 1, SrcLen);
+ pDest->str.p_str[SrcLen] = '\0';
+ pDest->Pos.StartCol = pSrc->Pos.StartCol + pSrcSplitPos + 1 - pSrc->str.p_str;
+ pDest->Pos.Len = SrcLen;
+ *pSrcSplitPos = '\0';
+ pSrc->Pos.Len = pSrcSplitPos - pSrc->str.p_str;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompSplitLeft(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
+ * \brief split off another component at the left of the source
+ * \param pSrc source to split off
+ * \param pDest where to put part splitted off
+ * \param pSrcSplitPos split position (not included in source or dest any more)
+ * ------------------------------------------------------------------------ */
+
+void StrCompSplitLeft(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
+{
+ size_t SrcLen;
+
+ *pSrcSplitPos = '\0';
+ SrcLen = strlen(pSrc->str.p_str);
+ check_capacity(pDest);
+ SrcLen = check_realloc(&pDest->str, SrcLen);
+
+ memcpy(pDest->str.p_str, pSrc->str.p_str, SrcLen);
+ pDest->str.p_str[SrcLen] = '\0';
+ pDest->Pos.StartCol = pSrc->Pos.StartCol;
+ pDest->Pos.Len = pSrcSplitPos - pSrc->str.p_str;
+
+ strmov(pSrc->str.p_str, pSrcSplitPos + 1);
+ pSrc->Pos.StartCol += pSrcSplitPos - pSrc->str.p_str + 1;
+ pSrc->Pos.Len -= pSrcSplitPos - pSrc->str.p_str + 1;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompSplitCopy(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos)
+ * \brief copy left & right part of string to new components
+ * \param pLeft dest for left part
+ * \param pRight dest for right part
+ * \param pSrc character source
+ * \param pSplitPos split position in source
+ * ------------------------------------------------------------------------ */
+
+void StrCompSplitCopy(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos)
+{
+ /* pLeft may be equal to pSrc, use memmove() and save SrcLen */
+
+ size_t SrcLen = pSrc->Pos.Len;
+
+ check_capacity(pLeft);
+ pLeft->Pos.StartCol = pSrc->Pos.StartCol;
+ pLeft->Pos.Len = check_realloc(&pLeft->str, pSplitPos - pSrc->str.p_str);
+ memmove(pLeft->str.p_str, pSrc->str.p_str, pLeft->Pos.Len);
+ pLeft->str.p_str[pLeft->Pos.Len] = '\0';
+
+ check_capacity(pRight);
+ pRight->Pos.StartCol = pSrc->Pos.StartCol + (pLeft->Pos.Len + 1);
+ pRight->Pos.Len = check_realloc(&pRight->str, SrcLen - (pLeft->Pos.Len + 1));
+ memcpy(pRight->str.p_str, pSplitPos + 1, pRight->Pos.Len);
+ pRight->str.p_str[pRight->Pos.Len] = '\0';
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompSplitRef(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos)
+ * \brief split string into left & right and form references
+ * \param pLeft dest for left part
+ * \param pRight dest for right part
+ * \param pSrc character source
+ * \param pSplitPos split position in source
+ * ------------------------------------------------------------------------ */
+
+char StrCompSplitRef(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos)
+{
+ char Old = *pSplitPos;
+ /* save because pLeft and pSrc might be equal */
+ tLineComp SrcPos = pSrc->Pos;
+
+ *pSplitPos = '\0';
+ pLeft->str.p_str = pSrc->str.p_str;
+ if (pLeft != pSrc)
+ {
+ pLeft->str.capacity = 0;
+ pLeft->str.dynamic = 0;
+ }
+ pLeft->Pos.StartCol = SrcPos.StartCol;
+ pLeft->Pos.Len = pSplitPos - pLeft->str.p_str;
+ pRight->str.p_str = pSrc->str.p_str + (pLeft->Pos.Len + 1);
+ pRight->str.capacity = 0;
+ pRight->str.dynamic = 0;
+ pRight->Pos.StartCol = SrcPos.StartCol + (pLeft->Pos.Len + 1);
+ pRight->Pos.Len = SrcPos.Len - (pLeft->Pos.Len + 1);
+
+ return Old;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn KillPrefBlanksStrComp(struct sStrComp *pComp)
+ * \brief remove leading spaces on string component
+ * \param pComp component to handle
+ * ------------------------------------------------------------------------ */
+
+void KillPrefBlanksStrComp(struct sStrComp *pComp)
+{
+ int Delta = KillPrefBlanks(pComp->str.p_str);
+ pComp->Pos.StartCol += Delta;
+ pComp->Pos.Len -= Delta;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn KillPrefBlanksStrCompRef(struct sStrComp *pComp)
+ * \brief remove leading spaces on string component by inc'ing pointer
+ * \param pComp component to handle
+ * ------------------------------------------------------------------------ */
+
+void KillPrefBlanksStrCompRef(struct sStrComp *pComp)
+{
+ check_no_capacity(pComp);
+ while (isspace(*pComp->str.p_str))
+ {
+ pComp->str.p_str++;
+ if (pComp->str.capacity > 0)
+ pComp->str.capacity--;
+ pComp->Pos.StartCol++;
+ pComp->Pos.Len--;
+ }
+}
+
+/*!------------------------------------------------------------------------
+ * \fn KillPostBlanksStrComp(struct sStrComp *pComp)
+ * \brief remove trailing spaces on string component
+ * \param pComp component to handle
+ * ------------------------------------------------------------------------ */
+
+void KillPostBlanksStrComp(struct sStrComp *pComp)
+{
+ pComp->Pos.Len -= KillPostBlanks(pComp->str.p_str);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompShorten(struct sStrComp *pComp, size_t Delta)
+ * \brief shorten string component by n characters
+ * \param pComp component to shorten
+ * \param Delta # of characters to chop off (no checks!)
+ * ------------------------------------------------------------------------ */
+
+void StrCompShorten(struct sStrComp *pComp, size_t Delta)
+{
+ pComp->str.p_str[strlen(pComp->str.p_str) - Delta] = '\0';
+ pComp->Pos.Len -= Delta;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompCutLeft(struct sStrComp *pComp, size_t Delta)
+ * \brief remove n characters at start of component
+ * \param pComp component to shorten
+ * \param Delta # of characters to cut off
+ * \return actual # of characters cut off
+ * ------------------------------------------------------------------------ */
+
+size_t StrCompCutLeft(struct sStrComp *pComp, size_t Delta)
+{
+ size_t len = strlen(pComp->str.p_str);
+
+ if (Delta > len)
+ Delta = len;
+ if (Delta > pComp->Pos.Len)
+ Delta = pComp->Pos.Len;
+ strmov(pComp->str.p_str, pComp->str.p_str + Delta);
+ pComp->Pos.StartCol += Delta;
+ pComp->Pos.Len -= Delta;
+ return Delta;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn StrCompIncRefLeft(struct sStrComp *pComp, size_t Delta)
+ * \brief move start of component by n characters
+ * \param pComp component to shorten
+ * \param Delta # of characters to move by (no checks!)
+ * ------------------------------------------------------------------------ */
+
+void StrCompIncRefLeft(struct sStrComp *pComp, size_t Delta)
+{
+ check_no_capacity(pComp);
+ pComp->str.p_str += Delta;
+ pComp->str.capacity = (pComp->str.capacity > Delta) ? pComp->str.capacity - Delta : 0;
+ pComp->Pos.StartCol += Delta;
+ pComp->Pos.Len -= Delta;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DumpStrComp(const char *pTitle, const struct sStrComp *pComp)
+ * \brief debug dump of component
+ * \param pTitle description of component
+ * \param pComp component to dump
+ * ------------------------------------------------------------------------ */
+
+void DumpStrComp(const char *pTitle, const struct sStrComp *pComp)
+{
+ fprintf(stderr, "%s: @ col %u len %u '%s'\n", pTitle, pComp->Pos.StartCol, pComp->Pos.Len, pComp->str.p_str);
+}
--- /dev/null
+#ifndef _STRCOMP_H
+#define _STRCOMP_H
+/* strcomp.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* Macro Assembler AS */
+/* */
+/* Definition of a source line's component present after parsing */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+#include "dynstr.h"
+
+typedef char *StringPtr;
+
+struct sLineComp
+{
+ int StartCol;
+ unsigned Len;
+};
+typedef struct sLineComp tLineComp;
+
+struct sStrComp
+{
+ tLineComp Pos;
+ as_dynstr_t str;
+};
+typedef struct sStrComp tStrComp;
+
+extern void StrCompAlloc(tStrComp *pComp, size_t Capacity);
+extern void StrCompFree(tStrComp *pComp);
+
+extern void StrCompReset(tStrComp *pComp);
+extern void LineCompReset(tLineComp *pComp);
+
+extern void StrCompMkTemp(tStrComp *pComp, char *pStr, size_t Capacity);
+
+extern void StrCompRefRight(tStrComp *pDest, const tStrComp *pSrc, size_t StartOffs);
+
+extern void StrCompCopy(tStrComp *pDest, const tStrComp *pSrc);
+
+extern void StrCompCopySub(tStrComp *pDest, const tStrComp *pSrc, size_t Start, size_t Count);
+
+extern void StrCompSplitRight(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos);
+
+extern void StrCompSplitLeft(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos);
+
+extern void StrCompSplitCopy(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos);
+extern char StrCompSplitRef(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos);
+
+extern void StrCompShorten(struct sStrComp *pComp, size_t Delta);
+
+extern size_t StrCompCutLeft(struct sStrComp *pComp, size_t Delta);
+extern void StrCompIncRefLeft(struct sStrComp *pComp, size_t Delta);
+
+extern void KillPrefBlanksStrComp(struct sStrComp *pComp);
+extern void KillPrefBlanksStrCompRef(struct sStrComp *pComp);
+
+extern void KillPostBlanksStrComp(struct sStrComp *pComp);
+
+extern void DumpStrComp(const char *pTitle, const struct sStrComp *pComp);
+
+#endif /* _STRCOMP_H */
--- /dev/null
+#ifndef _STRINGLISTS_H
+#define _STRINGLISTS_H
+/* stringlists.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Verwaltung von String-Listen */
+/* */
+/* Historie: 4. 5.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+#include "datatypes.h"
+
+typedef struct sStringRec
+{
+ struct sStringRec *Next;
+ char *Content;
+} StringRec, *StringRecPtr;
+typedef StringRecPtr StringList;
+
+extern void InitStringList(StringList *List);
+
+extern void ClearStringEntry(StringRecPtr *Elem);
+
+extern void ClearStringList(StringList *List);
+
+extern void AddStringListFirst(StringList *List, const char *NewStr);
+
+extern void AddStringListLast(StringList *List, const char *NewStr);
+
+extern void RemoveStringList(StringList *List, const char *OldStr);
+
+extern const char *GetStringListFirst(StringList List, StringRecPtr *Lauf);
+
+extern const char *GetStringListNext(StringRecPtr *Lauf);
+
+extern char *GetAndCutStringList(StringList *List);
+
+extern Boolean StringListEmpty(StringList List);
+
+extern StringList DuplicateStringList(StringList Src);
+
+extern Boolean StringListPresent(StringList List, char *Search);
+
+extern void DumpStringList(StringList List);
+#endif /* _STRINGLISTS_H */
--- /dev/null
+/* strutil.c */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* haeufig benoetigte String-Funktionen */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "dynstr.h"
+#include "strutil.h"
+#undef strlen /* VORSICHT, Rekursion!!! */
+
+char HexStartCharacter; /* characters to use for 10,11,...35 */
+char SplitByteCharacter; /* output large numbers per-byte with given split char */
+
+/*--------------------------------------------------------------------------*/
+/* eine bestimmte Anzahl Leerzeichen liefern */
+
+const char *Blanks(int cnt)
+{
+ static const char *BlkStr = " ";
+ static int BlkStrLen = 0;
+
+ if (!BlkStrLen)
+ BlkStrLen = strlen(BlkStr);
+
+ if (cnt < 0)
+ cnt = 0;
+ if (cnt > BlkStrLen)
+ cnt = BlkStrLen;
+
+ return BlkStr + (BlkStrLen - cnt);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn SysString(char *pDest, size_t DestSize, LargeWord i, int System, int Stellen, Boolean ForceLeadZero, char StartCharacter, char SplitCharacter)
+ * \brief convert number to string in given number system, leading zeros
+ * \param pDest where to write
+ * \param DestSize size of dest buffer
+ * \param i number to convert
+ * \param Stellen minimum length of output
+ * \param ForceLeadZero prepend zero if first character is no number
+ * \param System number system
+ * \param StartCharacter 'a' or 'A' for hex digits
+ * \param SplitCharacter split bytes if not NUL
+ * ------------------------------------------------------------------------ */
+
+char *SysStringCore(char *pDest, char *pDestCurr, LargeWord Num, int System, int Stellen, char StartCharacter)
+{
+ LargeWord Digit;
+
+ do
+ {
+ if (pDestCurr <= pDest)
+ break;
+ Digit = Num % System;
+ if (Digit < 10)
+ *(--pDestCurr) = Digit + '0';
+ else
+ *(--pDestCurr) = Digit - 10 + StartCharacter;
+ Num /= System;
+ Stellen--;
+ }
+ while ((Stellen > 0) || Num);
+ return pDestCurr;
+}
+
+int SysString(char *pDest, size_t DestSize, LargeWord Num, int System, int Stellen, Boolean ForceLeadZero, char StartCharacter, char SplitCharacter)
+{
+ int Len = 0;
+ char *pDestCurr, *pDestNext;
+
+ if (DestSize < 1)
+ return 0;
+
+ if (Stellen > (int)DestSize - 1)
+ Stellen = DestSize - 1;
+
+ pDestCurr = pDest + DestSize - 1;
+ *pDestCurr = '\0';
+ if (SplitCharacter)
+ {
+ LargeWord Part;
+ int ThisLen;
+ static int SystemByteLen[37];
+
+ if (!SystemByteLen[System])
+ {
+ char Dummy[50];
+
+ SystemByteLen[System] = SysString(Dummy, sizeof(Dummy), 0xff, System, 0, False, StartCharacter, False);
+ }
+
+ do
+ {
+ Part = Num % 256;
+ Num = Num / 256;
+ pDestNext = SysStringCore(pDest, pDestCurr, Part, System, Num ? SystemByteLen[System] : Stellen, StartCharacter);
+ ThisLen = pDestCurr - pDestNext;
+ Len += ThisLen;
+ pDestCurr = pDestNext;
+ Stellen -= ThisLen;
+ if (Num)
+ {
+ if (pDestCurr <= pDest)
+ break;
+ *(--pDestCurr) = SplitCharacter;
+ Len++;
+ }
+ }
+ while ((Stellen > 0) || Num);
+ }
+ else
+ {
+ pDestNext = SysStringCore(pDest, pDestCurr, Num, System, Stellen, StartCharacter);
+ Len += pDestCurr - pDestNext;
+ pDestCurr = pDestNext;
+ }
+
+ if (ForceLeadZero && !isdigit(*pDestCurr) && (pDestCurr > pDest))
+ {
+ *(--pDestCurr) = '0';
+ Len++;
+ }
+
+ if (pDestCurr != pDest)
+ strmov(pDest, pDestCurr);
+ return Len;
+}
+
+/*---------------------------------------------------------------------------*/
+/* strdup() is not part of ANSI C89 */
+
+char *as_strdup(const char *s)
+{
+ char *ptr;
+
+ if (!s)
+ return NULL;
+ ptr = (char *) malloc(strlen(s) + 1);
+#ifdef CKMALLOC
+ if (!ptr)
+ {
+ fprintf(stderr, "strdup: out of memory?\n");
+ exit(255);
+ }
+#endif
+ if (ptr != 0)
+ strcpy(ptr, s);
+ return ptr;
+}
+/*---------------------------------------------------------------------------*/
+/* ...so is snprintf... */
+
+typedef enum { eNotSet, eSet, eFinished } tArgState;
+
+typedef struct
+{
+ tArgState ArgState[3];
+ Boolean InFormat, LeadZero, Signed, LeftAlign, AddPlus, ForceLeadZero, ForceUpper;
+ int Arg[3], CurrArg, IntSize;
+} tFormatContext;
+
+typedef struct
+{
+ char *p_dest;
+ size_t dest_remlen;
+ as_dynstr_t *p_dynstr;
+} dest_format_context_t;
+
+static void ResetFormatContext(tFormatContext *pContext)
+{
+ int z;
+
+ for (z = 0; z < 3; z++)
+ {
+ pContext->Arg[z] = 0;
+ pContext->ArgState[z] = eNotSet;
+ }
+ pContext->CurrArg = 0;
+ pContext->IntSize = 0;
+ pContext->InFormat =
+ pContext->LeadZero =
+ pContext->ForceLeadZero =
+ pContext->Signed =
+ pContext->LeftAlign =
+ pContext->AddPlus =
+ pContext->ForceUpper = False;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn limit_minus_one(dest_format_context_t *p_dest_ctx, size_t cnt)
+ * \brief check if space is left to append given # of characters, plus trailing NUL
+ * \param p_dest_ctx destination context
+ * \param cnt requested # of characters to append
+ * \return actual # that can be appended
+ * ------------------------------------------------------------------------ */
+
+static size_t limit_minus_one(dest_format_context_t *p_dest_ctx, size_t cnt)
+{
+ /* anyway still enough space? */
+
+ if (p_dest_ctx->dest_remlen > cnt)
+ return cnt;
+
+ /* not enough space: try to realloc dynamic string dest */
+
+ if (p_dest_ctx->p_dynstr)
+ {
+ size_t curr_len = p_dest_ctx->p_dest - p_dest_ctx->p_dynstr->p_str;
+ size_t new_capacity = as_dynstr_roundup_len(curr_len + cnt + 1);
+
+ /* if realloc successful, pointer into string buffer must be adapted: */
+
+ if (!as_dynstr_realloc(p_dest_ctx->p_dynstr, new_capacity))
+ {
+ p_dest_ctx->p_dest = p_dest_ctx->p_dynstr->p_str + curr_len;
+ p_dest_ctx->dest_remlen = p_dest_ctx->p_dynstr->capacity - curr_len;
+ }
+ }
+
+ /* pathological case... */
+
+ if (!p_dest_ctx->dest_remlen)
+ return 0;
+
+ /* truncation */
+
+ else
+ return (cnt >= p_dest_ctx->dest_remlen) ? p_dest_ctx->dest_remlen - 1 : cnt;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn append_pad(dest_format_context_t *p_dest_ctx, char src, size_t cnt)
+ * \brief append given character n times
+ * \param p_dest_ctx destination context
+ * \param src character to append
+ * \param cnt # of times to append
+ * \return actual # of characters appended
+ * ------------------------------------------------------------------------ */
+
+static size_t append_pad(dest_format_context_t *p_dest_ctx, char src, size_t cnt)
+{
+ cnt = limit_minus_one(p_dest_ctx, cnt);
+
+ if (cnt > 0)
+ {
+ memset(p_dest_ctx->p_dest, src, cnt);
+ p_dest_ctx->p_dest += cnt;
+ p_dest_ctx->dest_remlen -= cnt;
+ }
+ return cnt;
+}
+
+#if 0
+static int FloatConvert(char *pDest, size_t DestSize, double Src, int Digits, Boolean TruncateTrailingZeros, char FormatType)
+{
+ int DecPt;
+ int Sign, Result = 0;
+ char *pBuf, *pEnd, *pRun;
+
+ (void)FormatType;
+
+ if (DestSize < Digits + 6)
+ {
+ *pDest = '\0';
+ return Result;
+ }
+
+ if (Digits < 0)
+ Digits = 6;
+
+ pBuf = ecvt(Src, Digits + 1, &DecPt, &Sign);
+ puts(pBuf);
+ pEnd = pBuf + strlen(pBuf) - 1;
+ if (TruncateTrailingZeros)
+ {
+ for (; pEnd > pBuf + 1; pEnd--)
+ if (*pEnd != '0')
+ break;
+ }
+
+ pRun = pDest;
+ if (Sign)
+ *pRun++ = '-';
+ *pRun++ = *pBuf;
+ *pRun++ = '.';
+ memcpy(pRun, pBuf + 1, pEnd - pBuf); pRun += pEnd - pBuf;
+ *pRun = '\0';
+ Result = pRun - pDest;
+ Result += as_snprintf(pRun, DestSize - Result, "e%+02d", DecPt - 1);
+ return Result;
+}
+#else
+static int FloatConvert(char *pDest, size_t DestSize, double Src, int Digits, Boolean TruncateTrailingZeros, char FormatType)
+{
+ char Format[10];
+
+ (void)DestSize;
+ (void)TruncateTrailingZeros;
+ strcpy(Format, "%0.*e");
+ Format[4] = (HexStartCharacter == 'a') ? FormatType : toupper(FormatType);
+ sprintf(pDest, Format, Digits, Src);
+ return strlen(pDest);
+}
+#endif
+
+/*!------------------------------------------------------------------------
+ * \fn append(dest_format_context_t *p_dest_ctx, const char *p_src, size_t cnt, tFormatContext *pFormatContext)
+ * \brief append given data, with possible left/right padding
+ * \param p_dest_ctx destination context
+ * \param p_src data to append
+ * \param cnt length of data to append
+ * \param pFormatContext formatting context
+ * \return actual # of characters appended
+ * ------------------------------------------------------------------------ */
+
+static size_t append(dest_format_context_t *p_dest_ctx, const char *p_src, size_t cnt, tFormatContext *pFormatContext)
+{
+ size_t pad_len, result = 0;
+
+ pad_len = (pFormatContext->Arg[0] > (int)cnt) ? pFormatContext->Arg[0] - cnt : 0;
+
+ if ((pad_len > 0) && !pFormatContext->LeftAlign)
+ result += append_pad(p_dest_ctx, ' ', pad_len);
+
+ cnt = limit_minus_one(p_dest_ctx, cnt);
+ if (cnt > 0)
+ {
+ memcpy(p_dest_ctx->p_dest, p_src, cnt);
+ p_dest_ctx->p_dest += cnt;
+ p_dest_ctx->dest_remlen -= cnt;
+ }
+
+ if ((pad_len > 0) && pFormatContext->LeftAlign)
+ result += append_pad(p_dest_ctx, ' ', pad_len);
+
+ if (pFormatContext->InFormat)
+ ResetFormatContext(pFormatContext);
+
+ return result + cnt;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn vsprcatf_core(dest_format_context_t *p_dest_ctx, const char *pFormat, va_list ap)
+ * \brief The actual core routine to process the format string
+ * \param p_dest_ctx context describing destination
+ * \param pFormat format specifier
+ * \param ap format arguments
+ * \return # of characters appended
+ * ------------------------------------------------------------------------ */
+
+static int vsprcatf_core(dest_format_context_t *p_dest_ctx, const char *pFormat, va_list ap)
+{
+ const char *pFormatStart = pFormat;
+ int Result = 0;
+ size_t OrigLen = strlen(p_dest_ctx->p_dest);
+ tFormatContext FormatContext;
+ LargeInt IntArg;
+
+ if (p_dest_ctx->dest_remlen > OrigLen)
+ p_dest_ctx->dest_remlen -= OrigLen;
+ else
+ p_dest_ctx->dest_remlen = 0;
+ p_dest_ctx->p_dest += OrigLen;
+
+ ResetFormatContext(&FormatContext);
+ for (; *pFormat; pFormat++)
+ if (FormatContext.InFormat)
+ switch (*pFormat)
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ if (!FormatContext.CurrArg && !FormatContext.ArgState[FormatContext.CurrArg] && (*pFormat == '0'))
+ FormatContext.LeadZero = True;
+ FormatContext.Arg[FormatContext.CurrArg] = (FormatContext.Arg[FormatContext.CurrArg] * 10) + (*pFormat - '0');
+ FormatContext.ArgState[FormatContext.CurrArg] = eSet;
+ break;
+ }
+ case '-':
+ if (!FormatContext.CurrArg && !FormatContext.ArgState[FormatContext.CurrArg])
+ FormatContext.LeftAlign = True;
+ break;
+ case '+':
+ FormatContext.AddPlus = True;
+ break;
+ case '~':
+ FormatContext.ForceLeadZero = True;
+ break;
+ case '*':
+ FormatContext.Arg[FormatContext.CurrArg] = va_arg(ap, int);
+ FormatContext.ArgState[FormatContext.CurrArg] = eFinished;
+ break;
+ case '.':
+ if (FormatContext.CurrArg < 3)
+ FormatContext.CurrArg++;
+ break;
+ case 'c':
+ {
+ char ch = va_arg(ap, int);
+
+ Result += append(p_dest_ctx, &ch, 1, &FormatContext);
+ break;
+ }
+ case '%':
+ Result += append(p_dest_ctx, "%", 1, &FormatContext);
+ break;
+ case 'l':
+ {
+ FormatContext.IntSize++;
+ FormatContext.CurrArg = 2;
+ break;
+ }
+ case 'd':
+ {
+ if (FormatContext.IntSize >= 3)
+ IntArg = va_arg(ap, LargeInt);
+ else
+#ifndef NOLONGLONG
+ if (FormatContext.IntSize >= 2)
+ IntArg = va_arg(ap, long long);
+ else
+#endif
+ if (FormatContext.IntSize >= 1)
+ IntArg = va_arg(ap, long);
+ else
+ IntArg = va_arg(ap, int);
+ FormatContext.Arg[1] = 10;
+ FormatContext.Signed = True;
+ goto IntCommon;
+ }
+ case 'u':
+ {
+ if (FormatContext.IntSize >= 3)
+ IntArg = va_arg(ap, LargeWord);
+ else
+#ifndef NOLONGLONG
+ if (FormatContext.IntSize >= 2)
+ IntArg = va_arg(ap, unsigned long long);
+ else
+#endif
+ if (FormatContext.IntSize >= 1)
+ IntArg = va_arg(ap, unsigned long);
+ else
+ IntArg = va_arg(ap, unsigned);
+ goto IntCommon;
+ }
+ case 'x':
+ case 'X':
+ {
+ if (FormatContext.IntSize >= 3)
+ IntArg = va_arg(ap, LargeWord);
+ else
+#ifndef NOLONGLONG
+ if (FormatContext.IntSize >= 2)
+ IntArg = va_arg(ap, unsigned long long);
+ else
+#endif
+ if (FormatContext.IntSize)
+ IntArg = va_arg(ap, unsigned long);
+ else
+ IntArg = va_arg(ap, unsigned);
+ FormatContext.Arg[1] = 16;
+ FormatContext.ForceUpper = as_isupper(*pFormat);
+ goto IntCommon;
+ }
+ IntCommon:
+ {
+ char Str[100], *pStr = Str;
+ int Cnt;
+ int NumPadZeros = 0;
+
+ if (FormatContext.Signed)
+ {
+ if (IntArg < 0)
+ {
+ *pStr++ = '-';
+ IntArg = 0 - IntArg;
+ }
+ else if (FormatContext.AddPlus)
+ *pStr++ = '+';
+ }
+ if (FormatContext.LeadZero)
+ {
+ NumPadZeros = FormatContext.Arg[0];
+ FormatContext.Arg[0] = 0;
+ }
+ Cnt = (pStr - Str)
+ + SysString(pStr, sizeof(Str) - (pStr - Str), IntArg,
+ FormatContext.Arg[1] ? FormatContext.Arg[1] : 10,
+ NumPadZeros, FormatContext.ForceLeadZero,
+ FormatContext.ForceUpper ? 'A' : HexStartCharacter,
+ SplitByteCharacter);
+ if (Cnt > (int)sizeof(Str))
+ Cnt = sizeof(Str);
+ Result += append(p_dest_ctx, Str, Cnt, &FormatContext);
+ break;
+ }
+ case 'e':
+ case 'f':
+ case 'g':
+ {
+ char Str[100];
+ int Cnt;
+
+ Cnt = FloatConvert(Str, sizeof(Str), va_arg(ap, double), FormatContext.Arg[1], False, *pFormat);
+ if (Cnt > (int)sizeof(Str))
+ Cnt = sizeof(Str);
+ Result += append(p_dest_ctx, Str, Cnt, &FormatContext);
+ break;
+ }
+ case 's':
+ {
+ const char *pStr = va_arg(ap, char*);
+
+ Result += append(p_dest_ctx, pStr, strlen(pStr), &FormatContext);
+ break;
+ }
+ default:
+ fprintf(stderr, "invalid format: '%c' in '%s'\n", *pFormat, pFormatStart);
+ exit(255);
+ }
+ else if (*pFormat == '%')
+ FormatContext.InFormat = True;
+ else
+ Result += append(p_dest_ctx, pFormat, 1, &FormatContext);
+
+ if (p_dest_ctx->dest_remlen > 0)
+ *(p_dest_ctx->p_dest++) = '\0';
+ return Result;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_vsdprcatf(as_dynstr_t *p_dest, const char *pFormat, va_list ap)
+ * \brief append to dynamic string by format
+ * \param p_dest string to be appended to
+ * \param pFormat format specifier
+ * \param ap format arguments
+ * \return # of characters appended
+ * ------------------------------------------------------------------------ */
+
+int as_vsdprcatf(as_dynstr_t *p_dest, const char *pFormat, va_list ap)
+{
+ dest_format_context_t ctx;
+
+ ctx.p_dest = p_dest->p_str;
+ ctx.dest_remlen = p_dest->capacity;
+ ctx.p_dynstr = p_dest;
+ return vsprcatf_core(&ctx, pFormat, ap);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_vsdprintf(as_dynstr_t *p_dest, const char *pFormat, va_list ap)
+ * \brief print to dynamic string by format
+ * \param p_dest string to be appended to
+ * \param pFormat format specifier
+ * \param ap format arguments
+ * \return # of characters written
+ * ------------------------------------------------------------------------ */
+
+int as_vsdprintf(as_dynstr_t *p_dest, const char *pFormat, va_list ap)
+{
+ if (p_dest->capacity > 0)
+ p_dest->p_str[0] = '\0';
+ return as_vsdprcatf(p_dest, pFormat, ap);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_sdprcatf(as_dynstr_t *p_dest, const char *pFormat, ...)
+ * \brief append to dynamic string by format
+ * \param p_dest string to be appended to
+ * \param pFormat format specifier
+ * \param ... format arguments
+ * \return # of characters written
+ * ------------------------------------------------------------------------ */
+
+int as_sdprcatf(as_dynstr_t *p_dest, const char *pFormat, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, pFormat);
+ ret = as_vsdprcatf(p_dest, pFormat, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_sdprintf(as_dynstr_t *p_dest, const char *pFormat, ...)
+ * \brief print to dynamic string by format
+ * \param p_dest string to be appended to
+ * \param pFormat format specifier
+ * \param ... format arguments
+ * \return # of characters written
+ * ------------------------------------------------------------------------ */
+
+int as_sdprintf(as_dynstr_t *p_dest, const char *pFormat, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, pFormat);
+ ret = as_vsdprintf(p_dest, pFormat, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_vsnprcatf(char *pDest, size_t DestSize, const char *pFormat, va_list ap)
+ * \brief append to string by format
+ * \param pDest string to be appended to
+ * \param DestSize capacity of string
+ * \param pFormat format specifier
+ * \param ap format arguments
+ * \return # of characters appended
+ * ------------------------------------------------------------------------ */
+
+int as_vsnprcatf(char *pDest, size_t DestSize, const char *pFormat, va_list ap)
+{
+ dest_format_context_t ctx;
+
+ if (DestSize == sizeof(char*))
+ {
+ fprintf(stderr, "pointer size passed to as_vsnprcatf\n");
+ exit(2);
+ }
+
+ ctx.p_dest = pDest;
+ ctx.dest_remlen = DestSize;
+ ctx.p_dynstr = NULL;
+ return vsprcatf_core(&ctx, pFormat, ap);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_vsnprintf(char *pDest, size_t DestSize, const char *pFormat, va_list ap)
+ * \brief print to string by format
+ * \param pDest string to be appended to
+ * \param DestSize capacity of string
+ * \param pFormat format specifier
+ * \param ap format arguments
+ * \return # of characters written
+ * ------------------------------------------------------------------------ */
+
+int as_vsnprintf(char *pDest, size_t DestSize, const char *pFormat, va_list ap)
+{
+ if (DestSize > 0)
+ *pDest = '\0';
+ return as_vsnprcatf(pDest, DestSize, pFormat, ap);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_snprintf(char *pDest, size_t DestSize, const char *pFormat, ...)
+ * \brief print to string by format
+ * \param pDest string to be appended to
+ * \param DestSize capacity of string
+ * \param pFormat format specifier
+ * \param ... format arguments
+ * \return # of characters written
+ * ------------------------------------------------------------------------ */
+
+int as_snprintf(char *pDest, size_t DestSize, const char *pFormat, ...)
+{
+ va_list ap;
+ int Result;
+
+ va_start(ap, pFormat);
+ if (DestSize > 0)
+ *pDest = '\0';
+ Result = as_vsnprcatf(pDest, DestSize, pFormat, ap);
+ va_end(ap);
+ return Result;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn as_snprcatf(char *pDest, size_t DestSize, const char *pFormat, ...)
+ * \brief append to string by format
+ * \param pDest string to be appended to
+ * \param DestSize capacity of string
+ * \param pFormat format specifier
+ * \param ... format arguments
+ * \return # of characters appended
+ * ------------------------------------------------------------------------ */
+
+int as_snprcatf(char *pDest, size_t DestSize, const char *pFormat, ...)
+{
+ va_list ap;
+ int Result;
+
+ va_start(ap, pFormat);
+ Result = as_vsnprcatf(pDest, DestSize, pFormat, ap);
+ va_end(ap);
+ return Result;
+}
+
+int as_strcasecmp(const char *src1, const char *src2)
+{
+ if (!src1)
+ src1 = "";
+ if (!src2)
+ src2 = "";
+ while (tolower(*src1) == tolower(*src2))
+ {
+ if ((!*src1) && (!*src2))
+ return 0;
+ src1++;
+ src2++;
+ }
+ return ((int) tolower(*src1)) - ((int) tolower(*src2));
+}
+
+int as_strncasecmp(const char *src1, const char *src2, size_t len)
+{
+ if (!src1)
+ src1 = "";
+ if (!src2)
+ src2 = "";
+ while (tolower(*src1) == tolower(*src2))
+ {
+ if (--len == 0)
+ return 0;
+ if ((!*src1) && (!*src2))
+ return 0;
+ src1++;
+ src2++;
+ }
+ return ((int) tolower(*src1)) - ((int) tolower(*src2));
+}
+
+#ifdef NEEDS_STRSTR
+char *strstr(const char *haystack, const char *needle)
+{
+ int lh = strlen(haystack), ln = strlen(needle);
+ int z;
+ char *p;
+
+ for (z = 0; z <= lh - ln; z++)
+ if (strncmp(p = haystack + z, needle, ln) == 0)
+ return p;
+ return NULL;
+}
+#endif
+
+/*!------------------------------------------------------------------------
+ * \fn strrmultchr(const char *haystack, const char *needles)
+ * \brief find the last occurence of either character in string
+ * \param haystack string to search in
+ * \param needles characters to search for
+ * \return last occurence or NULL
+ * ------------------------------------------------------------------------ */
+
+char *strrmultchr(const char *haystack, const char *needles)
+{
+ const char *pPos;
+
+ for (pPos = haystack + strlen(haystack) - 1; pPos >= haystack; pPos--)
+ if (strchr(needles, *pPos))
+ return (char*)pPos;
+ return NULL;
+}
+
+/*---------------------------------------------------------------------------*/
+/* das originale strncpy plaettet alle ueberstehenden Zeichen mit Nullen */
+
+size_t strmaxcpy(char *dest, const char *src, size_t Max)
+{
+ size_t cnt = strlen(src);
+
+ /* leave room for terminating NUL */
+
+ if (!Max)
+ return 0;
+ if (cnt + 1 > Max)
+ cnt = Max - 1;
+ memcpy(dest, src, cnt);
+ dest[cnt] = '\0';
+ return cnt;
+}
+
+/*---------------------------------------------------------------------------*/
+/* einfuegen, mit Begrenzung */
+
+size_t strmaxcat(char *Dest, const char *Src, size_t MaxLen)
+{
+ int TLen = strlen(Src);
+ size_t DLen = strlen(Dest);
+
+ if (TLen > (int)MaxLen - 1 - (int)DLen)
+ TLen = MaxLen - DLen - 1;
+ if (TLen > 0)
+ {
+ memcpy(Dest + DLen, Src, TLen);
+ Dest[DLen + TLen] = '\0';
+ return DLen + TLen;
+ }
+ else
+ return DLen;
+}
+
+void strprep(char *Dest, const char *Src)
+{
+ memmove(Dest + strlen(Src), Dest, strlen(Dest) + 1);
+ memmove(Dest, Src, strlen(Src));
+}
+
+/*!------------------------------------------------------------------------
+ * \fn strmaxprep(char *p_dest, const char *p_src, size_t max_len)
+ * \brief prepend as much as possible from src to dest
+ * \param p_dest string to be prepended
+ * \param p_src string to prepend
+ * \param max_len capacity of p_dest
+ * ------------------------------------------------------------------------ */
+
+void strmaxprep(char *p_dest, const char *p_src, size_t max_len)
+{
+ size_t src_len = strlen(p_src),
+ dest_len = strlen(p_dest);
+
+ assert(dest_len + 1 <= max_len);
+ if (src_len > max_len - dest_len - 1)
+ src_len = max_len - dest_len - 1;
+ memmove(p_dest + src_len, p_dest, dest_len + 1);
+ memmove(p_dest, p_src, src_len);
+}
+
+/*!------------------------------------------------------------------------
+ * \fn strmaxprep2(char *p_dest, const char *p_src, size_t max_len)
+ * \brief prepend as much as possible from src to dest, and possibly truncate dest by that
+ * \param p_dest string to be prepended
+ * \param p_src string to prepend
+ * \param max_len capacity of p_dest
+ * ------------------------------------------------------------------------ */
+
+void strmaxprep2(char *p_dest, const char *p_src, size_t max_len)
+{
+ size_t src_len = strlen(p_src),
+ dest_len = strlen(p_dest);
+
+ assert(max_len > 0);
+ if (src_len >= max_len)
+ src_len = max_len - 1;
+ max_len -= src_len;
+ if (dest_len >= max_len)
+ dest_len = max_len - 1;
+ memmove(p_dest + src_len, p_dest, dest_len + 1);
+ memmove(p_dest, p_src, src_len);
+}
+
+void strins(char *Dest, const char *Src, int Pos)
+{
+ memmove(Dest + Pos + strlen(Src), Dest + Pos, strlen(Dest) + 1 - Pos);
+ memmove(Dest + Pos, Src, strlen(Src));
+}
+
+void strmaxins(char *Dest, const char *Src, int Pos, size_t MaxLen)
+{
+ size_t RLen;
+
+ RLen = strlen(Src);
+ if (RLen > MaxLen - strlen(Dest))
+ RLen = MaxLen - strlen(Dest);
+ memmove(Dest + Pos + RLen, Dest + Pos, strlen(Dest) + 1 - Pos);
+ memmove(Dest + Pos, Src, RLen);
+}
+
+int strlencmp(const char *pStr1, unsigned Str1Len,
+ const char *pStr2, unsigned Str2Len)
+{
+ const char *p1, *p2, *p1End, *p2End;
+ int Diff;
+
+ for (p1 = pStr1, p1End = p1 + Str1Len,
+ p2 = pStr2, p2End = p2 + Str2Len;
+ p1 < p1End && p2 < p2End; p1++, p2++)
+ {
+ Diff = ((int)*p1) - ((int)*p2);
+ if (Diff)
+ return Diff;
+ }
+ return ((int)Str1Len) - ((int)Str2Len);
+}
+
+unsigned fstrlenprint(FILE *pFile, const char *pStr, unsigned StrLen)
+{
+ unsigned Result = 0;
+ const char *pRun, *pEnd;
+
+ for (pRun = pStr, pEnd = pStr + StrLen; pRun < pEnd; pRun++)
+ if ((*pRun == '\\') || (*pRun == '"') || (*pRun == ' ') || (!isprint(*pRun)))
+ {
+ fprintf(pFile, "\\%03d", *pRun);
+ Result += 4;
+ }
+ else
+ {
+ fputc(*pRun, pFile);
+ Result++;
+ }
+
+ return Result;
+}
+
+size_t as_strnlen(const char *pStr, size_t MaxLen)
+{
+ size_t Res = 0;
+
+ for (; (MaxLen > 0); MaxLen--, pStr++, Res++)
+ if (!*pStr)
+ break;
+ return Res;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn strreplace(char *pHaystack, const char *pFrom, const char *pTo, size_t ToMaxLen, size_t HaystackSize)
+ * \brief replaces all occurences of From to To in Haystack
+ * \param pHaystack string to search in
+ * \param pFrom what to find
+ * \param pFrom what to find
+ * \param pTo what to replace it with
+ * \param ToMaxLen if not -1, max. length of pTo (not NUL-terminated)
+ * \param HaystackSize buffer capacity
+ * \return # of occurences
+ * ------------------------------------------------------------------------ */
+
+int strreplace(char *pHaystack, const char *pFrom, const char *pTo, size_t ToMaxLen, size_t HaystackSize)
+{
+ int HaystackLen = -1, FromLen = -1, ToLen = -1, Count = 0;
+ int HeadLen, TailLen;
+ char *pSearch, *pPos;
+
+ pSearch = pHaystack;
+ while (True)
+ {
+ /* find an occurence */
+
+ pPos = strstr(pSearch, pFrom);
+ if (!pPos)
+ return Count;
+
+ /* compute some stuff upon first occurence when needed */
+
+ if (FromLen < 0)
+ {
+ HaystackLen = strlen(pHaystack);
+ FromLen = strlen(pFrom);
+ }
+ ToLen = (ToMaxLen > 0) ? as_strnlen(pTo, ToMaxLen) : strlen(pTo);
+
+ /* See how much of the remainder behind 'To' still fits into buffer after replacement,
+ and move accordingly: */
+
+ HeadLen = pPos - pHaystack;
+ TailLen = HaystackLen - HeadLen - FromLen;
+ if (HeadLen + ToLen + TailLen >= (int)HaystackSize)
+ {
+ TailLen = HaystackSize - 1 - HeadLen - ToLen;
+ if (TailLen < 0)
+ TailLen = 0;
+ }
+ if (TailLen > 0)
+ memmove(pPos + ToLen, pPos + FromLen, TailLen);
+
+ /* See how much of 'To' still fits into buffer, and set accordingly: */
+
+ if (HeadLen + ToLen >= (int)HaystackSize)
+ {
+ ToLen = HaystackSize - 1 - ToLen;
+ if (ToLen < 0)
+ ToLen = 0;
+ }
+ if (ToLen > 0)
+ memcpy(pPos, pTo, ToLen);
+
+ /* Update length & terminate new string */
+
+ HaystackLen = HeadLen + ToLen + TailLen;
+ pHaystack[HaystackLen] = '\0';
+
+ /* continue searching behind replacement: */
+
+ pSearch = &pHaystack[HeadLen + ToLen];
+
+ Count++;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/* Bis Zeilenende lesen */
+
+void ReadLn(FILE *Datei, char *Zeile)
+{
+ char *ptr;
+ int l;
+
+ *Zeile = '\0';
+ ptr = fgets(Zeile, 256, Datei);
+ if ((!ptr) && (ferror(Datei) != 0))
+ *Zeile = '\0';
+ l = strlen(Zeile);
+ if ((l > 0) && (Zeile[l - 1] == '\n'))
+ Zeile[--l] = '\0';
+ if ((l > 0) && (Zeile[l - 1] == '\r'))
+ Zeile[--l] = '\0';
+ if ((l > 0) && (Zeile[l - 1] == 26))
+ Zeile[--l] = '\0';
+}
+
+#if 0
+
+static void dump(const char *pLine, unsigned Cnt)
+{
+ unsigned z;
+
+ fputc('\n', stderr);
+ for (z = 0; z < Cnt; z++)
+ {
+ fprintf(stderr, " %02x", pLine[z]);
+ if ((z & 15) == 15)
+ fputc('\n', stderr);
+ }
+ fputc('\n', stderr);
+}
+
+#endif
+
+/*!------------------------------------------------------------------------
+ * \fn ReadLnCont(FILE *Datei, as_dynstr_t *p_line)
+ * \brief read line, regarding \ continuation characters
+ * \param Datei where to read from
+ * \param pLine dest buffer
+ * \return # of lines read
+ * ------------------------------------------------------------------------ */
+
+size_t ReadLnCont(FILE *Datei, as_dynstr_t *p_line)
+{
+ char *ptr, *pDest;
+ size_t l, Count, LineCount;
+ Boolean Terminated;
+
+ /* read from input until no continuation is present */
+
+ pDest = p_line->p_str;
+ LineCount = Count = 0;
+ while (1)
+ {
+ /* get a line from file, possibly reallocating until everything up to \n fits */
+
+ while (1)
+ {
+ if (p_line->capacity - Count < 128)
+ as_dynstr_realloc(p_line, p_line->capacity + 128);
+
+ pDest = p_line->p_str + Count;
+ *pDest = '\0';
+ ptr = fgets(pDest, p_line->capacity - Count, Datei);
+ if (!ptr)
+ {
+ if (ferror(Datei) != 0)
+ *pDest = '\0';
+ break;
+ }
+
+ /* If we have a trailing \n, we read up to end of line: */
+
+ l = strlen(pDest);
+ Terminated = ((l > 0) && (pDest[l - 1] == '\n'));
+
+ /* srtrip possible CR preceding LF: */
+
+ if (Terminated)
+ {
+ /* strip LF, and possible CR, and bail out: */
+
+ pDest[--l] = '\0';
+ if ((l > 0) && (pDest[l - 1] == '\r'))
+ pDest[--l] = '\0';
+ }
+
+ Count += l;
+ pDest += l;
+
+ if (Terminated)
+ break;
+ }
+
+ LineCount++;
+ if ((Count > 0) && (p_line->p_str[Count - 1] == 26))
+ p_line->p_str[--Count] = '\0';
+
+ /* optional line continuation */
+
+ if ((Count > 0) && (p_line->p_str[Count - 1] == '\\'))
+ p_line->p_str[--Count] = '\0';
+ else
+ break;
+ }
+
+ return LineCount;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn DigitVal(char ch, int Base)
+ * \brief get value of hex digit
+ * \param ch digit
+ * \param Base Number System
+ * \return 0..Base-1 or -1 if no valid digit
+ * ------------------------------------------------------------------------ */
+
+int DigitVal(char ch, int Base)
+{
+ int Result;
+
+ /* Ziffern 0..9 ergeben selbiges */
+
+ if ((ch >= '0') && (ch <= '9'))
+ Result = ch - '0';
+
+ /* Grossbuchstaben fuer Hexziffern */
+
+ else if ((ch >= 'A') && (ch <= 'Z'))
+ Result = ch - 'A' + 10;
+
+ /* Kleinbuchstaben nicht vergessen...! */
+
+ else if ((ch >= 'a') && (ch <= 'z'))
+ Result = ch - 'a' + 10;
+
+ /* alles andere ist Schrott */
+
+ else
+ Result = -1;
+
+ return (Result >= Base) ? -1 : Result;
+}
+
+/*--------------------------------------------------------------------*/
+/* Zahlenkonstante umsetzen: $ hex, % binaer, @ oktal */
+/* inp: Eingabezeichenkette */
+/* erg: Zeiger auf Ergebnis-Longint */
+/* liefert TRUE, falls fehlerfrei, sonst FALSE */
+
+LargeInt ConstLongInt(const char *inp, Boolean *pErr, LongInt Base)
+{
+ static const char Prefixes[4] = { '$', '@', '%', '\0' }; /* die moeglichen Zahlensysteme */
+ static const char Postfixes[4] = { 'H', 'O', '\0', '\0' };
+ static const LongInt Bases[3] = { 16, 8, 2 }; /* die dazugehoerigen Basen */
+ LargeInt erg, val;
+ int z, vorz = 1; /* Vermischtes */
+ int InpLen = strlen(inp);
+
+ /* eventuelles Vorzeichen abspalten */
+
+ if (*inp == '-')
+ {
+ vorz = -1;
+ inp++;
+ InpLen--;
+ }
+
+ /* Sonderbehandlung 0x --> $ */
+
+ if ((InpLen >= 2)
+ && (*inp == '0')
+ && (as_toupper(inp[1]) == 'X'))
+ {
+ inp += 2;
+ InpLen -= 2;
+ Base = 16;
+ }
+
+ /* Jetzt das Zahlensystem feststellen. Vorgabe ist dezimal, was
+ sich aber durch den Initialwert von Base jederzeit aendern
+ laesst. Der break-Befehl verhindert, dass mehrere Basenzeichen
+ hintereinander eingegeben werden koennen */
+
+ else if (InpLen > 0)
+ {
+ for (z = 0; z < 3; z++)
+ if (*inp == Prefixes[z])
+ {
+ Base = Bases[z];
+ inp++;
+ InpLen--;
+ break;
+ }
+ else if (as_toupper(inp[InpLen - 1]) == Postfixes[z])
+ {
+ Base = Bases[z];
+ InpLen--;
+ break;
+ }
+ }
+
+ /* jetzt die Zahlenzeichen der Reihe nach durchverwursten */
+
+ erg = 0;
+ *pErr = False;
+ for(; InpLen > 0; inp++, InpLen--)
+ {
+ val = DigitVal(*inp, 16);
+ if (val < -0)
+ break;
+
+ /* entsprechend der Basis zulaessige Ziffer ? */
+
+ if (val >= Base)
+ break;
+
+ /* Zahl linksschieben, zusammenfassen, naechster bitte */
+
+ erg = erg * Base + val;
+ }
+
+ /* bis zum Ende durchgelaufen ? */
+
+ if (!InpLen)
+ {
+ /* Vorzeichen beruecksichtigen */
+
+ erg *= vorz;
+ *pErr = True;
+ }
+
+ return erg;
+}
+
+/*--------------------------------------------------------------------------*/
+/* alle Leerzeichen aus einem String loeschen */
+
+void KillBlanks(char *s)
+{
+ char *z, *dest;
+ Boolean InSgl = False, InDbl = False, ThisEscaped = False, NextEscaped = False;
+
+ dest = s;
+ for (z = s; *z != '\0'; z++, ThisEscaped = NextEscaped)
+ {
+ NextEscaped = False;
+ switch (*z)
+ {
+ case '\'':
+ if (!InDbl && !ThisEscaped)
+ InSgl = !InSgl;
+ break;
+ case '"':
+ if (!InSgl && !ThisEscaped)
+ InDbl = !InDbl;
+ break;
+ case '\\':
+ if ((InSgl || InDbl) && !ThisEscaped)
+ NextEscaped = True;
+ break;
+ }
+ if (!as_isspace(*z) || InSgl || InDbl)
+ *dest++ = *z;
+ }
+ *dest = '\0';
+}
+
+int CopyNoBlanks(char *pDest, const char *pSrc, size_t MaxLen)
+{
+ const char *pSrcRun;
+ char *pDestRun = pDest;
+ size_t Cnt = 0;
+ Byte Flags = 0;
+ char ch;
+ Boolean ThisEscaped, PrevEscaped;
+
+ /* leave space for NUL */
+
+ MaxLen--;
+
+ PrevEscaped = False;
+ for (pSrcRun = pSrc; *pSrcRun; pSrcRun++)
+ {
+ ch = *pSrcRun;
+ ThisEscaped = False;
+ switch (ch)
+ {
+ case '\'':
+ if (!(Flags & 2) && !PrevEscaped)
+ Flags ^= 1;
+ break;
+ case '"':
+ if (!(Flags & 1) && !PrevEscaped)
+ Flags ^= 2;
+ break;
+ case '\\':
+ if (!PrevEscaped)
+ ThisEscaped = True;
+ break;
+ }
+ if (!as_isspace(ch) || Flags)
+ *(pDestRun++) = ch;
+ if (++Cnt >= MaxLen)
+ break;
+ PrevEscaped = ThisEscaped;
+ }
+ *pDestRun = '\0';
+
+ return Cnt;
+}
+
+/*--------------------------------------------------------------------------*/
+/* fuehrende Leerzeichen loeschen */
+
+int KillPrefBlanks(char *s)
+{
+ char *z = s;
+
+ while ((*z != '\0') && as_isspace(*z))
+ z++;
+ if (z != s)
+ strmov(s, z);
+ return z - s;
+}
+
+/*--------------------------------------------------------------------------*/
+/* anhaengende Leerzeichen loeschen */
+
+int KillPostBlanks(char *s)
+{
+ char *z = s + strlen(s) - 1;
+ int count = 0;
+
+ while ((z >= s) && as_isspace(*z))
+ {
+ *(z--) = '\0';
+ count++;
+ }
+ return count;
+}
+
+/*--------------------------------------------------------------------------*/
+
+int strqcmp(const char *s1, const char *s2)
+{
+ int erg = (*s1) - (*s2);
+
+ return (erg != 0) ? erg : strcmp(s1, s2);
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* we need a strcpy() with a defined behaviour in case of overlapping source
+ and destination: */
+
+char *strmov(char *pDest, const char *pSrc)
+{
+ memmove(pDest, pSrc, strlen(pSrc) + 1);
+ return pDest;
+}
+
+#ifdef __GNUC__
+
+#ifdef strcpy
+# undef strcpy
+#endif
+char *strcpy(char *pDest, const char *pSrc)
+{
+ int l = strlen(pSrc) + 1;
+ int Overlap = 0;
+
+ if (pSrc < pDest)
+ {
+ if (pSrc + l > pDest)
+ Overlap = 1;
+ }
+ else if (pSrc > pDest)
+ {
+ if (pDest + l > pSrc)
+ Overlap = 1;
+ }
+ else if (l > 0)
+ {
+ Overlap = 1;
+ }
+
+ if (Overlap)
+ {
+ fprintf(stderr, "overlapping strcpy() called from address %p, resolve this address with addr2line and report to author\n",
+ __builtin_return_address(0));
+ abort();
+ }
+
+ return strmov(pDest, pSrc);
+}
+
+#endif
+
+/*!------------------------------------------------------------------------
+ * \fn strmemcpy(char *pDest, size_t DestSize, const char *pSrc, size_t SrcLen)
+ * \brief copy string with length limitation
+ * \param pDest where to write
+ * \param DestSize destination capacity
+ * \param pSrc copy source
+ * \param SrcLen # of characters to copy at most
+ * \return actual, possibly limited length
+ * ------------------------------------------------------------------------ */
+
+int strmemcpy(char *pDest, size_t DestSize, const char *pSrc, size_t SrcLen)
+{
+ if (DestSize < SrcLen + 1)
+ SrcLen = DestSize - 1;
+ memmove(pDest, pSrc, SrcLen);
+ pDest[SrcLen] = '\0';
+ return SrcLen;
+}
+
+/*--------------------------------------------------------------------------*/
+
+char *ParenthPos(char *pHaystack, char Needle)
+{
+ char *pRun;
+ int Level = 0;
+
+ for (pRun = pHaystack; *pRun; pRun++)
+ {
+ switch (*pRun)
+ {
+ case '(':
+ Level++;
+ break;
+ case ')':
+ if (Level < 1)
+ return NULL;
+ Level--;
+ break;
+ default:
+ if (*pRun == Needle && !Level)
+ return pRun;
+ }
+ }
+ return NULL;
+}
+
+/*!------------------------------------------------------------------------
+ * \fn TabCompressed(char in)
+ * \brief replace TABs with spaces for error display
+ * \param in character to compress
+ * \return compressed result
+ * ------------------------------------------------------------------------ */
+
+char TabCompressed(char in)
+{
+ return (in == '\t') ? ' ' : (as_isprint(in) ? in : '*');
+}
+
+/*--------------------------------------------------------------------------*/
+
+void strutil_init(void)
+{
+ HexStartCharacter = 'A';
+}
--- /dev/null
+#ifndef _STRUTIL_H
+#define _STRUTIL_H
+/* strutil.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* haeufig benoetigte String-Funktionen */
+/* */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#include "datatypes.h"
+
+struct as_dynstr;
+
+extern char HexStartCharacter;
+extern char SplitByteCharacter;
+
+extern const char *Blanks(int cnt);
+
+#define HexString(pDest, DestSize, i, Stellen) SysString(pDest, DestSize, i, 16, Stellen, False, HexStartCharacter, SplitByteCharacter)
+#define DecString(pDest, DestSize, i, Digits) SysString(pDest, DestSize, i, 10, Digits, False, HexStartCharacter, '\0')
+
+extern int SysString(char *pDest, size_t DestSize, LargeWord i, int System, int Stellen, Boolean ForceLeadZero, char StartCharacter, char SplitCharacter);
+
+extern char *as_strdup(const char *s);
+
+extern int as_vsnprcatf(char *pDest, size_t DestSize, const char *pFormat, va_list ap);
+extern int as_snprcatf(char *pDest, size_t DestSize, const char *pFormat, ...);
+extern int as_vsnprintf(char *pDest, size_t DestSize, const char *pFormat, va_list ap);
+extern int as_snprintf(char *pDest, size_t DestSize, const char *pFormat, ...);
+
+extern int as_vsdprcatf(struct as_dynstr *p_dest, const char *pFormat, va_list ap);
+extern int as_sdprcatf(struct as_dynstr *p_dest, const char *pFormat, ...);
+extern int as_vsdprintf(struct as_dynstr *p_dest, const char *pFormat, va_list ap);
+extern int as_sdprintf(struct as_dynstr *p_dest, const char *pFormat, ...);
+
+extern int as_strcasecmp(const char *src1, const char *src2);
+extern int as_strncasecmp(const char *src1, const char *src2, size_t maxlen);
+
+#ifdef NEEDS_STRSTR
+extern char *strstr(const char *haystack, const char *needle);
+#endif
+
+extern char *strrmultchr(const char *haystack, const char *needles);
+
+extern size_t strmaxcpy(char *dest, const char *src, size_t Max);
+extern size_t strmaxcat(char *Dest, const char *Src, size_t MaxLen);
+extern void strprep(char *Dest, const char *Src);
+extern void strmaxprep(char *p_dest, const char *p_src, size_t max_len);
+extern void strmaxprep2(char *p_dest, const char *p_src, size_t max_len);
+extern void strins(char *Dest, const char *Src, int Pos);
+extern void strmaxins(char *Dest, const char *Src, int Pos, size_t MaxLen);
+
+extern size_t as_strnlen(const char *pStr, size_t MaxLen);
+
+extern int strreplace(char *pHaystack, const char *pFrom, const char *pTo, size_t ToMaxLen, size_t HaystackSize);
+
+extern int strlencmp(const char *pStr1, unsigned Str1Len,
+ const char *pStr2, unsigned Str2Len);
+
+extern unsigned fstrlenprint(FILE *pFile, const char *pStr, unsigned StrLen);
+
+extern void ReadLn(FILE *Datei, char *Zeile);
+
+extern size_t ReadLnCont(FILE *Datei, struct as_dynstr *p_line);
+
+extern int DigitVal(char ch, int Base);
+
+extern LargeInt ConstLongInt(const char *inp, Boolean *pErr, LongInt Base);
+
+extern char *ParenthPos(char *pHaystack, char Needle);
+
+extern void KillBlanks(char *s);
+
+extern int CopyNoBlanks(char *pDest, const char *pSrc, size_t MaxLen);
+
+extern int KillPrefBlanks(char *s);
+
+extern int KillPostBlanks(char *s);
+
+extern char TabCompressed(char in);
+
+extern int strqcmp(const char *s1, const char *s2);
+
+extern char *strmov(char *pDest, const char *pSrc);
+
+extern int strmemcpy(char *pDest, size_t DestSize, const char *pSrc, size_t SrcLen);
+
+extern void strutil_init(void);
+
+/* avoid nasty "subscript has type char..." messages on some platforms */
+
+#include <ctype.h>
+
+#define __chartouint(c) (((unsigned int)(c)) & 0xff)
+#define as_toupper(c) (toupper(__chartouint(c)))
+#define as_tolower(c) (tolower(__chartouint(c)))
+#define as_isspace(c) (!!isspace(__chartouint(c)))
+#define as_isdigit(c) (!!isdigit(__chartouint(c)))
+#define as_isxdigit(c) (!!isxdigit(__chartouint(c)))
+#define as_isprint(c) (!!isprint(__chartouint(c)))
+#define as_isalpha(c) (!!isalpha(__chartouint(c)))
+#define as_isupper(c) (!!isupper(__chartouint(c)))
+#define as_islower(c) (!!islower(__chartouint(c)))
+#define as_isalnum(c) (!!isalnum(__chartouint(c)))
+
+#endif /* _STRUTIL_H */
--- /dev/null
+#ifndef _SYMBOLSIZE_H
+#define _SYMBOLSIZE_H
+/* symbolsize.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* Macro Assembler AS */
+/* */
+/* Definition of a symbol's/instruction's operand type & size */
+/* */
+/*****************************************************************************/
+
+typedef enum
+{
+ eSymbolSizeUnknown = -1,
+ eSymbolSize8Bit = 0,
+ eSymbolSize16Bit = 1,
+ eSymbolSize32Bit = 2,
+ eSymbolSize64Bit = 3,
+ eSymbolSize80Bit = 4, /* Intel 80 Bit extended float */
+ eSymbolSizeFloat32Bit = 5,
+ eSymbolSizeFloat64Bit = 6,
+ eSymbolSizeFloat96Bit = 7,
+ eSymbolSize24Bit = 8,
+ eSymbolSizeFloatDec96Bit = 9,
+ eSymbolSizeFloat16Bit = 10
+} tSymbolSize;
+
+#ifdef __cplusplus
+#include "cppops.h"
+DefCPPOps_Enum(tSymbolSize)
+#endif
+
+extern const char *GetSymbolSizeName(tSymbolSize Size);
+
+extern unsigned GetSymbolSizeBytes(tSymbolSize Size);
+
+#endif /* _SYMBOLSIZE_H */
--- /dev/null
+#ifndef _SYMFLAGS_H
+#define _SYMFLAGS_H
+/* symflags.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS */
+/* */
+/* Symbol Flags Used in Symbol Table and TempResult */
+/* */
+/*****************************************************************************/
+
+typedef enum eSymbolFlags
+{
+ eSymbolFlag_None = 0,
+ eSymbolFlag_NextLabelAfterBSR = 1 << 0,
+ eSymbolFlag_StringSingleQuoted = 1 << 1,
+
+ /* Hinweisflag: evtl. im ersten Pass unbe-
+ kanntes Symbol, Ausdruck nicht ausgewertet */
+
+ eSymbolFlag_FirstPassUnknown = 1 << 2,
+
+ /* Hinweisflag: Dadurch, dass Phasenfehler
+ aufgetreten sind, ist dieser Symbolwert evtl.
+ nicht mehr aktuell */
+
+ eSymbolFlag_Questionable = 1 << 3,
+
+ /* Hinweisflag: benutzt Vorwaertsdefinitionen */
+
+ eSymbolFlag_UsesForwards = 1 << 4,
+
+ eSymbolFlag_Label = 1 << 5,
+
+ eSymbolFlags_Promotable = eSymbolFlag_FirstPassUnknown | eSymbolFlag_Questionable | eSymbolFlag_UsesForwards
+} tSymbolFlags;
+
+#ifdef __cplusplus
+#include "cppops.h"
+DefCPPOps_Mask(tSymbolFlags)
+#endif
+
+#define mFirstPassUnknown(Flags) (!!((Flags) & eSymbolFlag_FirstPassUnknown))
+
+#define mSymbolQuestionable(Flags) (!!((Flags) & eSymbolFlag_Questionable))
+
+#define mFirstPassUnknownOrQuestionable(Flags) (!!((Flags) & (eSymbolFlag_FirstPassUnknown | eSymbolFlag_Questionable)))
+
+#define mUsesForwards(Flags) (!!((Flags) & eSymbolFlag_UsesForwards))
+
+#endif /* _SYMFLAGS_H */
--- /dev/null
+#ifndef _SYSDEFS_H
+#define _SYSDEFS_H
+/* sysdefs.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS Port */
+/* */
+/* system-specific definitions */
+/* */
+/* History: 2001-04-13 activated DRSEP for Win32 platform */
+/* 2001-09-11 added MacOSX */
+/* 2001-10-13 added ARM/Linux */
+/* */
+/*****************************************************************************/
+
+/* NOTE:
+ *
+ * when adding new platforms, " gcc -dM -E - <<<'' " might be helpful to
+ * find out about predefined symbols
+ *
+ */
+
+/*---------------------------------------------------------------------------*/
+/* unify 68K platforms */
+
+#ifdef __mc68020
+#ifndef __m68k
+#define __m68k
+#endif
+#endif
+
+#ifdef m68000
+#ifndef __m68k
+#define __m68k
+#endif
+#endif
+
+#ifdef __mc68000
+# ifndef __m68k
+# define __m68k
+# endif
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* ditto for i386 platforms */
+
+/* MSDOS only runs on x86s... */
+
+#ifdef __MSDOS__
+#define __i386
+#endif
+
+/* For IBMC... */
+
+#ifdef _M_I386
+#define __i386
+#endif
+
+#ifdef __i386__
+#ifndef __i386
+#define __i386
+#endif
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* ditto for VAX platforms */
+
+#ifdef vax
+#define __vax__
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* ditto for PPC platforms */
+
+#ifdef __PPC
+#ifndef _POWER
+#define _POWER
+#endif
+#endif
+
+#ifdef __ppc__
+#ifndef _POWER
+#define _POWER
+#endif
+#endif
+
+#ifdef __PPC__
+# ifndef _POWER
+# define _POWER
+# endif
+#endif
+
+#ifdef __PPC64__
+# ifndef _POWER4
+# define _POWER4
+# endif
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* ditto for ARM platforms */
+
+#ifdef __arm__
+#ifndef __arm
+#define __arm
+#endif
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* If the compiler claims to be ANSI, we surely can use prototypes */
+
+#ifdef __STDC__
+#define __PROTOS__
+#define UNUSED(x) (void)x
+#else
+#define UNUSED(x) {}
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* just a hack to allow distinguishing SunOS from Solaris on Sparcs... */
+
+#ifdef sparc
+#ifndef __sparc
+#define __sparc
+#endif
+#endif
+
+#ifdef __sparc
+# ifndef __NetBSD__
+# ifndef __FreeBSD__
+# ifndef __linux__
+# ifndef __SVR4
+# define __sunos__
+# else /* __SVR4 */
+# define __solaris__
+# endif /* __SVR4 */
+# endif /* __linux__ */
+# endif /* __FreeBSD__ */
+# endif /* __NetBSD */
+#endif /* __sparc */
+
+#ifdef __sparc__
+#ifndef __sparc
+#define __sparc
+#endif
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* similar on Sun 3's... */
+
+#ifdef __m68k
+#ifndef __NetBSD__
+#ifndef __MUNIX__
+#ifndef __amiga
+#define __sunos__
+#endif
+#endif
+#endif
+#endif
+
+/*===========================================================================*/
+/* 68K platforms */
+
+#ifdef __m68k
+
+#define ARCHPRNAME "m68k"
+
+/*---------------------------------------------------------------------------*/
+/* SUN/3 with SunOS 4.x:
+
+ see my SunOS quarrels in the Sparc section... */
+
+#ifdef __sunos__
+#define ARCHSYSNAME "sun-sunos"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#ifdef __GNUC__
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#else
+#define NOLONGLONG
+#endif
+#define memmove(s1,s2,len) bcopy(s2,s1,len)
+extern void bcopy();
+#define NO_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* SUN/3 with NetBSD 1.x:
+
+ quite a normal 32-Bit-UNIX system */
+
+#ifdef __NetBSD__
+#define ARCHSYSNAME "sun-netbsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* PCS/Cadmus:
+
+ quite a bare system, lots of work required... */
+
+#ifdef __MUNIX__
+#define ARCHSYSNAME "pcs-munix"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+#define NEEDS_STRSTR
+typedef char Integ8;
+typedef unsigned char Card8;
+typedef short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#define NOLONGLONG
+#define memmove(s1,s2,len) bcopy(s2,s1,len)
+extern double strtod();
+extern char *getenv();
+#define NO_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Linux/68K:
+
+ quite a normal 32-Bit-UNIX system */
+
+#ifdef __linux__
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define NO_NLS
+#endif
+
+#endif /* __m68k */
+
+/*===========================================================================*/
+/* SPARC platforms */
+
+#ifdef __sparc
+
+#define ARCHPRNAME "sparc"
+
+/*---------------------------------------------------------------------------*/
+/* SUN Sparc with SunOS 4.1.x:
+
+ don't try cc, use gcc, it's hopeless without an ANSI-compliant compiler...
+ SunOS does have NLS support, but it does not have D_FMT and T_FMT
+ I should change this ...
+ Though the manual pages claim that memmove and atexit exist, I could not
+ find them in any library :-( Fortunately, bcopy claims to be safe for
+ overlapping arrays, we just have to reverse source and destination pointers.
+ The sources themselves contain a switch to use on_exit instead of atexit
+ (it uses a different callback scheme, so we cannot just make a #define here...)
+ To get rid of most of the messages about missing prototypes, add
+ -D__USE_FIXED_PROTOTYPES__ to your compiler flags!
+ Apart from these few points, one could claim SunOS to be quite a normal
+ 32-bit-UNIX... */
+
+#ifdef __sunos__
+#define ARCHSYSNAME "sun-sunos"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#ifdef __GNUC__
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#else
+#define NOLONGLONG
+#endif
+#define fpos_t long
+#ifdef __STDC__
+extern void bcopy();
+#endif
+#define memmove(s1,s2,len) bcopy(s2,s1,len)
+#define NO_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* SUN Sparc with Solaris 2.x:
+
+ quite a normal 32-Bit-UNIX system */
+
+#ifdef __solaris__
+#define ARCHSYSNAME "sun-solaris"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Sparc with NetBSD 1.x:
+
+ quite a normal 32-Bit-UNIX system */
+
+#ifdef __NetBSD__
+#define ARCHSYSNAME "sun-netbsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Sparc with Linux */
+
+#ifdef __linux__
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+#endif /* __sparc */
+
+/*===========================================================================*/
+/* Mips platforms */
+
+#ifdef __mips
+
+#define ARCHPRNAME "mips"
+
+/*---------------------------------------------------------------------------*/
+/* R3000 with Ultrix 4.3:
+
+ nl_langinfo prototype is there, but no function in library ?!
+ use long long only if you have gcc, c89 doesn't like them !
+ cc isn't worth trying, believe me! */
+
+#ifdef __ultrix
+#define ARCHSYSNAME "dec-ultrix"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+#define NEEDS_STRDUP
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#ifdef __GNUC__
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#else
+#define NOLONGLONG
+#endif
+#define NO_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* R2000/3000 with NetBSD 1.2:
+
+ quite a normal 32-Bit-UNIX system */
+
+#ifdef __NetBSD__
+#define ARCHSYSNAME "dec-netbsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* R3000/4x00 with Irix 5.x:
+
+ quite a normal 32-Bit-UNIX system
+ seems also to work with 6.2... */
+
+#ifdef __sgi
+#define ARCHSYSNAME "sgi-irix"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+#ifdef __linux__
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+#endif /* __mips */
+
+/*===========================================================================*/
+/* HP-PA platforms */
+
+#ifdef __hppa
+
+#define ARCHPRNAME "parisc"
+
+/*---------------------------------------------------------------------------*/
+/* HP-PA 1.x with HP-UX: */
+
+#ifdef __hpux
+#define ARCHSYSNAME "hp-hpux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+#endif /* __hppa */
+
+/*===========================================================================*/
+/* POWER 64 bit platforms */
+
+#ifdef _POWER64
+
+#define ARCHPRNAME "ppc64"
+
+/*---------------------------------------------------------------------------*/
+/* POWER64 with Linux (Macintosh) */
+
+#ifdef __linux__
+
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long Integ64;
+typedef unsigned long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*===========================================================================*/
+/* POWER(32) platforms */
+
+#elif defined _POWER
+
+#define ARCHPRNAME "ppc"
+
+/*---------------------------------------------------------------------------*/
+/* POWER with AIX 4.1: rs6000 */
+
+#ifdef _AIX
+#define ARCHSYSNAME "ibm-aix"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* POWER with Linux (Macintosh) */
+
+#ifdef __linux__
+
+/* no long long data type if C89 is used */
+
+#if (defined __STDC__) && (!defined __STDC_VERSION__)
+# define NOLONGLONG
+#endif
+
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#ifndef NOLONGLONG
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+# define HAS64
+#endif /* !NOLONGLONG */
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* POWER with OSX (Macintosh) */
+
+#ifdef __APPLE__
+#define ARCHSYSNAME "apple-macosx"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define NO_NLS
+#endif
+
+#endif /* _POWER */
+
+/*===========================================================================*/
+/* VAX platforms */
+
+#ifdef __vax__
+
+#define ARCHPRNAME "vax"
+
+/*---------------------------------------------------------------------------*/
+/* VAX with Ultrix: */
+
+#ifdef ultrix
+#define ARCHSYSNAME "dec-ultrix"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define VAXFLOAT
+#define NEEDS_STRDUP
+#define BKOKEN_SPRINTF
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#define NOLONGLONG
+#define NO_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* VAX with NetBSD 1.x:
+
+ quite a normal 32-Bit-UNIX system - apart from the float format... */
+
+#ifdef __NetBSD__
+#define ARCHSYSNAME "vax-netbsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define VAXFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+#endif /* vax */
+
+#ifdef __aarch64__
+
+#define ARCHPRNAME "aarch64"
+
+/*---------------------------------------------------------------------------*/
+/* AArch64 with Linux and GCC: */
+
+#ifdef __linux__
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long Integ64;
+typedef unsigned long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+#endif /* __aarch64__ */
+
+/*===========================================================================*/
+/* DEC Alpha platforms */
+
+#ifdef __alpha
+
+#define ARCHPRNAME "alpha"
+
+/*---------------------------------------------------------------------------*/
+/* DEC Alpha with Digital UNIX and DEC C / GCC:
+
+ Alpha is a 64 bit machine, so we do not need to use extra longs
+ OSF has full NLS support */
+
+#ifdef __osf__
+#define ARCHSYSNAME "dec-osf"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long Integ64;
+typedef unsigned long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* DEC Alpha with Linux and GCC:
+
+ see OSF... */
+
+#ifdef __linux__
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long Integ64;
+typedef unsigned long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* DEC Alpha with NetBSD and GCC:
+
+ see OSF... */
+
+#ifdef __NetBSD__
+#define ARCHSYSNAME "unknown-netbsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long Integ64;
+typedef unsigned long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+#ifdef __FreeBSD__
+#define ARCHSYSNAME "unknown-freebsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long Integ64;
+typedef unsigned long Card64;
+#define HAS64
+#define NO_NLS
+#endif
+
+#endif /* __alpha */
+
+/*===========================================================================*/
+/* Intel i386 platforms */
+
+#ifdef __i386
+
+#define ARCHPRNAME "i386"
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with NetBSD 1. and GCC: (tested on 1.5.3)
+
+ principally, a normal 32-bit UNIX */
+
+#ifdef __NetBSD__
+#define ARCHSYSNAME "i386-netbsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with Linux and GCC:
+
+ principally, a normal 32-bit *NIX */
+
+#ifdef __linux__
+
+/* no long long data type if C89 is used */
+
+#if (defined __STDC__) && (!defined __STDC_VERSION__)
+# define NOLONGLONG
+#endif
+
+#define ARCHSYSNAME "unknown-linux"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#ifndef NOLONGLONG
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#endif /* !NOLONGLONG */
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with FreeBSD and GCC:
+
+ principally, a normal 32-bit *NIX */
+
+#ifdef __FreeBSD__
+#define ARCHSYSNAME "unknown-freebsd"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define NO_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with Darwin and GCC:
+ principally, a normal 32-bit *NIX */
+
+#ifdef __APPLE__
+#define ARCHSYSNAME "apple-osx"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with WIN32 and Cygnus GCC:
+
+ well, not really a UNIX... */
+
+#ifdef _WIN32
+
+/* no long long data type if C89 is used */
+
+#if (defined __STDC__) && (!defined __STDC_VERSION__)
+# define NOLONGLONG
+#endif
+
+#define ARCHSYSNAME "unknown-win32"
+#define DEFSMADE
+#define OPENRDMODE "rb"
+#define OPENWRMODE "wb"
+#define OPENUPMODE "rb+"
+#define IEEEFLOAT
+#define SLASHARGS
+#define PATHSEP '\\'
+#define SPATHSEP "\\"
+#define DIRSEP ';'
+#define SDIRSEP ";"
+#define DRSEP ':'
+#define SDRSEP ":"
+#define NULLDEV "NUL"
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#ifndef NOLONGLONG
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+# define HAS64
+#endif
+#define W32_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with OS/2 and emx-GCC:
+
+ well, not really a UNIX... */
+
+#ifdef __EMX__
+#define ARCHSYSNAME "unknown-os2"
+#define DEFSMADE
+#define OPENRDMODE "rb"
+#define OPENWRMODE "wb"
+#define OPENUPMODE "rb+"
+#define IEEEFLOAT
+#define SLASHARGS
+#define PATHSEP '\\'
+#define SPATHSEP "\\"
+#define DIRSEP ';'
+#define SDIRSEP ";"
+#define DRSEP ':'
+#define SDRSEP ":"
+#define NULLDEV "NUL"
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define OS2_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with OS/2 and IBMC:
+
+well, not really a UNIX... */
+
+#ifdef __IBMC__
+#define DEFSMADE
+#define NODUP
+#define OPENRDMODE "rb"
+#define OPENWRMODE "wb"
+#define OPENUPMODE "rb+"
+#define IEEEFLOAT
+#define SLASHARGS
+#define PATHSEP '\\'
+#define SPATHSEP "\\"
+#define DRSEP ':'
+#define SDRSEP ":"
+#define NULLDEV "NUL"
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#define NOLONGLONG
+#define OS2_NLS
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Intel x86 with MS-DOS and Borland-C:
+
+ well, not really a UNIX...
+ assure we get a usable memory model */
+
+#ifdef __MSDOS__
+#ifdef __TURBOC__
+#ifndef __LARGE__
+#error Wrong memory model - use large!
+#endif
+#undef ARCHPRNAME
+#ifdef __DPMI16__
+#define ARCHPRNAME "i286"
+#define ARCHSYSNAME "unknown-dpmi"
+#else
+#define ARCHPRNAME "i86"
+#define ARCHSYSNAME "unknown-msdos"
+#endif
+#define CKMALLOC
+#define HEAPRESERVE 4096
+#define DEFSMADE
+#define OPENRDMODE "rb"
+#define OPENWRMODE "wb"
+#define OPENUPMODE "rb+"
+#define IEEEFLOAT
+#define SLASHARGS
+#define PATHSEP '\\'
+#define SPATHSEP "\\"
+#define DIRSEP ';'
+#define SDIRSEP ";"
+#define DRSEP ':'
+#define SDRSEP ":"
+#define NULLDEV "NUL"
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed long Integ32;
+#define PRIInteg32 "ld"
+typedef unsigned long Card32;
+#define NOLONGLONG
+#define DOS_NLS
+#define __PROTOS__
+#undef UNUSED
+#define UNUSED(x) (void)x
+#endif
+#endif
+
+#endif /* __i386 */
+
+
+/*===========================================================================*/
+/* Intel x86_64 platforms */
+
+#if (defined __k8__) || (defined __x86_64) || (defined __x86_64__)
+
+#define ARCHPRNAME "x86_64"
+
+/*---------------------------------------------------------------------------*/
+/* x86-64/amd64 with Linux/FreeBSD, OSX and GCC:
+
+ Principally, a normal *NIX. */
+
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
+
+/* no long long data type if C89 is used */
+
+#if (defined __STDC__) && (!defined __STDC_VERSION__)
+# define NOLONGLONG
+#endif
+
+#ifdef __linux__
+#define ARCHSYSNAME "unknown-linux"
+#elif defined __FreeBSD__
+#define ARCHSYSNAME "unknown-freebsd"
+#else
+#define ARCHSYSNAME "apple-osx"
+#endif
+
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long Integ64;
+typedef unsigned long Card64;
+#define HAS64
+#define LOCALE_NLS
+
+#endif /* __linux__ || __FreeBSD__ || __APPLE__ */
+
+/*---------------------------------------------------------------------------*/
+/* Intel i386 with WIN32 and MinGW:
+
+ Well, not really a UNIX...note that in contrast to Unix-like systems,
+ the size of 'long' remains 32 bit. One still has to use 'long long' to
+ get 64 bits. */
+
+#ifdef _WIN32
+
+/* no long long data type if C89 is used */
+
+#if (defined __STDC__) && (!defined __STDC_VERSION__)
+# define NOLONGLONG
+#endif
+
+#define ARCHSYSNAME "unknown-win64"
+#define DEFSMADE
+#define OPENRDMODE "rb"
+#define OPENWRMODE "wb"
+#define OPENUPMODE "rb+"
+#define IEEEFLOAT
+#define SLASHARGS
+#define PATHSEP '\\'
+#define SPATHSEP "\\"
+#define DIRSEP ';'
+#define SDIRSEP ";"
+#define DRSEP ':'
+#define SDRSEP ":"
+#define NULLDEV "NUL"
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+#ifndef NOLONGLONG
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+# define HAS64
+#endif
+#define NO_NLS
+
+#endif /* _WIN32 */
+
+#endif /* __k8__ || __x86_64 || __x86_64__ */
+
+/*===========================================================================*/
+/* ARM platform */
+
+#ifdef __arm
+
+#define ARCHPRNAME "arm"
+
+/*---------------------------------------------------------------------------*/
+/* ARM linux with GCC */
+
+#ifdef __linux__
+#define ARCHSYSNAME "unknown-linux-arm"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif /* __linux__ */
+
+/*---------------------------------------------------------------------------*/
+/* Psion PDA (ARM cpu) with SymbianOS Epoc32 rel.5 and installed epocemx-GCC:
+
+ well, not really a UNIX... */
+
+#ifdef __EPOC32__
+
+#ifdef __EPOCEMX__
+#define ARCHSYSNAME "psion-epoc32-epocemx"
+#define DEFSMADE
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ16;
+typedef unsigned short Card16;
+#define HAS16
+typedef signed int Integ32;
+#define PRIInteg32 "d"
+typedef unsigned int Card32;
+typedef signed long long Integ64;
+typedef unsigned long long Card64;
+#define HAS64
+#define NO_NLS
+#endif /* __EPOCEMX__ */
+
+
+#endif /* __EPOC32__ */
+
+#endif /* __arm */
+
+/*===========================================================================*/
+/* Misc... */
+
+/*---------------------------------------------------------------------------*/
+/* Just for curiosity, it won't work without 16 bit int's... */
+
+#ifdef _CRAYMPP
+#define OPENRDMODE "r"
+#define OPENWRMODE "w"
+#define OPENUPMODE "r+"
+#define IEEEFLOAT
+typedef signed char Integ8;
+typedef unsigned char Card8;
+typedef signed short Integ32;
+#define PRIInteg32 "d"
+typedef unsigned short Card32;
+typedef signed int Integ64;
+typedef unsigned int Card64;
+#define HAS64
+#define LOCALE_NLS
+#endif
+
+/*===========================================================================*/
+/* Post-Processing: check for definition, add defaults */
+
+
+#ifdef DEFSMADE
+#ifndef PATHSEP
+#define PATHSEP '/'
+#define SPATHSEP "/"
+#define DIRSEP ':'
+#define SDIRSEP ":"
+#endif
+#ifndef NULLDEV
+#define NULLDEV "/dev/null"
+#endif
+#else
+#error "your platform so far is not included in AS's header files!"
+#error "please edit sysdefs.h!"
+#endif
+
+#ifdef CKMALLOC
+#define malloc(s) ckmalloc(s)
+#define realloc(p,s) ckrealloc(p,s)
+
+extern void *ckmalloc(size_t s);
+
+extern void *ckrealloc(void *p, size_t s);
+#endif
+#endif /* _SYSDEFS_H */
--- /dev/null
+#ifndef _TEMPRESULT_H
+#define _TEMPRESULT_H
+/* tempresult.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* internal holder for int/float/string */
+/* */
+/*****************************************************************************/
+
+#include <stddef.h>
+
+#include "datatypes.h"
+#include "nonzstring.h"
+#include "symflags.h"
+#include "symbolsize.h"
+
+typedef enum
+{
+ TempNone = 0,
+ TempInt = 1,
+ TempFloat = 2,
+ TempString = 4,
+ TempReg = 8,
+ TempAll = 15
+} TempType;
+
+struct sRelocEntry;
+struct as_dynstr;
+
+typedef unsigned tRegInt;
+
+typedef void (*DissectRegProc)(
+#ifdef __PROTOS__
+char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize
+#endif
+);
+
+typedef struct sRegDescr
+{
+ DissectRegProc Dissect;
+ tRegInt Reg;
+} tRegDescr;
+
+struct sTempResult
+{
+ TempType Typ;
+ tSymbolFlags Flags;
+ unsigned AddrSpaceMask;
+ tSymbolSize DataSize;
+ struct sRelocEntry *Relocs;
+ union
+ {
+ LargeInt Int;
+ Double Float;
+ as_nonz_dynstr_t str;
+ tRegDescr RegDescr;
+ } Contents;
+};
+typedef struct sTempResult TempResult;
+
+extern void as_tempres_ini(TempResult *p_res);
+
+extern void as_tempres_free(TempResult *p_res);
+
+extern void as_tempres_set_none(TempResult *p_res);
+
+extern void as_tempres_set_int(TempResult *p_res, LargeInt value);
+
+extern void as_tempres_set_float(TempResult *p_res, Double value);
+
+extern void as_tempres_set_str(TempResult *p_res, const as_nonz_dynstr_t *p_value);
+
+extern void as_tempres_set_str_raw(TempResult *p_res, const char *p_value, size_t len);
+
+extern void as_tempres_set_c_str(TempResult *p_res, const char *p_value);
+
+extern void as_tempres_set_reg(TempResult *p_res, const tRegDescr *p_value);
+
+void as_tempres_copy_value(TempResult *p_dest, const TempResult *p_src);
+
+extern void as_tempres_copy(TempResult *p_dest, const TempResult *p_src);
+
+extern int as_tempres_cmp(const TempResult *p_res1, const TempResult *p_res2);
+
+extern int TempResultToFloat(TempResult *pResult);
+
+extern int as_tempres_append_dynstr(struct as_dynstr *p_dest, const TempResult *pResult);
+
+#endif /* _TEMPRESULT_H */
--- /dev/null
+#ifndef _TREES_H
+#define _TREES_H
+/* trees.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Tree management */
+/* */
+/*****************************************************************************/
+
+extern Boolean BalanceTrees;
+
+typedef struct _TTree
+{
+ struct _TTree *Left, *Right;
+ ShortInt Balance;
+ char *Name;
+ LongInt Attribute;
+} TTree, *PTree;
+
+typedef void (*TTreeCallback)(PTree Node, void *pData);
+
+typedef Boolean (*TTreeAdder)(PTree *PDest, PTree Neu, void *pData);
+
+extern void IterTree(PTree Tree, TTreeCallback Callback, void *pData);
+
+extern void GetTreeDepth(PTree Tree, LongInt *pMin, LongInt *pMax);
+
+extern void DestroyTree(PTree *Tree, TTreeCallback Callback, void *pData);
+
+extern void DumpTree(PTree Tree);
+
+extern PTree SearchTree(PTree Tree, char *Name, LongInt Attribute);
+
+extern Boolean EnterTree(PTree *PDest, PTree Neu, TTreeAdder Adder, void *pData);
+
+#endif /* _TREES_H */
--- /dev/null
+#ifndef _VERSION_H
+#define _VERSION_H
+/* version.h */
+/*****************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
+/* */
+/* AS-Portierung */
+/* */
+/* Lagert die Versionsnummer */
+/* */
+/*****************************************************************************/
+
+extern const char *Version;
+extern LongInt VerNo;
+
+extern const char *InfoMessCopyright;
+
+extern LongInt Magic;
+
+extern void version_init(void);
+
+#endif /* _VERSION_H */
rm -f $(SRCASX)*.o\r
rm -f $(SRCLNK)*.o\r
rm -f $(SRCMISC)*.o\r
+ rm -f $(SRCLSHIM)*.o\r
rm -f $(S19OS9)*.o\r
rm -f $(SRC1802)*.o\r
rm -f $(SRC2650)*.o\r
rm -f $(SRCASX)*.o\r
rm -f $(SRCLNK)*.o\r
rm -f $(SRCMISC)*.o\r
+ rm -f $(SRCLSHIM)*.o\r
rm -f $(S19OS9)*.o\r
rm -f $(SRC1802)*.o\r
rm -f $(SRC2650)*.o\r
SRCASX:= $(ASXBAS)asxxsrc/\r
SRCLNK:= $(ASXBAS)linksrc/\r
SRCMISC:= $(ASXBAS)asxxmisc/\r
+SRCLSHIM:= $(ASXBAS)aslshim/\r
SRCS19OS9:= $(ASXBAS)s19os9/\r
DSTEXE:= $(ASXBAS)asxmak/linux/exe/\r
\r
.SUFFIXES: .c .o\r
\r
%.o: %.c\r
- $(CC) $(CCFLAGS) -I$(SRCMISC) -I$(SRCASX) -c $< -o $@\r
+ $(CC) $(CCFLAGS) -I$(SRCLSHIM) -I$(SRCMISC) -I$(SRCASX) -c $< -o $@\r
\r
\r
ASXX = asdata.o asexpr.o aslex.o aslist.o \\r
$(ASXXSRC): $(SRCMISC)alloc.h $(SRCASX)asxxxx.h\r
\r
\r
+LSHIM = asmdef.c asmerr.c asmitree.c asmpars.c asmsub.c bpemu.c codevars.c \\r
+ cpulist.c dynstr.c errmsg.c intformat.c intpseudo.c natpseudo.c \\r
+ strcomp.c strutil.c\r
+\r
+LSHIMSRC = $(addprefix $(SRCLSHIM),$(LSHIM))\r
+\r
+$(LSHIMSRC): $(SRCLSHIM)addrspace.h $(SRCLSHIM)as.h $(SRCLSHIM)asmdebug.h \\r
+ $(SRCLSHIM)asmdef.h $(SRCLSHIM)asmerr.h $(SRCLSHIM)asmfnums.h \\r
+ $(SRCLSHIM)asmitree.h $(SRCLSHIM)asmpars.h \\r
+ $(SRCLSHIM)asmrelocs.h $(SRCLSHIM)asmstructs.h \\r
+ $(SRCLSHIM)asmsub.h $(SRCLSHIM)bpemu.h $(SRCLSHIM)chardefs.h \\r
+ $(SRCLSHIM)chunks.h $(SRCLSHIM)codepseudo.h \\r
+ $(SRCLSHIM)codevars.h $(SRCLSHIM)console.h \\r
+ $(SRCLSHIM)cppops.h $(SRCLSHIM)cpulist.h \\r
+ $(SRCLSHIM)datatypes.h $(SRCLSHIM)dynstr.h \\r
+ $(SRCLSHIM)endian.h $(SRCLSHIM)errmsg.h \\r
+ $(SRCLSHIM)fileformat.h $(SRCLSHIM)function.h \\r
+ $(SRCLSHIM)ieeefloat.h $(SRCLSHIM)intformat.h \\r
+ $(SRCLSHIM)intpseudo.h $(SRCLSHIM)ioerrs.h \\r
+ $(SRCLSHIM)lstmacroexp.h $(SRCLSHIM)math64.h \\r
+ $(SRCLSHIM)natpseudo.h $(SRCLSHIM)nlmessages.h \\r
+ $(SRCLSHIM)nls.h $(SRCLSHIM)nonzstring.h \\r
+ $(SRCLSHIM)onoff_common.h $(SRCLSHIM)operator.h \\r
+ $(SRCLSHIM)pascstyle.h $(SRCLSHIM)stdhandl.h \\r
+ $(SRCLSHIM)stdinc.h $(SRCLSHIM)strcomp.h \\r
+ $(SRCLSHIM)stringlists.h $(SRCLSHIM)strutil.h \\r
+ $(SRCLSHIM)symbolsize.h $(SRCLSHIM)symflags.h \\r
+ $(SRCLSHIM)sysdefs.h $(SRCLSHIM)tempresult.h \\r
+ $(SRCLSHIM)trees.h $(SRCLSHIM)version.h \r
+\r
+\r
####################################################################\r
# AS1802\r
####################################################################\r
# ASLCOP8\r
####################################################################\r
\r
-ASLCOP8 = lcop8mch.o lcop8pst.o\r
+ASLCOP8 = codecop8.o lcop8mch.o lcop8pst.o\r
\r
ASLCOP8SRC = $(addprefix $(SRCLCOP8),$(ASLCOP8))\r
\r
-$(ASLCOP8SRC): $(SRCMISC)alloc.h $(SRCASX)asxxxx.h $(SRCLCOP8)lcop8.h\r
+$(ASLCOP8SRC): $(SRCMISC)alloc.h $(SRCASX)asxxxx.h $(SRCLCOP8)lcop8.h \\r
+ $(SRCLCOP8)codecop8.h\r
\r
-aslcop8: $(ASXXSRC) $(ASLCOP8SRC)\r
- $(LD) $(LDFLAGS) $(ASXXSRC) $(ASLCOP8SRC) -o aslcop8\r
+aslcop8: $(ASXXSRC) $(LSHIMSRC) $(ASLCOP8SRC)\r
+ $(LD) $(LDFLAGS) $(ASXXSRC) $(LSHIMSRC) $(ASLCOP8SRC) -o aslcop8\r
cp aslcop8 $(DSTEXE)aslcop8\r
strip $(DSTEXE)aslcop8\r
chmod 755 $(DSTEXE)aslcop8\r