aboutsummaryrefslogtreecommitdiffstats
path: root/codeavr.c
diff options
context:
space:
mode:
Diffstat (limited to 'codeavr.c')
-rw-r--r--codeavr.c784
1 files changed, 784 insertions, 0 deletions
diff --git a/codeavr.c b/codeavr.c
new file mode 100644
index 0000000..bae2314
--- /dev/null
+++ b/codeavr.c
@@ -0,0 +1,784 @@
+/* codeavr.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator Atmel AVR */
+/* */
+/* Historie: 26.12.1996 Grundsteinlegung */
+/* 7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars */
+/* 18. 8.1998 BookKeeping-Aufruf bei RES */
+/* 15.10.1998 LDD/STD mit <reg>+<symbol> ging nicht */
+/* 2. 5.1999 JMP/CALL momentan bei keinem Mitglied erlaubt */
+/* WRAPMODE eingebaut */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#include "bpemu.h"
+#include "nls.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmallg.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+typedef struct
+ {
+ char *Name;
+ Word Code;
+ } FixedOrder;
+
+typedef struct
+ {
+ char *Name;
+ CPUVar MinCPU;
+ Word Code;
+ } ArchOrder;
+
+
+#define FixedOrderCnt 24
+#define Reg1OrderCnt 10
+#define Reg2OrderCnt 12
+#define Reg3OrderCnt 4
+#define ImmOrderCnt 7
+#define RelOrderCnt 18
+#define BitOrderCnt 4
+#define PBitOrderCnt 4
+
+
+static CPUVar CPU90S1200,CPU90S2313,CPU90S4414,CPU90S8515;
+
+static ArchOrder *FixedOrders;
+static ArchOrder *Reg1Orders;
+static ArchOrder *Reg2Orders;
+static FixedOrder *Reg3Orders;
+static FixedOrder *ImmOrders;
+static FixedOrder *RelOrders;
+static FixedOrder *BitOrders;
+static FixedOrder *PBitOrders;
+
+static Boolean WrapFlag;
+static LongInt ORMask, SignMask;
+
+static char *WrapFlagName = "WRAPMODE";
+
+/*---------------------------------------------------------------------------*/
+
+ static LongInt CutAdr(LongInt Adr)
+BEGIN
+ if ((Adr & SignMask) != 0) return (Adr | ORMask);
+ else return (Adr & SegLimits[SegCode]);
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static void AddFixed(char *NName, CPUVar NMin, Word NCode)
+BEGIN
+ if (InstrZ>FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Name=NName;
+ FixedOrders[InstrZ].MinCPU=NMin;
+ FixedOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddReg1(char *NName, CPUVar NMin, Word NCode)
+BEGIN
+ if (InstrZ>=Reg1OrderCnt) exit(255);
+ Reg1Orders[InstrZ].Name=NName;
+ Reg1Orders[InstrZ].MinCPU=NMin;
+ Reg1Orders[InstrZ++].Code=NCode;
+END
+
+ static void AddReg2(char *NName, CPUVar NMin, Word NCode)
+BEGIN
+ if (InstrZ>=Reg2OrderCnt) exit(255);
+ Reg2Orders[InstrZ].Name=NName;
+ Reg2Orders[InstrZ].MinCPU=NMin;
+ Reg2Orders[InstrZ++].Code=NCode;
+END
+
+ static void AddReg3(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=Reg3OrderCnt) exit(255);
+ Reg3Orders[InstrZ].Name=NName;
+ Reg3Orders[InstrZ++].Code=NCode;
+END
+
+ static void AddImm(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=ImmOrderCnt) exit(255);
+ ImmOrders[InstrZ].Name=NName;
+ ImmOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddRel(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=RelOrderCnt) exit(255);
+ RelOrders[InstrZ].Name=NName;
+ RelOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddBit(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=BitOrderCnt) exit(255);
+ BitOrders[InstrZ].Name=NName;
+ BitOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddPBit(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=PBitOrderCnt) exit(255);
+ PBitOrders[InstrZ].Name=NName;
+ PBitOrders[InstrZ++].Code=NCode;
+END
+
+ static void InitFields(void)
+BEGIN
+ FixedOrders=(ArchOrder *) malloc(sizeof(ArchOrder)*FixedOrderCnt); InstrZ=0;
+ AddFixed("IJMP" ,CPU90S2313,0x9409); AddFixed("ICALL",CPU90S2313,0x9509);
+ AddFixed("RET" ,CPU90S1200,0x9508); AddFixed("RETI" ,CPU90S1200,0x9518);
+ AddFixed("LPM" ,CPU90S2313,0x95c8); AddFixed("SEC" ,CPU90S1200,0x9408);
+ AddFixed("CLC" ,CPU90S1200,0x9488); AddFixed("SEN" ,CPU90S1200,0x9428);
+ AddFixed("CLN" ,CPU90S1200,0x94a8); AddFixed("SEZ" ,CPU90S1200,0x9418);
+ AddFixed("CLZ" ,CPU90S1200,0x9498); AddFixed("SEI" ,CPU90S1200,0x9478);
+ AddFixed("CLI" ,CPU90S1200,0x94f8); AddFixed("SES" ,CPU90S1200,0x9448);
+ AddFixed("CLS" ,CPU90S1200,0x94c8); AddFixed("SEV" ,CPU90S1200,0x9438);
+ AddFixed("CLV" ,CPU90S1200,0x94b8); AddFixed("SET" ,CPU90S1200,0x9468);
+ AddFixed("CLT" ,CPU90S1200,0x94e8); AddFixed("SEH" ,CPU90S1200,0x9458);
+ AddFixed("CLH" ,CPU90S1200,0x94d8); AddFixed("NOP" ,CPU90S1200,0x0000);
+ AddFixed("SLEEP",CPU90S1200,0x9588); AddFixed("WDR" ,CPU90S1200,0x95a8);
+
+ Reg1Orders=(ArchOrder *) malloc(sizeof(ArchOrder)*Reg1OrderCnt); InstrZ=0;
+ AddReg1("COM" ,CPU90S1200,0x9400); AddReg1("NEG" ,CPU90S1200,0x9401);
+ AddReg1("INC" ,CPU90S1200,0x9403); AddReg1("DEC" ,CPU90S1200,0x940a);
+ AddReg1("PUSH" ,CPU90S2313,0x920f); AddReg1("POP" ,CPU90S2313,0x900f);
+ AddReg1("LSR" ,CPU90S1200,0x9406); AddReg1("ROR" ,CPU90S1200,0x9407);
+ AddReg1("ASR" ,CPU90S1200,0x9405); AddReg1("SWAP" ,CPU90S1200,0x9402);
+
+ Reg2Orders=(ArchOrder *) malloc(sizeof(ArchOrder)*Reg2OrderCnt); InstrZ=0;
+ AddReg2("ADD" ,CPU90S1200,0x0c00); AddReg2("ADC" ,CPU90S1200,0x1c00);
+ AddReg2("SUB" ,CPU90S1200,0x1800); AddReg2("SBC" ,CPU90S1200,0x0800);
+ AddReg2("AND" ,CPU90S1200,0x2000); AddReg2("OR" ,CPU90S1200,0x2800);
+ AddReg2("EOR" ,CPU90S1200,0x2400); AddReg2("CPSE" ,CPU90S1200,0x1000);
+ AddReg2("CP" ,CPU90S1200,0x1400); AddReg2("CPC" ,CPU90S1200,0x0400);
+ AddReg2("MOV" ,CPU90S1200,0x2c00); AddReg2("MUL" ,CPU90S8515+1,0x9c00);
+
+ Reg3Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Reg3OrderCnt); InstrZ=0;
+ AddReg3("CLR" ,0x2400); AddReg3("TST" ,0x2000); AddReg3("LSL" ,0x0c00);
+ AddReg3("ROL" ,0x1c00);
+
+ ImmOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ImmOrderCnt); InstrZ=0;
+ AddImm("SUBI" ,0x5000); AddImm("SBCI" ,0x4000); AddImm("ANDI" ,0x7000);
+ AddImm("ORI" ,0x6000); AddImm("SBR" ,0x6000); AddImm("CPI" ,0x3000);
+ AddImm("LDI" ,0xe000);
+
+ RelOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RelOrderCnt); InstrZ=0;
+ AddRel("BRCC" ,0xf400); AddRel("BRCS" ,0xf000); AddRel("BREQ" ,0xf001);
+ AddRel("BRGE" ,0xf404); AddRel("BRSH" ,0xf400); AddRel("BRID" ,0xf407);
+ AddRel("BRIE" ,0xf007); AddRel("BRLO" ,0xf000); AddRel("BRLT" ,0xf004);
+ AddRel("BRMI" ,0xf002); AddRel("BRNE" ,0xf401); AddRel("BRHC" ,0xf405);
+ AddRel("BRHS" ,0xf005); AddRel("BRPL" ,0xf402); AddRel("BRTC" ,0xf406);
+ AddRel("BRTS" ,0xf006); AddRel("BRVC" ,0xf403); AddRel("BRVS" ,0xf003);
+
+ BitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BitOrderCnt); InstrZ=0;
+ AddBit("BLD" ,0xf800); AddBit("BST" ,0xfa00);
+ AddBit("SBRC" ,0xfc00); AddBit("SBRS" ,0xfe00);
+
+ PBitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*PBitOrderCnt); InstrZ=0;
+ AddPBit("CBI" ,0x9800); AddPBit("SBI" ,0x9a00);
+ AddPBit("SBIC",0x9900); AddPBit("SBIS",0x9b00);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(Reg1Orders);
+ free(Reg2Orders);
+ free(Reg3Orders);
+ free(ImmOrders);
+ free(RelOrders);
+ free(BitOrders);
+ free(PBitOrders);
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static Boolean DecodeReg(char *Asc, Word *Erg)
+BEGIN
+ Boolean io;
+ char *s;
+
+ if (FindRegDef(Asc,&s)) Asc=s;
+
+ if ((strlen(Asc)<2) OR (strlen(Asc)>3) OR (toupper(*Asc)!='R')) return False;
+ else
+ BEGIN
+ *Erg=ConstLongInt(Asc+1,&io);
+ return ((io) AND (*Erg<32));
+ END
+END
+
+ static Boolean DecodeMem(char * Asc, Word *Erg)
+BEGIN
+ if (strcasecmp(Asc,"X")==0) *Erg=0x1c;
+ else if (strcasecmp(Asc,"X+")==0) *Erg=0x1d;
+ else if (strcasecmp(Asc,"-X")==0) *Erg=0x1e;
+ else if (strcasecmp(Asc,"Y")==0) *Erg=0x08;
+ else if (strcasecmp(Asc,"Y+")==0) *Erg=0x19;
+ else if (strcasecmp(Asc,"-Y")==0) *Erg=0x1a;
+ else if (strcasecmp(Asc,"Z")==0) *Erg=0x00;
+ else if (strcasecmp(Asc,"Z+")==0) *Erg=0x11;
+ else if (strcasecmp(Asc,"-Z")==0) *Erg=0x12;
+ else return False;
+ return True;
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ Integer Size;
+ int z,z2;
+ Boolean ValOK;
+ TempResult t;
+ LongInt MinV,MaxV;
+
+ if (Memo("PORT"))
+ BEGIN
+ CodeEquate(SegIO,0,0x3f);
+ return True;
+ END
+
+ if (Memo("RES"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ Size=EvalIntExpression(ArgStr[1],Int16,&ValOK);
+ if (FirstPassUnknown) WrError(1820);
+ if ((ValOK) AND (NOT FirstPassUnknown))
+ BEGIN
+ DontPrint=True;
+ CodeLen=Size;
+ BookKeeping();
+ END
+ END
+ return True;
+ END
+
+ if (Memo("DATA"))
+ BEGIN
+ MaxV=(ActPC==SegCode)?65535:255; MinV=(-((MaxV+1) >> 1));
+ if (ArgCnt==0) WrError(1110);
+ else
+ BEGIN
+ ValOK=True;
+ for (z=1; z<=ArgCnt; z++)
+ if (ValOK)
+ BEGIN
+ EvalExpression(ArgStr[z],&t);
+ if ((FirstPassUnknown) AND (t.Typ==TempInt)) t.Contents.Int&=MaxV;
+ switch (t.Typ)
+ BEGIN
+ case TempInt:
+ if (ChkRange(t.Contents.Int,MinV,MaxV))
+ if (ActPC==SegCode) WAsmCode[CodeLen++]=t.Contents.Int;
+ else BAsmCode[CodeLen++]=t.Contents.Int;
+ break;
+ case TempFloat:
+ WrError(1135); ValOK=False;
+ break;
+ case TempString:
+ for (z2=0; z2<strlen(t.Contents.Ascii); z2++)
+ BEGIN
+ Size=CharTransTable[((usint) t.Contents.Ascii[z2])&0xff];
+ if (ActPC!=SegCode) BAsmCode[CodeLen++]=Size;
+ else if ((z2&1)==0) WAsmCode[CodeLen++]=Size;
+ else WAsmCode[CodeLen-1]+=Size<<8;
+ END
+ break;
+ default:
+ ValOK=False;
+ END
+ END
+ if (NOT ValOK) CodeLen=0;
+ END
+ return True;
+ END
+
+ if (Memo("REG"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else AddRegDef(LabPart,ArgStr[1]);
+ return True;
+ END
+
+ return False;
+END
+
+ static void MakeCode_AVR(void)
+BEGIN
+ int z;
+ LongInt AdrInt;
+ Word Reg1,Reg2;
+ Boolean OK;
+
+ CodeLen=0; DontPrint=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ /* kein Argument */
+
+ for (z=0; z<FixedOrderCnt; z++)
+ if (Memo(FixedOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else if (MomCPU<FixedOrders[z].MinCPU) WrXError(1500,OpPart);
+ else
+ BEGIN
+ WAsmCode[0]=FixedOrders[z].Code; CodeLen=1;
+ END
+ return;
+ END
+
+ /* nur Register */
+
+ for (z=0; z<Reg1OrderCnt; z++)
+ if (Memo(Reg1Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<Reg1Orders[z].MinCPU) WrXError(1500,OpPart);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ WAsmCode[0]=Reg1Orders[z].Code+(Reg1 << 4); CodeLen=1;
+ END
+ return;
+ END
+
+ for (z=0; z<Reg2OrderCnt; z++)
+ if (Memo(Reg2Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU<Reg2Orders[z].MinCPU) WrXError(1500,OpPart);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else if (NOT DecodeReg(ArgStr[2],&Reg2)) WrXError(1445,ArgStr[2]);
+ else
+ BEGIN
+ WAsmCode[0]=Reg2Orders[z].Code+(Reg2 & 15)+(Reg1 << 4)+
+ ((Reg2 & 16) << 5);
+ CodeLen=1;
+ END
+ return;
+ END
+
+ for (z=0; z<Reg3OrderCnt; z++)
+ if (Memo(Reg3Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ WAsmCode[0]=Reg3Orders[z].Code+(Reg1 & 15)+(Reg1 << 4)+
+ ((Reg1 & 16) << 5);
+ CodeLen=1;
+ END
+ return;
+ END
+
+ /* immediate mit Register */
+
+ for (z=0; z<ImmOrderCnt; z++)
+ if (Memo(ImmOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else if (Reg1<16) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ Reg2=EvalIntExpression(ArgStr[2],Int8,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=ImmOrders[z].Code+((Reg2 & 0xf0) << 4)+(Reg2 & 0x0f)+
+ ((Reg1 & 0x0f) << 4);
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("ADIW")) OR (Memo("SBIW")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU<CPU90S2313) WrError(1500);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else if ((Reg1<24) OR (Odd(Reg1))) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ Reg2=EvalIntExpression(ArgStr[2],UInt6,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=0x9600+(Ord(Memo("SBIW")) << 8)+((Reg1 & 6) << 3)+
+ (Reg2 & 15)+((Reg2 & 0x30) << 2);
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ /* Transfer */
+
+ if ((Memo("LD")) OR (Memo("ST")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if (Memo("ST"))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]);
+ strcpy(ArgStr[1],ArgStr[2]);
+ strcpy(ArgStr[2],ArgStr[3]);
+ z=0x200;
+ END
+ else z=0;
+ if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else if (NOT DecodeMem(ArgStr[2],&Reg2)) WrError(1350);
+ else if ((MomCPU<CPU90S2313) AND (Reg2!=0)) WrError(1351);
+ else
+ BEGIN
+ WAsmCode[0]=0x8000+z+(Reg1 << 4)+(Reg2 & 0x0f)+((Reg2 & 0x10) << 8);
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("LDD")) OR (Memo("STD")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU<CPU90S2313) WrXError(1500,OpPart);
+ else
+ BEGIN
+ if (Memo("STD"))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]);
+ strcpy(ArgStr[1],ArgStr[2]);
+ strcpy(ArgStr[2],ArgStr[3]);
+ z=0x200;
+ END
+ else z=0;
+ OK=True;
+ if (toupper(*ArgStr[2])=='Y') z+=8;
+ else if (toupper(*ArgStr[2])=='Z');
+ else OK=False;
+ if (NOT OK) WrError(1350);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ *ArgStr[2]='0';
+ Reg2=EvalIntExpression(ArgStr[2],UInt6,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=0x8000+z+(Reg1 << 4)+(Reg2 & 7)+((Reg2 & 0x18) << 7)+((Reg2 & 0x20) << 8);
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("IN")) OR (Memo("OUT")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if ((Memo("OUT")))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]);
+ strcpy(ArgStr[1],ArgStr[2]);
+ strcpy(ArgStr[2],ArgStr[3]);
+ z=0x800;
+ END
+ else z=0;
+ if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ Reg2=EvalIntExpression(ArgStr[2],UInt6,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegIO);
+ WAsmCode[0]=0xb000+z+(Reg1 << 4)+(Reg2 & 0x0f)+((Reg2 & 0xf0) << 5);
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("LDS")) OR (Memo("STS")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU<CPU90S2313) WrError(1500);
+ else
+ BEGIN
+ if (Memo("STS"))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]);
+ strcpy(ArgStr[1],ArgStr[2]);
+ strcpy(ArgStr[2],ArgStr[3]);
+ z=0x200;
+ END
+ else z=0;
+ if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ WAsmCode[1]=EvalIntExpression(ArgStr[2],UInt16,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegData);
+ WAsmCode[0]=0x9000+z+(Reg1 << 4);
+ CodeLen=2;
+ END
+ END
+ END
+ return;
+ END
+
+ /* Bitoperationen */
+
+ if ((Memo("BCLR")) OR (Memo("BSET")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ Reg1=EvalIntExpression(ArgStr[1],UInt3,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=0x9408+(Reg1 << 4)+(Ord(Memo("BCLR")) << 7);
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<BitOrderCnt; z++)
+ if (Memo(BitOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ Reg2=EvalIntExpression(ArgStr[2],UInt3,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=BitOrders[z].Code+(Reg1 << 4)+Reg2;
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ if (Memo("CBR"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else if (Reg1<16) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ Reg2=EvalIntExpression(ArgStr[2],Int8,&OK) ^ 0xff;
+ if (OK)
+ BEGIN
+ WAsmCode[0]=0x7000+((Reg2 & 0xf0) << 4)+(Reg2 & 0x0f)+
+ ((Reg1 & 0x0f) << 4);
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ if (Memo("SER"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeReg(ArgStr[1],&Reg1)) WrXError(1445,ArgStr[1]);
+ else if (Reg1<16) WrXError(1445,ArgStr[1]);
+ else
+ BEGIN
+ WAsmCode[0]=0xef0f+((Reg1 & 0x0f) << 4);
+ CodeLen=1;
+ END
+ return;
+ END
+
+ for (z=0; z<PBitOrderCnt; z++)
+ if (Memo(PBitOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ Reg1=EvalIntExpression(ArgStr[1],UInt5,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegIO);
+ Reg2=EvalIntExpression(ArgStr[2],UInt3,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=PBitOrders[z].Code+Reg2+(Reg1 << 3);
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ /* Spruenge */
+
+ for (z=0; z<RelOrderCnt; z++)
+ if (Memo(RelOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK)-(EProgCounter()+1);
+ if (OK)
+ BEGIN
+ if (WrapFlag) AdrInt = CutAdr(AdrInt);
+ if ((NOT SymbolQuestionable) AND ((AdrInt<-64) OR (AdrInt>63))) WrError(1370);
+ else
+ BEGIN
+ ChkSpace(SegCode);
+ WAsmCode[0]=RelOrders[z].Code+((AdrInt & 0x7f) << 3);
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("BRBC")) OR (Memo("BRBS")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ Reg1=EvalIntExpression(ArgStr[1],UInt3,&OK);
+ if (OK)
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+1);
+ if (OK)
+ BEGIN
+ if (WrapFlag) AdrInt = CutAdr(AdrInt);
+ if ((NOT SymbolQuestionable) AND ((AdrInt<-64) OR (AdrInt>63))) WrError(1370);
+ else
+ BEGIN
+ ChkSpace(SegCode);
+ WAsmCode[0]=0xf000+(Ord(Memo("BRBC")) << 10)+((AdrInt & 0x7f) << 3)+Reg1;
+ CodeLen=1;
+ END
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("JMP")) OR (Memo("CALL")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<CPU90S8515+1) WrError(1500);
+ else
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[1],UInt22,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode);
+ WAsmCode[0]=0x940c+(Ord(Memo("CALL")) << 1)+((AdrInt & 0x3e0000) >> 13)+((AdrInt & 0x10000) >> 16);
+ WAsmCode[1]=AdrInt & 0xffff;
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("RJMP")) OR (Memo("RCALL")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[1],UInt22,&OK)-(EProgCounter()+1);
+ if (OK)
+ BEGIN
+ if (WrapFlag) AdrInt = CutAdr(AdrInt);
+ if ((NOT SymbolQuestionable) AND ((AdrInt<-2048) OR (AdrInt>2047))) WrError(1370);
+ else
+ BEGIN
+ ChkSpace(SegCode);
+ WAsmCode[0]=0xc000+(Ord(Memo("RCALL")) << 12)+(AdrInt & 0xfff);
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static Boolean IsDef_AVR(void)
+BEGIN
+ return (Memo("PORT") OR Memo("REG"));
+END
+
+ static void SwitchFrom_AVR(void)
+BEGIN
+ DeinitFields(); ClearONOFF();
+END
+
+ static void SwitchTo_AVR(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=True;
+
+ PCSymbol="*"; HeaderID=0x3b; NOPCode=0x0000;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)|(1<<SegData)|(1<<SegIO);
+ Grans[SegCode]=2; ListGrans[SegCode]=2; SegInits[SegCode]=0;
+ Grans[SegData]=1; ListGrans[SegData]=1; SegInits[SegData]=32;
+ Grans[SegIO ]=1; ListGrans[SegIO ]=1; SegInits[SegIO ]=0; SegLimits[SegIO] = 0x3f;
+
+ if (MomCPU == CPU90S1200) SegLimits[SegCode] = 0x01ff;
+ else if (MomCPU == CPU90S2313) SegLimits[SegCode] = 0x03ff;
+ else if (MomCPU == CPU90S4414) SegLimits[SegCode] = 0x07ff;
+ else SegLimits[SegCode] = 0xfff;
+
+ if (MomCPU == CPU90S1200) SegLimits[SegData] = 0x5f;
+ else if (MomCPU == CPU90S2313) SegLimits[SegData] = 0xdf;
+ else SegLimits[SegData] = 0xffff;
+
+ SignMask = (SegLimits[SegCode] + 1) >> 1;
+ ORMask = ((LongInt) - 1) - SegLimits[SegCode];
+
+ AddONOFF("WRAPMODE", &WrapFlag, WrapFlagName, False);
+ SetFlag(&WrapFlag, WrapFlagName, False);
+
+ MakeCode=MakeCode_AVR; IsDef=IsDef_AVR;
+ SwitchFrom=SwitchFrom_AVR; InitFields();
+END
+
+ void codeavr_init(void)
+BEGIN
+ CPU90S1200=AddCPU("AT90S1200",SwitchTo_AVR);
+ CPU90S2313=AddCPU("AT90S2313",SwitchTo_AVR);
+ CPU90S4414=AddCPU("AT90S4414",SwitchTo_AVR);
+ CPU90S8515=AddCPU("AT90S8515",SwitchTo_AVR);
+END
+