diff options
Diffstat (limited to 'code8x30x.c')
-rw-r--r-- | code8x30x.c | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/code8x30x.c b/code8x30x.c new file mode 100644 index 0000000..1d15c07 --- /dev/null +++ b/code8x30x.c @@ -0,0 +1,559 @@ +/* code8x30x.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator Signetics 8X30x */ +/* */ +/* Historie: 25. 6.1997 Grundsteinlegung */ +/* 3. 1.1999 ChkPC-Anpassung */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include <string.h> +#include <ctype.h> + +#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<CPU8x305) WrError(1500); + else + BEGIN + Adr=EvalIntExpression(ArgStr[1],Int8,&OK); + if (OK) + BEGIN + WAsmCode[0]=0xca00+(Ord(Memo("XER")) << 8)+(Adr & 0xff); + CodeLen=1; + END + END + return; + END + + /* Datentransfer */ + + if (Memo("SEL")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + Op=EvalIntExpression(ArgStr[1],UInt24,&OK); + if (OK) + BEGIN + WAsmCode[0]=0xc700+((Op & 0x10) << 7)+((Op >> 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<AriOrderCnt; z++) + if (Memo(AriOrders[z].Name)) + BEGIN + if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110); + else if (DecodeReg(ArgStr[ArgCnt],&DestReg,&DestLen)) + if (DestReg<16) /* Ziel Register */ + BEGIN + if (ArgCnt==2) /* wenn nur zwei Operanden und Ziel Register... */ + BEGIN + p=HasDisp(ArgStr[1]); /* kann eine Rotation dabei sein */ + if (p!=Nil) + BEGIN /* jau! */ + strcpy(tmp,p+1); tmp[strlen(tmp)-1]='\0'; + Rot=EvalIntExpression(tmp,UInt3,&OK); + if (OK) + BEGIN + *p='\0'; + if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen)) + if (SrcReg>=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<<SegCode; + Grans[SegCode]=2; ListGrans[SegCode]=2; SegInits[SegCode]=0; + SegLimits[SegCode] = 0x1fff; + + MakeCode=MakeCode_8x30X; IsDef=IsDef_8x30X; + SwitchFrom=SwitchFrom_8x30X; InitFields(); +END + + void code8x30x_init(void) +BEGIN + CPU8x300=AddCPU("8x300",SwitchTo_8x30X); + CPU8x305=AddCPU("8x305",SwitchTo_8x30X); +END + |