1118 lines
28 KiB
C
1118 lines
28 KiB
C
/* code370.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Codegenerator 370-Familie */
|
|
/* */
|
|
/* Historie: 10.12.1996 Grundsteinlegung */
|
|
/* 2. 1.1999 ChkPC-Anpassung */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#include "stdinc.h"
|
|
|
|
#include <ctype.h>
|
|
#include <string.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;
|
|
Word Code;
|
|
} FixedOrder;
|
|
|
|
|
|
#define ModNone (-1)
|
|
#define ModAccA 0
|
|
#define MModAccA (1 << ModAccA) /* A */
|
|
#define ModAccB 1
|
|
#define MModAccB (1 << ModAccB) /* B */
|
|
#define ModReg 2
|
|
#define MModReg (1 << ModReg) /* Rn */
|
|
#define ModPort 3
|
|
#define MModPort (1 << ModPort) /* Pn */
|
|
#define ModAbs 4
|
|
#define MModAbs (1 << ModAbs) /* nnnn */
|
|
#define ModBRel 5
|
|
#define MModBRel (1 << ModBRel) /* nnnn(B) */
|
|
#define ModSPRel 6
|
|
#define MModSPRel (1 << ModSPRel) /* nn(SP) */
|
|
#define ModIReg 7
|
|
#define MModIReg (1 << ModIReg) /* @Rn */
|
|
#define ModRegRel 8
|
|
#define MModRegRel (1 << ModRegRel) /* nn(Rn) */
|
|
#define ModImm 9
|
|
#define MModImm (1 << ModImm) /* #nn */
|
|
#define ModImmBRel 10
|
|
#define MModImmBRel (1 << ModImmBRel) /* #nnnn(B) */
|
|
#define ModImmRegRel 11
|
|
#define MModImmRegRel (1 << ModImmRegRel) /* #nn(Rm) */
|
|
|
|
#define FixedOrderCount 12
|
|
#define Rel8OrderCount 18
|
|
#define ALU1OrderCount 7
|
|
#define ALU2OrderCount 5
|
|
#define JmpOrderCount 4
|
|
#define ABRegOrderCount 14
|
|
#define BitOrderCount 5
|
|
|
|
|
|
static CPUVar CPU37010,CPU37020,CPU37030,CPU37040,CPU37050;
|
|
|
|
static Byte OpSize;
|
|
static ShortInt AdrType;
|
|
static Byte AdrVals[2];
|
|
static Boolean AddrRel;
|
|
|
|
static FixedOrder *FixedOrders;
|
|
static FixedOrder *Rel8Orders;
|
|
static FixedOrder *ALU1Orders;
|
|
static FixedOrder *ALU2Orders;
|
|
static FixedOrder *JmpOrders;
|
|
static FixedOrder *ABRegOrders;
|
|
static FixedOrder *BitOrders;
|
|
|
|
/****************************************************************************/
|
|
|
|
static void InitFixed(char *NName, Word NCode)
|
|
BEGIN
|
|
if (InstrZ>=FixedOrderCount) exit(255);
|
|
FixedOrders[InstrZ].Name=NName;
|
|
FixedOrders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitRel8(char *NName, Word NCode)
|
|
BEGIN
|
|
if (InstrZ>=Rel8OrderCount) exit(255);
|
|
Rel8Orders[InstrZ].Name=NName;
|
|
Rel8Orders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitALU1(char *NName, Word NCode)
|
|
BEGIN
|
|
if (InstrZ>=ALU1OrderCount) exit(255);
|
|
ALU1Orders[InstrZ].Name=NName;
|
|
ALU1Orders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitALU2(char *NName, Word NCode)
|
|
BEGIN
|
|
if (InstrZ>=ALU2OrderCount) exit(255);
|
|
ALU2Orders[InstrZ].Name=NName;
|
|
ALU2Orders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitJmp(char *NName, Word NCode)
|
|
BEGIN
|
|
if (InstrZ>=JmpOrderCount) exit(255);
|
|
JmpOrders[InstrZ].Name=NName;
|
|
JmpOrders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitABReg(char *NName, Word NCode)
|
|
BEGIN
|
|
if (InstrZ>=ABRegOrderCount) exit(255);
|
|
ABRegOrders[InstrZ].Name=NName;
|
|
ABRegOrders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitBit(char *NName, Word NCode)
|
|
BEGIN
|
|
if (InstrZ>=BitOrderCount) exit(255);
|
|
BitOrders[InstrZ].Name=NName;
|
|
BitOrders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitFields(void)
|
|
BEGIN
|
|
FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0;
|
|
InitFixed("CLRC" ,0x00b0); InitFixed("DINT" ,0xf000);
|
|
InitFixed("EINT" ,0xf00c); InitFixed("EINTH",0xf004);
|
|
InitFixed("EINTL",0xf008); InitFixed("IDLE" ,0x00f6);
|
|
InitFixed("LDSP" ,0x00fd); InitFixed("NOP" ,0x00ff);
|
|
InitFixed("RTI" ,0x00fa); InitFixed("RTS" ,0x00f9);
|
|
InitFixed("SETC" ,0x00f8); InitFixed("STSP" ,0x00fe);
|
|
|
|
Rel8Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Rel8OrderCount); InstrZ=0;
|
|
InitRel8("JMP",0x00); InitRel8("JC" ,0x03); InitRel8("JEQ",0x02);
|
|
InitRel8("JG" ,0x0e); InitRel8("JGE",0x0d); InitRel8("JHS",0x0b);
|
|
InitRel8("JL" ,0x09); InitRel8("JLE",0x0a); InitRel8("JLO",0x0f);
|
|
InitRel8("JN" ,0x01); InitRel8("JNC",0x07); InitRel8("JNE",0x06);
|
|
InitRel8("JNV",0x0c); InitRel8("JNZ",0x06); InitRel8("JP" ,0x04);
|
|
InitRel8("JPZ",0x05); InitRel8("JV" ,0x08); InitRel8("JZ" ,0x02);
|
|
|
|
ALU1Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALU1OrderCount); InstrZ=0;
|
|
InitALU1("ADC", 9); InitALU1("ADD", 8);
|
|
InitALU1("DAC",14); InitALU1("DSB",15);
|
|
InitALU1("SBB",11); InitALU1("SUB",10); InitALU1("MPY",12);
|
|
|
|
ALU2Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALU2OrderCount); InstrZ=0;
|
|
InitALU2("AND" , 3); InitALU2("BTJO", 6);
|
|
InitALU2("BTJZ", 7); InitALU2("OR" , 4); InitALU2("XOR", 5);
|
|
|
|
JmpOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*JmpOrderCount); InstrZ=0;
|
|
InitJmp("BR" ,12); InitJmp("CALL" ,14);
|
|
InitJmp("JMPL", 9); InitJmp("CALLR",15);
|
|
|
|
ABRegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ABRegOrderCount); InstrZ=0;
|
|
InitABReg("CLR" , 5); InitABReg("COMPL",11); InitABReg("DEC" , 2);
|
|
InitABReg("INC" , 3); InitABReg("INV" , 4); InitABReg("POP" , 9);
|
|
InitABReg("PUSH" , 8); InitABReg("RL" ,14); InitABReg("RLC" ,15);
|
|
InitABReg("RR" ,12); InitABReg("RRC" ,13); InitABReg("SWAP" , 7);
|
|
InitABReg("XCHB" , 6); InitABReg("DJNZ" ,10);
|
|
|
|
BitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BitOrderCount); InstrZ=0;
|
|
InitBit("CMPBIT", 5); InitBit("JBIT0" , 7); InitBit("JBIT1" , 6);
|
|
InitBit("SBIT0" , 3); InitBit("SBIT1" , 4);
|
|
END
|
|
|
|
static void DeinitFields(void)
|
|
BEGIN
|
|
free(FixedOrders);
|
|
free(Rel8Orders);
|
|
free(ALU1Orders);
|
|
free(ALU2Orders);
|
|
free(JmpOrders);
|
|
free(ABRegOrders);
|
|
free(BitOrders);
|
|
END
|
|
|
|
static void ChkAdr(Word Mask)
|
|
BEGIN
|
|
if ((AdrType!=-1) AND ((Mask & (1 << AdrType))==0))
|
|
BEGIN
|
|
WrError(1350); AdrType=ModNone; AdrCnt=0;
|
|
END
|
|
END
|
|
|
|
static char *HasDisp(char *Asc)
|
|
BEGIN
|
|
char *p;
|
|
int Lev;
|
|
|
|
if (Asc[strlen(Asc)-1]==')')
|
|
BEGIN
|
|
p=Asc+strlen(Asc)-2; Lev=0;
|
|
while ((p>=Asc) AND (Lev!=-1))
|
|
BEGIN
|
|
switch (*p)
|
|
BEGIN
|
|
case '(': Lev--; break;
|
|
case ')': Lev++; break;
|
|
END
|
|
if (Lev!=-1) p--;
|
|
END
|
|
if (p<Asc)
|
|
BEGIN
|
|
WrXError(1300,Asc); return Nil;
|
|
END
|
|
END
|
|
else p=Nil;
|
|
|
|
return p;
|
|
END
|
|
|
|
static void DecodeAdr(char *Asc, Word Mask)
|
|
BEGIN
|
|
Integer HVal;
|
|
char *p;
|
|
Boolean OK;
|
|
|
|
AdrType=ModNone; AdrCnt=0;
|
|
|
|
if (strcasecmp(Asc,"A")==0)
|
|
BEGIN
|
|
if ((Mask & MModAccA)!=0) AdrType=ModAccA;
|
|
else if ((Mask & MModReg)!=0)
|
|
BEGIN
|
|
AdrCnt=1; AdrVals[0]=0; AdrType=ModReg;
|
|
END
|
|
else
|
|
BEGIN
|
|
AdrCnt=2; AdrVals[0]=0; AdrVals[1]=0; AdrType=ModAbs;
|
|
END
|
|
ChkAdr(Mask); return;
|
|
END
|
|
|
|
if (strcasecmp(Asc,"B")==0)
|
|
BEGIN
|
|
if ((Mask & MModAccB)!=0) AdrType=ModAccB;
|
|
else if ((Mask & MModReg)!=0)
|
|
BEGIN
|
|
AdrCnt=1; AdrVals[0]=1; AdrType=ModReg;
|
|
END
|
|
else
|
|
BEGIN
|
|
AdrCnt=2; AdrVals[0]=0; AdrVals[1]=1; AdrType=ModAbs;
|
|
END
|
|
ChkAdr(Mask); return;
|
|
END
|
|
|
|
if (*Asc=='#')
|
|
BEGIN
|
|
strcpy(Asc,Asc+1);
|
|
p=HasDisp(Asc);
|
|
if (p==Nil)
|
|
BEGIN
|
|
switch (OpSize)
|
|
BEGIN
|
|
case 0:
|
|
AdrVals[0]=EvalIntExpression(Asc,Int8,&OK);
|
|
break;
|
|
case 1:
|
|
HVal=EvalIntExpression(Asc,Int16,&OK);
|
|
AdrVals[0]=Hi(HVal); AdrVals[1]=Lo(HVal);
|
|
break;
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
AdrCnt=1+OpSize; AdrType=ModImm;
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
*p='\0'; FirstPassUnknown=False;
|
|
HVal=EvalIntExpression(Asc,Int16,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
*p='(';
|
|
if (strcasecmp(p,"(B)")==0)
|
|
BEGIN
|
|
AdrVals[0]=Hi(HVal); AdrVals[1]=Lo(HVal);
|
|
AdrCnt=2; AdrType=ModImmBRel;
|
|
END
|
|
else
|
|
BEGIN
|
|
if (FirstPassUnknown) HVal&=127;
|
|
if (ChkRange(HVal,-128,127))
|
|
BEGIN
|
|
AdrVals[0]=HVal & 0xff; AdrCnt=1;
|
|
AdrVals[1]=EvalIntExpression(Asc,UInt8,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
AdrCnt=2; AdrType=ModImmRegRel;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
END
|
|
ChkAdr(Mask); return;
|
|
END
|
|
|
|
if (*Asc=='@')
|
|
BEGIN
|
|
AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
AdrCnt=1; AdrType=ModIReg;
|
|
END
|
|
ChkAdr(Mask); return;
|
|
END
|
|
|
|
p=HasDisp(Asc);
|
|
|
|
if (p==Nil)
|
|
BEGIN
|
|
HVal=EvalIntExpression(Asc,Int16,&OK);
|
|
if (OK)
|
|
if (((Mask & MModReg)!=0) AND (Hi(HVal)==0))
|
|
BEGIN
|
|
AdrVals[0]=Lo(HVal); AdrCnt=1; AdrType=ModReg;
|
|
END
|
|
else if (((Mask & MModPort)!=0) AND (Hi(HVal)==0x10))
|
|
BEGIN
|
|
AdrVals[0]=Lo(HVal); AdrCnt=1; AdrType=ModPort;
|
|
END
|
|
else
|
|
BEGIN
|
|
if (AddrRel) HVal-=EProgCounter()+3;
|
|
AdrVals[0]=Hi(HVal); AdrVals[1]=Lo(HVal); AdrCnt=2;
|
|
AdrType=ModAbs;
|
|
END
|
|
ChkAdr(Mask); return;
|
|
END
|
|
else
|
|
BEGIN
|
|
*(p++)='\0';
|
|
FirstPassUnknown=False;
|
|
HVal=EvalIntExpression(Asc,Int16,&OK);
|
|
if (FirstPassUnknown) HVal&=0x7f;
|
|
if (OK)
|
|
BEGIN
|
|
p[strlen(p)-1]='\0';
|
|
if (strcasecmp(p,"B")==0)
|
|
BEGIN
|
|
if (AddrRel) HVal-=EProgCounter()+3;
|
|
AdrVals[0]=Hi(HVal); AdrVals[1]=Lo(HVal); AdrCnt=2;
|
|
AdrType=ModBRel;
|
|
END
|
|
else if (strcasecmp(p,"SP")==0)
|
|
BEGIN
|
|
if (AddrRel) HVal-=EProgCounter()+3;
|
|
if (HVal>127) WrError(1320);
|
|
else if (HVal<-128) WrError(1315);
|
|
else
|
|
BEGIN
|
|
AdrVals[0]=HVal & 0xff; AdrCnt=1; AdrType=ModSPRel;
|
|
END
|
|
END
|
|
else
|
|
if (HVal>127) WrError(1320);
|
|
else if (HVal<-128) WrError(1315);
|
|
else
|
|
BEGIN
|
|
AdrVals[0]=HVal & 0xff;
|
|
AdrVals[1]=EvalIntExpression(p,Int8,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
AdrCnt=2; AdrType=ModRegRel;
|
|
END
|
|
END
|
|
END
|
|
ChkAdr(Mask); return;
|
|
END
|
|
END
|
|
|
|
static Boolean DecodePseudo(void)
|
|
BEGIN
|
|
Boolean OK;
|
|
Byte Bit;
|
|
Word Adr;
|
|
|
|
if (Memo("DBIT"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown=False;
|
|
Bit=EvalIntExpression(ArgStr[1],UInt3,&OK);
|
|
if ((OK) AND (NOT FirstPassUnknown))
|
|
BEGIN
|
|
if ((strcasecmp(ArgStr[2],"A")==0) OR (strcasecmp(ArgStr[2],"B")==0))
|
|
BEGIN
|
|
Adr=(*ArgStr[2])-'A'; OK=True;
|
|
END
|
|
else Adr=EvalIntExpression(ArgStr[2],Int16,&OK);
|
|
if ((OK) AND (NOT FirstPassUnknown))
|
|
BEGIN
|
|
PushLocHandle(-1);
|
|
EnterIntSymbol(LabPart,(((LongInt)Bit) << 16)+Adr,SegNone,False);
|
|
sprintf(ListLine,"=%s:%c",HexString(Adr,0),Bit+'0');
|
|
PopLocHandle();
|
|
END
|
|
END
|
|
END
|
|
return True;
|
|
END
|
|
|
|
return False;
|
|
END
|
|
|
|
static void PutCode(Word Code)
|
|
BEGIN
|
|
if (Hi(Code)==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=Code;
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=Hi(Code); BAsmCode[1]=Lo(Code);
|
|
END
|
|
END
|
|
|
|
static void MakeCode_370(void)
|
|
BEGIN
|
|
int z;
|
|
Integer AdrInt;
|
|
LongInt Bit;
|
|
Boolean OK,Rela;
|
|
|
|
CodeLen=0; DontPrint=False; OpSize=0; AddrRel=False;
|
|
|
|
/* zu ignorierendes */
|
|
|
|
if (Memo("")) return;
|
|
|
|
/* Pseudoanweisungen */
|
|
|
|
if (DecodePseudo()) return;
|
|
|
|
if (DecodeIntelPseudo(True)) return;
|
|
|
|
for (z=0; z<FixedOrderCount; z++)
|
|
if (Memo(FixedOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else PutCode(FixedOrders[z].Code);
|
|
return;
|
|
END
|
|
|
|
if (Memo("MOV"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2],MModAccB+MModReg+MModPort+MModAbs+MModIReg+MModBRel
|
|
+MModSPRel+MModRegRel+MModAccA);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
DecodeAdr(ArgStr[1],MModReg+MModAbs+MModIReg+MModBRel+MModRegRel
|
|
+MModSPRel+MModAccB+MModPort+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=0x12; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModAbs:
|
|
BAsmCode[0]=0x8a; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
|
|
break;
|
|
case ModIReg:
|
|
BAsmCode[0]=0x9a; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModBRel:
|
|
BAsmCode[0]=0xaa; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
|
|
break;
|
|
case ModRegRel:
|
|
BAsmCode[0]=0xf4; BAsmCode[1]=0xea;
|
|
memcpy(BAsmCode+2,AdrVals,2); CodeLen=4;
|
|
break;
|
|
case ModSPRel:
|
|
BAsmCode[0]=0xf1; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModAccB:
|
|
BAsmCode[0]=0x62; CodeLen=1;
|
|
break;
|
|
case ModPort:
|
|
BAsmCode[0]=0x80; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x22; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
END
|
|
break;
|
|
case ModAccB:
|
|
DecodeAdr(ArgStr[1],MModAccA+MModReg+MModPort+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
BAsmCode[0]=0xc0; CodeLen=1;
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[0]=0x32; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModPort:
|
|
BAsmCode[0]=0x91; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x52; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
END
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[1]=BAsmCode[2]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModAccA+MModAccB+MModReg+MModPort+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
BAsmCode[0]=0xd0; CodeLen=2;
|
|
break;
|
|
case ModAccB:
|
|
BAsmCode[0]=0xd1; CodeLen=2;
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[0]=0x42; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
case ModPort:
|
|
BAsmCode[0]=0xa2; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x72; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
END
|
|
break;
|
|
case ModPort:
|
|
BAsmCode[1]=BAsmCode[2]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModAccA+MModAccB+MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
BAsmCode[0]=0x21; CodeLen=2;
|
|
break;
|
|
case ModAccB:
|
|
BAsmCode[0]=0x51; CodeLen=2;
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[0]=0x71; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0xf7; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
END
|
|
break;
|
|
case ModAbs:
|
|
memcpy(BAsmCode+1,AdrVals,AdrCnt);
|
|
DecodeAdr(ArgStr[1],MModAccA);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0x8b; CodeLen=3;
|
|
END
|
|
break;
|
|
case ModIReg:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModAccA);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0x9b; CodeLen=2;
|
|
END
|
|
break;
|
|
case ModBRel:
|
|
memcpy(BAsmCode+1,AdrVals,AdrCnt);
|
|
DecodeAdr(ArgStr[1],MModAccA);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0xab; CodeLen=3;
|
|
END
|
|
break;
|
|
case ModSPRel:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModAccA);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0xf2; CodeLen=2;
|
|
END
|
|
break;
|
|
case ModRegRel:
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
DecodeAdr(ArgStr[1],MModAccA);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0xf4; BAsmCode[1]=0xeb; CodeLen=4;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MOVW"))
|
|
BEGIN
|
|
OpSize=1;
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2],MModReg);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
z=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm+MModImmBRel+MModImmRegRel);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=0x98; BAsmCode[1]=AdrVals[0]; BAsmCode[2]=z;
|
|
CodeLen=3;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x88; memcpy(BAsmCode+1,AdrVals,2);
|
|
BAsmCode[3]=z; CodeLen=4;
|
|
break;
|
|
case ModImmBRel:
|
|
BAsmCode[0]=0xa8; memcpy(BAsmCode+1,AdrVals,2);
|
|
BAsmCode[3]=z; CodeLen=4;
|
|
break;
|
|
case ModImmRegRel:
|
|
BAsmCode[0]=0xf4; BAsmCode[1]=0xe8;
|
|
memcpy(BAsmCode+2,AdrVals,2); BAsmCode[4]=z;
|
|
CodeLen=5;
|
|
break;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<Rel8OrderCount; z++)
|
|
if (Memo(Rel8Orders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
AdrInt=EvalIntExpression(ArgStr[1],Int16,&OK)-(EProgCounter()+2);
|
|
if (OK)
|
|
if ((NOT SymbolQuestionable) AND ((AdrInt>127) OR (AdrInt<-128))) WrError(1370);
|
|
else
|
|
BEGIN
|
|
CodeLen=2;
|
|
BAsmCode[0]=Rel8Orders[z].Code; BAsmCode[1]=AdrInt & 0xff;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("CMP"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2],MModAccA+MModAccB+MModReg);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
DecodeAdr(ArgStr[1],MModAbs+MModIReg+MModBRel+MModRegRel+MModSPRel+MModAccB+MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAbs:
|
|
BAsmCode[0]=0x8d; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
|
|
break;
|
|
case ModIReg:
|
|
BAsmCode[0]=0x9d; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModBRel:
|
|
BAsmCode[0]=0xad; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
|
|
break;
|
|
case ModRegRel:
|
|
BAsmCode[0]=0xf4; BAsmCode[1]=0xed;
|
|
memcpy(BAsmCode+2,AdrVals,2); CodeLen=4;
|
|
break;
|
|
case ModSPRel:
|
|
BAsmCode[0]=0xf3; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModAccB:
|
|
BAsmCode[0]=0x6d; CodeLen=1;
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[0]=0x1d; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x2d; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
END
|
|
break;
|
|
case ModAccB:
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=0x3d; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x5d; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
END
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[2]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=0x4d; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x7d; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<ALU1OrderCount; z++)
|
|
if (Memo(ALU1Orders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2],MModAccA+MModAccB+MModReg);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
DecodeAdr(ArgStr[1],MModAccB+MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccB:
|
|
CodeLen=1; BAsmCode[0]=0x60+ALU1Orders[z].Code;
|
|
break;
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0x10+ALU1Orders[z].Code; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
case ModImm:
|
|
CodeLen=2; BAsmCode[0]=0x20+ALU1Orders[z].Code; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
END
|
|
break;
|
|
case ModAccB:
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0x30+ALU1Orders[z].Code; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
case ModImm:
|
|
CodeLen=2; BAsmCode[0]=0x50+ALU1Orders[z].Code; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
END
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[2]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=3; BAsmCode[0]=0x40+ALU1Orders[z].Code; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
case ModImm:
|
|
CodeLen=3; BAsmCode[0]=0x70+ALU1Orders[z].Code; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<ALU2OrderCount; z++)
|
|
if (Memo(ALU2Orders[z].Name))
|
|
BEGIN
|
|
Rela=((Memo("BTJO")) OR (Memo("BTJZ")));
|
|
if (((Rela) AND (ArgCnt!=3))
|
|
OR ((NOT Rela) AND (ArgCnt!=2))) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2],MModAccA+MModAccB+MModReg+MModPort);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
DecodeAdr(ArgStr[1],MModAccB+MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccB:
|
|
BAsmCode[0]=0x60+ALU2Orders[z].Code; CodeLen=1;
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[0]=0x10+ALU2Orders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x20+ALU2Orders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
END
|
|
break;
|
|
case ModAccB:
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=0x30+ALU2Orders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x50+ALU2Orders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
END
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[2]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=0x40+ALU2Orders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0x70+ALU2Orders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
END
|
|
break;
|
|
case ModPort:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModAccA+MModAccB+MModImm);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
BAsmCode[0]=0x80+ALU2Orders[z].Code; CodeLen=2;
|
|
break;
|
|
case ModAccB:
|
|
BAsmCode[0]=0x90+ALU2Orders[z].Code; CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
BAsmCode[0]=0xa0+ALU2Orders[z].Code; BAsmCode[2]=BAsmCode[1];
|
|
BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
if ((CodeLen!=0) AND (Rela))
|
|
BEGIN
|
|
AdrInt=EvalIntExpression(ArgStr[3],UInt16,&OK)-(EProgCounter()+CodeLen+1);
|
|
if (NOT OK) CodeLen=0;
|
|
else if ((NOT SymbolQuestionable) AND ((AdrInt>127) OR (AdrInt<-128)))
|
|
BEGIN
|
|
WrError(1370); CodeLen=0;
|
|
END
|
|
else BAsmCode[CodeLen++]=AdrInt & 0xff;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<JmpOrderCount; z++)
|
|
if (Memo(JmpOrders[z].Name))
|
|
BEGIN
|
|
AddrRel=(Memo("CALLR") OR Memo("JMPL"));
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModAbs+MModIReg+MModBRel+MModRegRel);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAbs:
|
|
CodeLen=3; BAsmCode[0]=0x80+JmpOrders[z].Code; memcpy(BAsmCode+1,AdrVals,2);
|
|
break;
|
|
case ModIReg:
|
|
CodeLen=2; BAsmCode[0]=0x90+JmpOrders[z].Code; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
case ModBRel:
|
|
CodeLen=3; BAsmCode[0]=0xa0+JmpOrders[z].Code; memcpy(BAsmCode+1,AdrVals,2);
|
|
break;
|
|
case ModRegRel:
|
|
CodeLen=4; BAsmCode[0]=0xf4; BAsmCode[1]=0xe0+JmpOrders[z].Code;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<ABRegOrderCount; z++)
|
|
if (Memo(ABRegOrders[z].Name))
|
|
BEGIN
|
|
if (((NOT Memo("DJNZ")) AND (ArgCnt!=1))
|
|
OR (( Memo("DJNZ")) AND (ArgCnt!=2))) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"ST")==0)
|
|
BEGIN
|
|
if ((Memo("PUSH")) OR (Memo("POP")))
|
|
BEGIN
|
|
BAsmCode[0]=0xf3+ABRegOrders[z].Code; CodeLen=1;
|
|
END
|
|
else WrError(1350);
|
|
END
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModAccA+MModAccB+MModReg);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
BAsmCode[0]=0xb0+ABRegOrders[z].Code; CodeLen=1;
|
|
break;
|
|
case ModAccB:
|
|
BAsmCode[0]=0xc0+ABRegOrders[z].Code; CodeLen=1;
|
|
break;
|
|
case ModReg:
|
|
BAsmCode[0]=0xd0+ABRegOrders[z].Code; BAsmCode[CodeLen+1]=AdrVals[0]; CodeLen=2;
|
|
break;
|
|
END
|
|
if ((Memo("DJNZ")) AND (CodeLen!=0))
|
|
BEGIN
|
|
AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK)-(EProgCounter()+CodeLen+1);
|
|
if (NOT OK) CodeLen=0;
|
|
else if ((NOT FirstPassUnknown) AND ((AdrInt>127) OR (AdrInt<-128)))
|
|
BEGIN
|
|
WrError(1370); CodeLen=0;
|
|
END
|
|
else BAsmCode[CodeLen++]=AdrInt & 0xff;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<BitOrderCount; z++)
|
|
if (Memo(BitOrders[z].Name))
|
|
BEGIN
|
|
Rela=((Memo("JBIT0")) OR (Memo("JBIT1")));
|
|
if (((Rela) AND (ArgCnt!=2))
|
|
OR ((NOT Rela) AND (ArgCnt!=1))) WrError(1110);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown=False;
|
|
Bit=EvalIntExpression(ArgStr[1],Int32,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
if (FirstPassUnknown) Bit&=0x000710ff;
|
|
BAsmCode[1]=1 << ((Bit >> 16) & 7);
|
|
BAsmCode[2]=Lo(Bit);
|
|
switch (Hi(Bit))
|
|
BEGIN
|
|
case 0:
|
|
BAsmCode[0]=0x70+BitOrders[z].Code; CodeLen=3;
|
|
break;
|
|
case 16:
|
|
BAsmCode[0]=0xa0+BitOrders[z].Code; CodeLen=3;
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
if ((CodeLen!=0) AND (Rela))
|
|
BEGIN
|
|
AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK)-(EProgCounter()+CodeLen+1);
|
|
if (NOT OK) CodeLen=0;
|
|
else if ((NOT FirstPassUnknown) AND ((AdrInt>127) OR (AdrInt<-128)))
|
|
BEGIN
|
|
WrError(1370); CodeLen=0;
|
|
END
|
|
else BAsmCode[CodeLen++]=AdrInt & 0xff;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("DIV"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2],MModAccA);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0xf4; BAsmCode[1]=0xf8;
|
|
BAsmCode[2]=AdrVals[0]; CodeLen=3;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("INCW"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2],MModReg);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[2]=AdrVals[0];
|
|
DecodeAdr(ArgStr[1],MModImm);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0x70; BAsmCode[1]=AdrVals[0]; CodeLen=3;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("LDST"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModImm);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
BAsmCode[0]=0xf0;
|
|
BAsmCode[1]=AdrVals[0];
|
|
CodeLen=2;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("TRAP"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
BAsmCode[0]=EvalIntExpression(ArgStr[1],Int4,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
BAsmCode[0]=0xef-BAsmCode[0]; CodeLen=1;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("TST"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModAccA+MModAccB);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAccA:
|
|
BAsmCode[0]=0xb0; CodeLen=1;
|
|
break;
|
|
case ModAccB:
|
|
BAsmCode[0]=0xc6; CodeLen=1;
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
WrXError(1200,OpPart);
|
|
END
|
|
|
|
static Boolean IsDef_370(void)
|
|
BEGIN
|
|
return (Memo("DBIT"));
|
|
END
|
|
|
|
static void InternSymbol_370(char *Asc, TempResult*Erg)
|
|
BEGIN
|
|
Boolean err;
|
|
String h;
|
|
|
|
Erg->Typ=TempNone;
|
|
if ((strlen(Asc)<2) OR ((toupper(*Asc)!='R') AND (toupper(*Asc)!='P'))) return;
|
|
|
|
strcpy(h,Asc+1);
|
|
if ((*h=='0') AND (strlen(h)>1)) *h='$';
|
|
Erg->Contents.Int=ConstLongInt(h,&err);
|
|
if ((NOT err) OR (Erg->Contents.Int<0) OR (Erg->Contents.Int>255)) return;
|
|
|
|
Erg->Typ=TempInt; if (toupper(*Asc)=='P') Erg->Contents.Int+=0x1000;
|
|
END
|
|
|
|
static void SwitchFrom_370(void)
|
|
BEGIN
|
|
DeinitFields();
|
|
END
|
|
|
|
static void SwitchTo_370(void)
|
|
BEGIN
|
|
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
|
|
|
|
PCSymbol="$"; HeaderID=0x49; NOPCode=0xff;
|
|
DivideChars=","; HasAttrs=False;
|
|
|
|
ValidSegs=1<<SegCode;
|
|
Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0;
|
|
SegLimits[SegCode] = 0xffff;
|
|
|
|
MakeCode=MakeCode_370; IsDef=IsDef_370;
|
|
SwitchFrom=SwitchFrom_370; InternSymbol=InternSymbol_370;
|
|
|
|
InitFields();
|
|
END
|
|
|
|
void code370_init(void)
|
|
BEGIN
|
|
CPU37010=AddCPU("370C010" ,SwitchTo_370);
|
|
CPU37020=AddCPU("370C020" ,SwitchTo_370);
|
|
CPU37030=AddCPU("370C030" ,SwitchTo_370);
|
|
CPU37040=AddCPU("370C040" ,SwitchTo_370);
|
|
CPU37050=AddCPU("370C050" ,SwitchTo_370);
|
|
END
|