dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/code78k0.c

1229 lines
31 KiB
C

/* code78k0.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Codegenerator 78K0-Familie */
/* */
/* Historie: 1.12.1996 Grundsteinlegung */
/* 3. 1.1999 ChkPC-Anpassung */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "codepseudo.h"
#include "codevars.h"
#define ModNone (-1)
#define ModReg8 0
#define MModReg8 (1 << ModReg8)
#define ModReg16 1
#define MModReg16 (1 << ModReg16)
#define ModImm 2
#define MModImm (1 << ModImm)
#define ModShort 3
#define MModShort (1 << ModShort)
#define ModSFR 4
#define MModSFR (1 << ModSFR)
#define ModAbs 5
#define MModAbs (1 << ModAbs)
#define ModIReg 6
#define MModIReg (1 << ModIReg)
#define ModIndex 7
#define MModIndex (1 << ModIndex)
#define ModDisp 8
#define MModDisp (1 << ModDisp)
#define AccReg 1
#define AccReg16 0
#define FixedOrderCount 11
#define AriOrderCount 8
#define Ari16OrderCount 3
#define ShiftOrderCount 4
#define Bit2OrderCount 3
#define RelOrderCount 4
#define BRelOrderCount 3
typedef struct
{
char *Name;
Word Code;
} FixedOrder;
static FixedOrder *FixedOrders;
static char **AriOrders;
static char **Ari16Orders;
static char **ShiftOrders;
static char **Bit2Orders;
static char **RelOrders;
static char **BRelOrders;
static Byte OpSize,AdrPart;
static Byte AdrVals[2];
static ShortInt AdrMode;
static CPUVar CPU78070;
/*-------------------------------------------------------------------------*/
/* dynamische Codetabellenverwaltung */
static void AddFixed(char *NewName, Word NewCode)
BEGIN
if (InstrZ>=FixedOrderCount) exit(255);
FixedOrders[InstrZ].Name=NewName;
FixedOrders[InstrZ++].Code=NewCode;
END
static void AddAri(char *NewName)
BEGIN
if (InstrZ>=AriOrderCount) exit(255);
AriOrders[InstrZ++]=NewName;
END
static void AddAri16(char *NewName)
BEGIN
if (InstrZ>=Ari16OrderCount) exit(255);
Ari16Orders[InstrZ++]=NewName;
END
static void AddShift(char *NewName)
BEGIN
if (InstrZ>=ShiftOrderCount) exit(255);
ShiftOrders[InstrZ++]=NewName;
END
static void AddBit2(char *NewName)
BEGIN
if (InstrZ>=Bit2OrderCount) exit(255);
Bit2Orders[InstrZ++]=NewName;
END
static void AddRel(char *NewName)
BEGIN
if (InstrZ>=RelOrderCount) exit(255);
RelOrders[InstrZ++]=NewName;
END
static void AddBRel(char *NewName)
BEGIN
if (InstrZ>=BRelOrderCount) exit(255);
BRelOrders[InstrZ++]=NewName;
END
static void InitFields(void)
BEGIN
FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0;
AddFixed("BRK" ,0x00bf);
AddFixed("RET" ,0x00af);
AddFixed("RETB" ,0x009f);
AddFixed("RETI" ,0x008f);
AddFixed("HALT" ,0x7110);
AddFixed("STOP" ,0x7100);
AddFixed("NOP" ,0x0000);
AddFixed("EI" ,0x7a1e);
AddFixed("DI" ,0x7b1e);
AddFixed("ADJBA",0x6180);
AddFixed("ADJBS",0x6190);
AriOrders=(char **) malloc(sizeof(char *)*AriOrderCount); InstrZ=0;
AddAri("ADD" ); AddAri("SUB" ); AddAri("ADDC"); AddAri("SUBC");
AddAri("CMP" ); AddAri("AND" ); AddAri("OR" ); AddAri("XOR" );
Ari16Orders=(char **) malloc(sizeof(char *)*Ari16OrderCount); InstrZ=0;
AddAri16("ADDW"); AddAri16("SUBW"); AddAri16("CMPW");
ShiftOrders=(char **) malloc(sizeof(char *)*ShiftOrderCount); InstrZ=0;
AddShift("ROR"); AddShift("RORC"); AddShift("ROL"); AddShift("ROLC");
Bit2Orders=(char **) malloc(sizeof(char *)*Bit2OrderCount); InstrZ=0;
AddBit2("AND1"); AddBit2("OR1"); AddBit2("XOR1");
RelOrders=(char **) malloc(sizeof(char *)*RelOrderCount); InstrZ=0;
AddRel("BC"); AddRel("BNC"); AddRel("BZ"); AddRel("BNZ");
BRelOrders=(char **) malloc(sizeof(char *)*BRelOrderCount); InstrZ=0;
AddBRel("BTCLR"); AddBRel("BT"); AddBRel("BF");
END
static void DeinitFields(void)
BEGIN
free(FixedOrders);
free(AriOrders);
free(Ari16Orders);
free(ShiftOrders);
free(Bit2Orders);
free(RelOrders);
free(BRelOrders);
END
/*-------------------------------------------------------------------------*/
/* Adressausdruck parsen */
static void ChkAdr(Word Mask)
BEGIN
if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0))
BEGIN
WrError(1350);
AdrMode=ModNone; AdrCnt=0;
END
END
static void DecodeAdr(char *Asc, Word Mask)
BEGIN
static char *RegNames[8]={"X","A","C","B","E","D","L","H"};
Word AdrWord;
int z;
Boolean OK,LongFlag;
AdrMode=ModNone; AdrCnt=0;
/* Register */
for (z=0; z<8; z++)
if (strcasecmp(Asc,RegNames[z])==0)
BEGIN
AdrMode=ModReg8; AdrPart=z; ChkAdr(Mask); return;
END
if (toupper(*Asc)=='R')
if ((strlen(Asc)==2) AND (Asc[1]>='0') AND (Asc[1]<='7'))
BEGIN
AdrMode=ModReg8; AdrPart=Asc[1]-'0'; ChkAdr(Mask); return;
END
else if ((strlen(Asc)==3) AND (toupper(Asc[1])=='P') AND (Asc[2]>='0') AND (Asc[2]<='3'))
BEGIN
AdrMode=ModReg16; AdrPart=Asc[2]-'0'; ChkAdr(Mask); return;
END
if (strlen(Asc)==2)
for (z=0; z<4; z++)
if ((toupper(*Asc)==*RegNames[(z<<1)+1]) AND (toupper(Asc[1])==*RegNames[z<<1]))
BEGIN
AdrMode=ModReg16; AdrPart=z; ChkAdr(Mask); return;
END
/* immediate */
if (*Asc=='#')
BEGIN
switch (OpSize)
BEGIN
case 0:
AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
break;
case 1:
AdrWord=EvalIntExpression(Asc+1,Int16,&OK);
if (OK)
BEGIN
AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
END
break;
END
if (OK)
BEGIN
AdrMode=ModImm; AdrCnt=OpSize+1;
END
ChkAdr(Mask); return;
END
/* indirekt */
if ((*Asc=='[') AND (Asc[strlen(Asc)-1]==']'))
BEGIN
strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
if ((strcasecmp(Asc,"DE")==0) OR (strcasecmp(Asc,"RP2")==0))
BEGIN
AdrMode=ModIReg; AdrPart=0;
END
else if ((strncasecmp(Asc,"HL",2)!=0) AND (strncasecmp(Asc,"RP3",3)!=0)) WrXError(1445,Asc);
else
BEGIN
strcpy(Asc,Asc+2); if (*Asc=='3') strcpy(Asc,Asc+1);
if ((strcasecmp(Asc,"+B")==0) OR (strcasecmp(Asc,"+R3")==0))
BEGIN
AdrMode=ModIndex; AdrPart=1;
END
else if ((strcasecmp(Asc,"+C")==0) OR (strcasecmp(Asc,"+R2")==0))
BEGIN
AdrMode=ModIndex; AdrPart=0;
END
else
BEGIN
AdrVals[0]=EvalIntExpression(Asc,UInt8,&OK);
if (OK)
if (AdrVals[0]==0)
BEGIN
AdrMode=ModIReg; AdrPart=1;
END
else
BEGIN
AdrMode=ModDisp; AdrCnt=1;
END;
END
END
ChkAdr(Mask); return;
END
/* erzwungen lang ? */
if (*Asc=='!')
BEGIN
LongFlag=True; strcpy(Asc,Asc+1);
END
else LongFlag=False;
/* -->absolut */
FirstPassUnknown=True;
AdrWord=EvalIntExpression(Asc,UInt16,&OK);
if (FirstPassUnknown)
BEGIN
AdrWord&=0xffffe;
if ((Mask & MModAbs)==0)
AdrWord=(AdrWord | 0xff00) & 0xff1f;
END
if (OK)
if ((NOT LongFlag) AND ((Mask & MModShort)!=0) AND (AdrWord>=0xfe20) AND (AdrWord<=0xff1f))
BEGIN
AdrMode=ModShort; AdrCnt=1; AdrVals[0]=Lo(AdrWord);
END
else if ((NOT LongFlag) AND ((Mask & MModSFR)!=0) AND (((AdrWord>=0xff00) AND (AdrWord<=0xffcf)) OR (AdrWord>=0xffe0)))
BEGIN
AdrMode=ModSFR; AdrCnt=1; AdrVals[0]=Lo(AdrWord);
END
else
BEGIN
AdrMode=ModAbs; AdrCnt=2; AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
END
ChkAdr(Mask);
END
static void ChkEven(void)
BEGIN
if ((AdrMode==ModAbs) OR (AdrMode==ModShort) OR (AdrMode==ModSFR))
if ((AdrVals[0]&1)==1) WrError(180);
END
static Boolean DecodeBitAdr(char *Asc, Byte *Erg)
BEGIN
char *p;
Boolean OK;
p=RQuotPos(Asc,'.');
if (p==Nil)
BEGIN
WrError(1510); return False;
END
*p='\0';
*Erg=EvalIntExpression(p+1,UInt3,&OK) << 4;
if (NOT OK) return False;
DecodeAdr(Asc,MModShort+MModSFR+MModIReg+MModReg8);
switch (AdrMode)
BEGIN
case ModReg8:
if (AdrPart!=AccReg)
BEGIN
WrError(1350); return False;
END
else
BEGIN
*Erg+=0x88; return True;
END
case ModShort:
return True;
case ModSFR:
*Erg+=0x08; return True;
case ModIReg:
if (AdrPart==0)
BEGIN
WrError(1350); return False;
END
else
BEGIN
*Erg+=0x80; return True;
END
default:
return False;
END
END
/*-------------------------------------------------------------------------*/
static Boolean DecodePseudo(void)
BEGIN
return False;
END
static void MakeCode_78K0(void)
BEGIN
int z;
Byte HReg;
Word AdrWord;
Integer AdrInt;
Boolean OK;
CodeLen=0; DontPrint=False; OpSize=0;
/* zu ignorierendes */
if (Memo("")) return;
/* Pseudoanweisungen */
if (DecodePseudo()) return;
if (DecodeIntelPseudo(False)) return;
/* ohne Argument */
for (z=0; z<FixedOrderCount; z++)
if (Memo(FixedOrders[z].Name))
BEGIN
if (ArgCnt!=0) WrError(1110);
else if (Hi(FixedOrders[z].Code)==0) CodeLen=1;
else
BEGIN
BAsmCode[0]=Hi(FixedOrders[z].Code); CodeLen=2;
END
BAsmCode[CodeLen-1]=Lo(FixedOrders[z].Code);
return;
END
/* Datentransfer */
if (Memo("MOV"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModShort+MModSFR+MModAbs+MModIReg+MModIndex+MModDisp);
switch (AdrMode)
BEGIN
case ModReg8:
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModImm+MModReg8+((HReg==AccReg)?MModShort+MModSFR+MModAbs+MModIReg+MModIndex+MModDisp:0));
switch (AdrMode)
BEGIN
case ModReg8:
if ((HReg==AccReg)==(AdrPart==AccReg)) WrError(1350);
else if (HReg==AccReg)
BEGIN
CodeLen=1; BAsmCode[0]=0x60+AdrPart;
END
else
BEGIN
CodeLen=1; BAsmCode[0]=0x70+HReg;
END
break;
case ModImm:
CodeLen=2; BAsmCode[0]=0xa0+HReg; BAsmCode[1]=AdrVals[0];
break;
case ModShort:
CodeLen=2; BAsmCode[0]=0xf0; BAsmCode[1]=AdrVals[0];
break;
case ModSFR:
CodeLen=2; BAsmCode[0]=0xf4; BAsmCode[1]=AdrVals[0];
break;
case ModAbs:
CodeLen=3; BAsmCode[0]=0xfe; memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
case ModIReg:
CodeLen=1; BAsmCode[0]=0x85+(AdrPart << 1);
break;
case ModIndex:
CodeLen=1; BAsmCode[0]=0xaa+AdrPart;
break;
case ModDisp:
CodeLen=2; BAsmCode[0]=0xae; BAsmCode[1]=AdrVals[0];
break;
END
break;
case ModShort:
BAsmCode[1]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg8+MModImm);
switch (AdrMode)
BEGIN
case ModReg8:
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
BAsmCode[0]=0xf2; CodeLen=2;
END
break;
case ModImm:
BAsmCode[0]=0x11; BAsmCode[2]=AdrVals[0]; CodeLen=3;
break;
END
break;
case ModSFR:
BAsmCode[1]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg8+MModImm);
switch (AdrMode)
BEGIN
case ModReg8:
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
BAsmCode[0]=0xf6; CodeLen=2;
END
break;
case ModImm:
BAsmCode[0]=0x13; BAsmCode[2]=AdrVals[0]; CodeLen=3;
break;
END
break;
case ModAbs:
memcpy(BAsmCode+1,AdrVals,2);
DecodeAdr(ArgStr[2],MModReg8);
if (AdrMode==ModReg8)
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
BAsmCode[0]=0x9e; CodeLen=3;
END
break;
case ModIReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg8);
if (AdrMode==ModReg8)
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
BAsmCode[0]=0x95+(AdrPart << 1); CodeLen=1;
END
break;
case ModIndex:
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg8);
if (AdrMode==ModReg8)
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
BAsmCode[0]=0xba+HReg; CodeLen=1;
END
break;
case ModDisp:
BAsmCode[1]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg8);
if (AdrMode==ModReg8)
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
BAsmCode[0]=0xbe; CodeLen=2;
END
break;
END
END
return;
END
if (Memo("XCH"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
if ((strcasecmp(ArgStr[2],"A")==0) OR (strcasecmp(ArgStr[2],"RP1")==0))
BEGIN
strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]);
END
DecodeAdr(ArgStr[1],MModReg8);
if (AdrMode!=ModNone)
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
DecodeAdr(ArgStr[2],MModReg8+MModShort+MModSFR+MModAbs+MModIReg+MModIndex+MModDisp);
switch (AdrMode)
BEGIN
case ModReg8:
if (AdrPart==AccReg) WrError(1350);
else
BEGIN
BAsmCode[0]=0x30+AdrPart; CodeLen=1;
END
break;
case ModShort:
BAsmCode[0]=0x83; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
case ModSFR:
BAsmCode[0]=0x93; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
case ModAbs:
BAsmCode[0]=0xce; memcpy(BAsmCode+1,AdrVals,AdrCnt); CodeLen=3;
break;
case ModIReg:
BAsmCode[0]=0x05+(AdrPart << 1); CodeLen=1;
break;
case ModIndex:
BAsmCode[0]=0x31; BAsmCode[1]=0x8a+AdrPart; CodeLen=2;
break;
case ModDisp:
BAsmCode[0]=0xde; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
END
END
END
return;
END
if (Memo("MOVW"))
BEGIN
OpSize=1;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16+MModShort+MModSFR+MModAbs);
switch (AdrMode)
BEGIN
case ModReg16:
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg16+MModImm+((HReg==AccReg16)?MModShort+MModSFR+MModAbs:0));
switch (AdrMode)
BEGIN
case ModReg16:
if ((HReg==AccReg16)==(AdrPart==AccReg16)) WrError(1350);
else if (HReg==AccReg16)
BEGIN
BAsmCode[0]=0xc0+(AdrPart << 1); CodeLen=1;
END
else
BEGIN
BAsmCode[0]=0xd0+(HReg << 1); CodeLen=1;
END
break;
case ModImm:
BAsmCode[0]=0x10+(HReg << 1); memcpy(BAsmCode+1,AdrVals,2);
CodeLen=3;
break;
case ModShort:
BAsmCode[0]=0x89; BAsmCode[1]=AdrVals[0]; CodeLen=2;
ChkEven();
break;
case ModSFR:
BAsmCode[0]=0xa9; BAsmCode[1]=AdrVals[0]; CodeLen=2;
ChkEven();
break;
case ModAbs:
BAsmCode[0]=0x02; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
ChkEven();
break;
END
break;
case ModShort:
ChkEven();
BAsmCode[1]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg16+MModImm);
switch (AdrMode)
BEGIN
case ModReg16:
if (AdrPart!=AccReg16) WrError(1350);
else
BEGIN
BAsmCode[0]=0x99; CodeLen=2;
END
break;
case ModImm:
BAsmCode[0]=0xee; memcpy(BAsmCode+2,AdrVals,2); CodeLen=4;
break;
END
break;
case ModSFR:
ChkEven();
BAsmCode[1]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg16+MModImm);
switch (AdrMode)
BEGIN
case ModReg16:
if (AdrPart!=AccReg16) WrError(1350);
else
BEGIN
BAsmCode[0]=0xb9; CodeLen=2;
END
break;
case ModImm:
BAsmCode[0]=0xfe; memcpy(BAsmCode+2,AdrVals,2); CodeLen=4;
break;
END
break;
case ModAbs:
ChkEven();
memcpy(BAsmCode+1,AdrVals,AdrCnt);
DecodeAdr(ArgStr[2],MModReg16);
if (AdrMode==ModReg16)
if (AdrPart!=AccReg16) WrError(1350);
else
BEGIN
BAsmCode[0]=0x03; CodeLen=3;
END
break;
END
END
return;
END
if (Memo("XCHW"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
if (AdrMode==ModReg16)
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg16);
if (AdrMode==ModReg16)
if ((HReg==AccReg16)==(AdrPart==AccReg16)) WrError(1350);
else
BEGIN
BAsmCode[0]=(HReg==AccReg16) ? 0xe0+(AdrPart << 1) : 0xe0+(HReg << 1);
CodeLen=1;
END
END
END
return;
END
if ((Memo("PUSH")) OR (Memo("POP")))
BEGIN
z=Ord(Memo("POP"));
if (ArgCnt!=1) WrError(1110);
else if (strcasecmp(ArgStr[1],"PSW")==0)
BEGIN
BAsmCode[0]=0x22+z; CodeLen=1;
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
if (AdrMode==ModReg16)
BEGIN
BAsmCode[0]=0xb1-z+(AdrPart << 1); CodeLen=1;
END
END
return;
END
/* Arithmetik */
for (z=0; z<AriOrderCount; z++)
if (Memo(AriOrders[z]))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModShort);
switch (AdrMode)
BEGIN
case ModReg8:
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg8+((HReg==AccReg)?(MModImm+MModShort+MModAbs+MModIReg+MModIndex+MModDisp):0));
switch (AdrMode)
BEGIN
case ModReg8:
if (AdrPart==AccReg)
BEGIN
BAsmCode[0]=0x61; BAsmCode[1]=(z << 4)+HReg; CodeLen=2;
END
else if (HReg==AccReg)
BEGIN
BAsmCode[0]=0x61; BAsmCode[1]=0x08+(z << 4)+AdrPart; CodeLen=2;
END
else WrError(1350);
break;
case ModImm:
BAsmCode[0]=(z << 4)+0x0d; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
case ModShort:
BAsmCode[0]=(z << 4)+0x0e; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
case ModAbs:
BAsmCode[0]=(z << 4)+0x08; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
break;
case ModIReg:
if (AdrPart==0) WrError(1350);
else
BEGIN
BAsmCode[0]=(z << 4)+0x0f; CodeLen=2;
END
break;
case ModIndex:
BAsmCode[0]=0x31; BAsmCode[1]=(z << 4)+0x0a+AdrPart; CodeLen=2;
break;
case ModDisp:
BAsmCode[0]=(z << 4)+0x09; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
END
break;
case ModShort:
BAsmCode[1]=AdrVals[0];
DecodeAdr(ArgStr[2],MModImm);
if (AdrMode==ModImm)
BEGIN
BAsmCode[0]=(z << 4)+0x88; BAsmCode[2]=AdrVals[0]; CodeLen=3;
END
break;
END
END
return;
END
for (z=0; z<Ari16OrderCount; z++)
if (Memo(Ari16Orders[z]))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
OpSize=1;
DecodeAdr(ArgStr[1],MModReg16);
if (AdrMode==ModReg16)
BEGIN
DecodeAdr(ArgStr[2],MModImm);
if (AdrMode==ModImm)
BEGIN
BAsmCode[0]=0xca+(z << 4); memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
END
END
END
return;
END
if (Memo("MULU"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8);
if (AdrMode==ModReg8)
if (AdrPart!=0) WrError(1350);
else
BEGIN
BAsmCode[0]=0x31; BAsmCode[1]=0x88; CodeLen=2;
END
END
return;
END
if (Memo("DIVUW"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8);
if (AdrMode==ModReg8)
if (AdrPart!=2) WrError(1350);
else
BEGIN
BAsmCode[0]=0x31; BAsmCode[1]=0x82; CodeLen=2;
END
END
return;
END
if ((Memo("INC")) OR (Memo("DEC")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
z=Ord(Memo("DEC")) << 4;
DecodeAdr(ArgStr[1],MModReg8+MModShort);
switch (AdrMode)
BEGIN
case ModReg8:
BAsmCode[0]=0x40+AdrPart+z; CodeLen=1;
break;
case ModShort:
BAsmCode[0]=0x81+z; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
END
END
return;
END
if ((Memo("INCW")) OR (Memo("DECW")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
if (AdrMode==ModReg16)
BEGIN
BAsmCode[0]=0x80+(Ord(Memo("DECW")) << 4)+(AdrPart << 1);
CodeLen=1;
END
END
return;
END
for (z=0; z<ShiftOrderCount; z++)
if (Memo(ShiftOrders[z]))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8);
if (AdrMode==ModReg8)
if (AdrPart!=AccReg) WrError(1350);
else
BEGIN
HReg=EvalIntExpression(ArgStr[2],UInt1,&OK);
if (OK)
if (HReg!=1) WrError(1315);
else
BEGIN
BAsmCode[0]=0x24+z; CodeLen=1;
END
END
END
return;
END
if ((Memo("ROL4")) OR (Memo("ROR4")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModIReg);
if (AdrMode==ModIReg)
if (AdrPart==0) WrError(1350);
else
BEGIN
BAsmCode[0]=0x31; BAsmCode[1]=0x80+(Ord(Memo("ROR4")) << 4);
CodeLen=2;
END
END
return;
END
/* Bitoperationen */
if (Memo("MOV1"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
if (strcasecmp(ArgStr[2],"CY")==0)
BEGIN
strcpy(ArgStr[3],ArgStr[1]);
strcpy(ArgStr[1],ArgStr[2]);
strcpy(ArgStr[2],ArgStr[3]);
z=1;
END
else z=4;
if (strcasecmp(ArgStr[1],"CY")!=0) WrError(1110);
else if (DecodeBitAdr(ArgStr[2],&HReg))
BEGIN
BAsmCode[0]=0x61+(Ord((HReg & 0x88)!=0x88) << 4);
BAsmCode[1]=z+HReg;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
END
END
return;
END
for (z=0; z<Bit2OrderCount; z++)
if (Memo(Bit2Orders[z]))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (strcasecmp(ArgStr[1],"CY")!=0) WrError(1110);
else if (DecodeBitAdr(ArgStr[2],&HReg))
BEGIN
BAsmCode[0]=0x61+(Ord((HReg & 0x88)!=0x88) << 4);
BAsmCode[1]=z+5+HReg;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
END
return;
END
if ((Memo("SET1")) OR (Memo("CLR1")))
BEGIN
z=Ord(Memo("CLR1"));
if (ArgCnt!=1) WrError(1110);
else if (strcasecmp(ArgStr[1],"CY")==0)
BEGIN
BAsmCode[0]=0x20+z; CodeLen=1;
END
else if (DecodeBitAdr(ArgStr[1],&HReg))
if ((HReg & 0x88)==0)
BEGIN
BAsmCode[0]=0x0a+z+(HReg & 0x70);
BAsmCode[1]=AdrVals[0];
CodeLen=2;
END
else
BEGIN
BAsmCode[0]=0x61+(Ord((HReg & 0x88)!=0x88) << 4);
BAsmCode[1]=HReg+2+z;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
END
return;
END
if (Memo("NOT1"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (strcasecmp(ArgStr[1],"CY")!=0) WrError(1350);
else
BEGIN
BAsmCode[0]=0x01;
CodeLen=1;
END
return;
END
/* Spruenge */
if (Memo("CALL"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModAbs);
if (AdrMode==ModAbs)
BEGIN
BAsmCode[0]=0x9a; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
END
END
return;
END
if (Memo("CALLF"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
if (*ArgStr[1]=='!') strcpy(ArgStr[1],ArgStr[1]+1);
AdrWord=EvalIntExpression(ArgStr[1],UInt11,&OK);
if (OK)
BEGIN
BAsmCode[0]=0x0c+(Hi(AdrWord) << 4);
BAsmCode[1]=Lo(AdrWord);
CodeLen=2;
END
END
return;
END
if (Memo("CALLT"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if ((*ArgStr[1]!='[') OR (ArgStr[1][strlen(ArgStr[1])-1]!=']')) WrError(1350);
else
BEGIN
FirstPassUnknown=False;
ArgStr[1][strlen(ArgStr[1])-1]='\0';
AdrWord=EvalIntExpression(ArgStr[1]+1,UInt6,&OK);
if (FirstPassUnknown) AdrWord&=0xfffe;
if (OK)
if (Odd(AdrWord)) WrError(1325);
else
BEGIN
BAsmCode[0]=0xc1+(AdrWord & 0x3e);
CodeLen=1;
END
END
return;
END
if (Memo("BR"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if ((strcasecmp(ArgStr[1],"AX")==0) OR (strcasecmp(ArgStr[1],"RP0")==0))
BEGIN
BAsmCode[0]=0x31; BAsmCode[1]=0x98; CodeLen=2;
END
else
BEGIN
if (*ArgStr[1]=='!')
BEGIN
strcpy(ArgStr[1],ArgStr[1]+1); HReg=1;
END
else if (*ArgStr[1]=='$')
BEGIN
strcpy(ArgStr[1],ArgStr[1]+1); HReg=2;
END
else HReg=0;
AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK);
if (OK)
BEGIN
if (HReg==0)
BEGIN
AdrInt=AdrWord-(EProgCounter()-2);
HReg=((AdrInt>=-128) AND (AdrInt<127)) ? 2 : 1;
END
switch (HReg)
BEGIN
case 1:
BAsmCode[0]=0x9b; BAsmCode[1]=Lo(AdrWord); BAsmCode[2]=Hi(AdrWord);
CodeLen=3;
break;
case 2:
AdrInt=AdrWord-(EProgCounter()+2);
if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
else
BEGIN
BAsmCode[0]=0xfa; BAsmCode[1]=AdrInt & 0xff; CodeLen=2;
END
break;
END
END
END
return;
END
for (z=0; z<RelOrderCount; z++)
if (Memo(RelOrders[z]))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
if (*ArgStr[1]=='$') strcpy(ArgStr[1],ArgStr[1]+1);
AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK)-(EProgCounter()+2);
if (OK)
if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
else
BEGIN
BAsmCode[0]=0x8b+(z << 4); BAsmCode[1]=AdrInt & 0xff;
CodeLen=2;
END
END
return;
END
for (z=0; z<BRelOrderCount; z++)
if (Memo(BRelOrders[z]))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (DecodeBitAdr(ArgStr[1],&HReg))
BEGIN
if ((z==1) AND ((HReg & 0x88)==0))
BEGIN
BAsmCode[0]=0x8c+HReg; BAsmCode[1]=AdrVals[0]; HReg=2;
END
else
BEGIN
BAsmCode[0]=0x31;
switch (HReg & 0x88)
BEGIN
case 0x00:
BAsmCode[1]=0x00; break;
case 0x08:
BAsmCode[1]=0x04; break;
case 0x80:
BAsmCode[1]=0x84; break;
case 0x88:
BAsmCode[1]=0x0c; break;
END
BAsmCode[1]+=(HReg & 0x70)+z+1;
BAsmCode[2]=AdrVals[0];
HReg=2+AdrCnt;
END
if (*ArgStr[2]=='$') strcpy(ArgStr[2],ArgStr[2]+1);
AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+HReg+1);
if (OK)
if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
else
BEGIN
BAsmCode[HReg]=AdrInt & 0xff;
CodeLen=HReg+1;
END
END
return;
END
if (Memo("DBNZ"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModShort);
if ((AdrMode==ModReg8) AND ((AdrPart & 6)!=2)) WrError(1350);
else if (AdrMode!=ModNone)
BEGIN
BAsmCode[0]=(AdrMode==ModReg8) ? 0x88+AdrPart : 0x04;
BAsmCode[1]=AdrVals[0];
if (*ArgStr[2]=='$') strcpy(ArgStr[2],ArgStr[2]+1);
AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+AdrCnt+2);
if (OK)
if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
else
BEGIN
BAsmCode[AdrCnt+1]=AdrInt & 0xff;
CodeLen=AdrCnt+2;
END
END
END
return;
END
/* Steueranweisungen */
if (Memo("SEL"))
BEGIN
if (ArgCnt!=1) WrError(1350);
else if ((strlen(ArgStr[1])!=3) OR (strncasecmp(ArgStr[1],"RB",2)!=0)) WrError(1350);
else
BEGIN
HReg=ArgStr[1][2]-'0';
if (ChkRange(HReg,0,3))
BEGIN
BAsmCode[0]=0x61;
BAsmCode[1]=0xd0+((HReg & 1) << 3)+((HReg & 2) << 4);
CodeLen=2;
END
END
return;
END
WrXError(1200,OpPart);
END
static Boolean IsDef_78K0(void)
BEGIN
return False;
END
static void SwitchFrom_78K0(void)
BEGIN
DeinitFields();
END
static void SwitchTo_78K0(void)
BEGIN
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
PCSymbol="PC"; HeaderID=0x7c; NOPCode=0x00;
DivideChars=","; HasAttrs=False;
ValidSegs=1<<SegCode;
Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
SegLimits[SegCode] = 0xffff;
MakeCode=MakeCode_78K0; IsDef=IsDef_78K0;
SwitchFrom=SwitchFrom_78K0; InitFields();
END
void code78k0_init(void)
BEGIN
CPU78070=AddCPU("78070",SwitchTo_78K0);
END