aboutsummaryrefslogtreecommitdiffstats
path: root/codecop8.c
diff options
context:
space:
mode:
Diffstat (limited to 'codecop8.c')
-rw-r--r--codecop8.c727
1 files changed, 727 insertions, 0 deletions
diff --git a/codecop8.c b/codecop8.c
new file mode 100644
index 0000000..465f556
--- /dev/null
+++ b/codecop8.c
@@ -0,0 +1,727 @@
+/* codecop8.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegeneratormodul COP8-Familie */
+/* */
+/* Historie: 7.10.1996 Grundsteinlegung */
+/* 18. 8.1998 BookKeeping-Aufruf bei DSx */
+/* 2. 1.1998 ChkPC umgebaut */
+/* 14. 8.1999 Maskierung in ChkAdr falsch */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+
+#include <string.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"
+
+#define ModNone (-1)
+#define ModAcc 0
+#define MModAcc (1 << ModAcc)
+#define ModBInd 1
+#define MModBInd (1 << ModBInd)
+#define ModBInc 2
+#define MModBInc (1 << ModBInc)
+#define ModBDec 3
+#define MModBDec (1 << ModBDec)
+#define ModXInd 4
+#define MModXInd (1 << ModXInd)
+#define ModXInc 5
+#define MModXInc (1 << ModXInc)
+#define ModXDec 6
+#define MModXDec (1 << ModXDec)
+#define ModDir 7
+#define MModDir (1 << ModDir)
+#define ModImm 8
+#define MModImm (1 << ModImm)
+
+#define DirPrefix 0xbd
+#define BReg 0xfe
+
+#define FixedOrderCnt 13
+#define AccOrderCnt 9
+#define AccMemOrderCnt 7
+#define BitOrderCnt 3
+
+ typedef struct
+ {
+ char *Name;
+ Byte Code;
+ } FixedOrder;
+
+static CPUVar CPUCOP87L84;
+
+static FixedOrder *FixedOrders;
+static FixedOrder *AccOrders;
+static FixedOrder *AccMemOrders;
+static FixedOrder *BitOrders;
+
+static ShortInt AdrMode;
+static Byte AdrVal;
+static Boolean BigFlag;
+
+/*---------------------------------------------------------------------------*/
+
+ static void AddFixed(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Name=NName;
+ FixedOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddAcc(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=AccOrderCnt) exit(255);
+ AccOrders[InstrZ].Name=NName;
+ AccOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddAccMem(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=AccMemOrderCnt) exit(255);
+ AccMemOrders[InstrZ].Name=NName;
+ AccMemOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddBit(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=BitOrderCnt) exit(255);
+ BitOrders[InstrZ].Name=NName;
+ BitOrders[InstrZ++].Code=NCode;
+END
+
+ static void InitFields(void)
+BEGIN
+ FixedOrders=(FixedOrder *) malloc(FixedOrderCnt*sizeof(FixedOrder)); InstrZ=0;
+ AddFixed("LAID" ,0xa4); AddFixed("SC" ,0xa1); AddFixed("RC" ,0xa0);
+ AddFixed("IFC" ,0x88); AddFixed("IFNC" ,0x89); AddFixed("VIS" ,0xb4);
+ AddFixed("JID" ,0xa5); AddFixed("RET" ,0x8e); AddFixed("RETSK",0x8d);
+ AddFixed("RETI" ,0x8f); AddFixed("INTR" ,0x00); AddFixed("NOP" ,0xb8);
+ AddFixed("RPND" ,0xb5);
+
+ AccOrders=(FixedOrder *) malloc(AccOrderCnt*sizeof(FixedOrder)); InstrZ=0;
+ AddAcc("CLR" ,0x64); AddAcc("INC" ,0x8a); AddAcc("DEC" ,0x8b);
+ AddAcc("DCOR" ,0x66); AddAcc("RRC" ,0xb0); AddAcc("RLC" ,0xa8);
+ AddAcc("SWAP" ,0x65); AddAcc("POP" ,0x8c); AddAcc("PUSH" ,0x67);
+
+ AccMemOrders=(FixedOrder *) malloc(AccMemOrderCnt*sizeof(FixedOrder)); InstrZ=0;
+ AddAccMem("ADD" ,0x84); AddAccMem("ADC" ,0x80); AddAccMem("SUBC" ,0x81);
+ AddAccMem("AND" ,0x85); AddAccMem("OR" ,0x87); AddAccMem("XOR" ,0x86);
+ AddAccMem("IFGT" ,0x83);
+
+ BitOrders=(FixedOrder *) malloc(BitOrderCnt*sizeof(FixedOrder)); InstrZ=0;
+ AddBit("IFBIT",0x70); AddBit("SBIT",0x78); AddBit("RBIT",0x68);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(AccOrders);
+ free(AccMemOrders);
+ free(BitOrders);
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static void ChkAdr(Word Mask)
+BEGIN
+ if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0))
+ BEGIN
+ AdrMode=ModNone; WrError(1350);
+ END
+END
+
+ static void DecodeAdr(char *Asc, Word Mask)
+BEGIN
+ static char *ModStrings[ModXDec+1]=
+ {"A","[B]","[B+]","[B-]","[X]","[X+]","[X-]"};
+
+ int z;
+ Boolean OK;
+
+ AdrMode=ModNone;
+
+ /* indirekt/Akku */
+
+ for (z=ModAcc; z<=ModXDec; z++)
+ if (strcasecmp(Asc,ModStrings[z])==0)
+ BEGIN
+ AdrMode=z; ChkAdr(Mask); return;
+ END
+
+ /* immediate */
+
+ if (*Asc=='#')
+ BEGIN
+ AdrVal=EvalIntExpression(Asc+1,Int8,&OK);
+ if (OK) AdrMode=ModImm;
+ ChkAdr(Mask); return;
+ END
+
+ /* direkt */
+
+ AdrVal=EvalIntExpression(Asc,Int8,&OK);
+ if (OK)
+ BEGIN
+ AdrMode=ModDir; ChkSpace(SegData);
+ END
+
+ ChkAdr(Mask);
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ Boolean ValOK;
+ Word Size,Value,t,z;
+
+ if (Memo("SFR"))
+ BEGIN
+ CodeEquate(SegData,0,0xff);
+ return True;
+ END;
+
+ if (Memo("ADDR"))
+ BEGIN
+ strcpy(OpPart,"DB"); BigFlag=True;
+ END
+
+ if (Memo("ADDRW"))
+ BEGIN
+ strcpy(OpPart,"DW"); BigFlag=True;
+ END
+
+ if (Memo("BYTE")) strcpy(OpPart,"DB");
+
+ if (Memo("WORD")) strcpy(OpPart,"DW");
+
+ if ((Memo("DSB")) OR (Memo("DSW")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ Size=EvalIntExpression(ArgStr[1],UInt16,&ValOK);
+ if (FirstPassUnknown) WrError(1820);
+ if ((ValOK) AND (NOT FirstPassUnknown))
+ BEGIN
+ DontPrint=True;
+ if (Memo("DSW")) Size+=Size;
+ CodeLen=Size;
+ BookKeeping();
+ END
+ END
+ return True;
+ END
+
+ if (Memo("FB"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ Size=EvalIntExpression(ArgStr[1],UInt16,&ValOK);
+ if (FirstPassUnknown) WrError(1820);
+ if ((ValOK) AND (NOT FirstPassUnknown))
+ if (Size>MaxCodeLen) WrError(1920);
+ else
+ BEGIN
+ BAsmCode[0]=EvalIntExpression(ArgStr[2],Int8,&ValOK);
+ if (ValOK)
+ BEGIN
+ CodeLen=Size;
+ memset(BAsmCode+1,BAsmCode[0],Size-1);
+ END
+ END
+ END
+ return True;
+ END
+
+ if (Memo("FW"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ Size=EvalIntExpression(ArgStr[1],UInt16,&ValOK);
+ if (FirstPassUnknown) WrError(1820);
+ if ((ValOK) AND (NOT FirstPassUnknown))
+ if ((Size << 1)>MaxCodeLen) WrError(1920);
+ else
+ BEGIN
+ Value=EvalIntExpression(ArgStr[2],Int16,&ValOK);
+ if (ValOK)
+ BEGIN
+ CodeLen=Size << 1; t=0;
+ for (z=0; z<Size; z++)
+ BEGIN
+ BAsmCode[t++]=Lo(Value); BAsmCode[t++]=Hi(Value);
+ END
+ END
+ END
+ END
+ return True;
+ END
+
+ return False;
+END
+
+ static void MakeCode_COP8(void)
+BEGIN
+ Integer AdrInt;
+ int z;
+ Byte HReg;
+ Boolean OK;
+ Word AdrWord;
+
+ CodeLen=0; DontPrint=False; BigFlag=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ if (DecodeIntelPseudo(BigFlag)) return;
+
+ /* ohne Argument */
+
+ for (z=0; z<FixedOrderCnt; z++)
+ if Memo(FixedOrders[z].Name)
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0]=FixedOrders[z].Code; CodeLen=1;
+ END
+ return;
+ END
+
+ /* Datentransfer */
+
+ if (Memo("LD"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc+MModDir+MModBInd+MModBInc+MModBDec);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2],MModDir+MModImm+MModBInd+MModXInd+MModBInc+MModXInc+MModBDec+MModXDec);
+ switch (AdrMode)
+ BEGIN
+ case ModDir:
+ BAsmCode[0]=0x9d; BAsmCode[1]=AdrVal; CodeLen=2;
+ break;
+ case ModImm:
+ BAsmCode[0]=0x98; BAsmCode[1]=AdrVal; CodeLen=2;
+ break;
+ case ModBInd:
+ BAsmCode[0]=0xae; CodeLen=1;
+ break;
+ case ModXInd:
+ BAsmCode[0]=0xbe; CodeLen=1;
+ break;
+ case ModBInc:
+ BAsmCode[0]=0xaa; CodeLen=1;
+ break;
+ case ModXInc:
+ BAsmCode[0]=0xba; CodeLen=1;
+ break;
+ case ModBDec:
+ BAsmCode[0]=0xab; CodeLen=1;
+ break;
+ case ModXDec:
+ BAsmCode[0]=0xbb; CodeLen=1;
+ break;
+ END
+ break;
+ case ModDir:
+ HReg=AdrVal; DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode==ModImm)
+ if (HReg==BReg)
+ if (AdrVal<=15)
+ BEGIN
+ BAsmCode[0]=0x5f-AdrVal; CodeLen=1;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=0x9f; BAsmCode[1]=AdrVal; CodeLen=2;
+ END
+ else if (HReg>=0xf0)
+ BEGIN
+ BAsmCode[0]=HReg-0x20; BAsmCode[1]=AdrVal; CodeLen=2;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=0xbc; BAsmCode[1]=HReg; BAsmCode[2]=AdrVal; CodeLen=3;
+ END
+ break;
+ case ModBInd:
+ DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode!=ModNone)
+ BEGIN
+ BAsmCode[0]=0x9e; BAsmCode[1]=AdrVal; CodeLen=2;
+ END
+ break;
+ case ModBInc:
+ DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode!=ModNone)
+ BEGIN
+ BAsmCode[0]=0x9a; BAsmCode[1]=AdrVal; CodeLen=2;
+ END
+ break;
+ case ModBDec:
+ DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode!=ModNone)
+ BEGIN
+ BAsmCode[0]=0x9b; BAsmCode[1]=AdrVal; CodeLen=2;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if (Memo("X"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if (strcasecmp(ArgStr[1],"A")!=0)
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]);
+ END
+ DecodeAdr(ArgStr[1],MModAcc);
+ if (AdrMode!=ModNone)
+ BEGIN
+ DecodeAdr(ArgStr[2],MModDir+MModBInd+MModXInd+MModBInc+MModXInc+MModBDec+MModXDec);
+ switch (AdrMode)
+ BEGIN
+ case ModDir:
+ BAsmCode[0]=0x9c; BAsmCode[1]=AdrVal; CodeLen=2;
+ break;
+ case ModBInd:
+ BAsmCode[0]=0xa6; CodeLen=1;
+ break;
+ case ModBInc:
+ BAsmCode[0]=0xa2; CodeLen=1;
+ break;
+ case ModBDec:
+ BAsmCode[0]=0xa3; CodeLen=1;
+ break;
+ case ModXInd:
+ BAsmCode[0]=0xb6; CodeLen=1;
+ break;
+ case ModXInc:
+ BAsmCode[0]=0xb2; CodeLen=1;
+ break;
+ case ModXDec:
+ BAsmCode[0]=0xb3; CodeLen=1;
+ break;
+ END
+ END
+ END
+ return;
+ END
+
+ /* Arithmetik */
+
+ for (z=0; z<AccOrderCnt; z++)
+ if Memo(AccOrders[z].Name)
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc);
+ if (AdrMode!=ModNone)
+ BEGIN
+ BAsmCode[0]=AccOrders[z].Code; CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<AccMemOrderCnt; z++)
+ if Memo(AccMemOrders[z].Name)
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc);
+ if (AdrMode!=ModNone)
+ BEGIN
+ DecodeAdr(ArgStr[2],MModDir+MModImm+MModBInd);
+ switch (AdrMode)
+ BEGIN
+ case ModBInd:
+ BAsmCode[0]=AccMemOrders[z].Code; CodeLen=1;
+ break;
+ case ModImm:
+ BAsmCode[0]=AccMemOrders[z].Code+0x10; BAsmCode[1]=AdrVal;
+ CodeLen=2;
+ break;
+ case ModDir:
+ BAsmCode[0]=DirPrefix; BAsmCode[1]=AdrVal;
+ BAsmCode[2]=AccMemOrders[z].Code;
+ CodeLen=3;
+ break;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("ANDSZ"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc);
+ if (AdrMode!=ModNone)
+ BEGIN
+ DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode==ModImm)
+ BEGIN
+ BAsmCode[0]=0x60; BAsmCode[1]=AdrVal; CodeLen=2;
+ END
+ END
+ END
+ return;
+ END
+
+ /* Bedingungen */
+
+ if (Memo("IFEQ"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc+MModDir);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2],MModDir+MModBInd+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModDir:
+ BAsmCode[0]=DirPrefix; BAsmCode[1]=AdrVal; BAsmCode[2]=0x82;
+ CodeLen=3;
+ break;
+ case ModBInd:
+ BAsmCode[0]=0x82; CodeLen=1;
+ break;
+ case ModImm:
+ BAsmCode[0]=0x92; BAsmCode[1]=AdrVal; CodeLen=2;
+ break;
+ END
+ break;
+ case ModDir:
+ BAsmCode[1]=AdrVal;
+ DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode==ModImm)
+ BEGIN
+ BAsmCode[0]=0xa9; BAsmCode[2]=AdrVal; CodeLen=3;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if (Memo("IFNE"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2],MModDir+MModBInd+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModDir:
+ BAsmCode[0]=DirPrefix; BAsmCode[1]=AdrVal; BAsmCode[2]=0xb9;
+ CodeLen=3;
+ break;
+ case ModBInd:
+ BAsmCode[0]=0xb9; CodeLen=1;
+ break;
+ case ModImm:
+ BAsmCode[0]=0x99; BAsmCode[1]=AdrVal; CodeLen=2;
+ break;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if (Memo("IFBNE"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (*ArgStr[1]!='#') WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=EvalIntExpression(ArgStr[1]+1,UInt4,&OK);
+ if (OK)
+ BEGIN
+ BAsmCode[0]+=0x40; CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ /* Bitbefehle */
+
+ for (z=0; z<BitOrderCnt; z++)
+ if Memo(BitOrders[z].Name)
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ HReg=EvalIntExpression(ArgStr[1],UInt3,&OK);
+ if (OK)
+ BEGIN
+ DecodeAdr(ArgStr[2],MModDir+MModBInd);
+ switch (AdrMode)
+ BEGIN
+ case ModDir:
+ BAsmCode[0]=DirPrefix; BAsmCode[1]=AdrVal;
+ BAsmCode[2]=BitOrders[z].Code+HReg; CodeLen=3;
+ break;
+ case ModBInd:
+ BAsmCode[0]=BitOrders[z].Code+HReg; CodeLen=1;
+ break;
+ END
+ END
+ END
+ return;
+ END
+
+ /* Spruenge */
+
+ if ((Memo("JMP")) OR (Memo("JSR")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK);
+ if (OK)
+ if (((EProgCounter()+2) >> 12)!=(AdrWord >> 12)) WrError(1910);
+ else
+ BEGIN
+ ChkSpace(SegCode);
+ BAsmCode[0]=0x20+(Ord(Memo("JSR")) << 4)+((AdrWord >> 8) & 15);
+ BAsmCode[1]=Lo(AdrWord);
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("JMPL")) OR (Memo("JSRL")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode);
+ BAsmCode[0]=0xac+Ord(Memo("JSRL"));
+ BAsmCode[1]=Hi(AdrWord);
+ BAsmCode[2]=Lo(AdrWord);
+ CodeLen=3;
+ END
+ END
+ return;
+ END
+
+ if (Memo("JP"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK)-(EProgCounter()+1);
+ if (OK)
+ if (AdrInt==0)
+ BEGIN
+ BAsmCode[0]=NOPCode; CodeLen=1; WrError(60);
+ END
+ else if (((AdrInt>31) OR (AdrInt<-32)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[0]=AdrInt & 0xff; CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ if (Memo("DRSZ"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ DecodeAdr(ArgStr[1],MModDir);
+ if (FirstPassUnknown) AdrVal|=0xf0;
+ if (AdrVal<0xf0) WrError(1315);
+ else
+ BEGIN
+ BAsmCode[0]=AdrVal-0x30; CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static Boolean IsDef_COP8(void)
+BEGIN
+ return (Memo("SFR"));
+END
+
+ static void SwitchFrom_COP8(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_COP8(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeC; SetIsOccupied=False;
+
+ PCSymbol="."; HeaderID=0x6f; NOPCode=0xb8;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)|(1<<SegData);
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = 0x1fff;
+ Grans[SegData]=1; ListGrans[SegData]=1; SegInits[SegData]=0;
+ SegLimits[SegData] = 0xff;
+
+ MakeCode=MakeCode_COP8; IsDef=IsDef_COP8;
+ SwitchFrom=SwitchFrom_COP8; InitFields();
+END
+
+ void codecop8_init(void)
+BEGIN
+ CPUCOP87L84=AddCPU("COP87L84",SwitchTo_COP8);
+END
+
+