diff options
Diffstat (limited to 'asmallg.c')
-rw-r--r-- | asmallg.c | 1341 |
1 files changed, 1341 insertions, 0 deletions
diff --git a/asmallg.c b/asmallg.c new file mode 100644 index 0000000..abe52a1 --- /dev/null +++ b/asmallg.c @@ -0,0 +1,1341 @@ +/* codeallg.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* von allen Codegeneratoren benutzte Pseudobefehle */ +/* */ +/* Historie: 10. 5.1996 Grundsteinlegung */ +/* 24. 6.1998 CODEPAGE-Kommando */ +/* 17. 7.1998 CHARSET ohne Argumente */ +/* 17. 8.1998 BookKeeping-Aufruf bei ALIGN */ +/* 18. 8.1998 RADIX-Kommando */ +/* 2. 1.1999 Standard-ChkPC-Routine */ +/* 9. 1.1999 BINCLUDE gefixt... */ +/* 30. 5.1999 OUTRADIX-Kommando */ +/* 12. 7.1999 EXTERN-Kommando */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include <string.h> + + +#include "nls.h" +#include "strutil.h" +#include "stringlists.h" +#include "bpemu.h" +#include "cmdarg.h" +#include "chunks.h" +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "asmmac.h" +#include "asmcode.h" +#include "asmitree.h" +#include "codepseudo.h" + +/*--------------------------------------------------------------------------*/ + +static char *PseudoStrs[3]={Nil,Nil,Nil}; + +static PInstTable PseudoTable=Nil,ONOFFTable; + +/*--------------------------------------------------------------------------*/ + + static Boolean DefChkPC(LargeWord Addr) +BEGIN + if (((1 << ActPC) & ValidSegs) == 0) return 0; + else return (Addr <= SegLimits[ActPC]); +END + + void SetCPU(CPUVar NewCPU, Boolean NotPrev) +BEGIN + LongInt HCPU; + char *z,*dest; + Boolean ECPU; + char s[11]; + PCPUDef Lauf; + + Lauf=FirstCPUDef; + while ((Lauf!=Nil) AND (Lauf->Number!=NewCPU)) Lauf=Lauf->Next; + if (Lauf==Nil) return; + + strmaxcpy(MomCPUIdent,Lauf->Name,11); + MomCPU=Lauf->Orig; + MomVirtCPU=Lauf->Number; + strmaxcpy(s,MomCPUIdent,11); + for (z=dest=s; *z!='\0'; z++) + if (((*z>='0') AND (*z<='9')) OR ((*z>='A') AND (*z<='F'))) + *(dest++)=(*z); + *dest='\0'; + for (z=s; *z!='\0'; z++) + if ((*z>='0') AND (*z<='9')) break; + if (*z!='\0') strcpy(s,z); + strprep(s,"$"); + HCPU=ConstLongInt(s,&ECPU); + if (ParamCount!=0) + BEGIN + EnterIntSymbol(MomCPUName,HCPU,SegNone,True); + EnterStringSymbol(MomCPUIdentName,MomCPUIdent,True); + END + + InternSymbol=Default_InternSymbol; + ChkPC = DefChkPC; + if (NOT NotPrev) SwitchFrom(); + Lauf->SwitchProc(); + + DontPrint=True; +END + + Boolean SetNCPU(char *Name, Boolean NoPrev) +BEGIN + PCPUDef Lauf; + + Lauf = FirstCPUDef; + while ((Lauf != Nil) AND (strcmp(Name, Lauf->Name) != 0)) + Lauf = Lauf->Next; + if (Lauf == Nil) WrXError(1430, Name); + else SetCPU(Lauf->Number, NoPrev); + return (Lauf != Nil); +END + + char *IntLine(LongInt Inp) +BEGIN + static String s; + + switch (ConstMode) + BEGIN + case ConstModeIntel: + sprintf(s,"%sH",HexString(Inp,0)); + if (*s>'9') strmaxprep(s,"0",255); + break; + case ConstModeMoto: + sprintf(s,"$%s",HexString(Inp,0)); + break; + case ConstModeC: + sprintf(s,"0x%s",HexString(Inp,0)); + break; + END + + return s; +END + + + static void CodeSECTION(Word Index) +BEGIN + PSaveSection Neu; + + if (ArgCnt!=1) WrError(1110); + else if (ExpandSymbol(ArgStr[1])) + if (NOT ChkSymbName(ArgStr[1])) WrXError(1020,ArgStr[1]); + else if ((PassNo==1) AND (GetSectionHandle(ArgStr[1],False,MomSectionHandle)!=-2)) WrError(1483); + else + BEGIN + Neu=(PSaveSection) malloc(sizeof(TSaveSection)); + Neu->Next=SectionStack; + Neu->Handle=MomSectionHandle; + Neu->LocSyms=Nil; Neu->GlobSyms=Nil; Neu->ExportSyms=Nil; + SetMomSection(GetSectionHandle(ArgStr[1],True,MomSectionHandle)); + SectionStack=Neu; + END +END + + + static void CodeENDSECTION_ChkEmptList(PForwardSymbol *Root) +BEGIN + PForwardSymbol Tmp; + + while (*Root!=Nil) + BEGIN + WrXError(1488,(*Root)->Name); + free((*Root)->Name); + Tmp=(*Root); *Root=Tmp->Next; free(Tmp); + END +END + + static void CodeENDSECTION(Word Index) +BEGIN + PSaveSection Tmp; + + if (ArgCnt>1) WrError(1110); + else if (SectionStack==Nil) WrError(1487); + else if ((ArgCnt==0) OR (ExpandSymbol(ArgStr[1]))) + if ((ArgCnt==1) AND (GetSectionHandle(ArgStr[1],False,SectionStack->Handle)!=MomSectionHandle)) WrError(1486); + else + BEGIN + Tmp=SectionStack; SectionStack=Tmp->Next; + CodeENDSECTION_ChkEmptList(&(Tmp->LocSyms)); + CodeENDSECTION_ChkEmptList(&(Tmp->GlobSyms)); + CodeENDSECTION_ChkEmptList(&(Tmp->ExportSyms)); + TossRegDefs(MomSectionHandle); + if (ArgCnt==0) + sprintf(ListLine,"[%s]",GetSectionName(MomSectionHandle)); + SetMomSection(Tmp->Handle); + free(Tmp); + END +END + + + static void CodeCPU(Word Index) +BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else + BEGIN + NLS_UpString(ArgStr[1]); + if (SetNCPU(ArgStr[1], False)) ActPC = SegCode; + END +END + + + static void CodeSETEQU(Word Index) +BEGIN + TempResult t; + Boolean MayChange; + Integer DestSeg; + + FirstPassUnknown=False; + MayChange=((NOT Memo("EQU")) AND (NOT Memo("="))); + if (*AttrPart!='\0') WrError(1100); + else if ((ArgCnt<1) OR (ArgCnt>2)) WrError(1110); + else + BEGIN + EvalExpression(ArgStr[1],&t); + if (NOT FirstPassUnknown) + BEGIN + if (ArgCnt==1) DestSeg=SegNone; + else + BEGIN + NLS_UpString(ArgStr[2]); + if (strcmp(ArgStr[2],"MOMSEGMENT")==0) DestSeg=ActPC; + else if (*ArgStr[2]=='\0') DestSeg=SegNone; + else + BEGIN + DestSeg=0; + while ((DestSeg<=PCMax) AND + (strcmp(ArgStr[2],SegNames[DestSeg])!=0)) + DestSeg++; + END + END + if (DestSeg>PCMax) WrXError(1961,ArgStr[2]); + else + BEGIN + SetListLineVal(&t); + PushLocHandle(-1); + switch (t.Typ) + BEGIN + case TempInt : EnterIntSymbol (LabPart,t.Contents.Int,DestSeg,MayChange); break; + case TempFloat : EnterFloatSymbol (LabPart,t.Contents.Float,MayChange); break; + case TempString: EnterStringSymbol(LabPart,t.Contents.Ascii,MayChange); break; + case TempNone : break; + END + PopLocHandle(); + END + END + END +END + + + static void CodeORG(Word Index) +BEGIN + LargeInt HVal; + Boolean ValOK; + + FirstPassUnknown=False; + if (*AttrPart!='\0') WrError(1100); + else if (ArgCnt!=1) WrError(1110); + else + BEGIN +#ifndef HAS64 + HVal=EvalIntExpression(ArgStr[1],UInt32,&ValOK); +#else + HVal=EvalIntExpression(ArgStr[1],Int64,&ValOK); +#endif + if (FirstPassUnknown) WrError(1820); + if ((ValOK) AND (NOT FirstPassUnknown)) + BEGIN + PCs[ActPC]=HVal; DontPrint=True; + END + END +END + + + static void CodeSHARED_BuildComment(char *c) +BEGIN + switch (ShareMode) + BEGIN + case 1: sprintf(c,"(* %s *)",CommPart); break; + case 2: sprintf(c,"/* %s */",CommPart); break; + case 3: sprintf(c,"; %s",CommPart); break; + END +END + + static void CodeSHARED(Word Index) +BEGIN + int z; + Boolean ValOK; + LargeInt HVal; + Double FVal; + String s,c; + + if (ShareMode==0) WrError(30); + else if ((ArgCnt==0) AND (*CommPart!='\0')) + BEGIN + CodeSHARED_BuildComment(c); + errno=0; fprintf(ShareFile,"%s\n",c); ChkIO(10004); + END + else + for (z=1; z<=ArgCnt; z++) + BEGIN + if (IsSymbolString(ArgStr[z])) + BEGIN + ValOK=GetStringSymbol(ArgStr[z],s); + if (ShareMode==1) + BEGIN + strmaxprep(s,"\'",255); strmaxcat(s,"\'",255); + END + else + BEGIN + strmaxprep(s,"\"",255); strmaxcat(s,"\"",255); + END + END + else if (IsSymbolFloat(ArgStr[z])) + BEGIN + ValOK=GetFloatSymbol(ArgStr[z],&FVal); + sprintf(s,"%0.17g",FVal); + END + else + BEGIN + ValOK=GetIntSymbol(ArgStr[z],&HVal); + switch (ShareMode) + BEGIN + case 1: sprintf(s,"$%s",HexString(HVal,0)); break; + case 2: sprintf(s,"0x%s",HexString(HVal,0)); break; + case 3: strmaxcpy(s,IntLine(HVal),255); break; + END + END + if (ValOK) + BEGIN + if ((z==1) AND (*CommPart!='\0')) + BEGIN + CodeSHARED_BuildComment(c); strmaxprep(c," ",255); + END + else *c='\0'; + errno=0; + switch (ShareMode) + BEGIN + case 1: + fprintf(ShareFile,"%s = %s;%s\n",ArgStr[z],s,c); break; + case 2: + fprintf(ShareFile,"#define %s %s%s\n",ArgStr[z],s,c); break; + case 3: + strmaxprep(s,IsSymbolChangeable(ArgStr[z])?"set ":"equ ",255); + fprintf(ShareFile,"%s %s%s\n",ArgStr[z],s,c); break; + END + ChkIO(10004); + END + else if (PassNo==1) + BEGIN + Repass=True; + if ((MsgIfRepass) AND (PassNo>=PassNoForMessage)) WrXError(170,ArgStr[z]); + END + END +END + + + static void CodePAGE(Word Index) +BEGIN + Integer LVal,WVal; + Boolean ValOK; + + if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else + BEGIN + LVal=EvalIntExpression(ArgStr[1],UInt8,&ValOK); + if (ValOK) + BEGIN + if ((LVal<5) AND (LVal!=0)) LVal=5; + if (ArgCnt==1) + BEGIN + WVal=0; ValOK=True; + END + else WVal=EvalIntExpression(ArgStr[2],UInt8,&ValOK); + if (ValOK) + BEGIN + if ((WVal<5) AND (WVal!=0)) WVal=5; + PageLength=LVal; PageWidth=WVal; + END + END + END +END + + + static void CodeNEWPAGE(Word Index) +BEGIN + ShortInt HVal8; + Boolean ValOK; + + if (ArgCnt>1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else + BEGIN + if (ArgCnt==0) + BEGIN + HVal8=0; ValOK=True; + END + else HVal8=EvalIntExpression(ArgStr[1],Int8,&ValOK); + if ((ValOK) OR (ArgCnt==0)) + BEGIN + if (HVal8>ChapMax) HVal8=ChapMax; + else if (HVal8<0) HVal8=0; + NewPage(HVal8,True); + END + END +END + + + static void CodeString(Word Index) +BEGIN + String tmp; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + EvalStringExpression(ArgStr[1],&OK,tmp); + if (NOT OK) WrError(1970); else strmaxcpy(PseudoStrs[Index],tmp,255); + END +END + + + static void CodePHASE(Word Index) +BEGIN + Boolean OK; + LongInt HVal; + + if (ArgCnt!=1) WrError(1110); + else if (ActPC==StructSeg) WrError(1553); + else + BEGIN + HVal=EvalIntExpression(ArgStr[1],Int32,&OK); + if (OK) Phases[ActPC]=HVal-ProgCounter(); + END +END + + + static void CodeDEPHASE(Word Index) +BEGIN + if (ArgCnt!=0) WrError(1110); + else if (ActPC==StructSeg) WrError(1553); + else Phases[ActPC]=0; +END + + + static void CodeWARNING(Word Index) +BEGIN + String mess; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + EvalStringExpression(ArgStr[1],&OK,mess); + if (NOT OK) WrError(1970); + else WrErrorString(mess,"",True,False); + END +END + + + static void CodeMESSAGE(Word Index) +BEGIN + String mess; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + EvalStringExpression(ArgStr[1],&OK,mess); + if (NOT OK) WrError(1970); + printf("%s%s\n",mess,ClrEol); + if (strcmp(LstName,"/dev/null")!=0) WrLstLine(mess); + END +END + + + static void CodeERROR(Word Index) +BEGIN + String mess; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + EvalStringExpression(ArgStr[1],&OK,mess); + if (NOT OK) WrError(1970); + else WrErrorString(mess,"",False,False); + END +END + + + static void CodeFATAL(Word Index) +BEGIN + String mess; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + EvalStringExpression(ArgStr[1],&OK,mess); + if (NOT OK) WrError(1970); + else WrErrorString(mess,"",False,True); + END +END + + static void CodeCHARSET(Word Index) +BEGIN + TempResult t; + FILE *f; + unsigned char tfield[256]; + LongWord Start,l,TStart,Stop,z; + Boolean OK; + + if (ArgCnt>3) WrError(1110); + else if (ArgCnt==0) + BEGIN + for (z=0; z<256; z++) CharTransTable[z]=z; + END + else + BEGIN + FirstPassUnknown=False; EvalExpression(ArgStr[1],&t); + switch (t.Typ) + BEGIN + case TempInt: + if (FirstPassUnknown) t.Contents.Int&=255; + if (ChkRange(t.Contents.Int,0,255)) + if (ArgCnt<2) WrError(1110); + else + BEGIN + Start=t.Contents.Int; + FirstPassUnknown=False; EvalExpression(ArgStr[2],&t); + switch (t.Typ) + BEGIN + case TempInt: /* Übersetzungsbereich als Character-Angabe */ + if (FirstPassUnknown) t.Contents.Int&=255; + if (ArgCnt==2) + BEGIN + Stop=Start; TStart=t.Contents.Int; + OK=ChkRange(TStart,0,255); + END + else + BEGIN + Stop=t.Contents.Int; OK=ChkRange(Stop,Start,255); + if (OK) TStart=EvalIntExpression(ArgStr[3],UInt8,&OK); + else TStart=0; + END + if (OK) + for (z=Start; z<=Stop; z++) CharTransTable[z]=TStart+(z-Start); + break; + case TempString: + l=strlen(t.Contents.Ascii); /* Übersetzungsstring ab Start */ + if (Start+l>256) WrError(1320); + else + for (z=0; z<l; z++) + CharTransTable[Start+z]=t.Contents.Ascii[z]; + break; + case TempFloat: + WrError(1135); + break; + default: + break; + END + END + break; + case TempString: + if (ArgCnt!=1) WrError(1110); /* Tabelle von Datei lesen */ + else + BEGIN + f=fopen(t.Contents.Ascii,OPENRDMODE); + if (f==Nil) ChkIO(10001); + if (fread(tfield,sizeof(char),256,f)!=256) ChkIO(10003); + fclose(f); memcpy(CharTransTable,tfield,sizeof(char)*256); + END + break; + case TempFloat: + WrError(1135); + break; + default: + break; + END + END +END + + static void CodePRSET(Word Index) +BEGIN + int z,z2; + + for (z=0; z<16; z++) + BEGIN + for (z2=0; z2<16; z2++) printf(" %02x",CharTransTable[z*16+z2]); + printf(" "); + for (z2=0; z2<16; z2++) printf("%c",CharTransTable[z*16+z2]>' ' ? CharTransTable[z*16+z2] : '.'); + putchar('\n'); + END +END + + static void CodeCODEPAGE(Word Index) +BEGIN + PTransTable Prev,Run,New,Source; + int erg=0; + + if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); + else if (NOT ChkSymbName(ArgStr[1])) WrXError(1020,ArgStr[1]); + else + BEGIN + if (NOT CaseSensitive) + BEGIN + UpString(ArgStr[1]); + if (ArgCnt==2) UpString(ArgStr[2]); + END + + if (ArgCnt==1) Source=CurrTransTable; + else + for (Source=TransTables; Source!=Nil; Source=Source->Next) + if (strcmp(Source->Name,ArgStr[2])==0) break; + + if (Source==Nil) WrXError(1610,ArgStr[2]); + else + BEGIN + for (Prev=Nil,Run=TransTables; Run!=Nil; Prev=Run,Run=Run->Next) + if ((erg=strcmp(ArgStr[1],Run->Name))<=0) break; + + if ((Run==Nil) OR (erg<0)) + BEGIN + New=(PTransTable) malloc(sizeof(TTransTable)); + New->Next=Run; + New->Name=strdup(ArgStr[1]); + New->Table=(unsigned char *) malloc(256*sizeof(char)); + memcpy(New->Table,Source->Table,256*sizeof(char)); + if (Prev==Nil) TransTables=New; else Prev->Next=New; + CurrTransTable=New; + END + else CurrTransTable=Run; + END + END +END + + + static void CodeFUNCTION(Word Index) +BEGIN + String FName; + Boolean OK; + int z; + + if (ArgCnt<2) WrError(1110); + else + BEGIN + OK=True; z=1; + do + BEGIN + OK=(OK AND ChkMacSymbName(ArgStr[z])); + if (NOT OK) WrXError(1020,ArgStr[z]); + z++; + END + while ((z<ArgCnt) AND (OK)); + if (OK) + BEGIN + strmaxcpy(FName,ArgStr[ArgCnt],255); + for (z=1; z<ArgCnt; z++) + CompressLine(ArgStr[z],z,FName); + EnterFunction(LabPart,FName,ArgCnt-1); + END + END +END + + + static void CodeSAVE(Word Index) +BEGIN + PSaveState Neu; + + if (ArgCnt!=0) WrError(1110); + else + BEGIN + Neu=(PSaveState) malloc(sizeof(TSaveState)); + Neu->Next=FirstSaveState; + Neu->SaveCPU=MomCPU; + Neu->SavePC=ActPC; + Neu->SaveListOn=ListOn; + Neu->SaveLstMacroEx=LstMacroEx; + Neu->SaveTransTable=CurrTransTable; + FirstSaveState=Neu; + END +END + + + static void CodeRESTORE(Word Index) +BEGIN + PSaveState Old; + + if (ArgCnt!=0) WrError(1110); + else if (FirstSaveState==Nil) WrError(1450); + else + BEGIN + Old=FirstSaveState; FirstSaveState=Old->Next; + if (Old->SavePC!=ActPC) + BEGIN + ActPC=Old->SavePC; DontPrint=True; + END + if (Old->SaveCPU!=MomCPU) SetCPU(Old->SaveCPU,False); + EnterIntSymbol(ListOnName,ListOn=Old->SaveListOn,0,True); + SetFlag(&LstMacroEx,LstMacroExName,Old->SaveLstMacroEx); + CurrTransTable=Old->SaveTransTable; + free(Old); + END +END + + + static void CodeSEGMENT(Word Index) +BEGIN + Byte SegZ; + Word Mask; + Boolean Found; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + Found=False; NLS_UpString(ArgStr[1]); + for (SegZ=1,Mask=2; SegZ<=PCMax; SegZ++,Mask<<=1) + if (((ValidSegs&Mask)!=0) AND (strcmp(ArgStr[1],SegNames[SegZ])==0)) + BEGIN + Found=True; + if (ActPC!=SegZ) + BEGIN + ActPC=SegZ; + if (NOT PCsUsed[ActPC]) PCs[ActPC]=SegInits[ActPC]; + PCsUsed[ActPC]=True; + DontPrint=True; + END + END + if (NOT Found) WrXError(1961,ArgStr[1]); + END +END + + + static void CodeLABEL(Word Index) +BEGIN + LongInt Erg; + Boolean OK; + + FirstPassUnknown=False; + if (ArgCnt!=1) WrError(1110); + else + BEGIN + Erg=EvalIntExpression(ArgStr[1],Int32,&OK); + if ((OK) AND (NOT FirstPassUnknown)) + BEGIN + PushLocHandle(-1); + EnterIntSymbol(LabPart,Erg,SegCode,False); + sprintf(ListLine,"=%s",IntLine(Erg)); + PopLocHandle(); + END + END +END + + + static void CodeREAD(Word Index) +BEGIN + String Exp; + TempResult Erg; + Boolean OK; + LongInt SaveLocHandle; + + if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); + else + BEGIN + if (ArgCnt==2) EvalStringExpression(ArgStr[1],&OK,Exp); + else + BEGIN + sprintf(Exp,"Read %s ? ",ArgStr[1]); OK=True; + END + if (OK) + BEGIN + setbuf(stdout,Nil); printf("%s",Exp); + fgets(Exp,255,stdin); UpString(Exp); + FirstPassUnknown=False; + EvalExpression(Exp,&Erg); + if (OK) + BEGIN + SetListLineVal(&Erg); + SaveLocHandle=MomLocHandle; MomLocHandle=(-1); + if (FirstPassUnknown) WrError(1820); + else switch (Erg.Typ) + BEGIN + case TempInt : EnterIntSymbol(ArgStr[ArgCnt],Erg.Contents.Int,SegNone,True); break; + case TempFloat : EnterFloatSymbol(ArgStr[ArgCnt],Erg.Contents.Float,True); break; + case TempString: EnterStringSymbol(ArgStr[ArgCnt],Erg.Contents.Ascii,True); break; + case TempNone : break; + END + MomLocHandle=SaveLocHandle; + END + END + END +END + + static void CodeRADIX(Word Index) +BEGIN + Boolean OK; + LargeWord tmp; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + tmp=ConstLongInt(ArgStr[1],&OK); + if (NOT OK) WrError(1135); + else if (ChkRange(tmp,2,36)) + BEGIN + if (Index == 1) OutRadixBase = tmp; + else RadixBase = tmp; + END + END +END + + static void CodeALIGN(Word Index) +BEGIN + Word Dummy; + Boolean OK; + LongInt NewPC; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + FirstPassUnknown=False; + Dummy=EvalIntExpression(ArgStr[1],Int16,&OK); + if (OK) + if (FirstPassUnknown) WrError(1820); + else + BEGIN + NewPC=ProgCounter()+Dummy-1; + NewPC-=NewPC%Dummy; + CodeLen=NewPC-ProgCounter(); + DontPrint=(CodeLen!=0); + if (DontPrint) BookKeeping(); + END + END +END + + + static void CodeENUM(Word Index) +BEGIN + int z; + char *p=Nil; + Boolean OK; + LongInt Counter,First=0,Last=0; + String SymPart; + + Counter=0; + if (ArgCnt==0) WrError(1110); + else + for (z=1; z<=ArgCnt; z++) + BEGIN + p=QuotPos(ArgStr[z],'='); + if (p!=Nil) + BEGIN + strmaxcpy(SymPart,p+1,255); + FirstPassUnknown=False; + Counter=EvalIntExpression(SymPart,Int32,&OK); + if (NOT OK) return; + if (FirstPassUnknown) + BEGIN + WrXError(1820,SymPart); return; + END + *p='\0'; + END + EnterIntSymbol(ArgStr[z],Counter,SegNone,False); + if (z==1) First=Counter; + else if (z==ArgCnt) Last=Counter; + Counter++; + END + sprintf(ListLine,"=%s",IntLine(First)); + if (ArgCnt!=1) + BEGIN + strmaxcat(ListLine,"..",255); + strmaxcat(ListLine,IntLine(Last),255); + END +END + + + static void CodeEND(Word Index) +BEGIN + LongInt HVal; + Boolean OK; + + if (ArgCnt>1) WrError(1110); + else + BEGIN + if (ArgCnt==1) + BEGIN + FirstPassUnknown=False; + HVal=EvalIntExpression(ArgStr[1],Int32,&OK); + if ((OK) AND (NOT FirstPassUnknown)) + BEGIN + ChkSpace(SegCode); + StartAdr=HVal; + StartAdrPresent=True; + END + END + ENDOccured=True; + END +END + + + static void CodeLISTING(Word Index) +BEGIN + Byte Value=0xff; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else + BEGIN + OK=True; NLS_UpString(ArgStr[1]); + if (strcmp(ArgStr[1],"OFF")==0) Value=0; + else if (strcmp(ArgStr[1],"ON")==0) Value=1; + else if (strcmp(ArgStr[1],"NOSKIPPED")==0) Value=2; + else if (strcmp(ArgStr[1],"PURECODE")==0) Value=3; + else OK=False; + if (NOT OK) WrError(1520); + else EnterIntSymbol(ListOnName,ListOn=Value,0,True); + END +END + + static void CodeBINCLUDE(Word Index) +BEGIN + FILE *F; + LongInt Len=(-1); + LongWord Ofs=0,Curr,Rest,FSize; + Word RLen; + Boolean OK,SaveTurnWords; + LargeWord OldPC; + String Name; + + if ((ArgCnt<1) OR (ArgCnt>3)) WrError(1110); + else if (ActPC==StructSeg) WrError(1940); + else + BEGIN + if (ArgCnt==1) OK=True; + else + BEGIN + FirstPassUnknown=False; + Ofs=EvalIntExpression(ArgStr[2],Int32,&OK); + if (FirstPassUnknown) + BEGIN + WrError(1820); OK=False; + END + if (OK) + if (ArgCnt==2) Len=(-1); + else + BEGIN + Len=EvalIntExpression(ArgStr[3],Int32,&OK); + if (FirstPassUnknown) + BEGIN + WrError(1820); OK=False; + END + END + END + if (OK) + BEGIN + strmaxcpy(Name,ArgStr[1],255); + if (*Name=='"') strcpy(Name,Name+1); + if (Name[strlen(Name)-1]=='"') Name[strlen(Name)-1]='\0'; + strmaxcpy(ArgStr[1],Name,255); + strmaxcpy(Name,FExpand(FSearch(Name,IncludeList)),255); + if (Name[strlen(Name)-1]=='/') strmaxcat(Name,ArgStr[1],255); + F=fopen(Name,OPENRDMODE); ChkIO(10001); + FSize=FileSize(F); ChkIO(10003); + if (Len==-1) + if ((Len=FSize-Ofs)<0) + BEGIN + fclose(F); WrError(1600); return; + END + if (NOT ChkPC(PCs[ActPC]+Len-1)) WrError(1925); + else + BEGIN + fseek(F,Ofs,SEEK_SET); ChkIO(10003); + Rest=Len; SaveTurnWords=TurnWords; TurnWords=False; + OldPC = ProgCounter(); + do + BEGIN + if (Rest<MaxCodeLen) Curr=Rest; else Curr=MaxCodeLen; + RLen=fread(BAsmCode,1,Curr,F); ChkIO(10003); + CodeLen=RLen; + WriteBytes(); + PCs[ActPC]+=CodeLen; + Rest-=RLen; + END + while ((Rest!=0) AND (RLen==Curr)); + if (Rest!=0) WrError(1600); + TurnWords=SaveTurnWords; + DontPrint=True; CodeLen=ProgCounter()-OldPC; + PCs[ActPC]=OldPC; + END + fclose(F); + END + END +END + + static void CodePUSHV(Word Index) +BEGIN + int z; + + if (ArgCnt<2) WrError(1110); + else + BEGIN + if (NOT CaseSensitive) NLS_UpString(ArgStr[1]); + for (z=2; z<=ArgCnt; z++) + PushSymbol(ArgStr[z],ArgStr[1]); + END +END + + static void CodePOPV(Word Index) +BEGIN + int z; + + if (ArgCnt<2) WrError(1110); + else + BEGIN + if (NOT CaseSensitive) NLS_UpString(ArgStr[1]); + for (z=2; z<=ArgCnt; z++) + PopSymbol(ArgStr[z],ArgStr[1]); + END +END + + static PForwardSymbol CodePPSyms_SearchSym(PForwardSymbol Root, char *Comp) +BEGIN + PForwardSymbol Lauf=Root; + + while ((Lauf!=Nil) AND (strcmp(Lauf->Name,Comp)!=0)) Lauf=Lauf->Next; + return Lauf; +END + + + static void CodeSTRUCT(Word Index) +BEGIN + PStructure NStruct; + int z; + Boolean OK; + + if (ArgCnt>1) WrError(1110); + else if (NOT ChkSymbName(LabPart)) WrXError(1020,LabPart); + else + BEGIN + if (NOT CaseSensitive) NLS_UpString(LabPart); + if (StructureStack!=Nil) StructureStack->CurrPC=ProgCounter(); + NStruct=(PStructure) malloc(sizeof(TStructure)); + NStruct->Name=strdup(LabPart); + NStruct->CurrPC=0; NStruct->DoExt=True; + NStruct->Next=StructureStack; + OK=True; + for (z=1; z<=ArgCnt; z++) + if (OK) + if (strcasecmp(ArgStr[z],"EXTNAMES")==0) NStruct->DoExt=True; + else if (strcasecmp(ArgStr[z],"NOEXTNAMES")==0) NStruct->DoExt=False; + else + BEGIN + WrXError(1554,ArgStr[z]); OK=False; + END + if (OK) + BEGIN + StructureStack=NStruct; + if (ActPC!=StructSeg) StructSaveSeg=ActPC; ActPC=StructSeg; + PCs[ActPC]=0; + Phases[ActPC]=0; + Grans[ActPC]=Grans[SegCode]; ListGrans[ActPC]=ListGrans[SegCode]; + ClearChunk(SegChunks+StructSeg); + CodeLen=0; DontPrint=True; + END + else + BEGIN + free(NStruct->Name); free(NStruct); + END + END +END + + static void CodeENDSTRUCT(Word Index) +BEGIN + Boolean OK; + PStructure OStruct; + TempResult t; + String tmp; + + if (ArgCnt>1) WrError(1110); + else if (StructureStack==Nil) WrError(1550); + else + BEGIN + if (*LabPart=='\0') OK=True; + else + BEGIN + if (NOT CaseSensitive) NLS_UpString(LabPart); + OK=(strcmp(LabPart,StructureStack->Name)==0); + if (NOT OK) WrError(1552); + END + if (OK) + BEGIN + OStruct=StructureStack; StructureStack=OStruct->Next; + if (ArgCnt==0) sprintf(tmp,"%s_len",OStruct->Name); + else strmaxcpy(tmp,ArgStr[1],255); + EnterIntSymbol(tmp,ProgCounter(),SegNone,False); + t.Typ=TempInt; t.Contents.Int=ProgCounter(); SetListLineVal(&t); + free(OStruct->Name); + free(OStruct); + if (StructureStack==Nil) ActPC=StructSaveSeg; + else PCs[ActPC]+=StructureStack->CurrPC; + ClearChunk(SegChunks+StructSeg); + CodeLen=0; DontPrint=True; + END + END +END + + static void CodeEXTERN(Word Index) +BEGIN + char *Split; + int i; + Boolean OK; + Byte Type; + + if (ArgCnt < 1) WrError(1110); + else + BEGIN + i = 1; OK = True; + while ((OK) && (i <= ArgCnt)) + BEGIN + Split = strrchr(ArgStr[i], ':'); + if (Split == NULL) + Type = SegNone; + else + BEGIN + for (Type = SegNone + 1; Type <= PCMax; Type++) + if (strcasecmp(Split + 1, SegNames[Type]) == 0) + break; + if (Type > PCMax) WrXError(1961, Split + 1); + else + BEGIN + *Split = '\0'; + EnterExtSymbol(ArgStr[i], 0, Type, FALSE); + END + END + i++; + END + END +END + + static void CodePPSyms(PForwardSymbol *Orig, + PForwardSymbol *Alt1, + PForwardSymbol *Alt2) +BEGIN + PForwardSymbol Lauf; + int z; + String Sym,Section; + + if (ArgCnt==0) WrError(1110); + else + for (z=1; z<=ArgCnt; z++) + BEGIN + SplitString(ArgStr[z],Sym,Section,QuotPos(ArgStr[z],':')); + if (NOT ExpandSymbol(Sym)) return; + if (NOT ExpandSymbol(Section)) return; + if (NOT CaseSensitive) NLS_UpString(Sym); + Lauf=CodePPSyms_SearchSym(*Alt1,Sym); + if (Lauf!=Nil) WrXError(1489,ArgStr[z]); + else + BEGIN + Lauf=CodePPSyms_SearchSym(*Alt2,Sym); + if (Lauf!=Nil) WrXError(1489,ArgStr[z]); + else + BEGIN + Lauf=CodePPSyms_SearchSym(*Orig,Sym); + if (Lauf==Nil) + BEGIN + Lauf=(PForwardSymbol) malloc(sizeof(TForwardSymbol)); + Lauf->Next=(*Orig); *Orig=Lauf; + Lauf->Name=strdup(Sym); + END + IdentifySection(Section,&(Lauf->DestSection)); + END + END + END +END + +/*------------------------------------------------------------------------*/ + +#define ONOFFMax 32 +static int ONOFFCnt=0; +typedef struct + { + Boolean Persist,*FlagAddr; + char *FlagName,*InstName; + } ONOFFTab; +static ONOFFTab ONOFFList[ONOFFMax]; + + static void DecodeONOFF(Word Index) +BEGIN + ONOFFTab *Tab=ONOFFList+Index; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + NLS_UpString(ArgStr[1]); + if (*AttrPart!='\0') WrError(1100); + else if ((strcasecmp(ArgStr[1],"ON")!=0) AND (strcasecmp(ArgStr[1],"OFF")!=0)) WrError(1520); + else + BEGIN + OK=(strcasecmp(ArgStr[1],"ON")==0); + SetFlag(Tab->FlagAddr,Tab->FlagName,OK); + END + END +END + + void AddONOFF(char *InstName, Boolean *Flag, char *FlagName, Boolean Persist) +BEGIN + if (ONOFFCnt==ONOFFMax) exit(255); + ONOFFList[ONOFFCnt].Persist=Persist; + ONOFFList[ONOFFCnt].FlagAddr=Flag; + ONOFFList[ONOFFCnt].FlagName=FlagName; + ONOFFList[ONOFFCnt].InstName=InstName; + AddInstTable(ONOFFTable,InstName,ONOFFCnt++,DecodeONOFF); +END + + void ClearONOFF(void) +BEGIN + int z,z2; + + for (z=0; z<ONOFFCnt; z++) + if (NOT ONOFFList[z].Persist) break; + + for (z2=ONOFFCnt-1; z2>=z; z2--) + RemoveInstTable(ONOFFTable,ONOFFList[z2].InstName); + + ONOFFCnt=z; +END + +/*------------------------------------------------------------------------*/ + +typedef struct + { + char *Name; + void (*Proc)( +#ifdef __PROTOS__ + Word Index +#endif + ); + } PseudoOrder; +static PseudoOrder Pseudos[]= + {{"ALIGN", CodeALIGN }, + {"BINCLUDE", CodeBINCLUDE }, + {"CHARSET", CodeCHARSET }, + {"CODEPAGE", CodeCODEPAGE }, + {"CPU", CodeCPU }, + {"DEPHASE", CodeDEPHASE }, + {"END", CodeEND }, + {"ENDSECTION", CodeENDSECTION}, + {"ENDSTRUCT", CodeENDSTRUCT }, + {"ENUM", CodeENUM }, + {"ERROR", CodeERROR }, + {"EXTERN", CodeEXTERN }, + {"FATAL", CodeFATAL }, + {"FUNCTION", CodeFUNCTION }, + {"LABEL", CodeLABEL }, + {"LISTING", CodeLISTING }, + {"MESSAGE", CodeMESSAGE }, + {"NEWPAGE", CodeNEWPAGE }, + {"ORG", CodeORG }, + {"PAGE", CodePAGE }, + {"PHASE", CodePHASE }, + {"POPV", CodePOPV }, + {"PRSET", CodePRSET }, + {"PUSHV", CodePUSHV }, + {"RADIX", CodeRADIX }, + {"READ", CodeREAD }, + {"RESTORE", CodeRESTORE }, + {"SAVE", CodeSAVE }, + {"SECTION", CodeSECTION }, + {"SEGMENT", CodeSEGMENT }, + {"SHARED", CodeSHARED }, + {"STRUCT", CodeSTRUCT }, + {"WARNING", CodeWARNING }, + {"" , Nil }}; + + Boolean CodeGlobalPseudo(void) +BEGIN + switch (*OpPart) + BEGIN + case 'S': + if ((NOT SetIsOccupied) AND (Memo("SET"))) + BEGIN + CodeSETEQU(0); return True; + END + break; + case 'E': + if ((SetIsOccupied) AND (Memo("EVAL"))) + BEGIN + CodeSETEQU(0); return True; + END + break; + END + + if (LookupInstTable(ONOFFTable,OpPart)) return True; + + if (LookupInstTable(PseudoTable,OpPart)) return True; + + if (SectionStack!=Nil) + BEGIN + if (Memo("FORWARD")) + BEGIN + if (PassNo<=MaxSymPass) + CodePPSyms(&(SectionStack->LocSyms), + &(SectionStack->GlobSyms), + &(SectionStack->ExportSyms)); + return True; + END + if (Memo("PUBLIC")) + BEGIN + CodePPSyms(&(SectionStack->GlobSyms), + &(SectionStack->LocSyms), + &(SectionStack->ExportSyms)); + return True; + END + if (Memo("GLOBAL")) + BEGIN + CodePPSyms(&(SectionStack->ExportSyms), + &(SectionStack->LocSyms), + &(SectionStack->GlobSyms)); + return True; + END + END + + return False; +END + + + void codeallg_init(void) +BEGIN + PseudoOrder *POrder; + + PseudoStrs[0]=PrtInitString; + PseudoStrs[1]=PrtExitString; + PseudoStrs[2]=PrtTitleString; + + PseudoTable=CreateInstTable(201); + for (POrder=Pseudos; POrder->Proc!=Nil; POrder++) + AddInstTable(PseudoTable,POrder->Name,0,POrder->Proc); + AddInstTable(PseudoTable,"OUTRADIX", 1, CodeRADIX); + AddInstTable(PseudoTable,"EQU",0,CodeSETEQU); + AddInstTable(PseudoTable,"=",0,CodeSETEQU); + AddInstTable(PseudoTable,":=",0,CodeSETEQU); + AddInstTable(PseudoTable,"PRTINIT",0,CodeString); + AddInstTable(PseudoTable,"PRTEXIT",1,CodeString); + AddInstTable(PseudoTable,"TITLE",2,CodeString); + ONOFFTable=CreateInstTable(47); + AddONOFF("MACEXP",&LstMacroEx,LstMacroExName,True); + AddONOFF("RELAXED",&RelaxedMode,RelaxedName,True); +END |