/* codepseudo.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Haeufiger benutzte Pseudo-Befehle */ /* */ /* Historie: 23. 5.1996 Grundsteinlegung */ /* 7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars */ /* 18. 8.1998 BookKeeping-Aufrufe bei SPeicherreservierungen */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include "nls.h" #include "bpemu.h" #include "endian.h" #include "strutil.h" #include "chunks.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "asmallg.h" #include "asmitree.h" #include "codepseudo.h" int FindInst(void *Field, int Size, int Count) BEGIN char *cptr,**ptr; #ifdef OPT int l=0,r=Count-1,m,res; while (TRUE) BEGIN m=(l+r)>>1; cptr=((char *) Field)+(Size*m); ptr=(char**) cptr; res=strcmp(*ptr,OpPart); if (res==0) return m; else if (l==r) return -1; else if (res<0) BEGIN if (r-l==1) return -1; else l=m; END else r=m; END #else int z,res; cptr=(char *) Field; for (z=0; z0) return -1; cptr+=Size; END return -1; #endif END Boolean IsIndirect(char *Asc) BEGIN int z,Level,l; if (((l=strlen(Asc))<=2) OR (Asc[0]!='(') OR (Asc[l-1]!=')')) return False; Level=0; for (z=1; z<=l-2; z++) BEGIN if (Asc[z]=='(') Level++; if (Asc[z]==')') Level--; if (Level<0) return False; END return True; END static enum{DSNone,DSConstant,DSSpace} DSFlag; typedef Boolean (*TLayoutFunc)( #ifdef __PROTOS__ char *Asc, Word *Cnt, Boolean Turn #endif ); static Boolean LayoutByte(char *Asc, Word *Cnt, Boolean Turn) BEGIN Boolean Result; TempResult t; Result=False; if (strcmp(Asc,"?")==0) BEGIN if (DSFlag==DSConstant) WrError(1930); else BEGIN *Cnt=1; Result=True; DSFlag=DSSpace; CodeLen++; END return Result; END else BEGIN if (DSFlag==DSSpace) BEGIN WrError(1930); return Result; END else DSFlag=DSConstant; END FirstPassUnknown=False; EvalExpression(Asc,&t); switch (t.Typ) BEGIN case TempInt: if (FirstPassUnknown) t.Contents.Int&=0xff; if (NOT RangeCheck(t.Contents.Int,Int8)) WrError(1320); else BEGIN BAsmCode[CodeLen++]=t.Contents.Int; *Cnt=1; Result=True; END; break; case TempFloat: WrError(1135); break; case TempString: TranslateString(t.Contents.Ascii); memcpy(BAsmCode+CodeLen,t.Contents.Ascii,strlen(t.Contents.Ascii)); CodeLen+=(*Cnt=strlen(t.Contents.Ascii)); Result=True; break; case TempNone: break; END return Result; END static Boolean LayoutWord(char *Asc, Word *Cnt, Boolean Turn) BEGIN Boolean OK,Result; Word erg; *Cnt=2; Result=False; if (strcmp(Asc,"?")==0) BEGIN if (DSFlag==DSConstant) WrError(1930); else BEGIN Result=True; DSFlag=DSSpace; CodeLen+=2; END return Result; END else BEGIN if (DSFlag==DSSpace) BEGIN WrError(1930); return Result; END else DSFlag=DSConstant; END if (CodeLen+2>MaxCodeLen) BEGIN WrError(1920); return Result; END erg=EvalIntExpression(Asc,Int16,&OK); if (OK) BEGIN if (Turn) erg=((erg>>8)&0xff)+((erg&0xff)<<8); BAsmCode[CodeLen]=erg&0xff; BAsmCode[CodeLen+1]=erg>>8; CodeLen+=2; END return OK; END static Boolean LayoutDoubleWord(char *Asc, Word *Cnt, Boolean Turn) BEGIN TempResult erg; Boolean Result=False; *Cnt=4; if (strcmp(Asc,"?")==0) BEGIN if (DSFlag==DSConstant) WrError(1930); else BEGIN Result=True; DSFlag=DSSpace; CodeLen+=4; END return Result; END else BEGIN if (DSFlag==DSSpace) BEGIN WrError(1930); return Result; END else DSFlag=DSConstant; END if (CodeLen+4>MaxCodeLen) BEGIN WrError(1920); return Result; END KillBlanks(Asc); EvalExpression(Asc,&erg); switch (erg.Typ) BEGIN case TempNone: return Result; case TempInt: if (RangeCheck(erg.Contents.Int,Int32)) BEGIN BAsmCode[CodeLen ]=((erg.Contents.Int )&0xff); BAsmCode[CodeLen+1]=((erg.Contents.Int>> 8)&0xff); BAsmCode[CodeLen+2]=((erg.Contents.Int>>16)&0xff); BAsmCode[CodeLen+3]=((erg.Contents.Int>>24)&0xff); CodeLen+=4; END else BEGIN WrError(1320); return Result; END break; case TempFloat: if (FloatRangeCheck(erg.Contents.Float,Float32)) BEGIN Double_2_ieee4(erg.Contents.Float,BAsmCode+CodeLen,False); CodeLen+=4; END else BEGIN WrError(1320); return Result; END break; case TempString: WrError(1135); return Result; END if (Turn) DSwap(BAsmCode+CodeLen-4,4); return True; END static Boolean LayoutQuadWord(char *Asc, Word *Cnt, Boolean Turn) BEGIN Boolean Result; TempResult erg; #ifndef HAS64 int z; #endif Result=False; *Cnt=8; if (strcmp(Asc,"?")==0) BEGIN if (DSFlag==DSConstant) WrError(1930); else BEGIN Result=True; DSFlag=DSSpace; CodeLen+=8; END return Result; END else BEGIN if (DSFlag==DSSpace) BEGIN WrError(1930); return Result; END else DSFlag=DSConstant; END if (CodeLen+8>MaxCodeLen) BEGIN WrError(1920); return Result; END KillBlanks(Asc); EvalExpression(Asc,&erg); switch(erg.Typ) BEGIN case TempNone: return Result; case TempInt: memcpy(BAsmCode+CodeLen,&(erg.Contents.Int),sizeof(LargeInt)); #ifdef HAS64 if (BigEndian) QSwap(BAsmCode+CodeLen,8); #else if (BigEndian) DSwap(BAsmCode+CodeLen,4); for (z=4; z<8; BAsmCode[CodeLen+(z++)]=(BAsmCode[CodeLen+3]>=0x80)?0xff:0x00); #endif CodeLen+=8; break; case TempFloat: Double_2_ieee8(erg.Contents.Float,BAsmCode+CodeLen,False); CodeLen+=8; break; case TempString: WrError(1135); return Result; END if (Turn) QSwap(BAsmCode+CodeLen-8,8); return True; END static Boolean LayoutTenBytes(char *Asc, Word *Cnt, Boolean Turn) BEGIN Boolean OK,Result; Double erg; int z; Byte Exg; Result=False; *Cnt=10; if (strcmp(Asc,"?")==0) BEGIN if (DSFlag==DSConstant) WrError(1930); else BEGIN Result=True; DSFlag=DSSpace; CodeLen+=10; END return Result; END else BEGIN if (DSFlag==DSSpace) BEGIN WrError(1930); return Result; END else DSFlag=DSConstant; END if (CodeLen+10>MaxCodeLen) BEGIN WrError(1920); return Result; END erg=EvalFloatExpression(Asc,Float64,&OK); if (OK) BEGIN Double_2_ieee10(erg,BAsmCode+CodeLen,False); CodeLen+=10; if (Turn) for (z=0; z<5; z++) BEGIN Exg=BAsmCode[CodeLen-10+z]; BAsmCode[CodeLen-10+z]=BAsmCode[CodeLen-1-z]; BAsmCode[CodeLen-1-z]=Exg; END END return OK; END static Boolean DecodeIntelPseudo_ValidSymChar(char ch) BEGIN return (((ch>='A') AND (ch<='Z')) OR ((ch>='0') AND (ch<='9')) OR (ch=='_') OR (ch=='.')); END static Boolean DecodeIntelPseudo_LayoutMult(char *Asc_O, Word *Cnt, TLayoutFunc LayoutFunc, Boolean Turn) BEGIN int z,Depth,Fnd,ALen; String Asc,Part; Word SumCnt,ECnt,SInd; LongInt Rep; Boolean OK,Hyp; strmaxcpy(Asc,Asc_O,255); /* nach DUP suchen */ Depth=0; Fnd=0; ALen=strlen(Asc); for (z=0; z=2) AND (*Asc=='(') AND (Asc[strlen(Asc)-1]==')')) BEGIN strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0'; END do BEGIN Fnd=0; z=0; Hyp=False; Depth=0; do BEGIN if (Asc[z]=='\'') Hyp=NOT Hyp; else if (NOT Hyp) BEGIN if (Asc[z]=='(') Depth++; else if (Asc[z]==')') Depth--; else if ((Depth==0) AND (Asc[z]==',')) Fnd=z; END z++; END while ((zMaxCodeLen) BEGIN WrError(1920); return False; END for (z=1; z<=Rep-1; z++) BEGIN if (CodeLen+SumCnt>MaxCodeLen) return False; memcpy(BAsmCode+CodeLen,BAsmCode+SInd,SumCnt); CodeLen+=SumCnt; END END else CodeLen+=SumCnt*(Rep-1); *Cnt=SumCnt*Rep; return True; END /* kein DUP: einfacher Ausdruck */ else return LayoutFunc(Asc,Cnt,Turn); END Boolean DecodeIntelPseudo(Boolean Turn) BEGIN Word Dummy; int z; TLayoutFunc LayoutFunc=Nil; Boolean OK; LongInt HVal; char Ident; if ((strlen(OpPart)!=2) OR (*OpPart!='D')) return False; Ident=OpPart[1]; if ((Ident=='B') OR (Ident=='W') OR (Ident=='D') OR (Ident=='Q') OR (Ident=='T')) BEGIN DSFlag=DSNone; switch (Ident) BEGIN case 'B': LayoutFunc=LayoutByte; if (*LabPart!='\0') SetSymbolSize(LabPart,0); break; case 'W': LayoutFunc=LayoutWord; if (*LabPart!='\0') SetSymbolSize(LabPart,1); break; case 'D': LayoutFunc=LayoutDoubleWord; if (*LabPart!='\0') SetSymbolSize(LabPart,2); break; case 'Q': LayoutFunc=LayoutQuadWord; if (*LabPart!='\0') SetSymbolSize(LabPart,3); break; case 'T': LayoutFunc=LayoutTenBytes; if (*LabPart!='\0') SetSymbolSize(LabPart,4); break; END z=1; do BEGIN OK=DecodeIntelPseudo_LayoutMult(ArgStr[z],&Dummy,LayoutFunc,Turn); if (NOT OK) CodeLen=0; z++; END while ((OK) AND (z<=ArgCnt)); DontPrint=(DSFlag==DSSpace); if (DontPrint) BookKeeping(); if (OK) ActListGran=1; return True; END if (Ident=='S') BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; HVal=EvalIntExpression(ArgStr[1],Int32,&OK); if (FirstPassUnknown) WrError(1820); else if (OK) BEGIN DontPrint=True; CodeLen=HVal; BookKeeping(); END END return True; END return False; END /*--------------------------------------------------------------------------*/ static Boolean M16Turn=False; static Boolean CutRep(char *Asc, LongInt *Erg) BEGIN char *p; Boolean OK; if (*Asc!='[') BEGIN *Erg=1; return True; END else BEGIN strcpy(Asc,Asc+1); p=QuotPos(Asc,']'); if (p==Nil) BEGIN WrError(1300); return False; END else BEGIN *p='\0'; *Erg=EvalIntExpression(Asc,Int32,&OK); strcpy(Asc,p+1); return OK; END END END static void DecodeBYT(Word Index) BEGIN int z; Boolean OK; TempResult t; LongInt Rep,z2; if (ArgCnt==0) WrError(1110); else BEGIN z=1; OK=True; do BEGIN KillBlanks(ArgStr[z]); OK=CutRep(ArgStr[z],&Rep); if (OK) BEGIN EvalExpression(ArgStr[z],&t); switch (t.Typ) BEGIN case TempInt: if (NOT RangeCheck(t.Contents.Int,Int8)) BEGIN WrError(1320); OK=False; END else if (CodeLen+Rep>MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN memset(BAsmCode+CodeLen,t.Contents.Int,Rep); CodeLen+=Rep; END break; case TempFloat: WrError(1135); OK=False; break; case TempString: TranslateString(t.Contents.Ascii); if (CodeLen+Rep*strlen(t.Contents.Ascii)>MaxCodeLen) BEGIN WrError(1920); OK=False; END else for (z2=0; z2MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN HVal16=EvalIntExpression(ArgStr[z],Int16,&OK); if (OK) for (z2=0; z2=MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN TranslateString(SVal); for (z2=0; z2>2,bpos=(Pos&3)*4; Word dig=Ch-'0'; w[wpos]|=(dig<16) Man[16]='\0'; for (z=0; z4) strcpy(Exp,Exp+strlen(Exp)-4); for (z=strlen(Exp)-1; z>=0; z--) BEGIN epos=strlen(Exp)-1-z; if (epos==3) DigIns(Exp[z],19,w); else DigIns(Exp[z],epos+20,w); END END static void EnterByte(Byte b) BEGIN if (((CodeLen&1)==1) AND (NOT BigEndian) AND (ListGran()!=1)) BEGIN BAsmCode[CodeLen]=BAsmCode[CodeLen-1]; BAsmCode[CodeLen-1]=b; END else BEGIN BAsmCode[CodeLen]=b; END CodeLen++; END void AddMoto16PseudoONOFF(void) BEGIN AddONOFF("PADDING",&DoPadding,DoPaddingName,False); END Boolean DecodeMoto16Pseudo(ShortInt OpSize, Boolean Turn) BEGIN Byte z; Word TurnField[8]; char *zp; LongInt z2; LongInt WSize,Rep=0; LongInt NewPC,HVal,WLen; #ifdef HAS64 QuadInt QVal; #endif Integer HVal16; Double DVal; TempResult t; Boolean OK,ValOK; if (OpSize<0) OpSize=1; if (*OpPart!='D') return False; if (Memo("DC")) BEGIN if (ArgCnt==0) WrError(1110); else BEGIN OK=True; z=1; WLen=0; do BEGIN FirstPassUnknown=False; OK=CutRep(ArgStr[z],&Rep); if (OK) if (FirstPassUnknown) WrError(1820); else BEGIN switch (OpSize) BEGIN case 0: FirstPassUnknown=False; EvalExpression(ArgStr[z],&t); if ((FirstPassUnknown) AND (t.Typ==TempInt)) t.Contents.Int&=0xff; switch (t.Typ) BEGIN case TempInt: if (NOT RangeCheck(t.Contents.Int,Int8)) BEGIN WrError(1320); OK=False; END else if (CodeLen+Rep>MaxCodeLen) BEGIN WrError(1920); OK=False; END else for (z2=0; z2MaxCodeLen) BEGIN WrError(1920); OK=False; END else for (z2=0; z2MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN if (ListGran()==1) for (z2=0; z2MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN if (ListGran()==1) for (z2=0; z2> 24) & 0xff; BAsmCode[(WLen<<1)+1]=(HVal >> 16) & 0xff; BAsmCode[(WLen<<1)+2]=(HVal >> 8) & 0xff; BAsmCode[(WLen<<1)+3]=(HVal ) & 0xff; WLen+=2; END else for (z2=0; z2> 16; WAsmCode[WLen++]=HVal & 0xffff; END CodeLen+=Rep<<2; END break; #ifdef HAS64 case 3: QVal=EvalIntExpression(ArgStr[z],Int64,&OK); if (OK) if (CodeLen+(Rep<<3)>MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN if (ListGran()==1) for (z2=0; z2> 56) & 0xff; BAsmCode[(WLen<<1)+1]=(QVal >> 48) & 0xff; BAsmCode[(WLen<<1)+2]=(QVal >> 40) & 0xff; BAsmCode[(WLen<<1)+3]=(QVal >> 32) & 0xff; BAsmCode[(WLen<<1)+4]=(QVal >> 24) & 0xff; BAsmCode[(WLen<<1)+5]=(QVal >> 16) & 0xff; BAsmCode[(WLen<<1)+6]=(QVal >> 8) & 0xff; BAsmCode[(WLen<<1)+7]=(QVal ) & 0xff; WLen+=4; END else for (z2=0; z2> 48) & 0xffff; WAsmCode[WLen++]=(QVal >> 32) & 0xffff; WAsmCode[WLen++]=(QVal >> 16) & 0xffff; WAsmCode[WLen++]=QVal & 0xffff; END CodeLen+=Rep<<3; END break; #endif case 4: DVal=EvalFloatExpression(ArgStr[z],Float32,&OK); if (OK) if (CodeLen+(Rep<<2)>MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN Double_2_ieee4(DVal,(Byte *) TurnField,BigEndian); if (BigEndian) DWSwap((void*) TurnField,4); if (ListGran()==1) for (z2=0; z2MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN Double_2_ieee8(DVal,(Byte *) TurnField,BigEndian); if (BigEndian) QWSwap((void *) TurnField,8); if (ListGran()==1) for (z2=0; z2MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN Double_2_ieee10(DVal,(Byte *) TurnField,False); if (BigEndian) WSwap((void *) TurnField,10); if (ListGran()==1) for (z2=0; z2MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN ConvertDec(DVal,TurnField); if (ListGran()==1) for (z2=0; z2Erg) WrError(1315); else if (Erg>Max) WrError(1320); else BEGIN PushLocHandle(-1); EnterIntSymbol(LabPart,Erg,DestSeg,False); PopLocHandle(); if (MakeUseList) if (AddChunk(SegChunks+DestSeg,Erg,1,False)) WrError(90); t.Typ=TempInt; t.Contents.Int=Erg; SetListLineVal(&t); END END END void CodeASSUME(ASSUMERec *Def, Integer Cnt) BEGIN int z1,z2; Boolean OK; LongInt HVal; String RegPart,ValPart; if (ArgCnt==0) WrError(1110); else BEGIN z1=1; OK=True; while ((z1<=ArgCnt) AND (OK)) BEGIN SplitString(ArgStr[z1],RegPart,ValPart,QuotPos(ArgStr[z1],':')); z2=0; NLS_UpString(RegPart); while ((z2