/* code8x30x.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator Signetics 8X30x */ /* */ /* Historie: 25. 6.1997 Grundsteinlegung */ /* 3. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "nls.h" #include "chunks.h" #include "bpemu.h" #include "strutil.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" /*****************************************************************************/ #define AriOrderCnt 4 typedef struct { char *Name; Word Code; } FixedOrder; static CPUVar CPU8x300,CPU8x305; static FixedOrder *AriOrders; /*-------------------------------------------------------------------------*/ static int InstrZ; static void AddAri(char *NName, Word NCode) BEGIN if (InstrZ>=AriOrderCnt) exit(255); AriOrders[InstrZ].Name=NName; AriOrders[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN AriOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*AriOrderCnt); InstrZ=0; AddAri("MOVE",0); AddAri("ADD",1); AddAri("AND",2); AddAri("XOR",3); END static void DeinitFields(void) BEGIN free(AriOrders); END /*-------------------------------------------------------------------------*/ static Boolean DecodeReg(char *Asc, Word *Erg, ShortInt *ErgLen) BEGIN Boolean OK; Word Acc; LongInt Adr; char *z; *ErgLen=(-1); if (strcasecmp(Asc,"AUX")==0) BEGIN *Erg=0; return True; END if (strcasecmp(Asc,"OVF")==0) BEGIN *Erg=8; return True; END if (strcasecmp(Asc,"IVL")==0) BEGIN *Erg=7; return True; END if (strcasecmp(Asc,"IVR")==0) BEGIN *Erg=15; return True; END if ((toupper(*Asc)=='R') AND (strlen(Asc)>1) AND (strlen(Asc)<4)) BEGIN Acc=0; OK=True; for (z=Asc+1; *z!='\0'; z++) if (OK) if ((*z<'0') OR (*z>'7')) OK=False; else Acc=(Acc << 3)+(*z-'0'); if ((OK) AND (Acc<32)) BEGIN if ((MomCPU==CPU8x300) AND (Acc>9) AND (Acc<15)) BEGIN WrXError(1445,Asc); return False; END else *Erg=Acc; return True; END END if ((strlen(Asc)==4) AND (strncasecmp(Asc+1,"IV",2)==0) AND (Asc[3]>='0') AND (Asc[3]<='7')) if (toupper(*Asc)=='L') BEGIN *Erg=Asc[3]-'0'+0x10; return True; END else if (toupper(*Asc)=='R') BEGIN *Erg=Asc[3]-'0'+0x18; return True; END /* IV - Objekte */ Adr=EvalIntExpression(Asc,UInt24,&OK); if (OK) BEGIN *ErgLen=Adr & 7; *Erg=0x10+((Adr & 0x10) >> 1)+((Adr & 0x700) >> 8); return True; END else return False; END static char *HasDisp(char *Asc) BEGIN int Lev; char *z; int l=strlen(Asc); if (Asc[l-1]==')') BEGIN z=Asc+l-2; Lev=0; while ((z>=Asc) AND (Lev!=-1)) BEGIN switch (*z) BEGIN case '(': Lev--; break; case ')': Lev++; break; END if (Lev!=-1) z--; END if (Lev!=-1) BEGIN WrError(1300); return Nil; END END else z=Nil; return z; END static Boolean GetLen(char *Asc, Word *Erg) BEGIN Boolean OK; FirstPassUnknown=False; *Erg=EvalIntExpression(Asc,UInt4,&OK); if (NOT OK) return False; if (FirstPassUnknown) *Erg=8; if (NOT ChkRange(*Erg,1,8)) return False; *Erg&=7; return True; END /*-------------------------------------------------------------------------*/ /* Symbol: 00AA0ORL */ static Boolean DecodePseudo(void) BEGIN LongInt Adr,Ofs,Erg; Word Len; Boolean OK; if ((Memo("LIV")) OR (Memo("RIV"))) BEGIN Erg=0x10*Ord(Memo("RIV")); if (ArgCnt!=3) WrError(1110); else BEGIN Adr=EvalIntExpression(ArgStr[1],UInt8,&OK); if (OK) BEGIN Ofs=EvalIntExpression(ArgStr[2],UInt3,&OK); if (OK) if (GetLen(ArgStr[3],&Len)) BEGIN PushLocHandle(-1); EnterIntSymbol(LabPart,Erg+(Adr << 16)+(Ofs << 8)+(Len & 7),SegNone,False); PopLocHandle(); END END END return True; END return False; END static void MakeCode_8x30X(void) BEGIN Boolean OK; Word SrcReg,DestReg; ShortInt SrcLen,DestLen; LongInt Op; Word Rot,Adr; int z; char *p; String tmp; CodeLen=0; DontPrint=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; /* eingebaute Makros */ if (Memo("NOP")) /* NOP = MOVE AUX,AUX */ BEGIN if (ArgCnt!=0) WrError(1110); else BEGIN WAsmCode[0]=0x0000; CodeLen=1; END return; END if (Memo("HALT")) /* HALT = JMP * */ BEGIN if (ArgCnt!=0) WrError(1110); else BEGIN WAsmCode[0]=0xe000+(EProgCounter() & 0x1fff); CodeLen=1; END return; END if ((Memo("XML")) OR (Memo("XMR"))) BEGIN if (ArgCnt!=1) WrError(1110); else if (MomCPU> 16) & 0xff); CodeLen=1; END END return; END if (Memo("XMIT")) BEGIN if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110); else if (DecodeReg(ArgStr[2],&SrcReg,&SrcLen)) if (SrcReg<16) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN Adr=EvalIntExpression(ArgStr[1],Int8,&OK); if (OK) BEGIN WAsmCode[0]=0xc000+(SrcReg << 8)+(Adr & 0xff); CodeLen=1; END END END else BEGIN if (ArgCnt==2) BEGIN Rot=0xffff; OK=True; END else OK=GetLen(ArgStr[3],&Rot); if (OK) BEGIN if (Rot==0xffff) Rot=(SrcLen==-1) ? 0 : SrcLen; if ((SrcLen!=-1) AND (Rot!=SrcLen)) WrError(1131); else BEGIN Adr=EvalIntExpression(ArgStr[1],Int5,&OK); if (OK) BEGIN WAsmCode[0]=0xc000+(SrcReg << 8)+(Rot << 5)+(Adr & 0x1f); CodeLen=1; END END END END return; END /* Arithmetik */ for (z=0; z=16) WrXError(1445,ArgStr[1]); else BEGIN WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+(Rot << 5)+DestReg; CodeLen=1; END END END else /* noi! */ BEGIN if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen)) BEGIN WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+DestReg; if ((SrcReg>=16) AND (SrcLen!=-1)) WAsmCode[0]+=SrcLen << 5; CodeLen=1; END END END else /* 3 Operanden --> Quelle ist I/O */ BEGIN if (GetLen(ArgStr[2],&Rot)) if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen)) if (SrcReg<16) WrXError(1445,ArgStr[1]); else if ((SrcLen!=-1) AND (SrcLen!=Rot)) WrError(1131); else BEGIN WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+(Rot << 5)+DestReg; CodeLen=1; END END END else /* Ziel I/O */ BEGIN if (ArgCnt==2) /* 2 Argumente: Laenge=Laenge Ziel */ BEGIN Rot=DestLen; OK=True; END else /* 3 Argumente: Laenge=Laenge Ziel+Angabe */ BEGIN OK=GetLen(ArgStr[2],&Rot); if (OK) BEGIN if (FirstPassUnknown) Rot=DestLen; if (DestLen==-1) DestLen=Rot; OK=Rot==DestLen; if (NOT OK) WrError(1131); END END if (OK) if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen)) BEGIN if ((Rot==0xffff)) Rot=((SrcLen==-1)) ? 0 : SrcLen; if ((DestReg>=16) AND (SrcLen!=-1) AND (SrcLen!=Rot)) WrError(1131); else BEGIN WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+(Rot << 5)+DestReg; CodeLen=1; END END END return; END if (Memo("XEC")) BEGIN if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN p=HasDisp(ArgStr[1]); if (p==Nil) WrError(1350); else BEGIN strcpy(tmp,p+1); tmp[strlen(tmp)-1]='\0'; if (DecodeReg(tmp,&SrcReg,&SrcLen)) BEGIN *p='\0'; if (SrcReg<16) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN WAsmCode[0]=EvalIntExpression(ArgStr[1],UInt8,&OK); if (OK) BEGIN WAsmCode[0]+=0x8000+(SrcReg << 8); CodeLen=1; END END END else BEGIN if (ArgCnt==1) BEGIN Rot=0xffff; OK=True; END else OK=GetLen(ArgStr[2],&Rot); if (OK) BEGIN if (Rot==0xffff) Rot=(SrcLen==-1) ? 0 : SrcLen; if ((SrcLen!=-1) AND (Rot!=SrcLen)) WrError(1131); else BEGIN WAsmCode[0]=EvalIntExpression(ArgStr[1],UInt5,&OK); if (OK) BEGIN WAsmCode[0]+=0x8000+(SrcReg << 8)+(Rot << 5); CodeLen=1; END END END END END END END return; END /* Spruenge */ if (Memo("JMP")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN WAsmCode[0]=EvalIntExpression(ArgStr[1],UInt13,&OK); if (OK) BEGIN WAsmCode[0]+=0xe000; CodeLen=1; END END return; END if (Memo("NZT")) BEGIN if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110); else if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen)) if (SrcReg<16) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN Adr=EvalIntExpression(ArgStr[2],UInt13,&OK); if (OK) if ((NOT SymbolQuestionable) AND ((Adr >> 8)!=(EProgCounter() >> 8))) WrError(1910); else BEGIN WAsmCode[0]=0xa000+(SrcReg << 8)+(Adr & 0xff); CodeLen=1; END END END else BEGIN if (ArgCnt==2) BEGIN Rot=0xffff; OK=True; END else OK=GetLen(ArgStr[2],&Rot); if (OK) BEGIN if (Rot==0xffff) Rot=(SrcLen==-1) ? 0 : SrcLen; if ((SrcLen!=-1) AND (Rot!=SrcLen)) WrError(1131); else BEGIN Adr=EvalIntExpression(ArgStr[ArgCnt],UInt13,&OK); if (OK) if ((NOT SymbolQuestionable) AND ((Adr >> 5)!=(EProgCounter() >> 5))) WrError(1910); else BEGIN WAsmCode[0]=0xa000+(SrcReg << 8)+(Rot << 5)+(Adr & 0x1f); CodeLen=1; END END END END return; END; WrXError(1200,OpPart); END static Boolean IsDef_8x30X(void) BEGIN return (Memo("LIV") OR Memo("RIV")); END static void SwitchFrom_8x30X() BEGIN DeinitFields(); END static void SwitchTo_8x30X(void) BEGIN TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=False; PCSymbol="*"; HeaderID=0x3a; NOPCode=0x0000; DivideChars=","; HasAttrs=False; ValidSegs=1<