dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/as.c

2986 lines
74 KiB
C

/* as.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Hauptmodul */
/* */
/* Historie: 4. 5.1996 Grundsteinlegung */
/* 24. 6.1998 Zeichenübersetzungstabellen */
/* 30. 6.1998 Ausgabe in MacPro-File auch wenn Zeile nur aus */
/* Kommentar oder Label besteht */
/* 18. 7.1998 IRPC-Statement */
/* 24. 7.1998 Debug-Modus NoICE */
/* 25. 7.1998 Formate glattgezogen */
/* 16. 8.1998 Datei-Adressbereiche zurücksetzen */
/* 17. 8.1998 InMacroFlag nach asmdef verschoben */
/* 19. 8.1998 BranchExt-Initialisierung */
/* 25. 8.1998 i960-Initialisierung */
/* 28. 8.1998 32-Bit-Listen gehen auch korrekt mit */
/* Codelaengen != 4*n um */
/* 30. 8.1998 uPD7720-Initialisierung */
/* Einrueckung fuer 'R' in Retracted-Zeilen im Listing */
/* war nicht korrekt */
/* 13. 9.1998 uPD77230-Initialisierung */
/* 30. 9.1998 SYM53C8xx-Initialisierung */
/* 3.12.1998 8008-Initialisierung */
/* 9. 1.1999 PCs erst nach Schreiben des Codes hochzaehlen */
/* ChkPC mit Adresse als Parameter */
/* 30. 1.1999 Formate maschinenunabhaengig gemacht */
/* 12. 2.1999 Compilerwarnungen beseitigt */
/* 25. 3.1999 SC14xxx-Initialisierung */
/* 17. 4.1999 CPU per Kommandozeile setzen */
/* 18. 4.1999 Ausgabeliste Sharefiles */
/* 4. 7.1999 F2MC8-Initialisierung */
/* 8. 8.1999 Externliste immer am Ende einer Zeile loeschen */
/* 14. 8.1999 Initialisierung ACE */
/* 5.11.1999 ExtendErrors, 2. Stufe */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include <setjmp.h>
#include "version.h"
#include "endian.h"
#include "bpemu.h"
#include "stdhandl.h"
#include "cmdarg.h"
#include "nls.h"
#include "nlmessages.h"
#include "as.rsc"
#include "ioerrs.h"
#include "strutil.h"
#include "stringlists.h"
#include "asmitree.h"
#include "chunks.h"
#include "asminclist.h"
#include "asmfnums.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmmac.h"
#include "asmif.h"
#include "asmcode.h"
#include "asmdebug.h"
#include "asmrelocs.h"
#include "asmallg.h"
#include "codepseudo.h"
#include "as.h"
#include "code68k.h"
#include "code56k.h"
#include "code601.h"
#include "codemcore.h"
#include "code68.h"
#include "code6805.h"
#include "code6809.h"
#include "code6812.h"
#include "code6816.h"
#include "codeh8_3.h"
#include "codeh8_5.h"
#include "code7000.h"
#include "code65.h"
#include "code7700.h"
#include "code4500.h"
#include "codem16.h"
#include "codem16c.h"
#include "code4004.h"
#include "code8008.h"
#include "code48.h"
#include "code51.h"
#include "code96.h"
#include "code85.h"
#include "code86.h"
#include "code960.h"
#include "code8x30x.h"
#include "codexa.h"
#include "codeavr.h"
#include "code29k.h"
#include "code166.h"
#include "codez80.h"
#include "codez8.h"
#include "code96c141.h"
#include "code90c141.h"
#include "code87c800.h"
#include "code47c00.h"
#include "code97c241.h"
#include "code16c5x.h"
#include "code16c8x.h"
#include "code17c4x.h"
#include "codest6.h"
#include "codest7.h"
#include "codest9.h"
#include "code6804.h"
#include "code3201x.h"
#include "code3202x.h"
#include "code3203x.h"
#include "code3205x.h"
#include "code3206x.h"
#include "code9900.h"
#include "codetms7.h"
#include "code370.h"
#include "codemsp.h"
#include "codescmp.h"
#include "codecop8.h"
#include "codesc14xxx.h"
#include "codeace.h"
#include "code78c10.h"
#include "code75k0.h"
#include "code78k0.h"
#include "code7720.h"
#include "code77230.h"
#include "code53c8xx.h"
#include "codefmc8.h"
#include "as1750.h"
/** Code21xx};**/
/**
VAR
ParCnt,k:Integer;
CPU:CPUVar;**/
static String FileMask;
static long StartTime,StopTime;
static Boolean GlobErrFlag;
static Boolean MasterFile;
/*=== Zeilen einlesen ======================================================*/
#if 0
#define dbgentry(str) printf("***enter %s\n",str);
#define dbgexit(str) printf("***exit %s\n",str);
#else
#define dbgentry(str) {}
#define dbgexit(str) {}
#endif
static void NULL_Restorer(PInputTag PInp)
BEGIN
END
static Boolean NULL_GetPos(PInputTag PInp, char *dest)
BEGIN
*dest='\0'; return False;
END
static void GenerateProcessor(PInputTag *PInp)
BEGIN
*PInp=(PInputTag) malloc(sizeof(TInputTag));
(*PInp)->IsMacro=False;
(*PInp)->Next=Nil;
(*PInp)->First=True;
(*PInp)->OrigDoLst=DoLst;
(*PInp)->StartLine=CurrLine;
(*PInp)->ParCnt=0; (*PInp)->ParZ=0;
InitStringList(&((*PInp)->Params));
(*PInp)->LineCnt=0; (*PInp)->LineZ=1;
(*PInp)->Lines=Nil;
(*PInp)->SpecName[0]='\0';
(*PInp)->IsEmpty=False;
(*PInp)->Buffer=Nil;
(*PInp)->Datei=Nil;
(*PInp)->IfLevel=SaveIFs();
(*PInp)->Restorer=NULL_Restorer;
(*PInp)->GetPos=NULL_GetPos;
END
/*=========================================================================*/
/* Listing erzeugen */
static void MakeList_Gen2Line(char *h, Word EffLen, Word *n)
BEGIN
int z,Rest;
Rest=EffLen-(*n); if (Rest>8) Rest=8; if (DontPrint) Rest=0;
for (z=0; z<(Rest>>1); z++)
BEGIN
strmaxcat(h,HexString(WAsmCode[(*n)>>1],4),255);
strmaxcat(h," ",255);
(*n)+=2;
END
if ((Rest&1)!=0)
BEGIN
strmaxcat(h,HexString(BAsmCode[*n],2),255);
strmaxcat(h," ",255);
(*n)++;
END
for (z=1; z<=(8-Rest)>>1; z++)
strmaxcat(h," ",255);
END
static void MakeList_Gen4Line(char *h, Word EffLen, Word *n)
BEGIN
int z,Rest,wr=0;
Rest=EffLen-(*n); if (Rest>8) Rest=8; if (DontPrint) Rest=0;
for (z=0; z<(Rest>>2); z++)
BEGIN
strmaxcat(h,HexString(DAsmCode[(*n)>>2],8),255);
strmaxcat(h," ",255);
(*n)+=4; wr+=9;
END
for (z=0; z<(Rest&3); z++)
BEGIN
strmaxcat(h,HexString(BAsmCode[(*n)++],2),255);
strmaxcat(h," ",255);
wr+=3;
END
strmaxcat(h,Blanks(20-wr),255);
END
static void MakeList(void)
BEGIN
String h,h2,Tmp;
Byte i,k;
Word n;
Word EffLen;
EffLen=CodeLen*Granularity();
if ((NOT ListToNull) AND (DoLst) AND ((ListMask&1)!=0) AND (NOT IFListMask()))
BEGIN
/* Zeilennummer / Programmzaehleradresse: */
if (IncDepth==0) strmaxcpy(h2," ",255);
else
BEGIN
sprintf(Tmp,IntegerFormat,IncDepth);
sprintf(h2,"(%s)",Tmp);
END
if ((ListMask&0x10)!=0)
BEGIN
sprintf(h,"%5d/",CurrLine); strmaxcat(h2,h,255);
END
strmaxcpy(h,h2,255); strmaxcat(h,HexBlankString(EProgCounter()-CodeLen,8),255);
strmaxcat(h,Retracted?" R ":" : ",255);
/* Extrawurst in Listing ? */
if (*ListLine!='\0')
BEGIN
strmaxcat(h,ListLine,255);
strmaxcat(h,Blanks(20-strlen(ListLine)),255);
strmaxcat(h,OneLine,255);
WrLstLine(h);
*ListLine='\0';
END
/* Code ausgeben */
else
switch (ActListGran)
BEGIN
case 4:
n=0; MakeList_Gen4Line(h,EffLen,&n);
strmaxcat(h,OneLine,255); WrLstLine(h);
if (NOT DontPrint)
while (n<EffLen)
BEGIN
strmaxcpy(h," ",255);
MakeList_Gen4Line(h,EffLen,&n);
WrLstLine(h);
END
break;
case 2:
n=0; MakeList_Gen2Line(h,EffLen,&n);
strmaxcat(h,OneLine,255); WrLstLine(h);
if (NOT DontPrint)
while (n<EffLen)
BEGIN
strmaxcpy(h," ",255);
MakeList_Gen2Line(h,EffLen,&n);
WrLstLine(h);
END
break;
default:
if ((TurnWords) AND (Granularity()!=ActListGran)) DreheCodes();
for (i=0; i<6; i++)
if ((NOT DontPrint) AND (EffLen>i))
BEGIN
strmaxcat(h,HexString(BAsmCode[i],2),255); strmaxcat(h," ",255);
END
else strmaxcat(h," ",255);
strmaxcat(h," ",255); strmaxcat(h,OneLine,255);
WrLstLine(h);
if ((EffLen>6) AND (NOT DontPrint))
BEGIN
EffLen-=6;
n=EffLen/6; if ((EffLen%6)==0) n--;
for (i=0; i<=n; i++)
BEGIN
strmaxcpy(h," ",255);
for (k=0; k<6; k++)
if (EffLen>i*6+k)
BEGIN
strmaxcat(h,HexString(BAsmCode[i*6+k+6],2),255);
strmaxcat(h," ",255);
END
WrLstLine(h);
END
END
if ((TurnWords) AND (Granularity()!=ActListGran)) DreheCodes();
END
END
END
/*=========================================================================*/
/* Makroprozessor */
/*-------------------------------------------------------------------------*/
/* allgemein gebrauchte Subfunktionen */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* werden gebraucht, um festzustellen, ob innerhalb eines Makrorumpfes weitere
Makroschachtelungen auftreten */
Boolean MacroStart(void)
BEGIN
return ((Memo("MACRO")) OR (Memo("IRP")) OR (Memo("IRPC")) OR (Memo("REPT")) OR (Memo("WHILE")));
END
Boolean MacroEnd(void)
BEGIN
return (Memo("ENDM"));
END
/*-------------------------------------------------------------------------*/
/* Dieser Einleseprozessor dient nur dazu, eine fehlerhafte Makrodefinition
bis zum Ende zu ueberlesen */
static void WaitENDM_Processor(void)
BEGIN
POutputTag Tmp;
if (MacroStart()) FirstOutputTag->NestLevel++;
else if (MacroEnd()) FirstOutputTag->NestLevel--;
if (FirstOutputTag->NestLevel<=-1)
BEGIN
Tmp=FirstOutputTag;
FirstOutputTag=Tmp->Next;
free(Tmp);
END
END
static void AddWaitENDM_Processor(void)
BEGIN
POutputTag Neu;
Neu=(POutputTag) malloc(sizeof(TOutputTag));
Neu->Processor=WaitENDM_Processor;
Neu->NestLevel=0;
Neu->Next=FirstOutputTag;
FirstOutputTag=Neu;
END
/*-------------------------------------------------------------------------*/
/* normale Makros */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Diese Routine leitet die Quellcodezeilen bei der Makrodefinition in den
Makro-Record um */
static void MACRO_OutProcessor(void)
BEGIN
POutputTag Tmp;
int z;
StringRecPtr l;
PMacroRec GMacro;
String s;
if ((MacroOutput) AND (FirstOutputTag->DoExport))
BEGIN
errno=0;
fprintf(MacroFile,"%s\n",OneLine);
ChkIO(10004);
END
if (MacroStart()) FirstOutputTag->NestLevel++;
else if (MacroEnd()) FirstOutputTag->NestLevel--;
if (FirstOutputTag->NestLevel!=-1)
BEGIN
strmaxcpy(s,OneLine,255); KillCtrl(s);
l=FirstOutputTag->Params;
for (z=1; z<=FirstOutputTag->Mac->ParamCount; z++)
CompressLine(GetStringListNext(&l),z,s);
if (HasAttrs) CompressLine(AttrName,ParMax+1,s);
AddStringListLast(&(FirstOutputTag->Mac->FirstLine),s);
END
if (FirstOutputTag->NestLevel==-1)
BEGIN
if (IfAsm)
BEGIN
AddMacro(FirstOutputTag->Mac,FirstOutputTag->PubSect,True);
if ((FirstOutputTag->DoGlobCopy) AND (SectionStack!=Nil))
BEGIN
GMacro=(PMacroRec) malloc(sizeof(MacroRec));
GMacro->Name=strdup(FirstOutputTag->GName);
GMacro->ParamCount=FirstOutputTag->Mac->ParamCount;
GMacro->FirstLine=DuplicateStringList(FirstOutputTag->Mac->FirstLine);
AddMacro(GMacro,FirstOutputTag->GlobSect,False);
END
END
else ClearMacroRec(&(FirstOutputTag->Mac));
Tmp=FirstOutputTag; FirstOutputTag=Tmp->Next;
ClearStringList(&(Tmp->Params)); free(Tmp);
END
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Hierher kommen bei einem Makroaufruf die expandierten Zeilen */
Boolean MACRO_Processor(PInputTag PInp, char *erg)
BEGIN
StringRecPtr Lauf;
int z;
Boolean Result;
Result=True;
Lauf=PInp->Lines; for (z=1; z<=PInp->LineZ-1; z++) Lauf=Lauf->Next;
strcpy(erg,Lauf->Content);
Lauf=PInp->Params;
for (z=1; z<=PInp->ParCnt; z++)
BEGIN
ExpandLine(Lauf->Content,z,erg);
Lauf=Lauf->Next;
END
if (HasAttrs) ExpandLine(PInp->SaveAttr,ParMax+1,erg);
CurrLine=PInp->StartLine;
InMacroFlag=True;
if (PInp->LineZ==1) PushLocHandle(GetLocHandle());
if (++(PInp->LineZ)>PInp->LineCnt) Result=False;
return Result;
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Initialisierung des Makro-Einleseprozesses */
static Boolean ReadMacro_SearchArg(char *Test, char *Comp, Boolean *Erg)
BEGIN
if (strcasecmp(Test,Comp)==0)
BEGIN
*Erg=True; return True;
END
else if ((strlen(Test)>2) AND (strncasecmp(Test,"NO",2)==0) AND (strcasecmp(Test+2,Comp)==0))
BEGIN
*Erg=False; return True;
END
else return False;
END
static Boolean ReadMacro_SearchSect(char *Test_O, char *Comp, Boolean *Erg, LongInt *Section)
BEGIN
char *p;
String Test,Sect;
strmaxcpy(Test,Test_O,255); KillBlanks(Test);
p=strchr(Test,':');
if (p==Nil) *Sect='\0';
else
BEGIN
strmaxcpy(Sect,p+1,255); *p='\0';
END
if ((strlen(Test)>2) AND (strncasecmp(Test,"NO",2)==0) AND (strcasecmp(Test+2,Comp)==0))
BEGIN
*Erg=False; return True;
END
else if (strcasecmp(Test,Comp)==0)
BEGIN
*Erg=True;
return (IdentifySection(Sect,Section));
END
else return False;
END
static void ReadMacro(void)
BEGIN
String PList;
PSaveSection RunSection;
PMacroRec OneMacro;
int z1,z2;
POutputTag Neu;
Boolean DoMacExp,DoPublic;
LongInt HSect;
Boolean ErrFlag;
CodeLen=0; ErrFlag=False;
/* Makronamen pruefen */
/* Definition nur im ersten Pass */
if (PassNo!=1) ErrFlag=True;
else if (NOT ExpandSymbol(LabPart)) ErrFlag=True;
else if (NOT ChkSymbName(LabPart))
BEGIN
WrXError(1020,LabPart); ErrFlag=True;
END
Neu=(POutputTag) malloc(sizeof(TOutputTag));
Neu->Processor=MACRO_OutProcessor;
Neu->NestLevel=0;
Neu->Params=Nil;
Neu->DoExport=False;
Neu->DoGlobCopy=False;
Neu->Next=FirstOutputTag;
/* Argumente ueberpruefen */
DoMacExp=LstMacroEx; DoPublic=False;
*PList='\0'; z2=0;
for (z1=1; z1<=ArgCnt; z1++)
if ((ArgStr[z1][0]=='{') AND (ArgStr[z1][strlen(ArgStr[z1])-1]=='}'))
BEGIN
strcpy(ArgStr[z1],ArgStr[z1]+1); ArgStr[z1][strlen(ArgStr[z1])-1]='\0';
if (ReadMacro_SearchArg(ArgStr[z1],"EXPORT",&(Neu->DoExport)));
else if (ReadMacro_SearchArg(ArgStr[z1],"EXPAND",&DoMacExp))
BEGIN
strmaxcat(PList,",",255); strmaxcat(PList,ArgStr[z1],255);
END
else if (ReadMacro_SearchSect(ArgStr[z1],"GLOBAL",&(Neu->DoGlobCopy),&(Neu->GlobSect)));
else if (ReadMacro_SearchSect(ArgStr[z1],"PUBLIC",&DoPublic,&(Neu->PubSect)));
else
BEGIN
WrXError(1465,ArgStr[z1]); ErrFlag=True;
END
END
else
BEGIN
strmaxcat(PList,",",255); strmaxcat(PList,ArgStr[z1],255); z2++;
if (NOT ChkMacSymbName(ArgStr[z1]))
BEGIN
WrXError(1020,ArgStr[z1]); ErrFlag=True;
END
AddStringListLast(&(Neu->Params),ArgStr[z1]);
END
/* Abbruch bei Fehler */
if (ErrFlag)
BEGIN
ClearStringList(&(Neu->Params));
free(Neu);
AddWaitENDM_Processor();
return;
END
/* Bei Globalisierung Namen des Extramakros ermitteln */
if (Neu->DoGlobCopy)
BEGIN
strmaxcpy(Neu->GName,LabPart,255);
RunSection=SectionStack; HSect=MomSectionHandle;
while ((HSect!=Neu->GlobSect) AND (RunSection!=Nil))
BEGIN
strmaxprep(Neu->GName,"_",255); strmaxprep(Neu->GName,GetSectionName(HSect),255);
HSect=RunSection->Handle; RunSection=RunSection->Next;
END
END
if (NOT DoPublic) Neu->PubSect=MomSectionHandle;
OneMacro=(PMacroRec) malloc(sizeof(MacroRec)); Neu->Mac=OneMacro;
if ((MacroOutput) AND (Neu->DoExport))
BEGIN
if (strlen(PList)!=0) strcpy(PList,PList+1);
errno=0;
if (Neu->DoGlobCopy) fprintf(MacroFile,"%s MACRO %s\n",Neu->GName,PList);
else fprintf(MacroFile,"%s MACRO %s\n",LabPart,PList);
ChkIO(10004);
END
OneMacro->Used=False;
OneMacro->Name=strdup(LabPart);
OneMacro->ParamCount=z2;
OneMacro->FirstLine=Nil; OneMacro->LocMacExp=DoMacExp;
FirstOutputTag=Neu;
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Beendigung der Expansion eines Makros */
static void MACRO_Cleanup(PInputTag PInp)
BEGIN
ClearStringList(&(PInp->Params));
END
static Boolean MACRO_GetPos(PInputTag PInp, char *dest)
BEGIN
String Tmp;
sprintf(Tmp,LongIntFormat,PInp->LineZ-1);
sprintf(dest,"%s(%s) ",PInp->SpecName,Tmp);
return False;
END
static void MACRO_Restorer(PInputTag PInp)
BEGIN
PopLocHandle();
DoLst=PInp->OrigDoLst;
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Dies initialisiert eine Makroexpansion */
static void ExpandMacro(PMacroRec OneMacro)
BEGIN
int z1;
StringRecPtr Lauf;
PInputTag Tag;
CodeLen=0;
/* if (OneMacro->Used) WrError(1850);
else */
BEGIN
OneMacro->Used=True;
/* 1. Tag erzeugen */
GenerateProcessor(&Tag);
Tag->Processor=MACRO_Processor;
Tag->Restorer =MACRO_Restorer;
Tag->Cleanup =MACRO_Cleanup;
Tag->GetPos =MACRO_GetPos;
strmaxcpy(Tag->SpecName,OneMacro->Name,255);
strmaxcpy(Tag->SaveAttr,AttrPart,255);
Tag->IsMacro =True;
/* 2. Parameterzahl anpassen */
if (ArgCnt<OneMacro->ParamCount)
for (z1=ArgCnt+1; z1<=OneMacro->ParamCount; z1++) *(ArgStr[z1])='\0';
ArgCnt=OneMacro->ParamCount;
/* 3. Parameterliste aufbauen - umgekehrt einfacher */
for (z1=ArgCnt; z1>=1; z1--)
BEGIN
if (NOT CaseSensitive) UpString(ArgStr[z1]);
AddStringListFirst(&(Tag->Params),ArgStr[z1]);
END
Tag->ParCnt=ArgCnt;
/* 4. Zeilenliste anhaengen */
Tag->Lines=OneMacro->FirstLine; Tag->IsEmpty=(OneMacro->FirstLine==Nil);
Lauf=OneMacro->FirstLine;
while (Lauf!=Nil)
BEGIN
Tag->LineCnt++; Lauf=Lauf->Next;
END
END
/* 5. anhaengen */
if (IfAsm)
BEGIN
NextDoLst=(DoLst AND OneMacro->LocMacExp);
Tag->Next=FirstInputTag; FirstInputTag=Tag;
END
else
BEGIN
ClearStringList(&(Tag->Params)); free(Tag);
END
END
/*-------------------------------------------------------------------------*/
/* vorzeitiger Abbruch eines Makros */
static void ExpandEXITM(void)
BEGIN
if (ArgCnt!=0) WrError(1110);
else if (FirstInputTag==Nil) WrError(1805);
else if (NOT FirstInputTag->IsMacro) WrError(1805);
else if (IfAsm)
BEGIN
FirstInputTag->Cleanup(FirstInputTag);
RestoreIFs(FirstInputTag->IfLevel);
FirstInputTag->IsEmpty=True;
END
END
/*-------------------------------------------------------------------------*/
/*--- IRP (was das bei MASM auch immer heissen mag...)
Ach ja: Individual Repeat! Danke Bernhard, jetzt hab'
ich's gerafft! -----------------------*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Diese Routine liefert bei der Expansion eines IRP-Statements die expan-
dierten Zeilen */
Boolean IRP_Processor(PInputTag PInp, char *erg)
BEGIN
StringRecPtr Lauf;
int z;
Boolean Result;
Result=True;
Lauf=PInp->Lines; for (z=1; z<=PInp->LineZ-1; z++) Lauf=Lauf->Next;
strcpy(erg,Lauf->Content);
Lauf=PInp->Params; for (z=1; z<=PInp->ParZ-1; z++) Lauf=Lauf->Next;
ExpandLine(Lauf->Content,1,erg); CurrLine=PInp->StartLine+PInp->LineZ;
if (PInp->LineZ==1)
BEGIN
if (NOT PInp->First) PopLocHandle(); PInp->First=False;
PushLocHandle(GetLocHandle());
END
if (++(PInp->LineZ)>PInp->LineCnt)
BEGIN
PInp->LineZ=1;
if (++(PInp->ParZ)>PInp->ParCnt) Result=False;
END
return Result;
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Aufraeumroutine IRP/IRPC */
static void IRP_Cleanup(PInputTag PInp)
BEGIN
StringRecPtr Lauf;
/* letzten Parameter sichern, wird evtl. noch fuer GetPos gebraucht!
... SaveAttr ist aber frei */
if (PInp->Processor==IRP_Processor)
BEGIN
for (Lauf=PInp->Params; Lauf->Next!=Nil; Lauf=Lauf->Next);
strmaxcpy(PInp->SaveAttr,Lauf->Content,255);
END
ClearStringList(&(PInp->Lines));
ClearStringList(&(PInp->Params));
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Posisionsangabe im IRP(C) fuer Fehlermeldungen */
static Boolean IRP_GetPos(PInputTag PInp, char *dest)
BEGIN
StringRecPtr Lauf=PInp->Params;
int z,z1=PInp->ParZ,z2=PInp->LineZ;
char *IRPType,*IRPVal,tmp[10];
if (PInp->Processor==IRP_Processor)
BEGIN
IRPType="IRP";
if (*PInp->SaveAttr!='\0') IRPVal=PInp->SaveAttr;
else
BEGIN
for (z=1; z<=z1-1; z++) Lauf=Lauf->Next;
IRPVal=Lauf->Content;
END
END
else
BEGIN
IRPType="IRPC";
sprintf(tmp,"'%c'",PInp->SpecName[z1-1]); IRPVal=tmp;
END
if (--z2<=0)
BEGIN
z2=PInp->LineCnt; z1--;
END
sprintf(dest,"%s:%s/%ld ",IRPType,IRPVal,(long)z2);
return False;
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Diese Routine sammelt waehrend der Definition eines IRP(C)-Statements die
Quellzeilen ein */
static void IRP_OutProcessor(void)
BEGIN
POutputTag Tmp;
StringRecPtr Dummy;
String s;
/* Schachtelungen mitzaehlen */
if (MacroStart()) FirstOutputTag->NestLevel++;
else if (MacroEnd()) FirstOutputTag->NestLevel--;
/* falls noch nicht zuende, weiterzaehlen */
if (FirstOutputTag->NestLevel>-1)
BEGIN
strmaxcpy(s,OneLine,255); KillCtrl(s);
CompressLine(GetStringListFirst(FirstOutputTag->Params,&Dummy),1,s);
AddStringListLast(&(FirstOutputTag->Tag->Lines),s);
FirstOutputTag->Tag->LineCnt++;
END
/* alles zusammen? Dann umhaengen */
if (FirstOutputTag->NestLevel==-1)
BEGIN
Tmp=FirstOutputTag; FirstOutputTag=FirstOutputTag->Next;
Tmp->Tag->IsEmpty=(Tmp->Tag->Lines==Nil);
if (IfAsm)
BEGIN
NextDoLst=DoLst AND LstMacroEx;
Tmp->Tag->Next=FirstInputTag; FirstInputTag=Tmp->Tag;
END
else
BEGIN
ClearStringList(&(Tmp->Tag->Lines)); ClearStringList(&(Tmp->Tag->Params));
free(Tmp->Tag);
END
ClearStringList(&(Tmp->Params));
free(Tmp);
END
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Initialisierung der IRP-Bearbeitung */
static void ExpandIRP(void)
BEGIN
String Parameter;
int z1;
PInputTag Tag;
POutputTag Neu;
Boolean ErrFlag;
/* 1.Parameter pruefen */
if (ArgCnt<2)
BEGIN
WrError(1110); ErrFlag=True;
END
else
BEGIN
strmaxcpy(Parameter,ArgStr[1],255);
if (NOT ChkMacSymbName(ArgStr[1]))
BEGIN
WrXError(1020,Parameter); ErrFlag=True;
END
else ErrFlag=False;
END
if (ErrFlag)
BEGIN
AddWaitENDM_Processor();
return;
END
/* 2. Tag erzeugen */
GenerateProcessor(&Tag);
Tag->ParCnt=ArgCnt-1;
Tag->Processor=IRP_Processor;
Tag->Restorer =MACRO_Restorer;
Tag->Cleanup =IRP_Cleanup;
Tag->GetPos =IRP_GetPos;
Tag->ParZ =1;
Tag->IsMacro =True;
*Tag->SaveAttr='\0';
/* 3. Parameterliste aufbauen; rueckwaerts einen Tucken schneller */
for (z1=ArgCnt; z1>=2; z1--)
BEGIN
UpString(ArgStr[z1]);
AddStringListFirst(&(Tag->Params),ArgStr[z1]);
END
/* 4. einbetten */
Neu=(POutputTag) malloc(sizeof(TOutputTag));
Neu->Next=FirstOutputTag;
Neu->Processor=IRP_OutProcessor;
Neu->NestLevel=0;
Neu->Tag=Tag;
Neu->Params=Nil; AddStringListFirst(&(Neu->Params),ArgStr[1]);
FirstOutputTag=Neu;
END
/*--- IRPC: dito für Zeichen eines Strings ---------------------------------*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Diese Routine liefert bei der Expansion eines IRPC-Statements die expan-
dierten Zeilen */
Boolean IRPC_Processor(PInputTag PInp, char *erg)
BEGIN
StringRecPtr Lauf;
int z;
Boolean Result;
char tmp[5];
Result=True;
Lauf=PInp->Lines; for (z=1; z<=PInp->LineZ-1; z++) Lauf=Lauf->Next;
strcpy(erg,Lauf->Content);
*tmp=PInp->SpecName[PInp->ParZ-1]; tmp[1]='\0';
ExpandLine(tmp,1,erg); CurrLine=PInp->StartLine+PInp->LineZ;
if (PInp->LineZ==1)
BEGIN
if (NOT PInp->First) PopLocHandle(); PInp->First=False;
PushLocHandle(GetLocHandle());
END
if (++(PInp->LineZ)>PInp->LineCnt)
BEGIN
PInp->LineZ=1;
if (++(PInp->ParZ)>PInp->ParCnt) Result=False;
END
return Result;
END
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Initialisierung der IRPC-Bearbeitung */
static void ExpandIRPC(void)
BEGIN
String Parameter;
PInputTag Tag;
POutputTag Neu;
Boolean ErrFlag;
/* 1.Parameter pruefen */
if (ArgCnt<2)
BEGIN
WrError(1110); ErrFlag=True;
END
else
BEGIN
strmaxcpy(Parameter,ArgStr[1],255);
if (NOT ChkMacSymbName(ArgStr[1]))
BEGIN
WrXError(1020,Parameter); ErrFlag=True;
END
else ErrFlag=False;
END
if (NOT ErrFlag)
BEGIN
EvalStringExpression(ArgStr[2],&ErrFlag,Parameter);
ErrFlag=NOT ErrFlag;
END
if (ErrFlag)
BEGIN
AddWaitENDM_Processor();
return;
END
/* 2. Tag erzeugen */
GenerateProcessor(&Tag);
Tag->ParCnt =strlen(Parameter);
Tag->Processor=IRPC_Processor;
Tag->Restorer =MACRO_Restorer;
Tag->Cleanup =IRP_Cleanup;
Tag->GetPos =IRP_GetPos;
Tag->ParZ =1;
Tag->IsMacro =True;
*Tag->SaveAttr='\0';
strmaxcpy(Tag->SpecName,Parameter,255);
/* 4. einbetten */
Neu=(POutputTag) malloc(sizeof(TOutputTag));
Neu->Next=FirstOutputTag;
Neu->Processor=IRP_OutProcessor;
Neu->NestLevel=0;
Neu->Tag=Tag;
Neu->Params=Nil; AddStringListFirst(&(Neu->Params),ArgStr[1]);
FirstOutputTag=Neu;
END
/*--- Repetition -----------------------------------------------------------*/
static void REPT_Cleanup(PInputTag PInp)
BEGIN
ClearStringList(&(PInp->Lines));
END
static Boolean REPT_GetPos(PInputTag PInp, char *dest)
BEGIN
int z1=PInp->ParZ,z2=PInp->LineZ;
if (--z2<=0)
BEGIN
z2=PInp->LineCnt; z1--;
END
sprintf(dest,"REPT %ld/%ld",(long)z1,(long)z2);
return False;
END
Boolean REPT_Processor(PInputTag PInp, char *erg)
BEGIN
StringRecPtr Lauf;
int z;
Boolean Result;
Result=True;
Lauf=PInp->Lines; for(z=1; z<=PInp->LineZ-1; z++) Lauf=Lauf->Next;
strcpy(erg,Lauf->Content); CurrLine=PInp->StartLine+PInp->LineZ;
if (PInp->LineZ==1)
BEGIN
if (NOT PInp->First) PopLocHandle(); PInp->First=False;
PushLocHandle(GetLocHandle());
END
if ((++PInp->LineZ)>PInp->LineCnt)
BEGIN
PInp->LineZ=1;
if ((++PInp->ParZ)>PInp->ParCnt) Result=False;
END
return Result;
END
static void REPT_OutProcessor(void)
BEGIN
POutputTag Tmp;
/* Schachtelungen mitzaehlen */
if (MacroStart()) FirstOutputTag->NestLevel++;
else if (MacroEnd()) FirstOutputTag->NestLevel--;
/* falls noch nicht zuende, weiterzaehlen */
if (FirstOutputTag->NestLevel>-1)
BEGIN
AddStringListLast(&(FirstOutputTag->Tag->Lines),OneLine);
FirstOutputTag->Tag->LineCnt++;
END
/* alles zusammen? Dann umhaengen */
if (FirstOutputTag->NestLevel==-1)
BEGIN
Tmp=FirstOutputTag; FirstOutputTag=FirstOutputTag->Next;
Tmp->Tag->IsEmpty=(Tmp->Tag->Lines==Nil);
if ((IfAsm) AND (Tmp->Tag->ParCnt>0))
BEGIN
NextDoLst=(DoLst AND LstMacroEx);
Tmp->Tag->Next=FirstInputTag; FirstInputTag=Tmp->Tag;
END
else
BEGIN
ClearStringList(&(Tmp->Tag->Lines));
free(Tmp->Tag);
END
free(Tmp);
END
END
static void ExpandREPT(void)
BEGIN
Boolean ValOK;
LongInt ReptCount=0;
PInputTag Tag;
POutputTag Neu;
Boolean ErrFlag;
/* 1.Repetitionszahl ermitteln */
if (ArgCnt!=1)
BEGIN
WrError(1110); ErrFlag=True;
END
else
BEGIN
FirstPassUnknown=False;
ReptCount=EvalIntExpression(ArgStr[1],Int32,&ValOK);
if (FirstPassUnknown) WrError(1820);
ErrFlag=((NOT ValOK) OR (FirstPassUnknown));
END
if (ErrFlag)
BEGIN
AddWaitENDM_Processor();
return;
END
/* 2. Tag erzeugen */
GenerateProcessor(&Tag);
Tag->ParCnt=ReptCount;
Tag->Processor=REPT_Processor;
Tag->Restorer =MACRO_Restorer;
Tag->Cleanup =REPT_Cleanup;
Tag->GetPos =REPT_GetPos;
Tag->IsMacro =True;
Tag->ParZ=1;
/* 3. einbetten */
Neu=(POutputTag) malloc(sizeof(TOutputTag));
Neu->Processor=REPT_OutProcessor;
Neu->NestLevel=0;
Neu->Next=FirstOutputTag;
Neu->Tag=Tag;
FirstOutputTag=Neu;
END
/*- bedingte Wiederholung -------------------------------------------------------*/
static void WHILE_Cleanup(PInputTag PInp)
BEGIN
ClearStringList(&(PInp->Lines));
END
static Boolean WHILE_GetPos(PInputTag PInp, char *dest)
BEGIN
int z1=PInp->ParZ,z2=PInp->LineZ;
if (--z2<=0)
BEGIN
z2=PInp->LineCnt; z1--;
END
sprintf(dest, "WHILE %ld/%ld", (long)z1, (long)z2);
return False;
END
Boolean WHILE_Processor(PInputTag PInp, char *erg)
BEGIN
StringRecPtr Lauf;
int z;
Boolean OK,Result;
CurrLine=PInp->StartLine+PInp->LineZ;
if (PInp->LineZ==1)
BEGIN
if (NOT PInp->First) PopLocHandle(); PInp->First=False;
PushLocHandle(GetLocHandle());
END
else OK=True;
Lauf=PInp->Lines; for (z=1; z<=PInp->LineZ-1; z++) Lauf=Lauf->Next;
strcpy(erg,Lauf->Content);
if ((++PInp->LineZ)>PInp->LineCnt)
BEGIN
PInp->LineZ=1; PInp->ParZ++;
z=EvalIntExpression(PInp->SpecName,Int32,&OK);
OK=(OK AND (z!=0));
Result=OK;
END
else Result=True;
return Result;
END
static void WHILE_OutProcessor(void)
BEGIN
POutputTag Tmp;
Boolean OK;
LongInt Erg;
/* Schachtelungen mitzaehlen */
if (MacroStart()) FirstOutputTag->NestLevel++;
else if (MacroEnd()) FirstOutputTag->NestLevel--;
/* falls noch nicht zuende, weiterzaehlen */
if (FirstOutputTag->NestLevel>-1)
BEGIN
AddStringListLast(&(FirstOutputTag->Tag->Lines),OneLine);
FirstOutputTag->Tag->LineCnt++;
END
/* alles zusammen? Dann umhaengen */
if (FirstOutputTag->NestLevel==-1)
BEGIN
Tmp=FirstOutputTag; FirstOutputTag=FirstOutputTag->Next;
Tmp->Tag->IsEmpty=(Tmp->Tag->Lines==Nil);
FirstPassUnknown=False;
Erg=EvalIntExpression(Tmp->Tag->SpecName,Int32,&OK);
if (FirstPassUnknown) WrError(1820);
OK=(OK AND (NOT FirstPassUnknown) AND (Erg!=0));
if ((IfAsm) AND (OK))
BEGIN
NextDoLst=(DoLst AND LstMacroEx);
Tmp->Tag->Next=FirstInputTag; FirstInputTag=Tmp->Tag;
END
else
BEGIN
ClearStringList(&(Tmp->Tag->Lines));
free(Tmp->Tag);
END
free(Tmp);
END
END
static void ExpandWHILE(void)
BEGIN
PInputTag Tag;
POutputTag Neu;
Boolean ErrFlag;
/* 1.Bedingung ermitteln */
if (ArgCnt!=1)
BEGIN
WrError(1110); ErrFlag=True;
END
else ErrFlag=False;
if (ErrFlag)
BEGIN
AddWaitENDM_Processor();
return;
END
/* 2. Tag erzeugen */
GenerateProcessor(&Tag);
Tag->Processor=WHILE_Processor;
Tag->Restorer =MACRO_Restorer;
Tag->Cleanup =WHILE_Cleanup;
Tag->GetPos =WHILE_GetPos;
Tag->IsMacro =True;
Tag->ParZ=1;
strmaxcpy(Tag->SpecName,ArgStr[1],255);
/* 3. einbetten */
Neu=(POutputTag) malloc(sizeof(TOutputTag));
Neu->Processor=WHILE_OutProcessor;
Neu->NestLevel=0;
Neu->Next=FirstOutputTag;
Neu->Tag=Tag;
FirstOutputTag=Neu;
END
/*--------------------------------------------------------------------------*/
/* Einziehen von Include-Files */
static void INCLUDE_Cleanup(PInputTag PInp)
BEGIN
String Tmp;
fclose(PInp->Datei);
free(PInp->Buffer);
LineSum+=MomLineCounter;
if ((*LstName!='\0') AND (NOT QuietMode))
BEGIN
sprintf(Tmp,LongIntFormat,CurrLine);
printf("%s(%s)",NamePart(CurrFileName),Tmp);
printf("%s\n",ClrEol); fflush(stdout);
END
if (MakeIncludeList) PopInclude();
END
static Boolean INCLUDE_GetPos(PInputTag PInp, char *dest)
BEGIN
String Tmp;
sprintf(Tmp,LongIntFormat,CurrLine);
sprintf(dest,"%s(%s) ",NamePart(CurrFileName),Tmp);
return True;
END
Boolean INCLUDE_Processor(PInputTag PInp, char *Erg)
BEGIN
Boolean Result;
Result=True;
if (feof(PInp->Datei)) *Erg='\0';
else
BEGIN
ReadLn(PInp->Datei,Erg);
/**ChkIO(10003);**/
END
CurrLine=(++MomLineCounter);
if (feof(PInp->Datei)) Result=False;
return Result;
END
static void INCLUDE_Restorer(PInputTag PInp)
BEGIN
MomLineCounter=PInp->StartLine;
strmaxcpy(CurrFileName,PInp->SpecName,255);
IncDepth--;
END
static void ExpandINCLUDE(Boolean SearchPath)
BEGIN
PInputTag Tag;
if (NOT IfAsm) return;
if (ArgCnt!=1)
BEGIN
WrError(1110); return;
END
strmaxcpy(ArgPart,ArgStr[1],255);
if (*ArgPart=='"') strcpy(ArgPart,ArgPart+1);
if (ArgPart[strlen(ArgPart)-1]=='"') ArgPart[strlen(ArgPart)-1]='\0';
AddSuffix(ArgPart,IncSuffix); strmaxcpy(ArgStr[1],ArgPart,255);
if (SearchPath)
BEGIN
strmaxcpy(ArgPart,FExpand(FSearch(ArgPart,IncludeList)),255);
if (ArgPart[strlen(ArgPart)-1]=='/') strmaxcat(ArgPart,ArgStr[1],255);
END
/* Tag erzeugen */
GenerateProcessor(&Tag);
Tag->Processor=INCLUDE_Processor;
Tag->Restorer =INCLUDE_Restorer;
Tag->Cleanup =INCLUDE_Cleanup;
Tag->GetPos =INCLUDE_GetPos;
Tag->Buffer =(void *) malloc(BufferArraySize);
/* Sicherung alter Daten */
Tag->StartLine=MomLineCounter;
strmaxcpy(Tag->SpecName,CurrFileName,255);
/* Datei oeffnen */
Tag->Datei=fopen(ArgPart,"r");
if (Tag->Datei==Nil) ChkIO(10001);
setvbuf(Tag->Datei,Tag->Buffer,_IOFBF,BufferArraySize);
/* neu besetzen */
strmaxcpy(CurrFileName,ArgPart,255); MomLineCounter=0;
NextIncDepth++; AddFile(ArgPart);
PushInclude(ArgPart);
/* einhaengen */
Tag->Next=FirstInputTag; FirstInputTag=Tag;
END
/*=========================================================================*/
/* Einlieferung von Zeilen */
static void GetNextLine(char *Line)
BEGIN
PInputTag HTag;
InMacroFlag=False;
while ((FirstInputTag!=Nil) AND (FirstInputTag->IsEmpty))
BEGIN
FirstInputTag->Restorer(FirstInputTag);
HTag=FirstInputTag; FirstInputTag=HTag->Next;
free(HTag);
END
if (FirstInputTag==Nil)
BEGIN
*Line='\0'; return;
END
if (NOT FirstInputTag->Processor(FirstInputTag,Line))
BEGIN
FirstInputTag->Cleanup(FirstInputTag);
FirstInputTag->IsEmpty=True;
END
MacLineSum++;
END
char *GetErrorPos(void)
BEGIN
String ActPos;
PInputTag RunTag;
char *ErgPos=strdup(""),*tmppos;
Boolean Last;
for (RunTag=FirstInputTag; RunTag!=Nil; RunTag=RunTag->Next)
BEGIN
Last=RunTag->GetPos(RunTag,ActPos);
tmppos=(char *) malloc(strlen(ErgPos)+strlen(ActPos)+1);
strcpy(tmppos,ActPos); strcat(tmppos,ErgPos);
free(ErgPos); ErgPos=tmppos;
if (Last) break;
END
return ErgPos;
END
static Boolean InputEnd(void)
BEGIN
PInputTag Lauf;
Lauf=FirstInputTag;
while (Lauf!=Nil)
BEGIN
if (NOT Lauf->IsEmpty) return False;
Lauf=Lauf->Next;
END
return True;
END
/*=== Eine Quelldatei ( Haupt-oder Includedatei ) bearbeiten ===============*/
/*--- aus der zerlegten Zeile Code erzeugen --------------------------------*/
Boolean HasLabel(void)
BEGIN
if (*LabPart=='\0') return False;
if (IsDef()) return False;
switch (*OpPart)
BEGIN
case '=':
return (NOT Memo("="));
case ':':
return (NOT Memo(":"));
case 'M':
return (NOT Memo("MACRO"));
case 'F':
return (NOT Memo("FUNCTION"));
case 'L':
return (NOT Memo("LABEL"));
case 'S':
return ((NOT Memo("SET")) OR (SetIsOccupied)) AND (NOT Memo("STRUCT"));
case 'E':
return ((NOT Memo("EVAL")) OR (NOT SetIsOccupied)) AND (NOT Memo("EQU")) AND (NOT Memo("ENDSTRUCT"));
default:
return True;
END
END
static void Produce_Code(void)
BEGIN
Byte z;
PMacroRec OneMacro;
Boolean SearchMacros,Found;
String tmp,tmp2;
PStructure ZStruct;
ActListGran=ListGran();
/* Makrosuche unterdruecken ? */
if (*OpPart=='!')
BEGIN
SearchMacros=False; strcpy(OpPart,OpPart+1);
END
else
BEGIN
SearchMacros=True; ExpandSymbol(OpPart);
END
strcpy(LOpPart,OpPart); NLS_UpString(OpPart);
/* Prozessor eingehaengt ? */
if (FirstOutputTag!=Nil)
BEGIN
FirstOutputTag->Processor(); return;
END
/* ansonsten Code erzeugen */
/* evtl. voranstehendes Label ablegen */
if (IfAsm)
BEGIN
if (HasLabel())
if (StructureStack!=Nil)
BEGIN
strmaxcpy(tmp,LabPart,255);
for (ZStruct=StructureStack; ZStruct!=Nil; ZStruct=ZStruct->Next)
if (ZStruct->DoExt)
BEGIN
sprintf(tmp2,"%s_",ZStruct->Name);
strmaxprep(tmp,tmp2,255);
END
EnterIntSymbol(tmp,EProgCounter(),SegNone,False);
END
else EnterIntSymbol(LabPart,EProgCounter(),ActPC,False);
END
Found=False;
switch (*OpPart)
BEGIN
case 'I':
/* Makroliste ? */
if ((Found=Memo("IRP"))) ExpandIRP();
else if ((Found=Memo("IRPC"))) ExpandIRPC();
break;
case 'R':
/* Repetition ? */
if ((Found=Memo("REPT"))) ExpandREPT(); break;
case 'W':
/* bedingte Repetition ? */
if ((Found=Memo("WHILE"))) ExpandWHILE(); break;
END
/* bedingte Assemblierung ? */
if (NOT Found) Found=CodeIFs();
if (NOT Found)
switch (*OpPart)
BEGIN
case 'M':
/* Makrodefinition ? */
if ((Found=Memo(("MACRO")))) ReadMacro(); break;
case 'E':
/* Abbruch Makroexpansion ? */
if ((Found=Memo(("EXITM")))) ExpandEXITM(); break;
case 'I':
/* Includefile? */
if ((Found=Memo(("INCLUDE"))))
BEGIN
ExpandINCLUDE(True);
MasterFile=False;
END
break;
END
if (Found);
/* Makroaufruf ? */
else if ((SearchMacros) AND (FoundMacro(&OneMacro)))
BEGIN
if (IfAsm) ExpandMacro(OneMacro);
if (IfAsm) strmaxcpy(ListLine,"(MACRO)",255);
END
else
BEGIN
StopfZahl=0; CodeLen=0; DontPrint=False;
if (IfAsm)
BEGIN
if (NOT CodeGlobalPseudo()) MakeCode();
if ((MacProOutput) AND ((*OpPart!='\0') OR (*LabPart!='\0') OR (*CommPart!='\0')))
BEGIN
errno=0; fprintf(MacProFile,"%s\n",OneLine); ChkIO(10002);
END
END
for (z=0; z<StopfZahl; z++)
BEGIN
switch (ActListGran)
BEGIN
case 4:DAsmCode[CodeLen>>2]=NOPCode; break;
case 2:WAsmCode[CodeLen>>1]=NOPCode; break;
case 1:BAsmCode[CodeLen ]=NOPCode; break;
END
CodeLen+=ActListGran/Granularity();
END
if ((ActPC!=StructSeg) AND (NOT ChkPC(PCs[ActPC]+CodeLen-1)) AND (CodeLen!=0))
WrError(1925);
else
BEGIN
if ((NOT DontPrint) AND (ActPC!=StructSeg) AND (CodeLen>0)) BookKeeping();
if (ActPC==StructSeg)
BEGIN
if ((CodeLen!=0) AND (NOT DontPrint)) WrError(1940);
END
else if (CodeOutput)
BEGIN
if (DontPrint) NewRecord(PCs[ActPC]+CodeLen);
else WriteBytes();
END
PCs[ActPC]+=CodeLen;
END
END
/* dies ueberprueft implizit, ob von der letzten Eval...-Operation noch
externe Referenzen liegengeblieben sind. */
SetRelocs(Nil);
END
/*--- Zeile in Listing zerteilen -------------------------------------------*/
static void SplitLine(void)
BEGIN
jmp_buf Retry;
String h;
char *i,*k,*p,*div,*run;
int l;
Boolean lpos;
Retracted=False;
/* Kommentar loeschen */
strmaxcpy(h,OneLine,255); i=QuotPos(h,';');
if (i!=Nil)
BEGIN
strcpy(CommPart,i+1);
*i='\0';
END
else *CommPart='\0';
/* alles in Grossbuchstaben wandeln, Praeprozessor laufen lassen */
ExpandDefines(h);
/* Label abspalten */
if ((*h!='\0') AND (NOT isspace((unsigned char)*h)))
BEGIN
for (i=h; *i!='\0'; i++)
if ((isspace(((unsigned char)*i)&0xff)) OR (*i==':')) break;
if (*i=='\0')
BEGIN
strcpy(LabPart,h); *h='\0';
END
else
BEGIN
*i='\0'; strcpy(LabPart,h); strcpy(h,i+1);
END
if (LabPart[l=(strlen(LabPart)-1)]==':') LabPart[l]='\0';
END
else *LabPart='\0';
/* Opcode & Argument trennen */
setjmp(Retry);
KillPrefBlanks(h);
i=FirstBlank(h);
SplitString(h,OpPart,ArgPart,i);
/* Falls noch kein Label da war, kann es auch ein Label sein */
i=strchr(OpPart,':');
if ((*LabPart=='\0') AND (i!=Nil) AND (i[1]=='\0'))
BEGIN
*i='\0'; strcpy(LabPart,OpPart); strcpy(OpPart,i+1);
if (*OpPart=='\0')
BEGIN
strcpy(h,ArgPart);
longjmp(Retry,1);
END
END
/* Attribut abspalten */
if (HasAttrs)
BEGIN
k=Nil; AttrSplit=' ';
for (run=AttrChars; *run!='\0'; run++)
BEGIN
p=strchr(OpPart,*run);
if (p!=Nil) if ((k==Nil) OR (p<k)) k=p;
END
if (k!=Nil)
BEGIN
AttrSplit=(*k);
strmaxcpy(AttrPart,k+1,255); *k='\0';
if ((*OpPart=='\0') AND (*AttrPart!='\0'))
BEGIN
strmaxcpy(OpPart,AttrPart,255); *AttrPart='\0';
END
END
else *AttrPart='\0';
END
else *AttrPart='\0';
KillPostBlanks(ArgPart);
/* Argumente zerteilen: Da alles aus einem String kommt und die Teile alle auch
so lang sind, koennen wir uns Laengenabfragen sparen */
ArgCnt=0; strcpy(h,ArgPart); run=h;
if (*run!='\0')
do
BEGIN
while ((*run!='\0') AND (isspace((unsigned char)*run))) run++;
i=Nil;
for (div=DivideChars; *div!='\0'; div++)
BEGIN
p=QuotPos(run,*div);
if (p!=Nil) if ((i==Nil) OR (p<i)) i=p;
END
lpos=((i!=Nil) AND (i[1]=='\0'));
if (i!=Nil) *i='\0';
strcpy(ArgStr[++ArgCnt],run);
if ((lpos) AND (ArgCnt!=ParMax)) *ArgStr[++ArgCnt]='\0';
KillPostBlanks(ArgStr[ArgCnt]);
run=(i==Nil) ? i : i+1;
END
while ((run!=Nil) AND (ArgCnt!=ParMax) AND (NOT lpos));
if ((run!=Nil) AND (*run!='\0')) WrError(1140);
Produce_Code();
END
/**
CONST
LineBuffer:String='';
InComment:Boolean=FALSE;
static void C_SplitLine(void)
BEGIN
p,p2:int;
SaveLine,h:String;
{ alten Inhalt sichern }
SaveLine:=OneLine; h:=OneLine;
{ Falls in Kommentar, nach schliessender Klammer suchen und den Teil bis
dahin verwerfen; falls keine Klammer drin ist, die ganze Zeile weg-
schmeissen; da wir dann OneLine bisher noch nicht veraendert hatten,
stoert der Abbruch ohne Wiederherstellung von Oneline nicht. }
IF InComment THEN
BEGIN
p:=Pos('}',h);
IF p>Length(h) THEN Exit
ELSE
BEGIN
Delete(h,1,p); InComment:=False;
END;
END;
{ in der Zeile befindliche Teile loeschen; falls am Ende keine
schliessende Klammer kommt, muessen wir das Kommentarflag setzen. }
REPEAT
p:=QuotPos(h,'{');
IF p>Length(h) THEN p:=0
ELSE
BEGIN
p2:=QuotPos(h,'}');
IF (p2>p) AND (Length(h)>=p2) THEN Delete(h,p,p2-p+1)
ELSE
BEGIN
Byte(h[0]):=Pred(p);
InComment:=True;
p:=0;
END;
END;
UNTIL p=0;
{ alten Inhalt zurueckkopieren }
OneLine:=SaveLine;
END;**/
/*------------------------------------------------------------------------*/
static void ProcessFile(String FileName)
BEGIN
long NxtTime,ListTime;
String Num;
char *Name, *Run;
dbgentry("ProcessFile");
sprintf(OneLine," INCLUDE \"%s\"",FileName); MasterFile=False;
NextIncDepth=IncDepth;
SplitLine();
IncDepth=NextIncDepth;
ListTime=GTime();
while ((NOT InputEnd()) AND (NOT ENDOccured))
BEGIN
/* Zeile lesen */
GetNextLine(OneLine);
/* Ergebnisfelder vorinitialisieren */
DontPrint=False; CodeLen=0; *ListLine='\0';
NextDoLst=DoLst;
NextIncDepth=IncDepth;
for (Run=OneLine; *Run!='\0'; Run++)
if (NOT isspace(((unsigned int)*Run)&0xff)) break;
if (*Run=='#') Preprocess();
else SplitLine();
MakeList();
DoLst=NextDoLst;
IncDepth=NextIncDepth;
/* Zeilenzaehler */
if (NOT QuietMode)
BEGIN
NxtTime=GTime();
if (((NOT ListToStdout) OR ((ListMask&1)==0)) AND (DTime(ListTime,NxtTime)>50))
BEGIN
sprintf(Num,LongIntFormat,MomLineCounter); Name=NamePart(CurrFileName);
printf("%s(%s)%s",Name,Num,ClrEol);
/*for (z=0; z<strlen(Name)+strlen(Num)+2; z++) putchar('\b');*/
putchar('\r'); fflush(stdout);
ListTime=NxtTime;
END
END
/* bei Ende Makroprozessor ausraeumen
OK - das ist eine Hauruckmethode... */
if (ENDOccured)
while (FirstInputTag!=Nil) GetNextLine(OneLine);
END
while (FirstInputTag!=Nil) GetNextLine(OneLine);
/* irgendeine Makrodefinition nicht abgeschlossen ? */
if (FirstOutputTag!=Nil) WrError(1800);
dbgexit("ProcessFile");
END
/****************************************************************************/
static char *TWrite_Plur(int n)
BEGIN
return (n!=1) ? getmessage(Num_ListPlurName) : "";
END
static void TWrite_RWrite(char *dest, Double r, Byte Stellen)
BEGIN
String s;
sprintf(s,"%20.*f",Stellen,r);
while (*s==' ') strcpy(s,s+1); strcat(dest,s);
END
static void TWrite(Double DTime, char *dest)
BEGIN
int h;
String s;
*dest='\0';
h=(int) floor(DTime/3600.0);
if (h>0)
BEGIN
sprintf(s,"%d",h);
strcat(dest,s);
strcat(dest,getmessage(Num_ListHourName));
strcat(dest,TWrite_Plur(h));
strcat(dest,", ");
DTime-=3600.0*h;
END
h=(int) floor(DTime/60.0);
if (h>0)
BEGIN
sprintf(s,"%d",h);
strcat(dest,s);
strcat(dest,getmessage(Num_ListMinuName));
strcat(dest,TWrite_Plur(h));
strcat(dest,", ");
DTime-=60.0*h;
END
TWrite_RWrite(dest,DTime,2); strcat(dest,getmessage(Num_ListSecoName));
if (DTime!=1) strcat(dest,getmessage(Num_ListPlurName));
END
/*--------------------------------------------------------------------------*/
static void AssembleFile_InitPass(void)
BEGIN
static char DateS[31],TimeS[31];
int z;
String ArchVal;
dbgentry("AssembleFile_InitPass");
FirstInputTag=Nil; FirstOutputTag=Nil;
MomLineCounter=0; MomLocHandle=(-1); LocHandleCnt=0;
SectionStack=Nil;
FirstIfSave=Nil;
FirstSaveState=Nil;
StructureStack=Nil;
InitPassProc();
ActPC=SegCode; PCs[ActPC]=0; ENDOccured=False;
ErrorCount=0; WarnCount=0; LineSum=0; MacLineSum=0;
for (z=1; z<=StructSeg; z++)
BEGIN
PCsUsed[z]=(z==SegCode);
Phases[z]=0;
InitChunk(&SegChunks[z]);
END
TransTables=CurrTransTable=(PTransTable) malloc(sizeof(TTransTable));
CurrTransTable->Next=Nil;
CurrTransTable->Name=strdup("STANDARD");
CurrTransTable->Table=(unsigned char *) malloc(256*sizeof(char));
for (z=0; z<256; z++) CurrTransTable->Table[z]=z;
strmaxcpy(CurrFileName,"INTERNAL",255);
AddFile(CurrFileName); CurrLine=0;
IncDepth=(-1);
DoLst=True;
/* Pseudovariablen initialisieren */
ResetSymbolDefines(); ResetMacroDefines();
EnterIntSymbol(FlagTrueName,1,0,True);
EnterIntSymbol(FlagFalseName,0,0,True);
EnterFloatSymbol(PiName,4.0*atan(1.0),True);
EnterIntSymbol(VerName,VerNo,0,True);
sprintf(ArchVal,"%s-%s",ARCHPRNAME,ARCHSYSNAME);
EnterStringSymbol(ArchName,ArchVal,True);
#ifdef HAS64
EnterIntSymbol(Has64Name,1,0,True);
#else
EnterIntSymbol(Has64Name,0,0,True);
#endif
EnterIntSymbol(CaseSensName,Ord(CaseSensitive),0,True);
if (PassNo==0)
BEGIN
NLS_CurrDateString(DateS);
NLS_CurrTimeString(False,TimeS);
END
EnterStringSymbol(DateName,DateS,True);
EnterStringSymbol(TimeName,TimeS,True);
if (*DefCPU == '\0')
SetCPU(0, True);
else
if (NOT SetNCPU(DefCPU, True)) SetCPU(0, True);
SetFlag(&SupAllowed,SupAllowedName,False);
SetFlag(&FPUAvail,FPUAvailName,False);
SetFlag(&DoPadding,DoPaddingName,True);
SetFlag(&Maximum,MaximumName,False);
SetFlag(&DoBranchExt,BranchExtName,False);
EnterIntSymbol(ListOnName,ListOn=1,0,True);
SetFlag(&LstMacroEx,LstMacroExName,True);
SetFlag(&RelaxedMode,RelaxedName,False);
CopyDefSymbols();
ResetPageCounter();
StartAdrPresent=False;
Repass=False; PassNo++;
dbgexit("AssembleFile_InitPass");
END
static void AssembleFile_ExitPass(void)
BEGIN
SwitchFrom();
ClearLocStack();
ClearStacks();
TossRegDefs(-1);
if (FirstIfSave!=Nil) WrError(1470);
if (FirstSaveState!=Nil) WrError(1460);
if (SectionStack!=Nil) WrError(1485);
if (StructureStack!=Nil) WrXError(1551,StructureStack->Name);
END
static void AssembleFile(char *Name)
BEGIN
String s,Tmp;
dbgentry("AssembleFile");
strmaxcpy(SourceFile,Name,255);
if (MakeDebug) fprintf(Debug,"File %s\n",SourceFile);
/* Untermodule initialisieren */
AsmDefInit(); AsmParsInit(); AsmIFInit(); InitFileList(); ResetStack();
/* Kommandozeilenoptionen verarbeiten */
strmaxcpy(OutName,GetFromOutList(),255);
if (OutName[0]=='\0')
BEGIN
strmaxcpy(OutName,SourceFile,255); KillSuffix(OutName);
AddSuffix(OutName,PrgSuffix);
END
if (*ErrorPath=='\0')
BEGIN
strmaxcpy(ErrorName,SourceFile,255);
KillSuffix(ErrorName);
AddSuffix(ErrorName,LogSuffix);
unlink(ErrorName);
END
switch (ListMode)
BEGIN
case 0: strmaxcpy(LstName,NULLDEV,255); break;
case 1: strmaxcpy(LstName,"!1",255); break;
case 2:
strmaxcpy(LstName,SourceFile,255);
KillSuffix(LstName);
AddSuffix(LstName,LstSuffix);
break;
END
ListToStdout=(strcmp(LstName,"!1")==0);
ListToNull=(strcmp(LstName,NULLDEV)==0);
if (ShareMode!=0)
BEGIN
strmaxcpy(ShareName,GetFromShareOutList(),255);
if (*ShareName == '\0')
BEGIN
strmaxcpy(ShareName,SourceFile,255);
KillSuffix(ShareName);
switch (ShareMode)
BEGIN
case 1: AddSuffix(ShareName,".inc"); break;
case 2: AddSuffix(ShareName,".h"); break;
case 3: AddSuffix(ShareName,IncSuffix); break;
END
END
END
if (MacProOutput)
BEGIN
strmaxcpy(MacProName,SourceFile,255); KillSuffix(MacProName);
AddSuffix(MacProName,PreSuffix);
END
if (MacroOutput)
BEGIN
strmaxcpy(MacroName,SourceFile,255); KillSuffix(MacroName);
AddSuffix(MacroName,MacSuffix);
END
ClearIncludeList();
if (DebugMode!=DebugNone) InitLineInfo();
/* Variablen initialisieren */
StartTime=GTime();
PassNo=0; MomLineCounter=0;
/* Listdatei eroeffnen */
if (NOT QuietMode) printf("%s%s\n",getmessage(Num_InfoMessAssembling),SourceFile);
do
BEGIN
/* Durchlauf initialisieren */
AssembleFile_InitPass(); AsmSubInit();
if (NOT QuietMode)
BEGIN
sprintf(Tmp,IntegerFormat,PassNo);
printf("%s%s%s\n",getmessage(Num_InfoMessPass),Tmp,ClrEol);
END
/* Dateien oeffnen */
if (CodeOutput) OpenFile();
if (ShareMode!=0)
BEGIN
ShareFile=fopen(ShareName,"w");
if (ShareFile==Nil) ChkIO(10001);
errno=0;
switch (ShareMode)
BEGIN
case 1:fprintf(ShareFile,"(* %s-Includefile f%sr CONST-Sektion *)\n",SourceFile,CH_ue); break;
case 2:fprintf(ShareFile,"/* %s-Includefile f%sr C-Programm */\n",SourceFile,CH_ue); break;
case 3:fprintf(ShareFile,"; %s-Includefile f%sr Assembler-Programm\n",SourceFile,CH_ue); break;
END
ChkIO(10002);
END
if (MacProOutput)
BEGIN
MacProFile=fopen(MacProName,"w");
if (MacProFile==Nil) ChkIO(10001);
END
if ((MacroOutput) AND (PassNo==1))
BEGIN
MacroFile=fopen(MacroName,"w");
if (MacroFile==Nil) ChkIO(10001);
END
/* Listdatei oeffnen */
RewriteStandard(&LstFile,LstName);
if (LstFile==Nil) ChkIO(10001);
errno=0; fprintf(LstFile,"%s",PrtInitString); ChkIO(10002);
if ((ListMask&1)!=0) NewPage(0,False);
/* assemblieren */
ProcessFile(SourceFile);
AssembleFile_ExitPass();
/* Dateien schliessen */
if (CodeOutput) CloseFile();
if (ShareMode!=0)
BEGIN
errno=0;
switch (ShareMode)
BEGIN
case 1: fprintf(ShareFile,"(* Ende Includefile f%sr CONST-Sektion *)\n",CH_ue); break;
case 2: fprintf(ShareFile,"/* Ende Includefile f%sr C-Programm */\n",CH_ue); break;
case 3: fprintf(ShareFile,"; Ende Includefile f%sr Assembler-Programm\n",CH_ue); break;
END
ChkIO(10002);
fclose(ShareFile);
END
if (MacProOutput) fclose(MacProFile);
if ((MacroOutput) AND (PassNo==1)) fclose(MacroFile);
/* evtl. fuer naechsten Durchlauf aufraeumen */
if ((ErrorCount==0) AND (Repass))
BEGIN
fclose(LstFile);
if (CodeOutput) unlink(OutName);
CleanupRegDefs();
ClearCodepages();
if (MakeUseList) ClearUseList();
if (MakeCrossList) ClearCrossList();
ClearDefineList();
if (DebugMode!=DebugNone) ClearLineInfo();
ClearIncludeList();
if (DebugMode!=DebugNone) ResetAddressRanges();
END
END
while ((ErrorCount==0) AND (Repass));
/* bei Fehlern loeschen */
if (ErrorCount!=0)
BEGIN
if (CodeOutput) unlink(OutName);
if (MacProOutput) unlink(MacProName);
if ((MacroOutput) AND (PassNo==1)) unlink(MacroName);
if (ShareMode!=0) unlink(ShareName);
GlobErrFlag=True;
END
/* Debug-Ausgabe muss VOR die Symbollistenausgabe, weil letztere die
Symbolliste loescht */
if (DebugMode!=DebugNone)
BEGIN
if (ErrorCount==0) DumpDebugInfo();
ClearLineInfo();
END
/* Listdatei abschliessen */
if (strcmp(LstName,NULLDEV)!=0)
BEGIN
if ((ListMask&2)!=0) PrintSymbolList();
if ((ListMask&64)!=0) PrintRegDefs();
if ((ListMask&4)!=0) PrintMacroList();
if ((ListMask&8)!=0) PrintFunctionList();
if ((ListMask&32)!=0) PrintDefineList();
if ((ListMask&128)!=0) PrintCodepages();
if (MakeUseList)
BEGIN
NewPage(ChapDepth,True);
PrintUseList();
END
if (MakeCrossList)
BEGIN
NewPage(ChapDepth,True);
PrintCrossList();
END
if (MakeSectionList) PrintSectionList();
if (MakeIncludeList) PrintIncludeList();
errno=0; fprintf(LstFile,"%s",PrtExitString); ChkIO(10002);
END
if (MakeUseList) ClearUseList();
if (MakeCrossList) ClearCrossList();
ClearSectionList();
ClearIncludeList();
if ((*ErrorPath=='\0') AND (IsErrorOpen))
BEGIN
fclose(ErrorFile); IsErrorOpen=False;
END
ClearUpProc();
/* Statistik ausgeben */
StopTime=GTime();
TWrite(DTime(StartTime,StopTime)/100.0,s);
if (NOT QuietMode) printf("\n%s%s%s\n\n",s,getmessage(Num_InfoMessAssTime),ClrEol);
if (ListMode==2)
BEGIN
WrLstLine("");
strmaxcat(s,getmessage(Num_InfoMessAssTime),255); WrLstLine(s);
WrLstLine("");
END
strcpy(s,Dec32BlankString(LineSum,7));
strmaxcat(s,getmessage((LineSum==1)?Num_InfoMessAssLine:Num_InfoMessAssLines),255);
if (NOT QuietMode) printf("%s%s\n",s,ClrEol);
if (ListMode==2) WrLstLine(s);
if (LineSum!=MacLineSum)
BEGIN
strcpy(s,Dec32BlankString(MacLineSum,7));
strmaxcat(s,getmessage((MacLineSum==1)?Num_InfoMessMacAssLine:Num_InfoMessMacAssLines),255);
if (NOT QuietMode) printf("%s%s\n",s,ClrEol);
if (ListMode==2) WrLstLine(s);
END
strcpy(s,Dec32BlankString(PassNo,7));
strmaxcat(s,getmessage((PassNo==1)?Num_InfoMessPassCnt:Num_InfoMessPPassCnt),255);
if (NOT QuietMode) printf("%s%s\n",s,ClrEol);
if (ListMode==2) WrLstLine(s);
if ((ErrorCount>0) AND (Repass) AND (ListMode!=0))
WrLstLine(getmessage(Num_InfoMessNoPass));
#ifdef __TURBOC__
sprintf(s,"%s%s",Dec32BlankString(coreleft()>>10,7),getmessage(Num_InfoMessRemainMem));
if (NOT QuietMode) printf("%s%s\n",s,ClrEol);
if (ListMode==2) WrLstLine(s);
sprintf(s,"%s%s",Dec32BlankString(StackRes(),7),getmessage(Num_InfoMessRemainStack));
if (NOT QuietMode) printf("%s%s\n",s,ClrEol);
if (ListMode==2) WrLstLine(s);
#endif
sprintf(s,"%s%s",Dec32BlankString(ErrorCount,7),getmessage(Num_InfoMessErrCnt));
if (ErrorCount!=1) strmaxcat(s,getmessage(Num_InfoMessErrPCnt),255);
if (NOT QuietMode) printf("%s%s\n",s,ClrEol);
if (ListMode==2) WrLstLine(s);
sprintf(s,"%s%s",Dec32BlankString(WarnCount,7),getmessage(Num_InfoMessWarnCnt));
if (WarnCount!=1) strmaxcat(s,getmessage(Num_InfoMessWarnPCnt),255);
if (NOT QuietMode) printf("%s%s\n",s,ClrEol);
if (ListMode==2) WrLstLine(s);
fclose(LstFile);
/* verstecktes */
if (MakeDebug) PrintSymbolDepth();
/* Speicher freigeben */
ClearSymbolList();
ClearRegDefs();
ClearCodepages();
ClearMacroList();
ClearFunctionList();
ClearDefineList();
ClearFileList();
dbgentry("AssembleFile");
END
static void AssembleGroup(void)
BEGIN
AddSuffix(FileMask,SrcSuffix);
if (NOT DirScan(FileMask,AssembleFile))
fprintf(stderr,"%s%s\n",FileMask,getmessage(Num_InfoMessNFilesFound));
END
/*-------------------------------------------------------------------------*/
static CMDResult CMD_SharePascal(Boolean Negate, char *Arg)
BEGIN
if (NOT Negate) ShareMode=1;
else if (ShareMode==1) ShareMode=0;
return CMDOK;
END
static CMDResult CMD_ShareC(Boolean Negate, char *Arg)
BEGIN
if (NOT Negate) ShareMode=2;
else if (ShareMode==2) ShareMode=0;
return CMDOK;
END
static CMDResult CMD_ShareAssembler(Boolean Negate, char *Arg)
BEGIN
if (NOT Negate) ShareMode=3;
else if (ShareMode==3) ShareMode=0;
return CMDOK;
END
static CMDResult CMD_DebugMode(Boolean Negate, char *Arg)
BEGIN
UpString(Arg);
if (Negate)
if (Arg[0]!='\0') return CMDErr;
else
BEGIN
DebugMode=DebugNone; return CMDOK;
END
else if (strcmp(Arg,"")==0)
BEGIN
DebugMode=DebugMAP; return CMDOK;
END
else if (strcmp(Arg,"ATMEL")==0)
BEGIN
DebugMode=DebugAtmel; return CMDArg;
END
else if (strcmp(Arg,"MAP")==0)
BEGIN
DebugMode=DebugMAP; return CMDArg;
END
else if (strcmp(Arg,"NOICE")==0)
BEGIN
DebugMode=DebugNoICE; return CMDArg;
END
/*else if (strcmp(Arg,"A.OUT")==0)
BEGIN
DebugMode=DebugAOUT; return CMDArg;
END
else if (strcmp(Arg,"COFF")==0)
BEGIN
DebugMode=DebugCOFF; return CMDArg;
END
else if (strcmp(Arg,"ELF")==0)
BEGIN
DebugMode=DebugELF; return CMDArg;
END*/
else return CMDErr;
/* if (Negate) DebugMode=DebugNone;
else DebugMode=DebugMAP;
return CMDOK;*/
END
static CMDResult CMD_ListConsole(Boolean Negate, char *Arg)
BEGIN
if (NOT Negate) ListMode=1;
else if (ListMode==1) ListMode=0;
return CMDOK;
END
static CMDResult CMD_ListFile(Boolean Negate, char *Arg)
BEGIN
if (NOT Negate) ListMode=2;
else if (ListMode==2) ListMode=0;
return CMDOK;
END
static CMDResult CMD_SuppWarns(Boolean Negate, char *Arg)
BEGIN
SuppWarns=NOT Negate;
return CMDOK;
END
static CMDResult CMD_UseList(Boolean Negate, char *Arg)
BEGIN
MakeUseList=NOT Negate;
return CMDOK;
END
static CMDResult CMD_CrossList(Boolean Negate, char *Arg)
BEGIN
MakeCrossList=NOT Negate;
return CMDOK;
END
static CMDResult CMD_SectionList(Boolean Negate, char *Arg)
BEGIN
MakeSectionList=NOT Negate;
return CMDOK;
END
static CMDResult CMD_BalanceTree(Boolean Negate, char *Arg)
BEGIN
BalanceTree=NOT Negate;
return CMDOK;
END
static CMDResult CMD_MakeDebug(Boolean Negate, char *Arg)
BEGIN
if (NOT Negate)
BEGIN
MakeDebug=True;
errno=0; Debug=fopen("as.deb","w");
if (Debug==Nil) ChkIO(10002);
END
else if (MakeDebug)
BEGIN
MakeDebug=False;
fclose(Debug);
END
return CMDOK;
END
static CMDResult CMD_MacProOutput(Boolean Negate, char *Arg)
BEGIN
MacProOutput=NOT Negate;
return CMDOK;
END
static CMDResult CMD_MacroOutput(Boolean Negate, char *Arg)
BEGIN
MacroOutput=NOT Negate;
return CMDOK;
END
static CMDResult CMD_MakeIncludeList(Boolean Negate, char *Arg)
BEGIN
MakeIncludeList=NOT Negate;
return CMDOK;
END
static CMDResult CMD_CodeOutput(Boolean Negate, char *Arg)
BEGIN
CodeOutput=NOT Negate;
return CMDOK;
END
static CMDResult CMD_MsgIfRepass(Boolean Negate, String Arg)
BEGIN
Boolean OK;
MsgIfRepass=NOT Negate;
if (MsgIfRepass)
if (Arg[0]=='\0')
BEGIN
PassNoForMessage=1; return CMDOK;
END
else
BEGIN
PassNoForMessage=ConstLongInt(Arg,&OK);
if (NOT OK)
BEGIN
PassNoForMessage=1; return CMDOK;
END
else if (PassNoForMessage<1) return CMDErr;
else return CMDArg;
END
else return CMDOK;
END
static CMDResult CMD_ExtendErrors(Boolean Negate, char *Arg)
BEGIN
if ((Negate) AND (ExtendErrors > 0))
ExtendErrors--;
else if ((NOT Negate) AND (ExtendErrors < 2))
ExtendErrors++;
return CMDOK;
END
static CMDResult CMD_NumericErrors(Boolean Negate, char *Arg)
BEGIN
NumericErrors=NOT Negate;
return CMDOK;
END
static CMDResult CMD_HexLowerCase(Boolean Negate, char *Arg)
BEGIN
HexLowerCase=NOT Negate;
return CMDOK;
END
static CMDResult CMD_QuietMode(Boolean Negate, char *Arg)
BEGIN
QuietMode=NOT Negate;
return CMDOK;
END
static CMDResult CMD_ThrowErrors(Boolean Negate, char *Arg)
BEGIN
ThrowErrors=NOT Negate;
return CMDOK;
END
static CMDResult CMD_CaseSensitive(Boolean Negate, char *Arg)
BEGIN
CaseSensitive=NOT Negate;
return CMDOK;
END
static CMDResult CMD_IncludeList(Boolean Negate, char *Arg)
BEGIN
char *p;
String Copy,part;
if (*Arg=='\0') return CMDErr;
else
BEGIN
strncpy(Copy,Arg,255);
do
BEGIN
p=strrchr(Copy,DIRSEP);
if (p==Nil)
BEGIN
strmaxcpy(part,Copy,255);
*Copy='\0';
END
else
BEGIN
*p='\0'; strmaxcpy(part,p+1,255);
END
if (Negate) RemoveIncludeList(part); else AddIncludeList(part);
END
while (Copy[0]!='\0');
return CMDArg;
END
END
static CMDResult CMD_ListMask(Boolean Negate, char *Arg)
BEGIN
Byte erg;
Boolean OK;
if (Arg[0]=='\0') return CMDErr;
else
BEGIN
erg=ConstLongInt(Arg,&OK);
if ((NOT OK) OR (erg>31)) return CMDErr;
else
BEGIN
if (Negate) ListMask&=(~erg);
else ListMask|=erg;
return CMDArg;
END
END
END
static CMDResult CMD_DefSymbol(Boolean Negate, char *Arg)
BEGIN
String Copy,Part,Name;
char *p;
TempResult t;
if (Arg[0]=='\0') return CMDErr;
strmaxcpy(Copy,Arg,255);
do
BEGIN
p=QuotPos(Copy,',');
if (p==Nil)
BEGIN
strmaxcpy(Part,Copy,255); Copy[0]='\0';
END
else
BEGIN
*p='\0'; strmaxcpy(Part,Copy,255); strcpy(Copy,p+1);
END
UpString(Part);
p=QuotPos(Part,'=');
if (p==Nil)
BEGIN
strmaxcpy(Name,Part,255); Part[0]='\0';
END
else
BEGIN
*p='\0'; strmaxcpy(Name,Part,255); strcpy(Part,p+1);
END
if (NOT ChkSymbName(Name)) return CMDErr;
if (Negate) RemoveDefSymbol(Name);
else
BEGIN
AsmParsInit();
if (Part[0]!='\0')
BEGIN
FirstPassUnknown=False;
EvalExpression(Part,&t);
if ((t.Typ==TempNone) OR (FirstPassUnknown)) return CMDErr;
END
else
BEGIN
t.Typ=TempInt; t.Contents.Int=1;
END
AddDefSymbol(Name,&t);
END
END
while (Copy[0]!='\0');
return CMDArg;
END
static CMDResult CMD_ErrorPath(Boolean Negate, String Arg)
BEGIN
if (Negate) return CMDErr;
else if (Arg[0]=='\0')
BEGIN
ErrorPath[0]='\0'; return CMDOK;
END
else
BEGIN
strncpy(ErrorPath,Arg,255); return CMDArg;
END
END
static CMDResult CMD_HardRanges(Boolean Negate, char *Arg)
BEGIN
HardRanges=Negate; return CMDOK;
END
static CMDResult CMD_OutFile(Boolean Negate, char *Arg)
BEGIN
if (Arg[0]=='\0')
if (Negate)
BEGIN
ClearOutList(); return CMDOK;
END
else return CMDErr;
else
BEGIN
if (Negate) RemoveFromOutList(Arg);
else AddToOutList(Arg);
return CMDArg;
END
END
static CMDResult CMD_ShareOutFile(Boolean Negate, char *Arg)
BEGIN
if (Arg[0]=='\0')
if (Negate)
BEGIN
ClearShareOutList(); return CMDOK;
END
else return CMDErr;
else
BEGIN
if (Negate) RemoveFromShareOutList(Arg);
else AddToShareOutList(Arg);
return CMDArg;
END
END
static Boolean CMD_CPUAlias_ChkCPUName(char *s)
BEGIN
int z;
for(z=0; z<strlen(s); z++)
if (NOT isalnum((unsigned int) s[z])) return False;
return True;
END
static CMDResult CMD_CPUAlias(Boolean Negate, char *Arg)
BEGIN
char *p;
String s1,s2;
if (Negate) return CMDErr;
else if (Arg[0]=='\0') return CMDErr;
else
BEGIN
p=strchr(Arg,'=');
if (p==Nil) return CMDErr;
else
BEGIN
*p='\0';
strmaxcpy(s1,Arg,255); UpString(s1);
strmaxcpy(s2,p+1,255); UpString(s2);
*p='=';
if (NOT (CMD_CPUAlias_ChkCPUName(s1) AND CMD_CPUAlias_ChkCPUName(s2)))
return CMDErr;
else if (NOT AddCPUAlias(s2,s1)) return CMDErr;
else return CMDArg;
END
END
END
static CMDResult CMD_SetCPU(Boolean Negate, char *Arg)
BEGIN
if (Negate)
BEGIN
*DefCPU = '\0';
return CMDOK;
END
else
BEGIN
if (*Arg == '\0') return CMDErr;
strmaxcpy(DefCPU, Arg, sizeof(DefCPU) - 1);
NLS_UpString(DefCPU);
return CMDArg;
END
END
static void ParamError(Boolean InEnv, char *Arg)
BEGIN
printf("%s%s\n",getmessage((InEnv) ? Num_ErrMsgInvEnvParam : Num_ErrMsgInvParam),Arg);
exit(4);
END
#define ASParamCnt 33
static CMDRec ASParams[ASParamCnt]=
{{"A" , CMD_BalanceTree},
{"ALIAS", CMD_CPUAlias},
{"a" , CMD_ShareAssembler},
{"C" , CMD_CrossList},
{"c" , CMD_ShareC},
{"CPU" , CMD_SetCPU},
{"D" , CMD_DefSymbol},
{"E" , CMD_ErrorPath},
{"g" , CMD_DebugMode},
{"G" , CMD_CodeOutput},
{"h" , CMD_HexLowerCase},
{"i" , CMD_IncludeList},
{"I" , CMD_MakeIncludeList},
{"L" , CMD_ListFile},
{"l" , CMD_ListConsole},
{"M" , CMD_MacroOutput},
{"n" , CMD_NumericErrors},
{"o" , CMD_OutFile},
{"P" , CMD_MacProOutput},
{"p" , CMD_SharePascal},
{"q" , CMD_QuietMode},
{"QUIET", CMD_QuietMode},
{"r" , CMD_MsgIfRepass},
{"s" , CMD_SectionList},
{"SHAREOUT", CMD_ShareOutFile},
{"t" , CMD_ListMask},
{"u" , CMD_UseList},
{"U" , CMD_CaseSensitive},
{"w" , CMD_SuppWarns},
{"WARNRANGES", CMD_HardRanges},
{"x" , CMD_ExtendErrors},
{"X" , CMD_MakeDebug},
{"Y" , CMD_ThrowErrors}};
/*--------------------------------------------------------------------------*/
#ifdef __sunos__
extern void on_exit(void (*procp)(int status, caddr_t arg),caddr_t arg);
static void GlobExitProc(int status, caddr_t arg)
BEGIN
if (MakeDebug) fclose(Debug);
END
#else
static void GlobExitProc(void)
BEGIN
if (MakeDebug) fclose(Debug);
END
#endif
static int LineZ;
static void NxtLine(void)
BEGIN
if (++LineZ==23)
BEGIN
LineZ=0;
if (Redirected!=NoRedir) return;
printf("%s",getmessage(Num_KeyWaitMsg)); fflush(stdout);
while (getchar()!='\n');
printf("%s%s",CursUp,ClrEol);
END
END
static void WrHead(void)
BEGIN
if (!QuietMode)
BEGIN
printf("%s%s\n",getmessage(Num_InfoMessMacroAss),Version); NxtLine();
printf("(%s-%s)\n",ARCHPRNAME,ARCHSYSNAME); NxtLine();
printf("%s\n",InfoMessCopyright); NxtLine();
WriteCopyrights(NxtLine);
printf("\n"); NxtLine();
END
END
int main(int argc, char **argv)
BEGIN
char *Env,*ph1,*ph2;
String Dummy;
int i;
static Boolean First=TRUE;
CMDProcessed ParUnprocessed; /* bearbeitete Kommandozeilenparameter */
ParamCount=argc-1; ParamStr=argv;
if (First)
BEGIN
endian_init(); nls_init(); bpemu_init(); stdhandl_init();
strutil_init(); stringlists_init(); chunks_init();
NLS_Initialize();
nlmessages_init("as.msg",*argv,MsgId1,MsgId2); ioerrs_init(*argv);
cmdarg_init(*argv);
asmfnums_init(); asminclist_init(); asmitree_init();
asmdef_init(); asmsub_init(); asmpars_init();
asmmac_init(); asmif_init(); asmcode_init(); asmdebug_init();
codeallg_init(); codepseudo_init();
code68k_init();
code56k_init();
code601_init();
codemcore_init();
code68_init(); code6805_init(); code6809_init(); code6812_init(); code6816_init();
codeh8_3_init(); codeh8_5_init(); code7000_init();
code65_init(); code7700_init(); code4500_init(); codem16_init(); codem16c_init();
code4004_init(); code8008_init(); code48_init(); code51_init(); code96_init(); code85_init(); code86_init(); code960_init();
code8x30x_init(); codexa_init();
codeavr_init();
code29k_init();
code166_init();
codez80_init(); codez8_init();
code96c141_init(); code90c141_init(); code87c800_init(); code47c00_init(); code97c241_init();
code16c5x_init(); code16c8x_init(); code17c4x_init();
codest6_init(); codest7_init(); codest9_init(); code6804_init();
code3201x_init(); code3202x_init(); code3203x_init(); code3205x_init(); code3206x_init();
code9900_init(); codetms7_init(); code370_init(); codemsp_init();
code78c10_init(); code75k0_init(); code78k0_init(); code7720_init(); code77230_init();
codescmp_init(); codecop8_init(); codesc14xxx_init();
codeace_init();
code53c8xx_init();
codef2mc8_init();
/*as1750_init();*/
First=FALSE;
END
#ifdef __sunos__
on_exit(GlobExitProc,(caddr_t) Nil);
#else
#ifndef __MUNIX__
atexit(GlobExitProc);
#endif
#endif
*CursUp='\0'; *ClrEol='\0';
switch (Redirected)
BEGIN
case NoRedir:
Env=getenv("USEANSI"); strncpy(Dummy,(Env!=Nil)?Env:"Y",255);
if (toupper(Dummy[0])=='N')
BEGIN
END
else
BEGIN
strcpy(ClrEol," [K"); ClrEol[0]=Char_ESC; /* ANSI-Sequenzen */
strcpy(CursUp," [A"); CursUp[0]=Char_ESC;
END
break;
case RedirToDevice:
/* Basissteuerzeichen fuer Geraete */
for (i=1; i<=20; i++) strcat(ClrEol," ");
for (i=1; i<=20; i++) strcat(ClrEol,"\b");
break;
case RedirToFile:
strcpy(ClrEol,"\n"); /* CRLF auf Datei */
END
ShareMode=0; ListMode=0; IncludeList[0]='\0'; SuppWarns=False;
MakeUseList=False; MakeCrossList=False; MakeSectionList=False;
MakeIncludeList=False; ListMask=0xff;
MakeDebug=False; ExtendErrors=0;
MacroOutput=False; MacProOutput=False; CodeOutput=True;
strcpy(ErrorPath,"!2"); MsgIfRepass=False; QuietMode=False;
NumericErrors=False; DebugMode=DebugNone; CaseSensitive=False;
ThrowErrors=False; HardRanges=True;
LineZ=0;
if (ParamCount==0)
BEGIN
WrHead();
printf("%s%s%s\n",getmessage(Num_InfoMessHead1),GetEXEName(),getmessage(Num_InfoMessHead2)); NxtLine();
for (ph1=getmessage(Num_InfoMessHelp),ph2=strchr(ph1,'\n'); ph2!=Nil; ph1=ph2+1,ph2=strchr(ph1,'\n'))
BEGIN
*ph2='\0';
printf("%s\n",ph1); NxtLine();
*ph2='\n';
END
PrintCPUList(NxtLine);
ClearCPUList();
exit(1);
END
#if defined(STDINCLUDES)
CMD_IncludeList(False,STDINCLUDES);
#endif
ProcessCMD(ASParams,ASParamCnt,ParUnprocessed,EnvName,ParamError);
/* wegen QuietMode dahinter */
WrHead();
GlobErrFlag=False;
if (ErrorPath[0]!='\0')
BEGIN
strcpy(ErrorName,ErrorPath);
unlink(ErrorName);
END
IsErrorOpen=False;
for (i=1; i<=ParamCount; i++)
if (ParUnprocessed[i]) break;
if (i>ParamCount)
BEGIN
printf("%s [%s] ",getmessage(Num_InvMsgSource),SrcSuffix); fflush(stdout);
fgets(FileMask,255,stdin);
if (FileMask[strlen(FileMask)-1]=='\n') FileMask[strlen(FileMask)-1]='\0';
AssembleGroup();
END
else
for (i=1; i<=ParamCount; i++)
if (ParUnprocessed[i])
BEGIN
strmaxcpy(FileMask,ParamStr[i],255);
AssembleGroup();
END
if ((ErrorPath[0]!='\0') AND (IsErrorOpen))
BEGIN
fclose(ErrorFile); IsErrorOpen=False;
END
ClearCPUList();
if (GlobErrFlag) return (2); else return (0);
END