From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- asmsub.c | 1526 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1526 insertions(+) create mode 100644 asmsub.c (limited to 'asmsub.c') diff --git a/asmsub.c b/asmsub.c new file mode 100644 index 0000000..2569d95 --- /dev/null +++ b/asmsub.c @@ -0,0 +1,1526 @@ +/* asmsub.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Unterfunktionen, vermischtes */ +/* */ +/* Historie: 4. 5.1996 Grundsteinlegung */ +/* 13. 8.1997 KillBlanks-Funktionen nach stringutil.c geschoben */ +/* 26. 6.1998 Fehlermeldung Codepage nicht gefunden */ +/* 7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars */ +/* 17. 8.1998 Unterfunktion zur Buchhaltung Adressbereiche */ +/* 1. 9.1998 FloatString behandelte Sonderwerte nicht korrekt */ +/* 13. 9.1998 Prozessorliste macht Zeilenvorschub nach 6 Namen */ +/* 14.10.1998 Fehlerzeilen mit > > > */ +/* 30. 1.1999 Formatstrings maschinenunabhaengig gemacht */ +/* 18. 4.1999 Ausgabeliste Sharefiles */ +/* 13. 7.1999 Fehlermeldungen relokatible Symbole */ +/* 13. 9.1999 I/O-Fehler 25 ignorieren */ +/* 5.11.1999 ExtendErrors ist jetzt ShortInt */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include +#include + +#include "version.h" +#include "endian.h" +#include "stdhandl.h" +#include "nls.h" +#include "nlmessages.h" +#include "as.rsc" +#include "strutil.h" +#include "stringlists.h" +#include "chunks.h" +#include "ioerrs.h" +#include "asmdef.h" +#include "asmpars.h" +#include "asmdebug.h" +#include "as.h" + +#include "asmsub.h" + + +#ifdef __TURBOC__ +#ifdef __DPMI16__ +#define STKSIZE 40960 +#else +#define STKSIZE 49152 +#endif +#endif + + +Word ErrorCount,WarnCount; +static StringList CopyrightList, OutList, ShareOutList; + +static LongWord StartStack,MinStack,LowStack; + +/****************************************************************************/ +/* Modulinitialisierung */ + + void AsmSubInit(void) +BEGIN + PageLength=60; PageWidth=0; + ErrorCount=0; WarnCount=0; +END + +/****************************************************************************/ +/* neuen Prozessor definieren */ + + CPUVar AddCPU(char *NewName, TSwitchProc Switcher) +BEGIN + PCPUDef Lauf,Neu; + char *p; + + Neu=(PCPUDef) malloc(sizeof(TCPUDef)); + Neu->Name=strdup(NewName); + /* kein UpString, weil noch nicht initialisiert ! */ + for (p=Neu->Name; *p!='\0'; p++) *p=toupper(*p); + Neu->SwitchProc=Switcher; + Neu->Next=Nil; + Neu->Number=Neu->Orig=CPUCnt; + + Lauf=FirstCPUDef; + if (Lauf==Nil) FirstCPUDef=Neu; + else + BEGIN + while (Lauf->Next!=Nil) Lauf=Lauf->Next; + Lauf->Next=Neu; + END + + return CPUCnt++; +END + + Boolean AddCPUAlias(char *OrigName, char *AliasName) +BEGIN + PCPUDef Lauf=FirstCPUDef,Neu; + + while ((Lauf!=Nil) AND (strcmp(Lauf->Name,OrigName)!=0)) Lauf=Lauf->Next; + + if (Lauf==Nil) return False; + else + BEGIN + Neu=(PCPUDef) malloc(sizeof(TCPUDef)); + Neu->Next=Nil; + Neu->Name=strdup(AliasName); + Neu->Number=CPUCnt++; + Neu->Orig=Lauf->Orig; + Neu->SwitchProc=Lauf->SwitchProc; + while (Lauf->Next!=Nil) Lauf=Lauf->Next; + Lauf->Next=Neu; + return True; + END +END + + void PrintCPUList(TSwitchProc NxtProc) +BEGIN + PCPUDef Lauf; + TSwitchProc Proc; + int cnt; + + Lauf=FirstCPUDef; Proc=NullProc; cnt=0; + while (Lauf!=Nil) + BEGIN + if (Lauf->Number==Lauf->Orig) + BEGIN + if ((Lauf->SwitchProc!=Proc) OR (cnt==7)) + BEGIN + Proc=Lauf->SwitchProc; printf("\n"); NxtProc(); cnt=0; + END + printf("%-10s",Lauf->Name); cnt++; + END + Lauf=Lauf->Next; + END + printf("\n"); NxtProc(); +END + + void ClearCPUList(void) +BEGIN + PCPUDef Save; + + while (FirstCPUDef!=Nil) + BEGIN + Save=FirstCPUDef; FirstCPUDef=Save->Next; + free(Save->Name); free(Save); + END +END + +/****************************************************************************/ +/* Copyrightlistenverwaltung */ + + void AddCopyright(char *NewLine) +BEGIN + AddStringListLast(&CopyrightList,NewLine); +END + + void WriteCopyrights(TSwitchProc NxtProc) +BEGIN + StringRecPtr Lauf; + + if (NOT StringListEmpty(CopyrightList)) + BEGIN + printf("%s\n",GetStringListFirst(CopyrightList,&Lauf)); NxtProc(); + while (Lauf!=Nil) + BEGIN + printf("%s\n",GetStringListNext(&Lauf)); NxtProc(); + END + END +END + +/*--------------------------------------------------------------------------*/ +/* ermittelt das erste/letzte Auftauchen eines Zeichens ausserhalb */ +/* "geschuetzten" Bereichen */ + +#if 0 + char *QuotPos(char *s, char Zeichen) +BEGIN + register int Cnt=0; + register char *i; + register char ch,Cmp2,Cmp3; + + for (i=s; (ch=*i)!='\0'; i++) + if (Cnt==0) + BEGIN + if (ch==Zeichen) return i; + else switch (ch) + BEGIN + case '"': + case '\'': Cmp2='\0'; Cmp3=ch; Cnt=1; break; + case '(': Cmp2='('; Cmp3=')'; Cnt=1; break; + case '[': Cmp2='['; Cmp3=']'; Cnt=1; break; + END + END + else + BEGIN + if (ch==Cmp2) Cnt++; + else if (ch==Cmp3) Cnt--; + END + + return Nil; +END +#else + char *QuotPos(char *s, char Zeichen) +BEGIN + register ShortInt Brack=0,AngBrack=0; + register char *i; + register LongWord Flag=0; + static Boolean First=True,Imp[256],Save; + + if (First) + BEGIN + memset(Imp,False,256); + Imp['"']=Imp['\'']=Imp['(']=Imp[')']=Imp['[']=Imp[']']=True; + First=False; + END + + Save=Imp[(unsigned char)Zeichen]; Imp[(unsigned char)Zeichen]=True; + for (i=s; *i!='\0'; i++) + if (Imp[(unsigned char)*i]) + BEGIN + if (*i==Zeichen) + BEGIN + if ((AngBrack|Brack|Flag)==0) + { Imp[(unsigned char)Zeichen]=Save; return i;} + END + else switch(*i) + BEGIN + case '"': if (((Brack|AngBrack)==0) AND ((Flag&2)==0)) Flag^=1; break; + case '\'':if (((Brack|AngBrack)==0) AND ((Flag&1)==0)) Flag^=2; break; + case '(': if ((AngBrack|Flag)==0) Brack++; break; + case ')': if ((AngBrack|Flag)==0) Brack--; break; + case '[': if ((Brack|Flag)==0) AngBrack++; break; + case ']': if ((Brack|Flag)==0) AngBrack--; break; + END + END + + Imp[(unsigned char)Zeichen]=Save; return Nil; +END +#endif + char *RQuotPos(char *s, char Zeichen) +BEGIN + ShortInt Brack=0,AngBrack=0; + char *i; + Boolean Quot=False,Paren=False; + + for (i=s+strlen(s)-1; i>=s; i--) + if (*i==Zeichen) + BEGIN + if ((AngBrack==0) AND (Brack==0) AND (NOT Paren) AND (NOT Quot)) return i; + END + else switch (*i) + BEGIN + case '"': if ((Brack==0) AND (AngBrack==0) AND (NOT Quot)) Paren=NOT Paren; break; + case '\'':if ((Brack==0) AND (AngBrack==0) AND (NOT Paren)) Quot=NOT Quot; break; + case ')': if ((AngBrack==0) AND (NOT Paren) AND (NOT Quot)) Brack++; break; + case '(': if ((AngBrack==0) AND (NOT Paren) AND (NOT Quot)) Brack--; break; + case ']': if ((Brack==0) AND (NOT Paren) AND (NOT Quot)) AngBrack++; break; + case '[': if ((Brack==0) AND (NOT Paren) AND (NOT Quot)) AngBrack--; break; + END + + return Nil; +END + +/*--------------------------------------------------------------------------*/ +/* ermittelt das erste Leerzeichen in einem String */ + + char *FirstBlank(char *s) +BEGIN + char *h,*Min=Nil; + + h=strchr(s,' '); + if (h!=Nil) if ((Min==Nil) OR (h=Source+slen)) + Trenner=Source+slen; + Save=(*Trenner); *Trenner='\0'; + strcpy(Left,Source); *Trenner=Save; + if (Trenner>=Source+slen) *Right='\0'; + else strcpy(Right,Trenner+1); +END + +/*--------------------------------------------------------------------------*/ +/* verbesserte Grossbuchstabenfunktion */ + +/* einen String in Grossbuchstaben umwandeln. Dabei Stringkonstanten in Ruhe */ +/* lassen */ + + void UpString(char *s) +BEGIN + char *z; + int hypquot=0; + + for (z=s; *z!='\0'; z++) + BEGIN + if ((*z=='\'') AND ((hypquot&2)==0)) hypquot^=1; + else if ((*z=='"') AND ((hypquot&1)==0)) hypquot^=2; + else if (hypquot==0) *z=UpCaseTable[(int)*z]; + END +END + +/****************************************************************************/ + + void TranslateString(char *s) +BEGIN + char *z; + + for (z=s; *z!='\0'; z++) *z=CharTransTable[((usint)(*z))&0xff]; +END + + ShortInt StrCmp(char *s1, char *s2, LongInt Hand1, LongInt Hand2) +BEGIN + int tmp; + + tmp=(*s1)-(*s2); + if (tmp==0) tmp=strcmp(s1,s2); + if (tmp==0) tmp=Hand1-Hand2; + if (tmp<0) return -1; + if (tmp>0) return 1; + return 0; +END + +/****************************************************************************/ +/* an einen Dateinamen eine Endung anhaengen */ + + void AddSuffix(char *s, char *Suff) +BEGIN + char *p,*z,*Part; + + p=Nil; + for (z=s; *z!='\0'; z++) if (*z=='\\') p=z; + Part=(p!=Nil)?(p):(s); + if (strchr(Part,'.')==Nil) strmaxcat(s,Suff,255); +END + + +/*--------------------------------------------------------------------------*/ +/* von einem Dateinamen die Endung loeschen */ + + void KillSuffix(char *s) +BEGIN + char *p,*z,*Part; + + p=Nil; + for (z=s; *z!='\0'; z++) if (*z=='\\') p=z; + Part=(p!=Nil)?(p):(s); Part=strchr(Part,'.'); + if (Part!=Nil) *Part='\0'; +END + +/*--------------------------------------------------------------------------*/ +/* Pfadanteil (Laufwerk+Verzeichnis) von einem Dateinamen abspalten */ + + char *PathPart(char *Name) +BEGIN + static String s; + char *p; + + strmaxcpy(s,Name,255); + + p=strrchr(Name,PATHSEP); +#ifdef DRSEP + if (p==Nil) p=strrchr(Name,DRSEP); +#endif + + if (p==Nil) *s='\0'; else s[1]='\0'; + + return s; +END + +/*--------------------------------------------------------------------------*/ +/* Namensanteil von einem Dateinamen abspalten */ + + char *NamePart(char *Name) +BEGIN + char *p=strrchr(Name,PATHSEP); + +#ifdef DRSEP + if (p==Nil) p=strrchr(Name,DRSEP); +#endif + + return (p==Nil)?(Name):(p+1); +END + +/****************************************************************************/ +/* eine Gleitkommazahl in einen String umwandeln */ + + char *FloatString(Double f) +BEGIN +#define MaxLen 18 + static String s; + char *p,*d; + sint n,ExpVal,nzeroes; + Boolean WithE,OK; + + /* 1. mit Maximallaenge wandeln, fuehrendes Vorzeichen weg */ + + sprintf(s,"%27.15e",f); + for (p=s; (*p==' ') OR (*p=='+'); p++); + if (p!=s) strcpy(s,p); + + /* 2. Exponenten soweit als moeglich kuerzen, evtl. ganz streichen */ + + p=strchr(s,'e'); + if (p==Nil) return s; + switch (*(++p)) + BEGIN + case '+': strcpy(p,p+1); break; + case '-': p++; break; + END + + while (*p=='0') strcpy(p,p+1); + WithE=(*p!='\0'); + if (NOT WithE) s[strlen(s)-1]='\0'; + + /* 3. Nullen am Ende der Mantisse entfernen, Komma bleibt noch */ + + if (WithE) p=strchr(s,'e'); else p=s+strlen(s); p--; + while (*p=='0') + BEGIN + strcpy(p,p+1); p--; + END + + /* 4. auf die gewuenschte Maximalstellenzahl begrenzen */ + + if (WithE) p=strchr(s,'e'); else p=s+strlen(s); + d=strchr(s,'.'); + n=p-d-1; + + /* 5. Maximallaenge ueberschritten ? */ + + if (strlen(s)>MaxLen) strcpy(d+(n-(strlen(s)-MaxLen)),d+n); + + /* 6. Exponentenwert berechnen */ + + if (WithE) + BEGIN + p=strchr(s,'e'); + ExpVal=ConstLongInt(p+1,&OK); + END + else + BEGIN + p=s+strlen(s); + ExpVal=0; + END + + /* 7. soviel Platz, dass wir den Exponenten weglassen und evtl. Nullen + anhaengen koennen ? */ + + if (ExpVal>0) + BEGIN + nzeroes=ExpVal-(p-strchr(s,'.')-1); /* = Zahl von Nullen, die anzuhaengen waere */ + + /* 7a. nur Kommaverschiebung erforderlich. Exponenten loeschen und + evtl. auch Komma */ + + if (nzeroes<=0) + BEGIN + *p='\0'; + d=strchr(s,'.'); strcpy(d,d+1); + if (nzeroes!=0) + BEGIN + memmove(s+strlen(s)+nzeroes+1,s+strlen(s)+nzeroes,-nzeroes); + s[strlen(s)-1+nzeroes]='.'; + END + END + + /* 7b. Es muessen Nullen angehaengt werden. Schauen, ob nach Loeschen von + Punkt und E-Teil genuegend Platz ist */ + + else + BEGIN + n=strlen(p)+1+(MaxLen-strlen(s)); /* = Anzahl freizubekommender Zeichen+Gutschrift */ + if (n>=nzeroes) + BEGIN + *p='\0'; d=strchr(s,'.'); strcpy(d,d+1); + d=s+strlen(s); + for (n=0; nTyp) + BEGIN + case TempInt: + strcpy(Dest,HexString(t->Contents.Int,1)); + if (WithSystem) + switch (ConstMode) + BEGIN + case ConstModeIntel : strcat(Dest,"H"); break; + case ConstModeMoto : strprep(Dest,"$"); break; + case ConstModeC : strprep(Dest,"0x"); break; + END + break; + case TempFloat: + strcpy(Dest,FloatString(t->Contents.Float)); break; + case TempString: + strcpy(Dest,t->Contents.Ascii); break; + default: strcpy(Dest,"???"); + END +END + +/****************************************************************************/ +/* Listingzaehler zuruecksetzen */ + + void ResetPageCounter(void) +BEGIN + int z; + + for (z=0; z<=ChapMax; z++) PageCounter[z]=0; + LstCounter=0; ChapDepth=0; +END + +/*--------------------------------------------------------------------------*/ +/* eine neue Seite im Listing beginnen */ + + void NewPage(ShortInt Level, Boolean WithFF) +BEGIN + ShortInt z; + String Header,s; + char Save; + + if (ListOn==0) return; + + LstCounter=0; + + if (ChapDepth<(Byte) Level) + BEGIN + memmove(PageCounter+(Level-ChapDepth),PageCounter,(ChapDepth+1)*sizeof(Word)); + for (z=0; z<=Level-ChapDepth; PageCounter[z++]=1); + ChapDepth=Level; + END + for (z=0; z<=Level-1; PageCounter[z++]=1); + PageCounter[Level]++; + + if (WithFF) + BEGIN + errno=0; fprintf(LstFile,"%c",Char_FF); ChkIO(10002); + END + + sprintf(Header," AS V%s%s%s",Version,getmessage(Num_HeadingFileNameLab),NamePart(SourceFile)); + if ((strcmp(CurrFileName,"INTERNAL")!=0) AND (strcmp(NamePart(CurrFileName),NamePart(SourceFile))!=0)) + BEGIN + strmaxcat(Header,"(",255); + strmaxcat(Header,NamePart(CurrFileName),255); + strmaxcat(Header,")",255); + END + strmaxcat(Header,getmessage(Num_HeadingPageLab),255); + + for (z=ChapDepth; z>=0; z--) + BEGIN + sprintf(s, IntegerFormat, PageCounter[z]); + strmaxcat(Header,s,255); + if (z!=0) strmaxcat(Header,".",255); + END + + strmaxcat(Header," - ",255); + NLS_CurrDateString(s); strmaxcat(Header,s,255); + strmaxcat(Header," ",255); + NLS_CurrTimeString(False,s); strmaxcat(Header,s,255); + + if (PageWidth!=0) + while (strlen(Header)>PageWidth) + BEGIN + Save=Header[PageWidth]; Header[PageWidth]='\0'; + errno=0; fprintf(LstFile,"%s\n",Header); ChkIO(10002); + Header[PageWidth]=Save; strcpy(Header,Header+PageWidth); + END + errno=0; fprintf(LstFile,"%s\n",Header); ChkIO(10002); + + if (PrtTitleString[0]!='\0') + BEGIN + errno=0; fprintf(LstFile,"%s\n",PrtTitleString); ChkIO(10002); + END + + errno=0; fprintf(LstFile,"\n\n"); ChkIO(10002); +END + + +/*--------------------------------------------------------------------------*/ +/* eine Zeile ins Listing schieben */ + + void WrLstLine(char *Line) +BEGIN + int LLength; + char bbuf[2500]; + String LLine; + int blen=0,hlen,z,Start; + + if (ListOn==0) return; + + if (PageLength==0) + BEGIN + errno=0; fprintf(LstFile,"%s\n",Line); ChkIO(10002); + END + else + BEGIN + if ((PageWidth==0) OR ((strlen(Line)<<3) > >"); + strmaxcat(h,p=GetErrorPos(),255); free(p); + if (NOT Warning) + BEGIN + strmaxcat(h,getmessage(Num_ErrName),255); + strmaxcat(h,Add,255); + strmaxcat(h,": ",255); + ErrorCount++; + END + else + BEGIN + strmaxcat(h,getmessage(Num_WarnName),255); + strmaxcat(h,Add,255); + strmaxcat(h,": ",255); + WarnCount++; + END + + if ((strcmp(LstName, "/dev/null") != 0) AND (NOT Fatal)) + BEGIN + strmaxcpy(h2, h, 255); strmaxcat(h2, Message, 255); WrLstLine(h2); + if ((ExtendErrors > 0) AND (*ExtendError != '\0')) + BEGIN + sprintf(h2, "> > > %s", ExtendError); WrLstLine(h2); + END + if (ExtendErrors > 1) + BEGIN + sprintf(h2, "> > > %s", OneLine); WrLstLine(h2); + END + END + + ForceErrorOpen(); + if ((strcmp(LstName, "!1")!=0) OR (Fatal)) + BEGIN + errfile = (ErrorFile == Nil) ? stdout : ErrorFile; + fprintf(errfile, "%s%s%s\n", h, Message, ClrEol); + if ((ExtendErrors > 0) AND (*ExtendError != '\0')) + fprintf(errfile, "> > > %s%s\n", ExtendError, ClrEol); + if (ExtendErrors > 1) + fprintf(errfile, "> > > %s%s\n", OneLine, ClrEol); + END + *ExtendError = '\0'; + + if (Fatal) + BEGIN + fprintf((ErrorFile==Nil)?stdout:ErrorFile,"%s\n",getmessage(Num_ErrMsgIsFatal)); + EmergencyStop(); + exit(3); + END +END + +/*--------------------------------------------------------------------------*/ +/* eine Fehlermeldung ueber Code ausgeben */ + + static void WrErrorNum(Word Num) +BEGIN + String h; + char Add[11]; + int msgno; + + if ((NOT CodeOutput) AND (Num==1200)) return; + + if ((SuppWarns) AND (Num<1000)) return; + + switch (Num) + BEGIN + case 0: msgno=Num_ErrMsgUselessDisp; break; + case 10: msgno=Num_ErrMsgShortAddrPossible; break; + case 20: msgno=Num_ErrMsgShortJumpPossible; break; + case 30: msgno=Num_ErrMsgNoShareFile; break; + case 40: msgno=Num_ErrMsgBigDecFloat; break; + case 50: msgno=Num_ErrMsgPrivOrder; break; + case 60: msgno=Num_ErrMsgDistNull; break; + case 70: msgno=Num_ErrMsgWrongSegment; break; + case 75: msgno=Num_ErrMsgInAccSegment; break; + case 80: msgno=Num_ErrMsgPhaseErr; break; + case 90: msgno=Num_ErrMsgOverlap; break; + case 100: msgno=Num_ErrMsgNoCaseHit; break; + case 110: msgno=Num_ErrMsgInAccPage; break; + case 120: msgno=Num_ErrMsgRMustBeEven; break; + case 130: msgno=Num_ErrMsgObsolete; break; + case 140: msgno=Num_ErrMsgUnpredictable; break; + case 150: msgno=Num_ErrMsgAlphaNoSense; break; + case 160: msgno=Num_ErrMsgSenseless; break; + case 170: msgno=Num_ErrMsgRepassUnknown; break; + case 180: msgno=Num_ErrMsgAddrNotAligned; break; + case 190: msgno=Num_ErrMsgIOAddrNotAllowed; break; + case 200: msgno=Num_ErrMsgPipeline; break; + case 210: msgno=Num_ErrMsgDoubleAdrRegUse; break; + case 220: msgno=Num_ErrMsgNotBitAddressable; break; + case 230: msgno=Num_ErrMsgStackNotEmpty; break; + case 240: msgno=Num_ErrMsgNULCharacter; break; + case 250: msgno=Num_ErrMsgPageCrossing; break; + case 260: msgno=Num_ErrMsgWOverRange; break; + case 270: msgno=Num_ErrMsgNegDUP; break; + case 1000: msgno=Num_ErrMsgDoubleDef; break; + case 1010: msgno=Num_ErrMsgSymbolUndef; break; + case 1020: msgno=Num_ErrMsgInvSymName; break; + case 1090: msgno=Num_ErrMsgInvFormat; break; + case 1100: msgno=Num_ErrMsgUseLessAttr; break; + case 1105: msgno=Num_ErrMsgTooLongAttr; break; + case 1107: msgno=Num_ErrMsgUndefAttr; break; + case 1110: msgno=Num_ErrMsgWrongArgCnt; break; + case 1115: msgno=Num_ErrMsgWrongOptCnt; break; + case 1120: msgno=Num_ErrMsgOnlyImmAddr; break; + case 1130: msgno=Num_ErrMsgInvOpsize; break; + case 1131: msgno=Num_ErrMsgConfOpSizes; break; + case 1132: msgno=Num_ErrMsgUndefOpSizes; break; + case 1135: msgno=Num_ErrMsgInvOpType; break; + case 1140: msgno=Num_ErrMsgTooMuchArgs; break; + case 1150: msgno=Num_ErrMsgNoRelocs; break; + case 1155: msgno=Num_ErrMsgUnresRelocs; break; + case 1200: msgno=Num_ErrMsgUnknownOpcode; break; + case 1300: msgno=Num_ErrMsgBrackErr; break; + case 1310: msgno=Num_ErrMsgDivByZero; break; + case 1315: msgno=Num_ErrMsgUnderRange; break; + case 1320: msgno=Num_ErrMsgOverRange; break; + case 1325: msgno=Num_ErrMsgNotAligned; break; + case 1330: msgno=Num_ErrMsgDistTooBig; break; + case 1335: msgno=Num_ErrMsgInAccReg; break; + case 1340: msgno=Num_ErrMsgNoShortAddr; break; + case 1350: msgno=Num_ErrMsgInvAddrMode; break; + case 1351: msgno=Num_ErrMsgMustBeEven; break; + case 1355: msgno=Num_ErrMsgInvParAddrMode; break; + case 1360: msgno=Num_ErrMsgUndefCond; break; + case 1370: msgno=Num_ErrMsgJmpDistTooBig; break; + case 1375: msgno=Num_ErrMsgDistIsOdd; break; + case 1380: msgno=Num_ErrMsgInvShiftArg; break; + case 1390: msgno=Num_ErrMsgRange18; break; + case 1400: msgno=Num_ErrMsgShiftCntTooBig; break; + case 1410: msgno=Num_ErrMsgInvRegList; break; + case 1420: msgno=Num_ErrMsgInvCmpMode; break; + case 1430: msgno=Num_ErrMsgInvCPUType; break; + case 1440: msgno=Num_ErrMsgInvCtrlReg; break; + case 1445: msgno=Num_ErrMsgInvReg; break; + case 1450: msgno=Num_ErrMsgNoSaveFrame; break; + case 1460: msgno=Num_ErrMsgNoRestoreFrame; break; + case 1465: msgno=Num_ErrMsgUnknownMacArg; break; + case 1470: msgno=Num_ErrMsgMissEndif; break; + case 1480: msgno=Num_ErrMsgInvIfConst; break; + case 1483: msgno=Num_ErrMsgDoubleSection; break; + case 1484: msgno=Num_ErrMsgInvSection; break; + case 1485: msgno=Num_ErrMsgMissingEndSect; break; + case 1486: msgno=Num_ErrMsgWrongEndSect; break; + case 1487: msgno=Num_ErrMsgNotInSection; break; + case 1488: msgno=Num_ErrMsgUndefdForward; break; + case 1489: msgno=Num_ErrMsgContForward; break; + case 1490: msgno=Num_ErrMsgInvFuncArgCnt; break; + case 1495: msgno=Num_ErrMsgMissingLTORG; break; + case 1500: msgno= -1; + sprintf(h,"%s%s%s",getmessage(Num_ErrMsgNotOnThisCPU1), + MomCPUIdent,getmessage(Num_ErrMsgNotOnThisCPU2)); + break; + case 1505: msgno= -1; + sprintf(h,"%s%s%s",getmessage(Num_ErrMsgNotOnThisCPU3), + MomCPUIdent,getmessage(Num_ErrMsgNotOnThisCPU2)); + break; + case 1510: msgno=Num_ErrMsgInvBitPos; break; + case 1520: msgno=Num_ErrMsgOnlyOnOff; break; + case 1530: msgno=Num_ErrMsgStackEmpty; break; + case 1540: msgno=Num_ErrMsgNotOneBit; break; + case 1550: msgno=Num_ErrMsgMissingStruct; break; + case 1551: msgno=Num_ErrMsgOpenStruct; break; + case 1552: msgno=Num_ErrMsgWrongStruct; break; + case 1553: msgno=Num_ErrMsgPhaseDisallowed; break; + case 1554: msgno=Num_ErrMsgInvStructDir; break; + case 1600: msgno=Num_ErrMsgShortRead; break; + case 1610: msgno=Num_ErrMsgUnknownCodepage; break; + case 1700: msgno=Num_ErrMsgRomOffs063; break; + case 1710: msgno=Num_ErrMsgInvFCode; break; + case 1720: msgno=Num_ErrMsgInvFMask; break; + case 1730: msgno=Num_ErrMsgInvMMUReg; break; + case 1740: msgno=Num_ErrMsgLevel07; break; + case 1750: msgno=Num_ErrMsgInvBitMask; break; + case 1760: msgno=Num_ErrMsgInvRegPair; break; + case 1800: msgno=Num_ErrMsgOpenMacro; break; + case 1805: msgno=Num_ErrMsgEXITMOutsideMacro; break; + case 1810: msgno=Num_ErrMsgTooManyMacParams; break; + case 1815: msgno=Num_ErrMsgDoubleMacro; break; + case 1820: msgno=Num_ErrMsgFirstPassCalc; break; + case 1830: msgno=Num_ErrMsgTooManyNestedIfs; break; + case 1840: msgno=Num_ErrMsgMissingIf; break; + case 1850: msgno=Num_ErrMsgRekMacro; break; + case 1860: msgno=Num_ErrMsgUnknownFunc; break; + case 1870: msgno=Num_ErrMsgInvFuncArg; break; + case 1880: msgno=Num_ErrMsgFloatOverflow; break; + case 1890: msgno=Num_ErrMsgInvArgPair; break; + case 1900: msgno=Num_ErrMsgNotOnThisAddress; break; + case 1905: msgno=Num_ErrMsgNotFromThisAddress; break; + case 1910: msgno=Num_ErrMsgTargOnDiffPage; break; + case 1920: msgno=Num_ErrMsgCodeOverflow; break; + case 1925: msgno=Num_ErrMsgAdrOverflow; break; + case 1930: msgno=Num_ErrMsgMixDBDS; break; + case 1940: msgno=Num_ErrMsgNotInStruct; break; + case 1950: msgno=Num_ErrMsgParNotPossible; break; + case 1960: msgno=Num_ErrMsgInvSegment; break; + case 1961: msgno=Num_ErrMsgUnknownSegment; break; + case 1962: msgno=Num_ErrMsgUnknownSegReg; break; + case 1970: msgno=Num_ErrMsgInvString; break; + case 1980: msgno=Num_ErrMsgInvRegName; break; + case 1985: msgno=Num_ErrMsgInvArg; break; + case 1990: msgno=Num_ErrMsgNoIndir; break; + case 1995: msgno=Num_ErrMsgNotInThisSegment; break; + case 1996: msgno=Num_ErrMsgNotInMaxmode; break; + case 1997: msgno=Num_ErrMsgOnlyInMaxmode; break; + case 10001: msgno=Num_ErrMsgOpeningFile; break; + case 10002: msgno=Num_ErrMsgListWrError; break; + case 10003: msgno=Num_ErrMsgFileReadError; break; + case 10004: msgno=Num_ErrMsgFileWriteError; break; + case 10006: msgno=Num_ErrMsgHeapOvfl; break; + case 10007: msgno=Num_ErrMsgStackOvfl; break; + default : msgno= -1; + sprintf(h,"%s %d",getmessage(Num_ErrMsgIntError),(int) Num); + END + if (msgno!=-1) strmaxcpy(h,getmessage(msgno),255); + + if (((Num==1910) OR (Num==1370)) AND (NOT Repass)) JmpErrors++; + + if (NumericErrors) sprintf(Add,"#%d", (int)Num); + else *Add='\0'; + WrErrorString(h,Add,Num<1000,Num>=10000); +END + + void WrError(Word Num) +BEGIN + *ExtendError='\0'; WrErrorNum(Num); +END + + void WrXError(Word Num, char *Message) +BEGIN + strmaxcpy(ExtendError,Message,255); WrErrorNum(Num); +END + +/*--------------------------------------------------------------------------*/ +/* I/O-Fehler */ + + void ChkIO(Word ErrNo) +BEGIN + int io; + + io=errno; if ((io == 0) OR (io == 19) OR (io == 25)) return; + + WrXError(ErrNo,GetErrorMsg(io)); +END + +/*--------------------------------------------------------------------------*/ +/* Bereichsfehler */ + + Boolean ChkRange(LargeInt Value, LargeInt Min, LargeInt Max) +BEGIN + char s1[100],s2[100]; + + if (ValueMax) + BEGIN + strmaxcpy(s1,LargeString(Value),99); + strmaxcpy(s2,LargeString(Max),99); + strmaxcat(s1,">",99); strmaxcat(s1,s2,99); + WrXError(1320,s1); return False; + END + else return True; +END + +/****************************************************************************/ + + LargeWord ProgCounter(void) +BEGIN + return PCs[ActPC]; +END + +/*--------------------------------------------------------------------------*/ +/* aktuellen Programmzaehler mit Phasenverschiebung holen */ + + LargeWord EProgCounter(void) +BEGIN + return PCs[ActPC]+Phases[ActPC]; +END + + +/*--------------------------------------------------------------------------*/ +/* Granularitaet des aktuellen Segments holen */ + + Word Granularity(void) +BEGIN + return Grans[ActPC]; +END + +/*--------------------------------------------------------------------------*/ +/* Linstingbreite des aktuellen Segments holen */ + + Word ListGran(void) +BEGIN + return ListGrans[ActPC]; +END + +/*--------------------------------------------------------------------------*/ +/* pruefen, ob alle Symbole einer Formel im korrekten Adressraum lagen */ + + void ChkSpace(Byte Space) +BEGIN + Byte Mask=0xff-(1<RealLen; z++) + if (NChunk->Chunks[z].Start>=NewMin) + if (FMin>NChunk->Chunks[z].Start) + BEGIN + Found=True; FMin=NChunk->Chunks[z].Start; p=z; + END + + if (Found) + BEGIN + strmaxcat(BufferS,HexString(NChunk->Chunks[p].Start,0),255); + if (NChunk->Chunks[p].Length!=1) + BEGIN + strmaxcat(BufferS,"-",255); + strmaxcat(BufferS,HexString(NChunk->Chunks[p].Start+NChunk->Chunks[p].Length-1,0),255); + END + strmaxcat(BufferS,Blanks(19-strlen(BufferS)%19),255); + if (++BufferZ==4) + BEGIN + WrLstLine(BufferS); *BufferS='\0'; BufferZ=0; + END + NewMin=NChunk->Chunks[p].Start+NChunk->Chunks[p].Length; + END + END + while (Found); + + if (BufferZ!=0) WrLstLine(BufferS); +END + +/*--------------------------------------------------------------------------*/ +/* Listen ausgeben */ + + void PrintUseList(void) +BEGIN + int z,z2,l; + String s; + + for (z=1; z<=PCMax; z++) + if (SegChunks[z].Chunks!=Nil) + BEGIN + sprintf(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='A') AND (ch<='Z')) OR ((ch>='a') AND (ch<='z')) OR ((ch>='0') AND (ch<='9'))); +END + + void CompressLine(char *TokNam, Byte Num, char *Line) +BEGIN + int z,e,tlen,llen; + Boolean SFound; + + z=0; tlen=strlen(TokNam); llen=strlen(Line); + while (z<=llen-tlen) + BEGIN + e=z+strlen(TokNam); + SFound=(CaseSensitive) ? (strncmp(Line+z,TokNam,tlen)==0) + : (strncasecmp(Line+z,TokNam,tlen)==0); + if ( (SFound) + AND ((z==0) OR (NOT CompressLine_NErl(Line[z-1]))) + AND ((e>=strlen(Line)) OR (NOT CompressLine_NErl(Line[e]))) ) + BEGIN + strcpy(Line+z+1,Line+e); Line[z]=Num; + llen=strlen(Line); + END; + z++; + END +END + + void ExpandLine(char *TokNam, Byte Num, char *Line) +BEGIN + char *z; + + do + BEGIN + z=strchr(Line,Num); + if (z!=Nil) + BEGIN + strcpy(z,z+1); + strmaxins(Line,TokNam,z-Line,255); + END + END + while (z!=0); +END + + void KillCtrl(char *Line) +BEGIN + char *z; + + if (*(z=Line)=='\0') return; + do + BEGIN + if (*z=='\0'); + else if (*z==Char_HT) + BEGIN + strcpy(z,z+1); + strprep(z,Blanks(8-((z-Line)%8))); + END + else if ((*z&0xe0)==0) *z=' '; + z++; + END + while (*z!='\0'); +END + +/****************************************************************************/ +/* Buchhaltung */ + + void BookKeeping(void) +BEGIN + if (MakeUseList) + if (AddChunk(SegChunks+ActPC,ProgCounter(),CodeLen,ActPC==SegCode)) WrError(90); + if (DebugMode!=DebugNone) + BEGIN + AddSectionUsage(ProgCounter(),CodeLen); + AddLineInfo(InMacroFlag,CurrLine,CurrFileName,ActPC,PCs[ActPC],CodeLen); + END +END + +/****************************************************************************/ +/* Differenz zwischen zwei Zeiten mit Jahresueberlauf berechnen */ + + long DTime(long t1, long t2) +BEGIN + LongInt d; + + d=t2-t1; if (d<0) d+=(24*360000); + return (d>0) ? d : -d; +END + +/*--------------------------------------------------------------------------*/ +/* Zeit holen */ + +#ifdef __MSDOS__ + +#include + + long GTime(void) +BEGIN + static unsigned long *tick=MK_FP(0x40,0x6c); + double tmp=*tick; + + return ((long) (tmp*5.4931641)); +END + +#elif __IBMC__ + +#include +#define INCL_DOSDATETIME +#include + + long GTime(void) +BEGINM + 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); +END + +#else + +#include + + long GTime(void) +BEGIN + struct timeval tv; + + gettimeofday(&tv,Nil); + return (tv.tv_sec*100)+(tv.tv_usec/10000); +END + +#endif +/** +{****************************************************************************} +{ Heapfehler abfedern } + + FUNCTION MyHeapError(Size:Word):Integer; + Far; + BEGIN + IF Size<>0 THEN WrError(10006); + MyHeapError:=1; +END; +**/ +/*-------------------------------------------------------------------------*/ +/* Stackfehler abfangen - bis auf DOS nur Dummies */ + +#ifdef __TURBOC__ +#ifdef __DPMI16__ +#else +unsigned _stklen=STKSIZE; +unsigned _ovrbuffer=64*48; +#endif +#include +#endif + + void ChkStack(void) +BEGIN +#ifdef __TURBOC__ + LongWord avail=stackavail(); + if (avail