999 lines
23 KiB
C
999 lines
23 KiB
C
/* code48.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Codegeneratormodul MCS-48-Familie */
|
|
/* */
|
|
/* Historie: 16. 5.1996 Grundsteinlegung */
|
|
/* 2. 1.1999 ChkPC-Anpassung */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#include "stdinc.h"
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "nls.h"
|
|
#include "strutil.h"
|
|
#include "stringlists.h"
|
|
#include "asmdef.h"
|
|
#include "asmsub.h"
|
|
#include "asmpars.h"
|
|
#include "codepseudo.h"
|
|
#include "codevars.h"
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
Byte Code;
|
|
Byte May2X;
|
|
Byte UPIFlag;
|
|
} CondOrder;
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
Byte Code;
|
|
} AccOrder;
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
Byte Code;
|
|
Boolean Is22;
|
|
Boolean IsNUPI;
|
|
} SelOrder;
|
|
|
|
#define ModImm 0
|
|
#define ModReg 1
|
|
#define ModInd 2
|
|
#define ModAcc 3
|
|
#define ModNone (-1)
|
|
|
|
#define ClrCplCnt 4
|
|
#define CondOrderCnt 22
|
|
#define AccOrderCnt 6
|
|
#define SelOrderCnt 6
|
|
|
|
#define D_CPU8021 0
|
|
#define D_CPU8022 1
|
|
#define D_CPU8039 2
|
|
#define D_CPU8048 3
|
|
#define D_CPU80C39 4
|
|
#define D_CPU80C48 5
|
|
#define D_CPU8041 6
|
|
#define D_CPU8042 7
|
|
|
|
static ShortInt AdrMode;
|
|
static Byte AdrVal;
|
|
static CPUVar CPU8021,CPU8022,CPU8039,CPU8048,CPU80C39,CPU80C48,CPU8041,CPU8042;
|
|
|
|
static char **ClrCplVals;
|
|
static Byte *ClrCplCodes;
|
|
static CondOrder *CondOrders;
|
|
static AccOrder *AccOrders;
|
|
static SelOrder *SelOrders;
|
|
|
|
/****************************************************************************/
|
|
|
|
static void AddAcc(char *Name, Byte Code)
|
|
BEGIN
|
|
if (InstrZ==AccOrderCnt) exit(255);
|
|
AccOrders[InstrZ].Name=Name;
|
|
AccOrders[InstrZ++].Code=Code;
|
|
END
|
|
|
|
static void AddCond(char *Name, Byte Code, Byte May2X, Byte UPIFlag)
|
|
BEGIN
|
|
if (InstrZ==CondOrderCnt) exit(255);
|
|
CondOrders[InstrZ].Name=Name;
|
|
CondOrders[InstrZ].Code=Code;
|
|
CondOrders[InstrZ].May2X=May2X;
|
|
CondOrders[InstrZ++].UPIFlag=UPIFlag;
|
|
END
|
|
|
|
static void AddSel(char *Name, Byte Code, Byte Is22, Byte IsNUPI)
|
|
BEGIN
|
|
if (InstrZ==SelOrderCnt) exit(255);
|
|
SelOrders[InstrZ].Name=Name;
|
|
SelOrders[InstrZ].Code=Code;
|
|
SelOrders[InstrZ].Is22=Is22;
|
|
SelOrders[InstrZ++].IsNUPI=IsNUPI;
|
|
END
|
|
|
|
static void InitFields(void)
|
|
BEGIN
|
|
ClrCplVals=(char **) malloc(sizeof(char *)*ClrCplCnt);
|
|
ClrCplCodes=(Byte *) malloc(sizeof(Byte)*ClrCplCnt);
|
|
ClrCplVals[0]="A"; ClrCplVals[1]="C"; ClrCplVals[2]="F0"; ClrCplVals[3]="F1";
|
|
ClrCplCodes[0]=0x27; ClrCplCodes[1]=0x97; ClrCplCodes[2]=0x85; ClrCplCodes[3]=0xa5;
|
|
|
|
CondOrders=(CondOrder *) malloc(sizeof(CondOrder)*CondOrderCnt); InstrZ=0;
|
|
AddCond("JTF" ,0x16, 2, 3); AddCond("JNI" ,0x86, 0, 2);
|
|
AddCond("JC" ,0xf6, 2, 3); AddCond("JNC" ,0xe6, 2, 3);
|
|
AddCond("JZ" ,0xc6, 2, 3); AddCond("JNZ" ,0x96, 2, 3);
|
|
AddCond("JT0" ,0x36, 1, 3); AddCond("JNT0" ,0x26, 1, 3);
|
|
AddCond("JT1" ,0x56, 2, 3); AddCond("JNT1" ,0x46, 2, 3);
|
|
AddCond("JF0" ,0xb6, 0, 3); AddCond("JF1" ,0x76, 0, 3);
|
|
AddCond("JNIBF",0xd6, 2, 1); AddCond("JOBF" ,0x86, 2, 1);
|
|
AddCond("JB0" ,0x12, 0, 3); AddCond("JB1" ,0x32, 0, 3);
|
|
AddCond("JB2" ,0x52, 0, 3); AddCond("JB3" ,0x72, 0, 3);
|
|
AddCond("JB4" ,0x92, 0, 3); AddCond("JB5" ,0xb2, 0, 3);
|
|
AddCond("JB6" ,0xd2, 0, 3); AddCond("JB7" ,0xf2, 0, 3);
|
|
|
|
AccOrders=(AccOrder *) malloc(sizeof(AccOrder)*AccOrderCnt); InstrZ=0;
|
|
AddAcc("DA" ,0x57);
|
|
AddAcc("RL" ,0xe7);
|
|
AddAcc("RLC" ,0xf7);
|
|
AddAcc("RR" ,0x77);
|
|
AddAcc("RRC" ,0x67);
|
|
AddAcc("SWAP",0x47);
|
|
|
|
SelOrders=(SelOrder *) malloc(sizeof(SelOrder)*SelOrderCnt); InstrZ=0;
|
|
AddSel("MB0" ,0xe5, False, True );
|
|
AddSel("MB1" ,0xf5, False, True );
|
|
AddSel("RB0" ,0xc5, False, False);
|
|
AddSel("RB1" ,0xd5, False, False);
|
|
AddSel("AN0" ,0x95, True , False);
|
|
AddSel("AN1" ,0x85, True , False);
|
|
END
|
|
|
|
static void DeinitFields(void)
|
|
BEGIN
|
|
free(ClrCplVals);
|
|
free(ClrCplCodes);
|
|
free(CondOrders);
|
|
free(AccOrders);
|
|
free(SelOrders);
|
|
END
|
|
|
|
/****************************************************************************/
|
|
|
|
static void DecodeAdr(char *Asc_O)
|
|
BEGIN
|
|
Boolean OK;
|
|
String Asc;
|
|
|
|
strmaxcpy(Asc,Asc_O,255);
|
|
AdrMode=ModNone;
|
|
|
|
if (*Asc=='\0') return;
|
|
|
|
if (strcasecmp(Asc,"A")==0) AdrMode=ModAcc;
|
|
|
|
else if (*Asc=='#')
|
|
BEGIN
|
|
AdrVal=EvalIntExpression(Asc+1,Int8,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
AdrMode=ModImm; BAsmCode[1]=AdrVal;
|
|
END
|
|
END
|
|
|
|
else if ((strlen(Asc)==2) AND (toupper(*Asc)=='R'))
|
|
BEGIN
|
|
if ((Asc[1]>='0') AND (Asc[1]<='7'))
|
|
BEGIN
|
|
AdrMode=ModReg; AdrVal=Asc[1]-'0';
|
|
END
|
|
END
|
|
|
|
else if ((strlen(Asc)==3) AND (*Asc=='@') AND (toupper(Asc[1])=='R'))
|
|
BEGIN
|
|
if ((Asc[2]>='0') AND (Asc[2]<='1'))
|
|
BEGIN
|
|
AdrMode=ModInd; AdrVal=Asc[2]-'0';
|
|
END
|
|
END
|
|
END
|
|
|
|
static void ChkN802X(void)
|
|
BEGIN
|
|
if (CodeLen==0) return;
|
|
if ((MomCPU==CPU8021) OR (MomCPU==CPU8022))
|
|
BEGIN
|
|
WrError(1500); CodeLen=0;
|
|
END
|
|
END
|
|
|
|
static void Chk802X(void)
|
|
BEGIN
|
|
if (CodeLen==0) return;
|
|
if ((MomCPU!=CPU8021) AND (MomCPU!=CPU8022))
|
|
BEGIN
|
|
WrError(1500); CodeLen=0;
|
|
END
|
|
END
|
|
|
|
static void ChkNUPI(void)
|
|
BEGIN
|
|
if (CodeLen==0) return;
|
|
if ((MomCPU==CPU8041) OR (MomCPU==CPU8042))
|
|
BEGIN
|
|
WrError(1500); CodeLen=0;
|
|
END
|
|
END
|
|
|
|
static void ChkUPI(void)
|
|
BEGIN
|
|
if (CodeLen==0) return;
|
|
if ((MomCPU!=CPU8041) AND (MomCPU!=CPU8042))
|
|
BEGIN
|
|
WrError(1500); CodeLen=0;
|
|
END
|
|
END
|
|
|
|
static void ChkExt(void)
|
|
BEGIN
|
|
if (CodeLen==0) return;
|
|
if ((MomCPU==CPU8039) OR (MomCPU==CPU80C39))
|
|
BEGIN
|
|
WrError(1500); CodeLen=0;
|
|
END
|
|
END
|
|
|
|
static Boolean DecodePseudo(void)
|
|
BEGIN
|
|
return False;
|
|
END
|
|
|
|
void MakeCode_48(void)
|
|
BEGIN
|
|
Boolean OK;
|
|
Word AdrWord;
|
|
int z;
|
|
|
|
CodeLen=0; DontPrint=False;
|
|
|
|
/* zu ignorierendes */
|
|
|
|
if (Memo("")) return;
|
|
|
|
/* Pseudoanweisungen */
|
|
|
|
if (DecodePseudo()) return;
|
|
|
|
if (DecodeIntelPseudo(False)) return;
|
|
|
|
if ((Memo("ADD")) OR (Memo("ADDC")))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1135);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2]);
|
|
if ((AdrMode==ModNone) OR (AdrMode==ModAcc)) WrError(1350);
|
|
else
|
|
BEGIN
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModImm:
|
|
CodeLen=2; BAsmCode[0]=0x03;
|
|
break;
|
|
case ModReg:
|
|
CodeLen=1; BAsmCode[0]=0x68+AdrVal;
|
|
break;
|
|
case ModInd:
|
|
CodeLen=1; BAsmCode[0]=0x60+AdrVal;
|
|
break;
|
|
END
|
|
if (strlen(OpPart)==4) BAsmCode[0]+=0x10;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("ANL")) OR (Memo("ORL")) OR (Memo("XRL")))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"A")==0)
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2]);
|
|
if ((AdrMode==-1) OR (AdrMode==ModAcc)) WrError(1350);
|
|
else
|
|
BEGIN
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModImm:
|
|
CodeLen=2; BAsmCode[0]=0x43;
|
|
break;
|
|
case ModReg:
|
|
CodeLen=1; BAsmCode[0]=0x48+AdrVal;
|
|
break;
|
|
case ModInd:
|
|
CodeLen=1; BAsmCode[0]=0x40+AdrVal;
|
|
break;
|
|
END
|
|
if (Memo("ANL")) BAsmCode[0]+=0x10;
|
|
else if (Memo("XRL")) BAsmCode[0]+=0x90;
|
|
END
|
|
END
|
|
else if ((strcasecmp(ArgStr[1],"BUS")==0) OR (strcmp(ArgStr[1],"P1")==0) OR (strcmp(ArgStr[1],"P2")==0))
|
|
BEGIN
|
|
if (Memo("XRL")) WrError(1350);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2]);
|
|
if (AdrMode!=ModImm) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x88;
|
|
if (toupper(*ArgStr[1])=='P') BAsmCode[0]+=ArgStr[1][1]-'0';
|
|
if (Memo("ANL")) BAsmCode[0]+=0x10;
|
|
if (strcasecmp(ArgStr[1],"BUS")==0)
|
|
BEGIN
|
|
ChkExt(); ChkNUPI();
|
|
END
|
|
ChkN802X();
|
|
END
|
|
END
|
|
END
|
|
else WrError(1350);
|
|
return;
|
|
END
|
|
|
|
if ((Memo("CALL")) OR (Memo("JMP")))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if ((EProgCounter()&0x7fe)==0x7fe) WrError(1900);
|
|
else
|
|
BEGIN
|
|
AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK);
|
|
if (OK)
|
|
if (AdrWord>0xfff) WrError(1320);
|
|
else
|
|
BEGIN
|
|
if ((EProgCounter()&0x800)!=(AdrWord&0x800))
|
|
BEGIN
|
|
BAsmCode[0]=0xe5+((AdrWord&0x800)>>7); CodeLen=1;
|
|
END
|
|
BAsmCode[CodeLen+1]=AdrWord&0xff;
|
|
BAsmCode[CodeLen]=0x04+((AdrWord&0x700)>>3);
|
|
if (Memo("CALL")) BAsmCode[CodeLen]+=0x10;
|
|
CodeLen+=2; ChkSpace(SegCode);
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("CLR")) OR (Memo("CPL")))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
z=0; OK=False; NLS_UpString(ArgStr[1]);
|
|
do
|
|
BEGIN
|
|
if (strcmp(ClrCplVals[z],ArgStr[1])==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=ClrCplCodes[z]; OK=True;
|
|
if (*ArgStr[1]=='F') ChkN802X();
|
|
END
|
|
z++;
|
|
END
|
|
while ((z<ClrCplCnt) AND (CodeLen!=1));
|
|
if (NOT OK) WrError(1135);
|
|
else if (Memo("CPL")) BAsmCode[0]+=0x10;
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<AccOrderCnt; z++)
|
|
if (Memo(AccOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=AccOrders[z].Code;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("DEC"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1]);
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModAcc:
|
|
CodeLen=1; BAsmCode[0]=0x07;
|
|
break;
|
|
case ModReg:
|
|
CodeLen=1; BAsmCode[0]=0xc8+AdrVal;
|
|
ChkN802X();
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("DIS")) OR (Memo("EN")))
|
|
BEGIN
|
|
NLS_UpString(ArgStr[1]);
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
NLS_UpString(ArgStr[1]);
|
|
if (strcmp(ArgStr[1],"I")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x05;
|
|
END
|
|
else if (strcmp(ArgStr[1],"TCNTI")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x25;
|
|
END
|
|
else if ((Memo("EN")) AND (strcmp(ArgStr[1],"DMA")==0))
|
|
BEGIN
|
|
BAsmCode[0]=0xe5; CodeLen=1; ChkUPI();
|
|
END
|
|
else if ((Memo("EN")) AND (strcmp(ArgStr[1],"FLAGS")==0))
|
|
BEGIN
|
|
BAsmCode[0]=0xf5; CodeLen=1; ChkUPI();
|
|
END
|
|
else WrError(1350);
|
|
if (CodeLen!=0)
|
|
BEGIN
|
|
if (Memo("DIS")) BAsmCode[0]+=0x10;
|
|
if (MomCPU==CPU8021)
|
|
BEGIN
|
|
WrError(1500); CodeLen=0;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("DJNZ"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1]);
|
|
if (AdrMode!=ModReg) WrError(1350);
|
|
else
|
|
BEGIN
|
|
AdrWord=EvalIntExpression(ArgStr[2],Int16,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
if (((EProgCounter()+1)&0xff00)!=(AdrWord&0xff00)) WrError(1910);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0xe8+AdrVal; BAsmCode[1]=AdrWord&0xff;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("ENT0"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"CLK")!=0) WrError(1135);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x75;
|
|
ChkN802X(); ChkNUPI();
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("INC"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1]);
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModAcc:
|
|
CodeLen=1; BAsmCode[0]=0x17;
|
|
break;
|
|
case ModReg:
|
|
CodeLen=1; BAsmCode[0]=0x18+AdrVal;
|
|
break;
|
|
case ModInd:
|
|
CodeLen=1; BAsmCode[0]=0x10+AdrVal;
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("IN"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
|
|
else if (strcasecmp(ArgStr[2],"DBB")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x22; ChkUPI();
|
|
END
|
|
else if ((strlen(ArgStr[2])!=2) OR (toupper(*ArgStr[2])!='P')) WrError(1350);
|
|
else switch (ArgStr[2][1])
|
|
BEGIN
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
CodeLen=1; BAsmCode[0]=0x08+ArgStr[2][1]-'0';
|
|
if (ArgStr[2][1]=='0') Chk802X();
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("INS"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
|
|
else if (strcasecmp(ArgStr[2],"BUS")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x08; ChkExt(); ChkNUPI();
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("JMPP"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"@A")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0xb3;
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<CondOrderCnt; z++)
|
|
if (Memo(CondOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
AdrWord=EvalIntExpression(ArgStr[1],UInt12,&OK);
|
|
if (NOT OK);
|
|
else if (((EProgCounter()+1)&0xff00)!=(AdrWord&0xff00)) WrError(1910);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=CondOrders[z].Code; BAsmCode[1]=AdrWord&0xff;
|
|
ChkSpace(SegCode);
|
|
if (CondOrders[z].May2X==0) ChkN802X();
|
|
else if ((CondOrders[z].May2X==1) AND (MomCPU==CPU8021))
|
|
BEGIN
|
|
WrError(1500); CodeLen=0;
|
|
END
|
|
if (CondOrders[z].UPIFlag==1) ChkUPI();
|
|
else if (CondOrders[z].UPIFlag==2) ChkNUPI();
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("JB"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
AdrVal=EvalIntExpression(ArgStr[1],UInt3,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
AdrWord=EvalIntExpression(ArgStr[2],UInt12,&OK);
|
|
if (NOT OK);
|
|
else if (((EProgCounter()+1)&0xff00)!=(AdrWord&0xff00)) WrError(1910);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x12+(AdrVal<<5);
|
|
BAsmCode[1]=AdrWord&0xff;
|
|
ChkN802X();
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MOV"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"A")==0)
|
|
BEGIN
|
|
if (strcasecmp(ArgStr[2],"T")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x42;
|
|
END
|
|
else if (strcasecmp(ArgStr[2],"PSW")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0xc7; ChkN802X();
|
|
END
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2]);
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=1; BAsmCode[0]=0xf8+AdrVal;
|
|
break;
|
|
case ModInd:
|
|
CodeLen=1; BAsmCode[0]=0xf0+AdrVal;
|
|
break;
|
|
case ModImm:
|
|
CodeLen=2; BAsmCode[0]=0x23;
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
END
|
|
END
|
|
else if (strcasecmp(ArgStr[2],"A")==0)
|
|
BEGIN
|
|
if (strcasecmp(ArgStr[1],"STS")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x90; ChkUPI();
|
|
END
|
|
else if (strcasecmp(ArgStr[1],"T")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x62;
|
|
END
|
|
else if (strcasecmp(ArgStr[1],"PSW")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0xd7; ChkN802X();
|
|
END
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1]);
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=1; BAsmCode[0]=0xa8+AdrVal;
|
|
break;
|
|
case ModInd:
|
|
CodeLen=1; BAsmCode[0]=0xa0+AdrVal;
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
END
|
|
END
|
|
else if (*ArgStr[2]=='#')
|
|
BEGIN
|
|
AdrWord=EvalIntExpression(ArgStr[2]+1,Int8,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1]);
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0xb8+AdrVal; BAsmCode[1]=AdrWord;
|
|
break;
|
|
case ModInd:
|
|
CodeLen=2; BAsmCode[0]=0xb0+AdrVal; BAsmCode[1]=AdrWord;
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
END
|
|
END
|
|
else WrError(1135);
|
|
return;
|
|
END
|
|
|
|
if ((Memo("ANLD")) OR (Memo("ORLD")) OR (Memo("MOVD")))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
OK=False;
|
|
if ((Memo("MOVD")) AND (strcasecmp(ArgStr[1],"A")==0))
|
|
BEGIN
|
|
strcpy(ArgStr[1],ArgStr[2]); strmaxcpy(ArgStr[2],"A",255); OK=True;
|
|
END
|
|
if (strcasecmp(ArgStr[2],"A")!=0) WrError(1350);
|
|
else if ((strlen(ArgStr[1])!=2) OR (toupper(*ArgStr[1])!='P')) WrError(1350);
|
|
else if ((ArgStr[1][1]<'4') OR (ArgStr[1][1]>'7')) WrError(1320);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x0c+ArgStr[1][1]-'4';
|
|
if (Memo("ANLD")) BAsmCode[0]+=0x90;
|
|
else if (Memo("ORLD")) BAsmCode[0]+=0x80;
|
|
else if (NOT OK) BAsmCode[0]+=0x30;
|
|
ChkN802X();
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("MOVP")) OR (Memo("MOVP3")))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if ((strcasecmp(ArgStr[1],"A")!=0) OR (strcasecmp(ArgStr[2],"@A")!=0)) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0xa3;
|
|
if (Memo("MOVP3")) BAsmCode[0]+=0x40;
|
|
ChkN802X();
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MOVX"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
OK=False;
|
|
if (strcasecmp(ArgStr[2],"A")==0)
|
|
BEGIN
|
|
strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"A",255); OK=True;
|
|
END
|
|
if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2]);
|
|
if (AdrMode!=ModInd) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x80+AdrVal;
|
|
if (OK) BAsmCode[0]+=0x10;
|
|
ChkN802X(); ChkNUPI();
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("NOP"))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x00;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("OUT"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"DBB")!=0) WrError(1350);
|
|
else if (strcasecmp(ArgStr[2],"A")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
BAsmCode[0]=0x02; CodeLen=1; ChkUPI();
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("OUTL"))
|
|
BEGIN
|
|
NLS_UpString(ArgStr[1]);
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
NLS_UpString(ArgStr[1]);
|
|
if (strcasecmp(ArgStr[2],"A")!=0) WrError(1350);
|
|
else if (strcmp(ArgStr[1],"BUS")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x02;
|
|
ChkN802X(); ChkExt(); ChkNUPI();
|
|
END
|
|
else if (strcmp(ArgStr[1],"P0")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x90;
|
|
END
|
|
else if ((strcmp(ArgStr[1],"P1")==0) OR (strcmp(ArgStr[1],"P2")==0))
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x38+ArgStr[1][1]-'0';
|
|
END
|
|
else WrError(1350);
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("RET")) OR (Memo("RETR")))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x83;
|
|
if (strlen(OpPart)==4)
|
|
BEGIN
|
|
BAsmCode[0]+=0x10; ChkN802X();
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("SEL"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (MomCPU==CPU8021) WrError(1500);
|
|
else
|
|
BEGIN
|
|
OK=False; NLS_UpString(ArgStr[1]);
|
|
for (z=0; z<SelOrderCnt; z++)
|
|
if (strcmp(ArgStr[1],SelOrders[z].Name)==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=SelOrders[z].Code; OK=True;
|
|
if ((SelOrders[z].Is22) AND (MomCPU!=CPU8022))
|
|
BEGIN
|
|
CodeLen=0; WrError(1500);
|
|
END
|
|
if (SelOrders[z].IsNUPI) ChkNUPI();
|
|
END
|
|
if (NOT OK) WrError(1350);
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("STOP"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (strcasecmp(ArgStr[1],"TCNT")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x65;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("STRT"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
NLS_UpString(ArgStr[1]);
|
|
if (strcmp(ArgStr[1],"CNT")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x45;
|
|
END
|
|
else if (strcmp(ArgStr[1],"T")==0)
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x55;
|
|
END
|
|
else WrError(1350);
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("XCH"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
if (strcasecmp(ArgStr[2],"A")==0)
|
|
BEGIN
|
|
strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"A",255);
|
|
END
|
|
if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2]);
|
|
switch (AdrMode)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=1; BAsmCode[0]=0x28+AdrVal;
|
|
break;
|
|
case ModInd:
|
|
CodeLen=1; BAsmCode[0]=0x20+AdrVal;
|
|
break;
|
|
default:
|
|
WrError(1350);
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("XCHD"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
if (strcasecmp(ArgStr[2],"A")==0)
|
|
BEGIN
|
|
strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"A",255);
|
|
END
|
|
if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[2]);
|
|
if (AdrMode!=ModInd) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x30+AdrVal;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("RAD"))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else if (MomCPU!=CPU8022) WrError(1500);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x80;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("RETI"))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else if (MomCPU!=CPU8022) WrError(1500);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x93;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("IDL"))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else if ((MomCPU!=CPU80C39) AND (MomCPU!=CPU80C48)) WrError(1500);
|
|
else
|
|
BEGIN
|
|
CodeLen=1; BAsmCode[0]=0x01;
|
|
END
|
|
return;
|
|
END
|
|
|
|
WrXError(1200,OpPart);
|
|
END
|
|
|
|
static Boolean IsDef_48(void)
|
|
BEGIN
|
|
return False;
|
|
END
|
|
|
|
static void SwitchFrom_48(void)
|
|
BEGIN
|
|
DeinitFields();
|
|
END
|
|
|
|
static void SwitchTo_48(void)
|
|
BEGIN
|
|
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
|
|
|
|
PCSymbol="$"; HeaderID=0x21; NOPCode=0x00;
|
|
DivideChars=","; HasAttrs=False;
|
|
|
|
ValidSegs=(1<<SegCode)|(1<<SegIData)|(1<<SegXData);
|
|
Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0;
|
|
switch (MomCPU-CPU8021)
|
|
BEGIN
|
|
case D_CPU8041: SegLimits[SegCode] = 0x3ff; break;
|
|
case D_CPU8042: SegLimits[SegCode] = 0x7ff; break;
|
|
default : SegLimits[SegCode] = 0xfff; break;
|
|
END
|
|
Grans[SegIData]=1; ListGrans[SegIData]=1; SegInits[SegIData]=0x20;
|
|
SegLimits[SegIData] = 0xff;
|
|
Grans[SegXData]=1; ListGrans[SegXData]=1; SegInits[SegXData]=0;
|
|
SegLimits[SegXData] = 0xff;
|
|
|
|
MakeCode=MakeCode_48; IsDef=IsDef_48;
|
|
SwitchFrom=SwitchFrom_48; InitFields();
|
|
END
|
|
|
|
void code48_init(void)
|
|
BEGIN
|
|
CPU8021 =AddCPU("8021" ,SwitchTo_48);
|
|
CPU8022 =AddCPU("8022" ,SwitchTo_48);
|
|
CPU8039 =AddCPU("8039" ,SwitchTo_48);
|
|
CPU8048 =AddCPU("8048" ,SwitchTo_48);
|
|
CPU80C39=AddCPU("80C39",SwitchTo_48);
|
|
CPU80C48=AddCPU("80C48",SwitchTo_48);
|
|
CPU8041 =AddCPU("8041" ,SwitchTo_48);
|
|
CPU8042 =AddCPU("8042" ,SwitchTo_48);
|
|
END
|