aboutsummaryrefslogtreecommitdiffstats
path: root/codest6.c
diff options
context:
space:
mode:
Diffstat (limited to 'codest6.c')
-rw-r--r--codest6.c634
1 files changed, 634 insertions, 0 deletions
diff --git a/codest6.c b/codest6.c
new file mode 100644
index 0000000..ea7f242
--- /dev/null
+++ b/codest6.c
@@ -0,0 +1,634 @@
+/* codest6.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator ST6-Familie */
+/* */
+/* Historie: 14.11.1996 Grundsteinlegung */
+/* 2. 1.1998 ChkPC ersetzt */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+
+#include "strutil.h"
+#include "bpemu.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+typedef struct
+ {
+ char *Name;
+ Byte Code;
+ } FixedOrder;
+
+typedef struct
+ {
+ char *Name;
+ Word Code;
+ } AccOrder;
+
+
+#define FixedOrderCnt 5
+
+#define RelOrderCnt 4
+
+#define ALUOrderCnt 4
+
+#define AccOrderCnt 3
+
+
+#define ModNone (-1)
+#define ModAcc 0
+#define MModAcc (1 << ModAcc)
+#define ModDir 1
+#define MModDir (1 << ModDir)
+#define ModInd 2
+#define MModInd (1 << ModInd)
+
+
+static Byte AdrMode;
+static ShortInt AdrType;
+static Byte AdrVal;
+
+static LongInt WinAssume;
+
+static SimpProc SaveInitProc;
+
+static CPUVar CPUST6210,CPUST6215,CPUST6220,CPUST6225;
+
+static FixedOrder *FixedOrders;
+static FixedOrder *RelOrders;
+static FixedOrder *ALUOrders;
+static AccOrder *AccOrders;
+
+/*---------------------------------------------------------------------------------*/
+
+ static void AddFixed(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Name=NName;
+ FixedOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddRel(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=RelOrderCnt) exit(255);
+ RelOrders[InstrZ].Name=NName;
+ RelOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddALU(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=ALUOrderCnt) exit(255);
+ ALUOrders[InstrZ].Name=NName;
+ ALUOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddAcc(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=AccOrderCnt) exit(255);
+ AccOrders[InstrZ].Name=NName;
+ AccOrders[InstrZ++].Code=NCode;
+END
+
+ static void InitFields(void)
+BEGIN
+ FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
+ AddFixed("NOP" , 0x04);
+ AddFixed("RET" , 0xcd);
+ AddFixed("RETI", 0x4d);
+ AddFixed("STOP", 0x6d);
+ AddFixed("WAIT", 0xed);
+
+ RelOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RelOrderCnt); InstrZ=0;
+ AddRel("JRZ" , 0x04);
+ AddRel("JRNZ", 0x00);
+ AddRel("JRC" , 0x06);
+ AddRel("JRNC", 0x02);
+
+ ALUOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALUOrderCnt); InstrZ=0;
+ AddALU("ADD" , 0x47);
+ AddALU("AND" , 0xa7);
+ AddALU("CP" , 0x27);
+ AddALU("SUB" , 0xc7);
+
+ AccOrders=(AccOrder *) malloc(sizeof(AccOrder)*AccOrderCnt); InstrZ=0;
+ AddAcc("COM", 0x002d);
+ AddAcc("RLC", 0x00ad);
+ AddAcc("SLA", 0xff5f);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(RelOrders);
+ free(ALUOrders);
+ free(AccOrders);
+END
+
+/*---------------------------------------------------------------------------------*/
+
+ static void ResetAdr(void)
+BEGIN
+ AdrType=ModNone; AdrCnt=0;
+END
+
+ static void ChkAdr(Byte Mask)
+BEGIN
+ if ((AdrType!=ModNone) AND ((Mask AND (1 << AdrType))==0))
+ BEGIN
+ ResetAdr(); WrError(1350);
+ END
+END
+
+ static void DecodeAdr(char *Asc, Byte Mask)
+BEGIN
+#define RegCnt 5
+ static char *RegNames[RegCnt+1]={"A","V","W","X","Y"};
+ static Byte RegCodes[RegCnt+1]={0xff,0x82,0x83,0x80,0x81};
+
+ Boolean OK;
+ int z;
+ Integer AdrInt;
+
+ ResetAdr();
+
+ if ((strcasecmp(Asc,"A")==0) AND ((Mask & MModAcc)!=0))
+ BEGIN
+ AdrType=ModAcc; ChkAdr(Mask); return;
+ END
+
+ for (z=0; z<RegCnt; z++)
+ if (strcasecmp(Asc,RegNames[z])==0)
+ BEGIN
+ AdrType=ModDir; AdrCnt=1; AdrVal=RegCodes[z];
+ ChkAdr(Mask); return;
+ END
+
+ if (strcasecmp(Asc,"(X)")==0)
+ BEGIN
+ AdrType=ModInd; AdrMode=0; ChkAdr(Mask); return;
+ END
+
+ if (strcasecmp(Asc,"(Y)")==0)
+ BEGIN
+ AdrType=ModInd; AdrMode=1; ChkAdr(Mask); return;
+ END
+
+ AdrInt=EvalIntExpression(Asc,UInt16,&OK);
+ if (OK)
+ if ((TypeFlag & (1 << SegCode))!=0)
+ BEGIN
+ AdrType=ModDir; AdrVal=(AdrInt & 0x3f)+0x40; AdrCnt=1;
+ if (NOT FirstPassUnknown)
+ if (WinAssume!=(AdrInt >> 6)) WrError(110);
+ END
+ else
+ BEGIN
+ if (FirstPassUnknown) AdrInt=Lo(AdrInt);
+ if (AdrInt>0xff) WrError(1320);
+ else
+ BEGIN
+ AdrType=ModDir; AdrVal=AdrInt; ChkAdr(Mask); return;
+ END
+ END
+
+ ChkAdr(Mask);
+END
+
+ static Boolean DecodePseudo(void)
+BEGIN
+#define ASSUME62Count 1
+ static ASSUMERec ASSUME62s[ASSUME62Count]=
+ {{"ROMBASE", &WinAssume, 0, 0x3f, 0x40}};
+
+ Boolean OK,Flag;
+ int z;
+ String s;
+
+ if (Memo("SFR"))
+ BEGIN
+ CodeEquate(SegData,0,0xff);
+ return True;
+ END
+
+ if ((Memo("ASCII")) OR (Memo("ASCIZ")))
+ BEGIN
+ if (ArgCnt==0) WrError(1110);
+ else
+ BEGIN
+ z=1; Flag=Memo("ASCIZ");
+ do
+ BEGIN
+ EvalStringExpression(ArgStr[z],&OK,s);
+ if (OK)
+ BEGIN
+ TranslateString(s);
+ if (CodeLen+strlen(s)+Ord(Flag)>MaxCodeLen)
+ BEGIN
+ WrError(1920); OK=False;
+ END
+ else
+ BEGIN
+ memcpy(BAsmCode+CodeLen,s,strlen(s)); CodeLen+=strlen(s);
+ if (Flag) BAsmCode[CodeLen++]=0;
+ END
+ END
+ z++;
+ END
+ while ((OK) AND (z<=ArgCnt));
+ if (NOT OK) CodeLen=0;
+ END
+ return True;
+ END
+
+ if (Memo("BYTE"))
+ BEGIN
+ strmaxcpy(OpPart,"BYT",255); DecodeMotoPseudo(False);
+ return True;
+ END
+
+ if (Memo("WORD"))
+ BEGIN
+ strmaxcpy(OpPart,"ADR",255); DecodeMotoPseudo(False);
+ return True;
+ END
+
+ if (Memo("BLOCK"))
+ BEGIN
+ strmaxcpy(OpPart,"DFS",255); DecodeMotoPseudo(False);
+ return True;
+ END
+
+ if (Memo("ASSUME"))
+ BEGIN
+ CodeASSUME(ASSUME62s,ASSUME62Count);
+ return True;
+ END
+
+ return False;
+END
+
+ static Boolean IsReg(Byte Adr)
+BEGIN
+ return ((Adr & 0xfc)==0x80);
+END
+
+ static Byte MirrBit(Byte inp)
+BEGIN
+ return (((inp & 1) << 2)+(inp & 2)+((inp & 4) >> 2));
+END
+
+ static void MakeCode_ST62(void)
+BEGIN
+ Integer AdrInt;
+ int z;
+ Boolean OK;
+
+ CodeLen=0; DontPrint=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ /* ohne Argument */
+
+ for (z=0; z<FixedOrderCnt; z++)
+ if (Memo(FixedOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=FixedOrders[z].Code;
+ END
+ return;
+ END
+
+ /* Datentransfer */
+
+ if (Memo("LD"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc+MModDir+MModInd);
+ switch (AdrType)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2],MModDir+MModInd);
+ switch (AdrType)
+ BEGIN
+ case ModDir:
+ if (IsReg(AdrVal))
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x35+((AdrVal & 3) << 6);
+ END
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0x1f; BAsmCode[1]=AdrVal;
+ END
+ break;
+ case ModInd:
+ CodeLen=1; BAsmCode[0]=0x07+(AdrMode << 3);
+ break;
+ END
+ break;
+ case ModDir:
+ DecodeAdr(ArgStr[2],MModAcc);
+ if (AdrType!=ModNone)
+ if (IsReg(AdrVal))
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x3d+((AdrVal & 3) << 6);
+ END
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0x9f; BAsmCode[1]=AdrVal;
+ END
+ break;
+ case ModInd:
+ DecodeAdr(ArgStr[2],MModAcc);
+ if (AdrType!=ModNone)
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x87+(AdrMode << 3);
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if (Memo("LDI"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[2],Int8,&OK);
+ if (OK)
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc+MModDir);
+ switch (AdrType)
+ BEGIN
+ case ModAcc:
+ CodeLen=2; BAsmCode[0]=0x17; BAsmCode[1]=Lo(AdrInt);
+ break;
+ case ModDir:
+ CodeLen=3; BAsmCode[0]=0x0d; BAsmCode[1]=AdrVal;
+ BAsmCode[2]=Lo(AdrInt);
+ break;
+ 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)
+ if ((NOT SymbolQuestionable) AND ((AdrInt<-16) OR (AdrInt>15))) WrError(1370);
+ else
+ BEGIN
+ CodeLen=1;
+ BAsmCode[0]=RelOrders[z].Code+((AdrInt << 3) & 0xf8);
+ END
+ END
+ return;
+ END
+
+ if ((Memo("JP")) OR (Memo("CALL")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[1],Int16,&OK);
+ if (OK)
+ if ((AdrInt<0) OR (AdrInt>0xfff)) WrError(1925);
+ else
+ BEGIN
+ CodeLen=2;
+ BAsmCode[0]=0x01+(Ord(Memo("JP")) << 3)+((AdrInt & 0x00f) << 4);
+ BAsmCode[1]=AdrInt >> 4;
+ END
+ END
+ return;
+ END
+
+ /* Arithmetik */
+
+ for (z=0; z<ALUOrderCnt; z++)
+ if (strncmp(ALUOrders[z].Name,OpPart,strlen(ALUOrders[z].Name))==0)
+ switch (OpPart[strlen(ALUOrders[z].Name)])
+ BEGIN
+ case '\0':
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc);
+ if (AdrType!=ModNone)
+ BEGIN
+ DecodeAdr(ArgStr[2],MModDir+MModInd);
+ switch (AdrType)
+ BEGIN
+ case ModDir:
+ CodeLen=2; BAsmCode[0]=ALUOrders[z].Code+0x18;
+ BAsmCode[1]=AdrVal;
+ break;
+ case ModInd:
+ CodeLen=1; BAsmCode[0]=ALUOrders[z].Code+(AdrMode << 3);
+ break;
+ END
+ END
+ END
+ return;
+ case 'I':
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc);
+ if (AdrType!=ModNone)
+ BEGIN
+ BAsmCode[1]=EvalIntExpression(ArgStr[2],Int8,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=2; BAsmCode[0]=ALUOrders[z].Code+0x10;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("CLR"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc+MModDir);
+ switch (AdrType)
+ BEGIN
+ case ModAcc:
+ CodeLen=2; BAsmCode[0]=0xdf; BAsmCode[1]=0xff;
+ break;
+ case ModDir:
+ CodeLen=3; BAsmCode[0]=0x0d; BAsmCode[1]=AdrVal; BAsmCode[2]=0;
+ break;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<AccOrderCnt; z++)
+ if (Memo(AccOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAcc);
+ if (AdrType!=ModNone)
+ BEGIN
+ OK=(Hi(AccOrders[z].Code)!=0);
+ CodeLen=1+Ord(OK);
+ BAsmCode[0]=Lo(AccOrders[z].Code);
+ if (OK) BAsmCode[1]=Hi(AccOrders[z].Code);
+ END
+ END
+ return;
+ END
+
+ if ((Memo("INC")) OR (Memo("DEC")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModDir+MModInd);
+ switch (AdrType)
+ BEGIN
+ case ModDir:
+ if (IsReg(AdrVal))
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x15+((AdrVal & 3) << 6);
+ if (Memo("DEC")) BAsmCode[0]+=8;
+ END
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0x7f+(Ord(Memo("DEC")) << 7);
+ BAsmCode[1]=AdrVal;
+ END
+ break;
+ case ModInd:
+ CodeLen=1;
+ BAsmCode[0]=0x67+(AdrMode << 3)+(Ord(Memo("DEC")) << 7);
+ break;
+ END
+ END
+ return;
+ END
+
+ /* Bitbefehle */
+
+ if ((Memo("SET")) OR (Memo("RES")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0]=MirrBit(EvalIntExpression(ArgStr[1],UInt3,&OK));
+ if (OK)
+ BEGIN
+ DecodeAdr(ArgStr[2],MModDir);
+ if (AdrType!=ModNone)
+ BEGIN
+ CodeLen=2;
+ BAsmCode[0]=(BAsmCode[0] << 5)+(Ord(Memo("SET")) << 4)+0x0b;
+ BAsmCode[1]=AdrVal;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("JRR")) OR (Memo("JRS")))
+ BEGIN
+ if (ArgCnt!=3) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0]=MirrBit(EvalIntExpression(ArgStr[1],UInt3,&OK));
+ if (OK)
+ BEGIN
+ BAsmCode[0]=(BAsmCode[0] << 5)+3+(Ord(Memo("JRS")) << 4);
+ DecodeAdr(ArgStr[2],MModDir);
+ if (AdrType!=ModNone)
+ BEGIN
+ BAsmCode[1]=AdrVal;
+ AdrInt=EvalIntExpression(ArgStr[3],UInt16,&OK)-(EProgCounter()+3);
+ if (OK)
+ if ((NOT SymbolQuestionable) AND ((AdrInt>127) OR (AdrInt<-128))) WrError(1370);
+ else
+ BEGIN
+ CodeLen=3; BAsmCode[2]=Lo(AdrInt);
+ END
+ END
+ END
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static void InitCode_ST62(void)
+BEGIN
+ SaveInitProc();
+ WinAssume=0x40;
+END
+
+ static Boolean IsDef_ST62(void)
+BEGIN
+ return (Memo("SFR"));
+END
+
+ static void SwitchFrom_ST62(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_ST62(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=True;
+
+ PCSymbol="PC"; HeaderID=0x78; NOPCode=0x04;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)+(1<<SegData);
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = (MomCPU < CPUST6220) ? 0xfff : 0x7ff;
+ Grans[SegData]=1; ListGrans[SegData]=1; SegInits[SegData]=0;
+ SegLimits[SegData] = 0xff;
+
+ MakeCode=MakeCode_ST62; IsDef=IsDef_ST62;
+ SwitchFrom=SwitchFrom_ST62; InitFields();
+END
+
+ void codest6_init(void)
+BEGIN
+ CPUST6210=AddCPU("ST6210",SwitchTo_ST62);
+ CPUST6215=AddCPU("ST6215",SwitchTo_ST62);
+ CPUST6220=AddCPU("ST6220",SwitchTo_ST62);
+ CPUST6225=AddCPU("ST6225",SwitchTo_ST62);
+
+ SaveInitProc=InitPassProc; InitPassProc=InitCode_ST62;
+END
+