/* code16c5x.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* AS - Codegenerator fuer PIC16C5x */ /* */ /* Historie: 19.8.1996 Grundsteinlegung */ /* 7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars */ /* 17. 8.1998 RES mit Bookkeeping */ /* 3. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #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 Code; Byte DefaultDir; } AriOrder; #define FixedOrderCnt 5 #define LitOrderCnt 5 #define AriOrderCnt 14 #define BitOrderCnt 4 #define FOrderCnt 2 #define D_CPU16C54 0 #define D_CPU16C55 1 #define D_CPU16C56 2 #define D_CPU16C57 3 static FixedOrder *FixedOrders; static FixedOrder *LitOrders; static AriOrder *AriOrders; static FixedOrder *BitOrders; static FixedOrder *FOrders; static CPUVar CPU16C54,CPU16C55,CPU16C56,CPU16C57; /*-------------------------------------------------------------------------*/ static void AddFixed(char *NName, Word NCode) BEGIN if (InstrZ>=FixedOrderCnt) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ++].Code=NCode; END static void AddLit(char *NName, Word NCode) BEGIN if (InstrZ>=LitOrderCnt) exit(255); LitOrders[InstrZ].Name=NName; LitOrders[InstrZ++].Code=NCode; END static void AddAri(char *NName, Word NCode, Byte NDef) 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("CLRW" , 0x040); AddFixed("NOP" , 0x000); AddFixed("CLRWDT", 0x004); AddFixed("OPTION", 0x002); AddFixed("SLEEP" , 0x003); LitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*LitOrderCnt); InstrZ=0; AddLit("ANDLW", 0xe00); AddLit("IORLW", 0xd00); AddLit("MOVLW", 0xc00); AddLit("RETLW", 0x800); AddLit("XORLW", 0xf00); AriOrders=(AriOrder *) malloc(sizeof(AriOrder)*AriOrderCnt); InstrZ=0; AddAri("ADDWF" , 0x1c0, 0); AddAri("ANDWF" , 0x140, 0); AddAri("COMF" , 0x240, 1); AddAri("DECF" , 0x0c0, 1); AddAri("DECFSZ", 0x2c0, 1); AddAri("INCF" , 0x280, 1); AddAri("INCFSZ", 0x3c0, 1); AddAri("IORWF" , 0x100, 0); AddAri("MOVF" , 0x200, 0); AddAri("RLF" , 0x340, 1); AddAri("RRF" , 0x300, 1); AddAri("SUBWF" , 0x080, 0); AddAri("SWAPF" , 0x380, 1); AddAri("XORWF" , 0x180, 0); BitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BitOrderCnt); InstrZ=0; AddBit("BCF" , 0x400); AddBit("BSF" , 0x500); AddBit("BTFSC", 0x600); AddBit("BTFSS", 0x700); FOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FOrderCnt); InstrZ=0; AddF("CLRF" , 0x060); AddF("MOVWF", 0x020); END static void DeinitFields(void) BEGIN free(FixedOrders); free(LitOrders); free(AriOrders); free(BitOrders); free(FOrders); END /*-------------------------------------------------------------------------*/ static Word ROMEnd(void) BEGIN switch (MomCPU-CPU16C54) BEGIN case D_CPU16C54: case D_CPU16C55: return 511; case D_CPU16C56: return 1023; case D_CPU16C57: return 2047; default: return 0; END END static Boolean DecodePseudo(void) BEGIN Word Size; Boolean ValOK; int z; TempResult t; char *p; LongInt MinV,MaxV; if (Memo("SFR")) BEGIN CodeEquate(SegData,0,0x1f); 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)?4095: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 & MaxV; else BAsmCode[CodeLen++]=t.Contents.Int & MaxV; break; case TempFloat: WrError(1135); ValOK=False; break; case TempString: for (p=t.Contents.Ascii; *p!='\0'; p++) if (ActPC==SegCode) WAsmCode[CodeLen++]=CharTransTable[((usint) *p)&0xff]; else BAsmCode[CodeLen++]=CharTransTable[((usint) *p)&0xff]; 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_16C5X(void) BEGIN Boolean OK; Word AdrWord; int z; CodeLen=0; DontPrint=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; /* Anweisungen ohne Argument */ for (z=0; z2)) WrError(1110); else BEGIN AdrWord=EvalIntExpression(ArgStr[1],UInt5,&OK); if (OK) BEGIN ChkSpace(SegData); WAsmCode[0]=AriOrders[z].Code+(AdrWord & 0x1f); if (ArgCnt==1) BEGIN CodeLen=1; WAsmCode[0]+=AriOrders[z].DefaultDir << 5; END else if (strcasecmp(ArgStr[2],"W")==0) CodeLen=1; else if (strcasecmp(ArgStr[2],"F")==0) BEGIN CodeLen=1; WAsmCode[0]+=0x20; END else BEGIN AdrWord=EvalIntExpression(ArgStr[2],UInt1,&OK); if (OK) BEGIN CodeLen=1; WAsmCode[0]+=AdrWord << 5; END END END END return; END for (z=0; zROMEnd()) WrError(1320); else if ((Memo("CALL")) AND ((AdrWord & 0x100)!=0)) WrError(1905); else BEGIN ChkSpace(SegCode); if (((ProgCounter() ^ AdrWord) & 0x200)!=0) WAsmCode[CodeLen++]=0x4a3+((AdrWord & 0x200) >> 1); /* BCF/BSF 3,5 */ if (((ProgCounter() ^ AdrWord) & 0x400)!=0) WAsmCode[CodeLen++]=0x4c3+((AdrWord & 0x400) >> 2); /* BCF/BSF 3,6 */ if (Memo("CALL")) WAsmCode[CodeLen++]=0x900+(AdrWord & 0xff); else WAsmCode[CodeLen++]=0xa00+(AdrWord & 0x1ff); END END return; END; WrXError(1200,OpPart); END static Boolean IsDef_16C5X(void) BEGIN return Memo("SFR"); END static void SwitchFrom_16C5X() BEGIN DeinitFields(); END static void SwitchTo_16C5X(void) BEGIN TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=False; PCSymbol="*"; HeaderID=0x71; NOPCode=0x000; DivideChars=","; HasAttrs=False; ValidSegs=(1<