424 lines
11 KiB
C
424 lines
11 KiB
C
/* 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
|