From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- code7000.c | 1315 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1315 insertions(+) create mode 100644 code7000.c (limited to 'code7000.c') diff --git a/code7000.c b/code7000.c new file mode 100644 index 0000000..dfdb423 --- /dev/null +++ b/code7000.c @@ -0,0 +1,1315 @@ +/* code7000.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator SH7x00 */ +/* */ +/* Historie: 25.12.1996 Grundsteinlegung */ +/* 12. 4.1998 SH7700-Erweiterungen */ +/* 3. 1.1999 ChkPC-Anpassung */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" + +#include +#include + +#include "bpemu.h" +#include "strutil.h" +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "asmallg.h" +#include "codepseudo.h" +#include "codevars.h" + + +#define FixedOrderCount 13 +#define OneRegOrderCount 22 +#define TwoRegOrderCount 20 +#define MulRegOrderCount 3 +#define BWOrderCount 3 +#define LogOrderCount 4 + + +#define ModNone (-1) +#define ModReg 0 +#define MModReg (1 << ModReg) +#define ModIReg 1 +#define MModIReg (1 << ModIReg) +#define ModPreDec 2 +#define MModPreDec (1 << ModPreDec) +#define ModPostInc 3 +#define MModPostInc (1 << ModPostInc) +#define ModIndReg 4 +#define MModIndReg (1 << ModIndReg) +#define ModR0Base 5 +#define MModR0Base (1 << ModR0Base) +#define ModGBRBase 6 +#define MModGBRBase (1 << ModGBRBase) +#define ModGBRR0 7 +#define MModGBRR0 (1 << ModGBRR0) +#define ModPCRel 8 +#define MModPCRel (1 << ModPCRel) +#define ModImm 9 +#define MModImm (1 << ModImm) + + +#define CompLiteralsName "COMPRESSEDLITERALS" + +typedef struct + { + char *Name; + CPUVar MinCPU; + Boolean Priv; + Word Code; + } FixedOrder; + +typedef struct + { + char *Name; + CPUVar MinCPU; + Boolean Priv; + Word Code; + ShortInt DefSize; + } TwoRegOrder; + +typedef struct + { + char *Name; + CPUVar MinCPU; + Word Code; + } FixedMinOrder; + + typedef struct _TLiteral + { + struct _TLiteral *Next; + LongInt Value,FCount; + Boolean Is32,IsForward; + Integer PassNo; + LongInt DefSection; + } *PLiteral,TLiteral; + +static ShortInt OpSize; /* Groesse=8*(2^OpSize) */ +static ShortInt AdrMode; /* Ergebnisadressmodus */ +static Word AdrPart; /* Adressierungsmodusbits im Opcode */ + +static PLiteral FirstLiteral; +static LongInt ForwardCount; +static SimpProc SaveInitProc; + +static CPUVar CPU7000,CPU7600,CPU7700; + +static FixedOrder *FixedOrders; +static FixedMinOrder *OneRegOrders; +static TwoRegOrder *TwoRegOrders; +static FixedMinOrder *MulRegOrders; +static FixedOrder *BWOrders; +static char **LogOrders; + +static Boolean CurrDelayed,PrevDelayed,CompLiterals; +static LongInt DelayedAdr; + +/*-------------------------------------------------------------------------*/ +/* dynamische Belegung/Freigabe Codetabellen */ + + static void AddFixed(char *NName, Word NCode, Boolean NPriv, CPUVar NMin) +BEGIN + if (InstrZ>=FixedOrderCount) exit(255); + FixedOrders[InstrZ].Name=NName; + FixedOrders[InstrZ].Priv=NPriv; + FixedOrders[InstrZ].MinCPU=NMin; + FixedOrders[InstrZ++].Code=NCode; +END + + static void AddOneReg(char *NName, Word NCode, CPUVar NMin) +BEGIN + if (InstrZ>=OneRegOrderCount) exit(255); + OneRegOrders[InstrZ].Name=NName; + OneRegOrders[InstrZ].Code=NCode; + OneRegOrders[InstrZ++].MinCPU=NMin; +END + + static void AddTwoReg(char *NName, Word NCode, Boolean NPriv, CPUVar NMin, ShortInt NDef) +BEGIN + if (InstrZ>=TwoRegOrderCount) exit(255); + TwoRegOrders[InstrZ].Name=NName; + TwoRegOrders[InstrZ].Priv=NPriv; + TwoRegOrders[InstrZ].DefSize=NDef; + TwoRegOrders[InstrZ].MinCPU=NMin; + TwoRegOrders[InstrZ++].Code=NCode; +END + + static void AddMulReg(char *NName, Word NCode, CPUVar NMin) +BEGIN + if (InstrZ>=MulRegOrderCount) exit(255); + MulRegOrders[InstrZ].Name=NName; + MulRegOrders[InstrZ].Code=NCode; + MulRegOrders[InstrZ++].MinCPU=NMin; +END + + static void AddBW(char *NName, Word NCode) +BEGIN + if (InstrZ>=BWOrderCount) exit(255); + BWOrders[InstrZ].Name=NName; + BWOrders[InstrZ++].Code=NCode; +END + + static void InitFields(void) +BEGIN + FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0; + AddFixed("CLRT" ,0x0008,False,CPU7000); + AddFixed("CLRMAC",0x0028,False,CPU7000); + AddFixed("NOP" ,0x0009,False,CPU7000); + AddFixed("RTE" ,0x002b,False,CPU7000); + AddFixed("SETT" ,0x0018,False,CPU7000); + AddFixed("SLEEP" ,0x001b,False,CPU7000); + AddFixed("RTS" ,0x000b,False,CPU7000); + AddFixed("DIV0U" ,0x0019,False,CPU7000); + AddFixed("BRK" ,0x0000,True ,CPU7000); + AddFixed("RTB" ,0x0001,True ,CPU7000); + AddFixed("CLRS" ,0x0048,False,CPU7700); + AddFixed("SETS" ,0x0058,False,CPU7700); + AddFixed("LDTLB" ,0x0038,True ,CPU7700); + + OneRegOrders=(FixedMinOrder *) malloc(sizeof(FixedMinOrder)*OneRegOrderCount); InstrZ=0; + AddOneReg("MOVT" ,0x0029,CPU7000); AddOneReg("CMP/PZ",0x4011,CPU7000); + AddOneReg("CMP/PL",0x4015,CPU7000); AddOneReg("ROTL" ,0x4004,CPU7000); + AddOneReg("ROTR" ,0x4005,CPU7000); AddOneReg("ROTCL" ,0x4024,CPU7000); + AddOneReg("ROTCR" ,0x4025,CPU7000); AddOneReg("SHAL" ,0x4020,CPU7000); + AddOneReg("SHAR" ,0x4021,CPU7000); AddOneReg("SHLL" ,0x4000,CPU7000); + AddOneReg("SHLR" ,0x4001,CPU7000); AddOneReg("SHLL2" ,0x4008,CPU7000); + AddOneReg("SHLR2" ,0x4009,CPU7000); AddOneReg("SHLL8" ,0x4018,CPU7000); + AddOneReg("SHLR8" ,0x4019,CPU7000); AddOneReg("SHLL16",0x4028,CPU7000); + AddOneReg("SHLR16",0x4029,CPU7000); AddOneReg("LDBR" ,0x0021,CPU7000); + AddOneReg("STBR" ,0x0020,CPU7000); AddOneReg("DT" ,0x4010,CPU7600); + AddOneReg("BRAF" ,0x0032,CPU7600); AddOneReg("BSRF" ,0x0003,CPU7600); + + TwoRegOrders=(TwoRegOrder *) malloc(sizeof(TwoRegOrder)*TwoRegOrderCount); InstrZ=0; + AddTwoReg("XTRCT" ,0x200d,False,CPU7000,2); + AddTwoReg("ADDC" ,0x300e,False,CPU7000,2); + AddTwoReg("ADDV" ,0x300f,False,CPU7000,2); + AddTwoReg("CMP/HS",0x3002,False,CPU7000,2); + AddTwoReg("CMP/GE",0x3003,False,CPU7000,2); + AddTwoReg("CMP/HI",0x3006,False,CPU7000,2); + AddTwoReg("CMP/GT",0x3007,False,CPU7000,2); + AddTwoReg("CMP/STR",0x200c,False,CPU7000,2); + AddTwoReg("DIV1" ,0x3004,False,CPU7000,2); + AddTwoReg("DIV0S" ,0x2007,False,CPU7000,-1); + AddTwoReg("MULS" ,0x200f,False,CPU7000,1); + AddTwoReg("MULU" ,0x200e,False,CPU7000,1); + AddTwoReg("NEG" ,0x600b,False,CPU7000,2); + AddTwoReg("NEGC" ,0x600a,False,CPU7000,2); + AddTwoReg("SUB" ,0x3008,False,CPU7000,2); + AddTwoReg("SUBC" ,0x300a,False,CPU7000,2); + AddTwoReg("SUBV" ,0x300b,False,CPU7000,2); + AddTwoReg("NOT" ,0x6007,False,CPU7000,2); + AddTwoReg("SHAD" ,0x400c,False,CPU7700,2); + AddTwoReg("SHLD" ,0x400d,False,CPU7700,2); + + MulRegOrders=(FixedMinOrder *) malloc(sizeof(FixedMinOrder)*MulRegOrderCount); InstrZ=0; + AddMulReg("MUL" ,0x0007,CPU7600); + AddMulReg("DMULU" ,0x3005,CPU7600); + AddMulReg("DMULS" ,0x300d,CPU7600); + + BWOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BWOrderCount); InstrZ=0; + AddBW("SWAP",0x6008); AddBW("EXTS",0x600e); AddBW("EXTU",0x600c); + + LogOrders=(char **) malloc(sizeof(char *)*LogOrderCount); InstrZ=0; + LogOrders[InstrZ++]="TST"; LogOrders[InstrZ++]="AND"; + LogOrders[InstrZ++]="XOR"; LogOrders[InstrZ++]="OR" ; +END + + static void DeinitFields(void) +BEGIN + free(FixedOrders); + free(OneRegOrders); + free(TwoRegOrders); + free(MulRegOrders); + free(BWOrders); + free(LogOrders); +END + +/*-------------------------------------------------------------------------*/ +/* die PC-relative Adresse: direkt nach verzoegerten Spruengen = Sprungziel+2 */ + + static LongInt PCRelAdr(void) +BEGIN + if (PrevDelayed) return DelayedAdr+2; + else return EProgCounter()+4; +END + + static void ChkDelayed(void) +BEGIN + if (PrevDelayed) WrError(200); +END + +/*-------------------------------------------------------------------------*/ +/* Adressparsing */ + + static char *LiteralName(PLiteral Lit) +BEGIN + String Tmp; + static String Result; + + if (Lit->IsForward) sprintf(Tmp,"F_%s",HexString(Lit->FCount,8)); + else if (Lit->Is32) sprintf(Tmp,"L_%s",HexString(Lit->Value,8)); + else sprintf(Tmp,"W_%s",HexString(Lit->Value,4)); + sprintf(Result,"LITERAL_%s_%s",Tmp,HexString(Lit->PassNo,0)); + return Result; +END +/* + static void PrintLiterals(void) +BEGIN + PLiteral Lauf; + + WrLstLine("LiteralList"); + Lauf=FirstLiteral; + while (Lauf!=Nil) + BEGIN + WrLstLine(LiteralName(Lauf)); Lauf=Lauf->Next; + END +END +*/ + static void SetOpSize(ShortInt Size) +BEGIN + if (OpSize==-1) OpSize=Size; + else if (Size!=OpSize) + BEGIN + WrError(1131); AdrMode=ModNone; + END +END + + static Boolean DecodeReg(char *Asc, Byte *Erg) +BEGIN + Boolean Err; + + if (strcasecmp(Asc,"SP")==0) + BEGIN + *Erg=15; return True; + END + else if ((strlen(Asc)<2) OR (strlen(Asc)>3) OR (toupper(*Asc)!='R')) return False; + else + BEGIN + *Erg=ConstLongInt(Asc+1,&Err); + return (Err AND (*Erg<=15)); + END +END + + static Boolean DecodeCtrlReg(char *Asc, Byte *Erg) +BEGIN + CPUVar MinCPU=CPU7000; + + *Erg=0xff; + if (strcasecmp(Asc,"SR")==0) *Erg=0; + else if (strcasecmp(Asc,"GBR")==0) *Erg=1; + else if (strcasecmp(Asc,"VBR")==0) *Erg=2; + else if (strcasecmp(Asc,"SSR")==0) + BEGIN + *Erg=3; MinCPU=CPU7700; + END + else if (strcasecmp(Asc,"SPC")==0) + BEGIN + *Erg=4; MinCPU=CPU7700; + END + else if ((strlen(Asc)==7) AND (toupper(*Asc)=='R') + AND (strcasecmp(Asc+2,"_BANK")==0) + AND (Asc[1]>='0') AND (Asc[1]<='7')) + BEGIN + *Erg=Asc[1]-'0'+8; MinCPU=CPU7700; + END + if ((*Erg==0xff) OR (MomCPU> OpSize; + if (OK) + BEGIN + switch (BaseReg) + BEGIN + case 0: + if ((IndReg<0) OR (DispAcc!=0)) WrError(1350); + else + BEGIN + AdrMode=ModR0Base; AdrPart=IndReg; + END + break; + case RegGBR: + if ((IndReg==0) AND (DispAcc==0)) AdrMode=ModGBRR0; + else if (IndReg!=RegNone) WrError(1350); + else if (DispAcc>255) WrError(1320); + else + BEGIN + AdrMode=ModGBRBase; AdrPart=DispAcc; + END + break; + case RegNone: + if (IndReg==RegNone) WrError(1350); + else if (DispAcc>15) WrError(1320); + else + BEGIN + AdrMode=ModIndReg; AdrPart=(IndReg << 4)+DispAcc; + END + break; + case RegPC: + if (IndReg!=RegNone) WrError(1350); + else if (DispAcc>255) WrError(1320); + else + BEGIN + AdrMode=ModPCRel; AdrPart=DispAcc; + END + break; + END + END + ChkAdr(Mask); return; + END + else + BEGIN + if (DecodeReg(Asc,&HReg)) + BEGIN + AdrPart=HReg; AdrMode=ModIReg; + END + else if ((strlen(Asc)>1) AND (*Asc=='-') AND (DecodeReg(Asc+1,&HReg))) + BEGIN + AdrPart=HReg; AdrMode=ModPreDec; + END + else if ((strlen(Asc)>1) AND (Asc[strlen(Asc)-1]=='+')) + BEGIN + strmaxcpy(AdrStr,Asc,255); AdrStr[strlen(AdrStr)-1]='\0'; + if (DecodeReg(AdrStr,&HReg)) + BEGIN + AdrPart=HReg; AdrMode=ModPostInc; + END + else WrError(1350); + END + else WrError(1350); + ChkAdr(Mask); return; + END + END + + if (*Asc=='#') + BEGIN + FirstPassUnknown=False; + switch (OpSize) + BEGIN + case 0: DispAcc=EvalIntExpression(Asc+1,Int8,&OK); break; + case 1: DispAcc=EvalIntExpression(Asc+1,Int16,&OK); break; + case 2: DispAcc=EvalIntExpression(Asc+1,Int32,&OK); break; + default: DispAcc=0; OK=True; + END + Critical=FirstPassUnknown OR UsesForwards; + if (OK) + BEGIN + /* minimale Groesse optimieren */ + DOpSize=(OpSize==0) ? 0 : Ord(Critical); + while (((ExtOp(DispAcc,DOpSize,Signed) ^ DispAcc) & OpMask(OpSize))!=0) DOpSize++; + if (DOpSize==0) + BEGIN + AdrPart=DispAcc & 0xff; + AdrMode=ModImm; + END + else if ((Mask & MModPCRel)!=0) + BEGIN + /* Literalgroesse ermitteln */ + NIs32=(DOpSize==2); + if (NOT NIs32) DispAcc&=0xffff; + /* Literale sektionsspezifisch */ + strcpy(AdrStr,"[PARENT0]"); + /* schon vorhanden ? */ + Lauf=FirstLiteral; p=0; OK=False; Last=Nil; Found=False; + while ((Lauf!=Nil) AND (NOT Found)) + BEGIN + Last=Lauf; + if ((NOT Critical) AND (NOT Lauf->IsForward) + AND (Lauf->DefSection==MomSectionHandle)) + if (((Lauf->Is32==NIs32) AND (DispAcc==Lauf->Value)) + OR ((Lauf->Is32) AND (NOT NIs32) AND (DispAcc==(Lauf->Value >> 16)))) Found=True; + else if ((Lauf->Is32) AND (NOT NIs32) AND (DispAcc==(Lauf->Value & 0xffff))) + BEGIN + Found=True; p=2; + END + if (NOT Found) Lauf=Lauf->Next; + END + /* nein - erzeugen */ + if (NOT Found) + BEGIN + Lauf=(PLiteral) malloc(sizeof(TLiteral)); + Lauf->Is32=NIs32; Lauf->Value=DispAcc; + Lauf->IsForward=Critical; + if (Critical) Lauf->FCount=ForwardCount++; + Lauf->Next=Nil; Lauf->PassNo=1; Lauf->DefSection=MomSectionHandle; + do + BEGIN + sprintf(LStr,"%s%s",LiteralName(Lauf),AdrStr); + LDef=IsSymbolDefined(LStr); + if (LDef) Lauf->PassNo++; + END + while (LDef); + if (Last==Nil) FirstLiteral=Lauf; else Last->Next=Lauf; + END + /* Distanz abfragen - im naechsten Pass... */ + FirstPassUnknown=False; + sprintf(LStr,"%s%s",LiteralName(Lauf),AdrStr); + DispAcc=EvalIntExpression(LStr,Int32,&OK)+p; + if (OK) + BEGIN + if (FirstPassUnknown) + DispAcc=0; + else if (NIs32) + DispAcc=(DispAcc-(PCRelAdr() & 0xfffffffc)) >> 2; + else + DispAcc=(DispAcc-PCRelAdr()) >> 1; + if (DispAcc<0) + BEGIN + WrXError(1315,"Disp<0"); OK=False; + END + else if ((DispAcc>255) AND (NOT SymbolQuestionable)) WrError(1330); + else + BEGIN + AdrMode=ModPCRel; AdrPart=DispAcc; OpSize=Ord(NIs32)+1; + END + END + END + else WrError(1350); + END + ChkAdr(Mask); return; + END + + /* absolut ueber PC-relativ abwickeln */ + + if ((OpSize!=1) AND (OpSize!=2)) WrError(1130); + else + BEGIN + FirstPassUnknown=False; + DispAcc=EvalIntExpression(Asc,Int32,&OK); + if (FirstPassUnknown) DispAcc=0; + else if (OpSize==2) DispAcc-=(PCRelAdr() & 0xfffffffc); + else DispAcc-=PCRelAdr(); + if (DispAcc<0) WrXError(1315,"Disp<0"); + else if ((DispAcc & ((1 << OpSize)-1))!=0) WrError(1325); + else + BEGIN + DispAcc=DispAcc >> OpSize; + if (DispAcc>255) WrError(1320); + else + BEGIN + AdrMode=ModPCRel; AdrPart=DispAcc; + END + END + END + + ChkAdr(Mask); +END + +/*-------------------------------------------------------------------------*/ + + static void LTORG_16(void) +BEGIN + PLiteral Lauf; + + Lauf=FirstLiteral; + while (Lauf!=Nil) + BEGIN + if ((NOT Lauf->Is32) AND (Lauf->DefSection==MomSectionHandle)) + BEGIN + WAsmCode[CodeLen >> 1]=Lauf->Value; + EnterIntSymbol(LiteralName(Lauf),EProgCounter()+CodeLen,SegCode,False); + Lauf->PassNo=(-1); + CodeLen+=2; + END + Lauf=Lauf->Next; + END +END + + static void LTORG_32(void) +BEGIN + PLiteral Lauf,EqLauf; + + Lauf=FirstLiteral; + while (Lauf!=Nil) + BEGIN + if ((Lauf->Is32) AND (Lauf->DefSection==MomSectionHandle) AND (Lauf->PassNo>=0)) + BEGIN + if (((EProgCounter()+CodeLen) & 2)!=0) + BEGIN + WAsmCode[CodeLen >> 1]=0; CodeLen+=2; + END + WAsmCode[CodeLen >> 1]=(Lauf->Value >> 16); + WAsmCode[(CodeLen >> 1)+1]=(Lauf->Value & 0xffff); + EnterIntSymbol(LiteralName(Lauf),EProgCounter()+CodeLen,SegCode,False); + Lauf->PassNo=(-1); + if (CompLiterals) + BEGIN + EqLauf=Lauf->Next; + while (EqLauf!=Nil) + BEGIN + if ((EqLauf->Is32) AND (EqLauf->PassNo>=0) AND + (EqLauf->DefSection==MomSectionHandle) AND + (EqLauf->Value==Lauf->Value)) + BEGIN + EnterIntSymbol(LiteralName(EqLauf),EProgCounter()+CodeLen,SegCode,False); + EqLauf->PassNo=(-1); + END + EqLauf=EqLauf->Next; + END + END + CodeLen+=4; + END + Lauf=Lauf->Next; + END +END + + static Boolean DecodePseudo(void) +BEGIN + PLiteral Lauf,Tmp,Last; + + /* ab hier (und weiter in der Hauptroutine) stehen die Befehle, + die Code erzeugen, deshalb wird der Merker fuer verzoegerte + Spruenge hier weiter geschaltet. */ + + PrevDelayed=CurrDelayed; CurrDelayed=False; + + if (Memo("LTORG")) + BEGIN + if (ArgCnt!=0) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else + BEGIN + if ((EProgCounter() & 3)==0) + BEGIN + LTORG_32(); LTORG_16(); + END + else + BEGIN + LTORG_16(); LTORG_32(); + END + Lauf=FirstLiteral; Last=Nil; + while (Lauf!=Nil) + BEGIN + if ((Lauf->DefSection==MomSectionHandle) AND (Lauf->PassNo<0)) + BEGIN + Tmp=Lauf->Next; + if (Last==Nil) FirstLiteral=Tmp; else Last->Next=Tmp; + free(Lauf); Lauf=Tmp; + END + else + BEGIN + Last=Lauf; Lauf=Lauf->Next; + END + END + END + return True; + END + + return False; +END + + static void SetCode(Word Code) +BEGIN + CodeLen=2; WAsmCode[0]=Code; +END + + static void MakeCode_7000(void) +BEGIN + int z; + LongInt AdrLong; + Boolean OK; + Byte HReg; + + CodeLen=0; DontPrint=False; OpSize=(-1); + + /* zu ignorierendes */ + + if (Memo("")) return; + + /* Pseudoanweisungen */ + + if (DecodePseudo()) return; + + /* Attribut verwursten */ + + if (*AttrPart!='\0') + BEGIN + if (strlen(AttrPart)!=1) + BEGIN + WrError(1105); return; + END + switch (toupper(*AttrPart)) + BEGIN + case 'B': SetOpSize(0); break; + case 'W': SetOpSize(1); break; + case 'L': SetOpSize(2); break; + case 'Q': SetOpSize(3); break; + case 'S': SetOpSize(4); break; + case 'D': SetOpSize(5); break; + case 'X': SetOpSize(6); break; + case 'P': SetOpSize(7); break; + default: + WrError(1107); return; + END + END + + if (DecodeMoto16Pseudo(OpSize,True)) return; + + /* Anweisungen ohne Argument */ + + for (z=0; z2) WrError(1130); + else if (DecodeReg(ArgStr[1],&HReg)) + BEGIN + DecodeAdr(ArgStr[2],MModReg+MModIReg+MModPreDec+MModIndReg+MModR0Base+MModGBRBase,True); + switch (AdrMode) + BEGIN + case ModReg: + if (OpSize!=2) WrError(1130); + else SetCode(0x6003+(HReg << 4)+(AdrPart << 8)); + break; + case ModIReg: + SetCode(0x2000+(HReg << 4)+(AdrPart << 8)+OpSize); + break; + case ModPreDec: + SetCode(0x2004+(HReg << 4)+(AdrPart << 8)+OpSize); + break; + case ModIndReg: + if (OpSize==2) + SetCode(0x1000+(HReg << 4)+(AdrPart & 15)+((AdrPart & 0xf0) << 4)); + else if (HReg!=0) WrError(1350); + else SetCode(0x8000+AdrPart+(((Word)OpSize) << 8)); + break; + case ModR0Base: + SetCode(0x0004+(AdrPart << 8)+(HReg << 4)+OpSize); + break; + case ModGBRBase: + if (HReg!=0) WrError(1350); + else SetCode(0xc000+AdrPart+(((Word)OpSize) << 8)); + break; + END + END + else if (DecodeReg(ArgStr[2],&HReg)) + BEGIN + DecodeAdr(ArgStr[1],MModImm+MModPCRel+MModIReg+MModPostInc+MModIndReg+MModR0Base+MModGBRBase,True); + switch (AdrMode) + BEGIN + case ModIReg: + SetCode(0x6000+(AdrPart << 4)+(((Word)HReg) << 8)+OpSize); + break; + case ModPostInc: + SetCode(0x6004+(AdrPart << 4)+(((Word)HReg) << 8)+OpSize); + break; + case ModIndReg: + if (OpSize==2) + SetCode(0x5000+(((Word)HReg) << 8)+AdrPart); + else if (HReg!=0) WrError(1350); + else SetCode(0x8400+AdrPart+(((Word)OpSize) << 8)); + break; + case ModR0Base: + SetCode(0x000c+(AdrPart << 4)+(((Word)HReg) << 8)+OpSize); + break; + case ModGBRBase: + if (HReg!=0) WrError(1350); + else SetCode(0xc400+AdrPart+(((Word)OpSize) << 8)); + break; + case ModPCRel: + if (OpSize==0) WrError(1350); + else SetCode(0x9000+(((Word)OpSize-1) << 14)+(((Word)HReg) << 8)+AdrPart); + break; + case ModImm: + SetCode(0xe000+(((Word)HReg) << 8)+AdrPart); + break; + END + END + else WrError(1350); + return; + END + + if (Memo("MOVA")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (NOT DecodeReg(ArgStr[2],&HReg)) WrError(1350); + else if (HReg!=0) WrError(1350); + else + BEGIN + SetOpSize(2); + DecodeAdr(ArgStr[1],MModPCRel,False); + if (AdrMode!=ModNone) + BEGIN + CodeLen=2; WAsmCode[0]=0xc700+AdrPart; + END + END + return; + END + + if (Memo("PREF")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else + BEGIN + DecodeAdr(ArgStr[1],MModIReg,False); + if (AdrMode!=ModNone) + BEGIN + CodeLen=2; WAsmCode[0]=0x0083+(AdrPart << 8); + END; + END; + return; + END + + if ((Memo("LDC")) OR (Memo("STC"))) + BEGIN + if (OpSize==-1) SetOpSize(2); + if (ArgCnt!=2) WrError(1110); + else + BEGIN + if (Memo("LDC")) + BEGIN + strcpy(ArgStr[3],ArgStr[1]); + strcpy(ArgStr[1],ArgStr[2]); + strcpy(ArgStr[2],ArgStr[3]); + END + if (DecodeCtrlReg(ArgStr[1],&HReg)) + BEGIN + DecodeAdr(ArgStr[2],MModReg+((Memo("LDC"))?MModPostInc:MModPreDec),False); + switch (AdrMode) + BEGIN + case ModReg: + if (Memo("LDC")) SetCode(0x400e + (AdrPart << 8)+(HReg << 4)); /* ANSI :-0 */ + else SetCode(0x0002+(AdrPart << 8)+(HReg << 4)); + break; + case ModPostInc: + SetCode(0x4007+(AdrPart << 8)+(HReg << 4)); + break; + case ModPreDec: + SetCode(0x4003+(AdrPart << 8)+(HReg << 4)); + break; + END + if ((AdrMode!=ModNone) AND (NOT SupAllowed)) WrError(50); + END + END + return; + END + + if ((Memo("LDS")) OR (Memo("STS"))) + BEGIN + if (OpSize==-1) SetOpSize(2); + if (ArgCnt!=2) WrError(1110); + else + BEGIN + if (Memo("LDS")) + BEGIN + strcpy(ArgStr[3],ArgStr[1]); + strcpy(ArgStr[1],ArgStr[2]); + strcpy(ArgStr[2],ArgStr[3]); + END + if (strcasecmp(ArgStr[1],"MACH")==0) HReg=0; + else if (strcasecmp(ArgStr[1],"MACL")==0) HReg=1; + else if (strcasecmp(ArgStr[1],"PR")==0) HReg=2; + else + BEGIN + WrError(1440); HReg=0xff; + END + if (HReg<0xff) + BEGIN + DecodeAdr(ArgStr[2],MModReg+((Memo("LDS"))?MModPostInc:MModPreDec),False); + switch (AdrMode) + BEGIN + case ModReg: + if (Memo("LDS")) SetCode(0x400a+(AdrPart << 8)+(HReg << 4)); + else SetCode(0x000a+(AdrPart << 8)+(HReg << 4)); + break; + case ModPostInc: + SetCode(0x4006+(AdrPart << 8)+(HReg << 4)); + break; + case ModPreDec: + SetCode(0x4002+(AdrPart << 8)+(HReg << 4)); + break; + END + END + END + return; + END + + /* nur ein Register als Argument */ + + for (z=0; z254)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + WAsmCode[0]=0x8900+((AdrLong >> 1) & 0xff); + if (OpPart[1]=='F') WAsmCode[0]+=0x200; + if (strlen(OpPart)==4) + BEGIN + WAsmCode[0]+=0x400; CurrDelayed=True; + END + CodeLen=2; + ChkDelayed(); + END + END + return; + END + + if ((Memo("BRA")) OR (Memo("BSR"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1110); + else + BEGIN + DelayedAdr=EvalIntExpression(ArgStr[1],Int32,&OK); + AdrLong=DelayedAdr-(EProgCounter()+4); + if (OK) + if (Odd(AdrLong)) WrError(1375); + else if (((AdrLong<-4096) OR (AdrLong>4094)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + WAsmCode[0]=0xa000+((AdrLong >> 1) & 0xfff); + if (Memo("BSR")) WAsmCode[0]+=0x1000; + CodeLen=2; + CurrDelayed=True; ChkDelayed(); + END + END + return; + END + + if ((Memo("JSR")) OR (Memo("JMP"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1130); + else + BEGIN + DecodeAdr(ArgStr[1],MModIReg,False); + if (AdrMode!=ModNone) + BEGIN + SetCode(0x400b+(AdrPart << 8)+(Ord(Memo("JMP")) << 5)); + CurrDelayed=True; DelayedAdr=0x7fffffff; + ChkDelayed(); + END + END + return; + END + + WrXError(1200,OpPart); +END + + static void InitCode_7000(void) +BEGIN + SaveInitProc(); + FirstLiteral=Nil; ForwardCount=0; +END + + static Boolean IsDef_7000(void) +BEGIN + return False; +END + + static void SwitchFrom_7000(void) +BEGIN + DeinitFields(); + if (FirstLiteral!=Nil) WrError(1495); + ClearONOFF(); +END + + static void SwitchTo_7000(void) +BEGIN + TurnWords=True; ConstMode=ConstModeMoto; SetIsOccupied=False; + + PCSymbol="*"; HeaderID=0x6c; NOPCode=0x0009; + DivideChars=","; HasAttrs=True; AttrChars="."; + + ValidSegs=1<