/* 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