aboutsummaryrefslogtreecommitdiffstats
path: root/code85.c
diff options
context:
space:
mode:
Diffstat (limited to 'code85.c')
-rw-r--r--code85.c423
1 files changed, 423 insertions, 0 deletions
diff --git a/code85.c b/code85.c
new file mode 100644
index 0000000..aa1e25d
--- /dev/null
+++ b/code85.c
@@ -0,0 +1,423 @@
+/* code85.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator 8080/8085 */
+/* */
+/* Historie: 24.10.1996 Grundsteinlegung */
+/* 2. 1.1999 ChkPC-Anpassung */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "nls.h"
+#include "bpemu.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+/*--------------------------------------------------------------------------------------------------*/
+
+typedef struct
+ {
+ char *Name;
+ Boolean May80;
+ Byte Code;
+ } FixedOrder;
+
+typedef struct
+ {
+ char *Name;
+ Byte Code;
+ } BaseOrder;
+
+#define FixedOrderCnt 27
+#define Op16OrderCnt 22
+#define Op8OrderCnt 10
+#define ALUOrderCnt 8
+
+static FixedOrder *FixedOrders;
+static BaseOrder *Op16Orders;
+static BaseOrder *Op8Orders;
+static BaseOrder *ALUOrders;
+
+static CPUVar CPU8080,CPU8085;
+
+/*--------------------------------------------------------------------------------------------------------*/
+
+ static void AddFixed(char *NName, Boolean NMay, Byte NCode)
+BEGIN
+ if (InstrZ>=FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Name=NName;
+ FixedOrders[InstrZ].May80=NMay;
+ FixedOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddOp16(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=Op16OrderCnt) exit(255);
+ Op16Orders[InstrZ].Name=NName;
+ Op16Orders[InstrZ++].Code=NCode;
+END
+
+ static void AddOp8(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=Op8OrderCnt) exit(255);
+ Op8Orders[InstrZ].Name=NName;
+ Op8Orders[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 InitFields(void)
+BEGIN
+ FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
+ AddFixed("XCHG", True , 0xeb); AddFixed("XTHL", True , 0xe3);
+ AddFixed("SPHL", True , 0xf9); AddFixed("PCHL", True , 0xe9);
+ AddFixed("RET" , True , 0xc9); AddFixed("RC" , True , 0xd8);
+ AddFixed("RNC" , True , 0xd0); AddFixed("RZ" , True , 0xc8);
+ AddFixed("RNZ" , True , 0xc0); AddFixed("RP" , True , 0xf0);
+ AddFixed("RM" , True , 0xf8); AddFixed("RPE" , True , 0xe8);
+ AddFixed("RPO" , True , 0xe0); AddFixed("RLC" , True , 0x07);
+ AddFixed("RRC" , True , 0x0f); AddFixed("RAL" , True , 0x17);
+ AddFixed("RAR" , True , 0x1f); AddFixed("CMA" , True , 0x2f);
+ AddFixed("STC" , True , 0x37); AddFixed("CMC" , True , 0x3f);
+ AddFixed("DAA" , True , 0x27); AddFixed("EI" , True , 0xfb);
+ AddFixed("DI" , True , 0xf3); AddFixed("NOP" , True , 0x00);
+ AddFixed("HLT" , True , 0x76); AddFixed("RIM" , False, 0x20);
+ AddFixed("SIM" , False, 0x30);
+
+ Op16Orders=(BaseOrder *) malloc(sizeof(BaseOrder)*Op16OrderCnt); InstrZ=0;
+ AddOp16("STA" , 0x32); AddOp16("LDA" , 0x3a);
+ AddOp16("SHLD", 0x22); AddOp16("LHLD", 0x2a);
+ AddOp16("JMP" , 0xc3); AddOp16("JC" , 0xda);
+ AddOp16("JNC" , 0xd2); AddOp16("JZ" , 0xca);
+ AddOp16("JNZ" , 0xc2); AddOp16("JP" , 0xf2);
+ AddOp16("JM" , 0xfa); AddOp16("JPE" , 0xea);
+ AddOp16("JPO" , 0xe2); AddOp16("CALL", 0xcd);
+ AddOp16("CC" , 0xdc); AddOp16("CNC" , 0xd4);
+ AddOp16("CZ" , 0xcc); AddOp16("CNZ" , 0xc4);
+ AddOp16("CP" , 0xf4); AddOp16("CM" , 0xfc);
+ AddOp16("CPE" , 0xec); AddOp16("CPO" , 0xe4);
+
+ Op8Orders=(BaseOrder *) malloc(sizeof(BaseOrder)*Op8OrderCnt); InstrZ=0;
+ AddOp8("IN" , 0xdb); AddOp8("OUT" , 0xd3);
+ AddOp8("ADI" , 0xc6); AddOp8("ACI" , 0xce);
+ AddOp8("SUI" , 0xd6); AddOp8("SBI" , 0xde);
+ AddOp8("ANI" , 0xe6); AddOp8("XRI" , 0xee);
+ AddOp8("ORI" , 0xf6); AddOp8("CPI" , 0xfe);
+
+ ALUOrders=(BaseOrder *) malloc(sizeof(BaseOrder)*ALUOrderCnt); InstrZ=0;
+ AddALU("ADD" , 0x80); AddALU("ADC" , 0x88);
+ AddALU("SUB" , 0x90); AddALU("SBB" , 0x98);
+ AddALU("ANA" , 0xa0); AddALU("XRA" , 0xa8);
+ AddALU("ORA" , 0xb0); AddALU("CMP" , 0xb8);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(Op16Orders);
+ free(Op8Orders);
+ free(ALUOrders);
+END
+
+/*--------------------------------------------------------------------------------------------------------*/
+
+ static Boolean DecodeReg8(char *Asc, Byte *Erg)
+BEGIN
+ static char *RegNames="BCDEHLMA";
+ char *p;
+
+ if (strlen(Asc)!=1) return False;
+ else
+ BEGIN
+ p=strchr(RegNames,toupper(*Asc));
+ if (p==0) return False;
+ else
+ BEGIN
+ *Erg=p-RegNames; return True;
+ END
+ END
+END
+
+ static Boolean DecodeReg16(char *Asc, Byte *Erg)
+BEGIN
+ static char *RegNames[4]={"B","D","H","SP"};
+
+ for (*Erg=0; (*Erg)<4; (*Erg)++)
+ if (strcasecmp(Asc,RegNames[*Erg])==0) break;
+
+ return ((*Erg)<4);
+END
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ if (Memo("PORT"))
+ BEGIN
+ CodeEquate(SegIO,0,0xff);
+ return True;
+ END
+
+ return False;
+END
+
+ static void MakeCode_85(void)
+BEGIN
+ Boolean OK;
+ Word AdrWord;
+ Byte AdrByte;
+ int z;
+
+ CodeLen=0; DontPrint=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ if (DecodeIntelPseudo(False)) return;
+
+ /* Anweisungen ohne Operanden */
+
+ for (z=0; z<FixedOrderCnt; z++)
+ if (Memo(FixedOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else if ((MomCPU<CPU8085) AND (NOT FixedOrders[z].May80)) WrError(1500);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=FixedOrders[z].Code;
+ END
+ return;
+ END
+
+ /* ein 16-Bit-Operand */
+
+ for (z=0; z<Op16OrderCnt; z++)
+ if (Memo(Op16Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=3; BAsmCode[0]=Op16Orders[z].Code;
+ BAsmCode[1]=Lo(AdrWord); BAsmCode[2]=Hi(AdrWord);
+ ChkSpace(SegCode);
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<Op8OrderCnt; z++)
+ if (Memo(Op8Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrByte=EvalIntExpression(ArgStr[1],Int8,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=2; BAsmCode[0]=Op8Orders[z].Code; BAsmCode[1]=AdrByte;
+ if (z<2) ChkSpace(SegIO);
+ END
+ END
+ return;
+ END
+
+ if (Memo("MOV"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (NOT DecodeReg8(ArgStr[1],&AdrByte)) WrError(1980);
+ else if (NOT DecodeReg8(ArgStr[2],BAsmCode+0)) WrError(1980);
+ else
+ BEGIN
+ BAsmCode[0]+=0x40+(AdrByte << 3);
+ if (BAsmCode[0]==0x76) WrError(1760); else CodeLen=1;
+ END
+ return;
+ END
+
+ if (Memo("MVI"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[1]=EvalIntExpression(ArgStr[2],Int8,&OK);
+ if (OK)
+ if (NOT DecodeReg8(ArgStr[1],&AdrByte)) WrError(1980);
+ else
+ BEGIN
+ BAsmCode[0]=0x06+(AdrByte << 3); CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ if (Memo("LXI"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[2],Int16,&OK);
+ if (OK)
+ if (NOT DecodeReg16(ArgStr[1],&AdrByte)) WrError(1980);
+ else
+ BEGIN
+ BAsmCode[0]=0x01+(AdrByte << 4);
+ BAsmCode[1]=Lo(AdrWord); BAsmCode[2]=Hi(AdrWord);
+ CodeLen=3;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("LDAX")) OR (Memo("STAX")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeReg16(ArgStr[1],&AdrByte)) WrError(1980);
+ else switch (AdrByte)
+ BEGIN
+ case 3: /* SP */
+ WrError(1135); break;
+ case 2: /* H --> MOV A,M oder M,A */
+ CodeLen=1;
+ BAsmCode[0]=(Memo("LDAX")) ? 0x7e : 0x77;
+ break;
+ default:
+ CodeLen=1;
+ BAsmCode[0]=0x02+(AdrByte << 4);
+ if (Memo("LDAX")) BAsmCode[0]+=8;
+ break;
+ END
+ return;
+ END
+
+ if ((Memo("PUSH")) OR (Memo("POP")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ if (strcasecmp(ArgStr[1],"PSW")==0) strmaxcpy(ArgStr[1],"SP",255);
+ if (NOT DecodeReg16(ArgStr[1],&AdrByte)) WrError(1980);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xc1+(AdrByte << 4);
+ if (Memo("PUSH")) BAsmCode[0]+=4;
+ END
+ END
+ return;
+ END
+
+ if (Memo("RST"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrByte=EvalIntExpression(ArgStr[1],UInt3,&OK);
+ if (OK)
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xc7+(AdrByte << 3);
+ END
+ END
+ return;
+ END
+
+ if ((Memo("INR")) OR (Memo("DCR")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeReg8(ArgStr[1],&AdrByte)) WrError(1980);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x04+(AdrByte << 3);
+ if (Memo("DCR")) BAsmCode[0]++;
+ END
+ return;
+ END
+
+ if ((Memo("INX")) OR (Memo("DCX")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeReg16(ArgStr[1],&AdrByte)) WrError(1980);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x03+(AdrByte << 4);
+ if (Memo("DCX")) BAsmCode[0]+=8;
+ END
+ return;
+ END
+
+ if (Memo("DAD"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeReg16(ArgStr[1],&AdrByte)) WrError(1980);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x09+(AdrByte << 4);
+ END
+ return;
+ END
+
+ for (z=0; z<ALUOrderCnt; z++)
+ if (Memo(ALUOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeReg8(ArgStr[1],&AdrByte)) WrError(1980);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=ALUOrders[z].Code+AdrByte;
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static Boolean IsDef_85(void)
+BEGIN
+ return (Memo("PORT"));
+END
+
+ static void SwitchFrom_85(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_85(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
+
+ PCSymbol="$"; HeaderID=0x41; NOPCode=0x00;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)|(1<<SegIO);
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = 0xffff;
+ Grans[SegIO ]=1; ListGrans[SegIO ]=1; SegInits[SegIO ]=0;
+ SegLimits[SegIO ] = 0xff;
+
+ MakeCode=MakeCode_85; IsDef=IsDef_85;
+ SwitchFrom=SwitchFrom_85; InitFields();
+END
+
+ void code85_init(void)
+BEGIN
+ CPU8080=AddCPU("8080",SwitchTo_85);
+ CPU8085=AddCPU("8085",SwitchTo_85);
+END