aboutsummaryrefslogtreecommitdiffstats
path: root/code17c4x.c
diff options
context:
space:
mode:
Diffstat (limited to 'code17c4x.c')
-rw-r--r--code17c4x.c521
1 files changed, 521 insertions, 0 deletions
diff --git a/code17c4x.c b/code17c4x.c
new file mode 100644
index 0000000..b2e0cdd
--- /dev/null
+++ b/code17c4x.c
@@ -0,0 +1,521 @@
+/* code17c4x.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator PIC17C4x */
+/* */
+/* Historie: 21.8.1996 Grundsteinlegung */
+/* 7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars */
+/* 18. 8.1998 Bookkeeping-Aufruf in RES */
+/* 3. 1.1999 ChkPC-Anpassung */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "bpemu.h"
+#include "strutil.h"
+#include "chunks.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct
+ {
+ char *Name;
+ Word Code;
+ } FixedOrder;
+
+typedef struct
+ {
+ char *Name;
+ Word DefaultDir;
+ Word Code;
+ } AriOrder;
+
+#define FixedOrderCnt 5
+#define LittOrderCnt 8
+#define AriOrderCnt 23
+#define BitOrderCnt 5
+#define FOrderCnt 5
+
+
+/*---------------------------------------------------------------------------*/
+
+static FixedOrder *FixedOrders;
+static FixedOrder *LittOrders;
+static AriOrder *AriOrders;
+static FixedOrder *BitOrders;
+static FixedOrder *FOrders;
+
+static CPUVar CPU17C42;
+
+/*---------------------------------------------------------------------------*/
+
+ static void AddFixed(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Name=NName;
+ FixedOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddLitt(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=LittOrderCnt) exit(255);
+ LittOrders[InstrZ].Name=NName;
+ LittOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddAri(char *NName, Word NDef, Word NCode)
+BEGIN
+ if (InstrZ>=AriOrderCnt) exit(255);
+ AriOrders[InstrZ].Name=NName;
+ AriOrders[InstrZ].Code=NCode;
+ AriOrders[InstrZ++].DefaultDir=NDef;
+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 AddF(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=FOrderCnt) exit(255);
+ FOrders[InstrZ].Name=NName;
+ FOrders[InstrZ++].Code=NCode;
+END
+
+ static void InitFields(void)
+BEGIN
+ FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
+ AddFixed("RETFIE", 0x0005);
+ AddFixed("RETURN", 0x0002);
+ AddFixed("CLRWDT", 0x0004);
+ AddFixed("NOP" , 0x0000);
+ AddFixed("SLEEP" , 0x0003);
+
+ LittOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*LittOrderCnt); InstrZ=0;
+ AddLitt("MOVLB", 0xb800);
+ AddLitt("ADDLW", 0xb100);
+ AddLitt("ANDLW", 0xb500);
+ AddLitt("IORLW", 0xb300);
+ AddLitt("MOVLW", 0xb000);
+ AddLitt("SUBLW", 0xb200);
+ AddLitt("XORLW", 0xb400);
+ AddLitt("RETLW", 0xb600);
+
+ AriOrders=(AriOrder *) malloc(sizeof(AriOrder)*AriOrderCnt); InstrZ=0;
+ AddAri("ADDWF" , 0, 0x0e00);
+ AddAri("ADDWFC", 0, 0x1000);
+ AddAri("ANDWF" , 0, 0x0a00);
+ AddAri("CLRF" , 1, 0x2800);
+ AddAri("COMF" , 1, 0x1200);
+ AddAri("DAW" , 1, 0x2e00);
+ AddAri("DECF" , 1, 0x0600);
+ AddAri("INCF" , 1, 0x1400);
+ AddAri("IORWF" , 0, 0x0800);
+ AddAri("NEGW" , 1, 0x2c00);
+ AddAri("RLCF" , 1, 0x1a00);
+ AddAri("RLNCF" , 1, 0x2200);
+ AddAri("RRCF" , 1, 0x1800);
+ AddAri("RRNCF" , 1, 0x2000);
+ AddAri("SETF" , 1, 0x2a00);
+ AddAri("SUBWF" , 0, 0x0400);
+ AddAri("SUBWFB", 0, 0x0200);
+ AddAri("SWAPF" , 1, 0x1c00);
+ AddAri("XORWF" , 0, 0x0c00);
+ AddAri("DECFSZ", 1, 0x1600);
+ AddAri("DCFSNZ", 1, 0x2600);
+ AddAri("INCFSZ", 1, 0x1e00);
+ AddAri("INFSNZ", 1, 0x2400);
+
+ BitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BitOrderCnt); InstrZ=0;
+ AddBit("BCF" , 0x8800);
+ AddBit("BSF" , 0x8000);
+ AddBit("BTFSC", 0x9800);
+ AddBit("BTFSS", 0x9000);
+ AddBit("BTG" , 0x3800);
+
+ FOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FOrderCnt); InstrZ=0;
+ AddF("MOVWF" , 0x0100);
+ AddF("CPFSEQ", 0x3100);
+ AddF("CPFSGT", 0x3200);
+ AddF("CPFSLT", 0x3000);
+ AddF("TSTFSZ", 0x3300);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(LittOrders);
+ free(AriOrders);
+ free(BitOrders);
+ free(FOrders);
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ Word Size;
+ Boolean ValOK;
+ int z,z2;
+ TempResult t;
+ LongInt MinV,MaxV;
+
+ if (Memo("SFR"))
+ BEGIN
+ CodeEquate(SegData,0,0xff);
+ 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
+ FirstPassUnknown=False;
+ 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==SegData) 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("ZERO"))
+ 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))
+ if ((Size << 1)>MaxCodeLen) WrError(1920);
+ else
+ BEGIN
+ CodeLen=Size;
+ memset(WAsmCode,0,2*Size);
+ END
+ END
+ return True;
+ END
+
+ return False;
+END
+
+ static void MakeCode_17c4x(void)
+BEGIN
+ Boolean OK;
+ Word AdrWord;
+ int z;
+
+ 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
+ BEGIN
+ CodeLen=1; WAsmCode[0]=FixedOrders[z].Code;
+ END
+ return;
+ END
+
+ /* konstantes Argument */
+
+ for (z=0; z<LittOrderCnt; z++)
+ if (Memo(LittOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],Int8,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=LittOrders[z].Code+(AdrWord & 0xff); CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ /* W-mit-f-Operationen */
+
+ for (z=0; z<AriOrderCnt; z++)
+ if (Memo(AriOrders[z].Name))
+ BEGIN
+ if ((ArgCnt==0) OR (ArgCnt>2)) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],Int8,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegData);
+ WAsmCode[0]=AriOrders[z].Code+(AdrWord & 0xff);
+ if (ArgCnt==1)
+ BEGIN
+ CodeLen=1; WAsmCode[0]+=AriOrders[z].DefaultDir << 8;
+ END
+ else if (strcasecmp(ArgStr[2],"W")==0) CodeLen=1;
+ else if (strcasecmp(ArgStr[2],"F")==0)
+ BEGIN
+ CodeLen=1; WAsmCode[0]+=0x100;
+ END
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[2],UInt1,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=1; WAsmCode[0]+=(AdrWord << 8);
+ END
+ END
+ END
+ END
+ return;
+ END
+
+ /* Bitoperationen */
+
+ for (z=0; z<BitOrderCnt; z++)
+ if (Memo(BitOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[2],UInt3,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=EvalIntExpression(ArgStr[1],Int8,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=1; WAsmCode[0]+=BitOrders[z].Code+(AdrWord << 8);
+ ChkSpace(SegData);
+ END
+ END
+ END
+ return;
+ END
+
+ /* Register als Operand */
+
+ for (z=0; z<FOrderCnt; z++)
+ if (Memo(FOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],Int8,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=1; WAsmCode[0]=FOrders[z].Code+AdrWord;
+ ChkSpace(SegData);
+ END
+ END
+ return;
+ END
+
+ if ((Memo("MOVFP")) OR (Memo("MOVPF")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if (Memo("MOVFP"))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]);
+ strcpy(ArgStr[1],ArgStr[2]);
+ strcpy(ArgStr[2],ArgStr[3]);
+ END
+ AdrWord=EvalIntExpression(ArgStr[1],UInt5,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=EvalIntExpression(ArgStr[2],Int8,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]=Lo(WAsmCode[0])+(AdrWord << 8)+0x4000;
+ if (Memo("MOVFP")) WAsmCode[0]+=0x2000;
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("TABLRD")) OR (Memo("TABLWT")))
+ BEGIN
+ if (ArgCnt!=3) WrError(1110);
+ else
+ BEGIN
+ WAsmCode[0]=Lo(EvalIntExpression(ArgStr[3],Int8,&OK));
+ if (OK)
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[2],UInt1,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]+=AdrWord << 8;
+ AdrWord=EvalIntExpression(ArgStr[1],UInt1,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]+=0xa800+(AdrWord << 9);
+ if (Memo("TABLWT")) WAsmCode[0]+=0x400;
+ CodeLen=1;
+ END
+ END
+ END
+ END;
+ return;
+ END
+
+ if ((Memo("TLRD")) OR (Memo("TLWT")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ WAsmCode[0]=Lo(EvalIntExpression(ArgStr[2],Int8,&OK));
+ if (OK)
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],UInt1,&OK);
+ if (OK)
+ BEGIN
+ WAsmCode[0]+=(AdrWord << 9)+0xa000;
+ if (Memo("TLWT")) WAsmCode[0]+=0x400;
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("CALL")) OR (Memo("GOTO")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK);
+ if (OK)
+ if (((ProgCounter() ^ AdrWord) & 0xe000)!=0) WrError(1910);
+ else
+ BEGIN
+ WAsmCode[0]=0xc000+(AdrWord & 0x1fff);
+ if (Memo("CALL")) WAsmCode[0]+=0x2000;
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ if (Memo("LCALL"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=3;
+ WAsmCode[0]=0xb000+Hi(AdrWord);
+ WAsmCode[1]=0x0103;
+ WAsmCode[2]=0xb700+Lo(AdrWord);
+ END
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static Boolean IsDef_17c4x(void)
+BEGIN
+ return Memo("SFR");
+END
+
+ static void SwitchFrom_17c4x(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_17c4x(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=False;
+
+ PCSymbol="*"; HeaderID=0x72; NOPCode=0x0000;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)+(1<<SegData);
+ Grans[SegCode]=2; ListGrans[SegCode]=2; SegInits[SegCode]=0;
+ SegLimits[SegCode] = 0xffff;
+ Grans[SegData]=1; ListGrans[SegData]=1; SegInits[SegData]=0;
+ SegLimits[SegData] = 0xff;
+
+ MakeCode=MakeCode_17c4x; IsDef=IsDef_17c4x;
+ SwitchFrom=SwitchFrom_17c4x; InitFields();
+END
+
+ void code17c4x_init(void)
+BEGIN
+ CPU17C42=AddCPU("17C42",SwitchTo_17c4x);
+END