452 lines
10 KiB
C
452 lines
10 KiB
C
|
/* code6804.c */
|
||
|
/*****************************************************************************/
|
||
|
/* AS-Portierung */
|
||
|
/* */
|
||
|
/* AS-Codeenerator Motorola/ST 6804 */
|
||
|
/* */
|
||
|
/* Historie: 17.10.1996 Grundsteinlegung */
|
||
|
/* 2. 1.1999 ChkPC-Anpassung */
|
||
|
/* */
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
#include "stdinc.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;
|
||
|
LongInt Code;
|
||
|
} BaseOrder;
|
||
|
|
||
|
#define FixedOrderCnt 19
|
||
|
#define RelOrderCnt 6
|
||
|
#define ALUOrderCnt 4
|
||
|
|
||
|
#define ModNone (-1)
|
||
|
#define ModInd 0
|
||
|
#define MModInd (1 << ModInd)
|
||
|
#define ModDir 1
|
||
|
#define MModDir (1 << ModDir)
|
||
|
#define ModImm 2
|
||
|
#define MModImm (1 << ModImm)
|
||
|
|
||
|
static ShortInt AdrMode;
|
||
|
static Byte AdrVal;
|
||
|
|
||
|
static CPUVar CPU6804;
|
||
|
|
||
|
static BaseOrder *FixedOrders;
|
||
|
static BaseOrder *RelOrders;
|
||
|
static BaseOrder *ALUOrders;
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
static void AddFixed(char *NName, LongInt NCode)
|
||
|
BEGIN
|
||
|
if (InstrZ>=FixedOrderCnt) exit(255);
|
||
|
FixedOrders[InstrZ].Name=NName;
|
||
|
FixedOrders[InstrZ++].Code=NCode;
|
||
|
END
|
||
|
|
||
|
static void AddRel(char *NName, LongInt NCode)
|
||
|
BEGIN
|
||
|
if (InstrZ>=RelOrderCnt) exit(255);
|
||
|
RelOrders[InstrZ].Name=NName;
|
||
|
RelOrders[InstrZ++].Code=NCode;
|
||
|
END
|
||
|
|
||
|
static void AddALU(char *NName, LongInt NCode)
|
||
|
BEGIN
|
||
|
if (InstrZ>=ALUOrderCnt) exit(255);
|
||
|
ALUOrders[InstrZ].Name=NName;
|
||
|
ALUOrders[InstrZ++].Code=NCode;
|
||
|
END
|
||
|
|
||
|
static void InitFields(void)
|
||
|
BEGIN
|
||
|
FixedOrders=(BaseOrder *) malloc(sizeof(BaseOrder)*FixedOrderCnt); InstrZ=0;
|
||
|
AddFixed("CLRA", 0x00fbff);
|
||
|
AddFixed("CLRX", 0xb08000);
|
||
|
AddFixed("CLRY", 0xb08100);
|
||
|
AddFixed("COMA", 0x0000b4);
|
||
|
AddFixed("ROLA", 0x0000b5);
|
||
|
AddFixed("ASLA", 0x00faff);
|
||
|
AddFixed("INCA", 0x00feff);
|
||
|
AddFixed("INCX", 0x0000a8);
|
||
|
AddFixed("INCY", 0x0000a9);
|
||
|
AddFixed("DECA", 0x00ffff);
|
||
|
AddFixed("DECX", 0x0000b8);
|
||
|
AddFixed("DECY", 0x0000b9);
|
||
|
AddFixed("TAX" , 0x0000bc);
|
||
|
AddFixed("TAY" , 0x0000bd);
|
||
|
AddFixed("TXA" , 0x0000ac);
|
||
|
AddFixed("TYA" , 0x0000ad);
|
||
|
AddFixed("RTS" , 0x0000b3);
|
||
|
AddFixed("RTI" , 0x0000b2);
|
||
|
AddFixed("NOP" , 0x000020);
|
||
|
|
||
|
RelOrders=(BaseOrder *) malloc(sizeof(BaseOrder)*RelOrderCnt); InstrZ=0;
|
||
|
AddRel("BCC", 0x40);
|
||
|
AddRel("BHS", 0x40);
|
||
|
AddRel("BCS", 0x60);
|
||
|
AddRel("BLO", 0x60);
|
||
|
AddRel("BNE", 0x00);
|
||
|
AddRel("BEQ", 0x20);
|
||
|
|
||
|
ALUOrders=(BaseOrder *) malloc(sizeof(BaseOrder)*ALUOrderCnt); InstrZ=0;
|
||
|
AddALU("ADD", 0x02);
|
||
|
AddALU("SUB", 0x03);
|
||
|
AddALU("CMP", 0x04);
|
||
|
AddALU("AND", 0x05);
|
||
|
END
|
||
|
|
||
|
static void DeinitFields(void)
|
||
|
BEGIN
|
||
|
free(FixedOrders);
|
||
|
free(RelOrders);
|
||
|
free(ALUOrders);
|
||
|
END
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
static void ChkAdr(Boolean MayImm)
|
||
|
BEGIN
|
||
|
if ((AdrMode==ModImm) AND (NOT MayImm))
|
||
|
BEGIN
|
||
|
WrError(1350); AdrMode=ModNone;
|
||
|
END
|
||
|
END
|
||
|
|
||
|
static void DecodeAdr(char *Asc, Boolean MayImm)
|
||
|
BEGIN
|
||
|
Boolean OK;
|
||
|
|
||
|
AdrMode=ModNone;
|
||
|
|
||
|
if (strcasecmp(Asc,"(X)")==0)
|
||
|
BEGIN
|
||
|
AdrMode=ModInd; AdrVal=0x00; ChkAdr(MayImm); return;
|
||
|
END
|
||
|
if (strcasecmp(Asc,"(Y)")==0)
|
||
|
BEGIN
|
||
|
AdrMode=ModInd; AdrVal=0x10; ChkAdr(MayImm); return;
|
||
|
END
|
||
|
|
||
|
if (*Asc=='#')
|
||
|
BEGIN
|
||
|
AdrVal=EvalIntExpression(Asc+1,Int8,&OK);
|
||
|
if (OK) AdrMode=ModImm; ChkAdr(MayImm); return;
|
||
|
END
|
||
|
|
||
|
AdrVal=EvalIntExpression(Asc,Int8,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
AdrMode=ModDir; ChkAdr(MayImm); return;
|
||
|
END
|
||
|
|
||
|
ChkAdr(MayImm);
|
||
|
END
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
static Boolean DecodePseudo(void)
|
||
|
BEGIN
|
||
|
if (Memo("SFR"))
|
||
|
BEGIN
|
||
|
CodeEquate(SegData,0,0xff);
|
||
|
return True;
|
||
|
END
|
||
|
|
||
|
return False;
|
||
|
END
|
||
|
|
||
|
static Boolean IsShort(Byte Adr)
|
||
|
BEGIN
|
||
|
return ((Adr & 0xfc)==0x80);
|
||
|
END
|
||
|
|
||
|
static void MakeCode_6804(void)
|
||
|
BEGIN
|
||
|
int z;
|
||
|
Integer AdrInt;
|
||
|
Boolean OK;
|
||
|
|
||
|
CodeLen=0; DontPrint=False;
|
||
|
|
||
|
/* zu ignorierendes */
|
||
|
|
||
|
if (Memo("")) return;
|
||
|
|
||
|
/* Pseudoanweisungen */
|
||
|
|
||
|
if (DecodePseudo()) return;
|
||
|
|
||
|
if (DecodeMotoPseudo(True)) return;
|
||
|
|
||
|
/* Anweisungen ohne Argument */
|
||
|
|
||
|
for (z=0; z<FixedOrderCnt; z++)
|
||
|
if Memo(FixedOrders[z].Name)
|
||
|
BEGIN
|
||
|
if (ArgCnt!=0) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
if ((FixedOrders[z].Code >> 16)!=0) CodeLen=3;
|
||
|
else CodeLen=1+Ord(Hi(FixedOrders[z].Code)!=0);
|
||
|
if (CodeLen==3) BAsmCode[0]=FixedOrders[z].Code >> 16;
|
||
|
if (CodeLen>=2) BAsmCode[CodeLen-2]=Hi(FixedOrders[z].Code);
|
||
|
BAsmCode[CodeLen-1]=Lo(FixedOrders[z].Code);
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
/* relative/absolute Spruenge */
|
||
|
|
||
|
for (z=0; z<RelOrderCnt; z++)
|
||
|
if Memo(RelOrders[z].Name)
|
||
|
BEGIN
|
||
|
if (ArgCnt!=1) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
AdrInt=EvalIntExpression(ArgStr[1],Int16,&OK)-(EProgCounter()+1);
|
||
|
if (OK)
|
||
|
if ((NOT SymbolQuestionable) AND ((AdrInt<-16) OR (AdrInt>15))) WrError(1370);
|
||
|
else
|
||
|
BEGIN
|
||
|
CodeLen=1; BAsmCode[0]=RelOrders[z].Code+(AdrInt & 0x1f);
|
||
|
ChkSpace(SegCode);
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
if ((Memo("JSR")) OR (Memo("JMP")))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=1) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
AdrInt=EvalIntExpression(ArgStr[1],UInt12,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
CodeLen=2; BAsmCode[1]=Lo(AdrInt);
|
||
|
BAsmCode[0]=0x80+(Ord(Memo("JMP")) << 4)+(Hi(AdrInt) & 15);
|
||
|
ChkSpace(SegCode);
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
/* AKKU-Operationen */
|
||
|
|
||
|
for (z=0; z<ALUOrderCnt; z++)
|
||
|
if (Memo(ALUOrders[z].Name))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=1) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
DecodeAdr(ArgStr[1],True);
|
||
|
switch (AdrMode)
|
||
|
BEGIN
|
||
|
case ModInd:
|
||
|
CodeLen=1; BAsmCode[0]=0xe0+AdrVal+ALUOrders[z].Code;
|
||
|
break;
|
||
|
case ModDir:
|
||
|
CodeLen=2; BAsmCode[0]=0xf8+ALUOrders[z].Code; BAsmCode[1]=AdrVal;
|
||
|
break;
|
||
|
case ModImm:
|
||
|
CodeLen=2; BAsmCode[0]=0xe8+ALUOrders[z].Code; BAsmCode[1]=AdrVal;
|
||
|
break;
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
/* Datentransfer */
|
||
|
|
||
|
if ((Memo("LDA")) OR (Memo("STA")))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=1) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
DecodeAdr(ArgStr[1],Memo("LDA"));
|
||
|
AdrInt=Ord(Memo("STA"));
|
||
|
switch (AdrMode)
|
||
|
BEGIN
|
||
|
case ModInd:
|
||
|
CodeLen=1; BAsmCode[0]=0xe0+AdrInt+AdrVal;
|
||
|
break;
|
||
|
case ModDir:
|
||
|
if (IsShort(AdrVal))
|
||
|
BEGIN
|
||
|
CodeLen=1; BAsmCode[0]=0xac+(AdrInt << 4)+(AdrVal & 3);
|
||
|
END
|
||
|
else
|
||
|
BEGIN
|
||
|
CodeLen=2; BAsmCode[0]=0xf8+AdrInt; BAsmCode[1]=AdrVal;
|
||
|
END
|
||
|
break;
|
||
|
case ModImm:
|
||
|
CodeLen=2; BAsmCode[0]=0xe8+AdrInt; BAsmCode[1]=AdrVal;
|
||
|
break;
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
if ((Memo("LDXI")) OR (Memo("LDYI")))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=1) WrError(1110);
|
||
|
else if (*ArgStr[1]!='#') WrError(1350);
|
||
|
else
|
||
|
BEGIN
|
||
|
BAsmCode[2]=EvalIntExpression(ArgStr[1]+1,Int8,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
CodeLen=3; BAsmCode[0]=0xb0;
|
||
|
BAsmCode[1]=0x80+Ord(Memo("LDYI"));
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
if (Memo("MVI"))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=2) WrError(1110);
|
||
|
else if (*ArgStr[2]!='#') WrError(1350);
|
||
|
else
|
||
|
BEGIN
|
||
|
BAsmCode[1]=EvalIntExpression(ArgStr[1],Int8,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
ChkSpace(SegData);
|
||
|
BAsmCode[2]=EvalIntExpression(ArgStr[2]+1,Int8,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
BAsmCode[0]=0xb0; CodeLen=3;
|
||
|
END
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
/* Read/Modify/Write-Operationen */
|
||
|
|
||
|
if ((Memo("INC")) OR (Memo("DEC")))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=1) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
DecodeAdr(ArgStr[1],False);
|
||
|
AdrInt=Ord(Memo("DEC"));
|
||
|
switch (AdrMode)
|
||
|
BEGIN
|
||
|
case ModInd:
|
||
|
CodeLen=1; BAsmCode[0]=0xe6+AdrInt+AdrVal;
|
||
|
break;
|
||
|
case ModDir:
|
||
|
if (IsShort(AdrVal))
|
||
|
BEGIN
|
||
|
CodeLen=1; BAsmCode[0]=0xa8+(AdrInt << 4)+(AdrVal & 3);
|
||
|
END
|
||
|
else
|
||
|
BEGIN
|
||
|
CodeLen=2; BAsmCode[0]=0xfe + AdrInt; /* ANSI :-O */
|
||
|
BAsmCode[1]=AdrVal;
|
||
|
END
|
||
|
break;
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
/* Bitbefehle */
|
||
|
|
||
|
if ((Memo("BSET")) OR (Memo("BCLR")))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=2) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
AdrVal=EvalIntExpression(ArgStr[1],UInt3,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
BAsmCode[0]=0xd0+(Ord(Memo("BSET")) << 3)+AdrVal;
|
||
|
BAsmCode[1]=EvalIntExpression(ArgStr[2],Int8,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
CodeLen=2; ChkSpace(SegData);
|
||
|
END
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
if ((Memo("BRSET")) OR (Memo("BRCLR")))
|
||
|
BEGIN
|
||
|
if (ArgCnt!=3) WrError(1110);
|
||
|
else
|
||
|
BEGIN
|
||
|
AdrVal=EvalIntExpression(ArgStr[1],UInt3,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
BAsmCode[0]=0xc0+(Ord(Memo("BRSET")) << 3)+AdrVal;
|
||
|
BAsmCode[1]=EvalIntExpression(ArgStr[2],Int8,&OK);
|
||
|
if (OK)
|
||
|
BEGIN
|
||
|
ChkSpace(SegData);
|
||
|
AdrInt=EvalIntExpression(ArgStr[3],Int16,&OK)-(EProgCounter()+3);
|
||
|
if (OK)
|
||
|
if ((NOT SymbolQuestionable) AND ((AdrInt<-128) OR (AdrInt>127))) WrError(1370);
|
||
|
else
|
||
|
BEGIN
|
||
|
ChkSpace(SegCode); BAsmCode[2]=AdrInt & 0xff; CodeLen=3;
|
||
|
END
|
||
|
END
|
||
|
END
|
||
|
END
|
||
|
return;
|
||
|
END
|
||
|
|
||
|
WrXError(1200,OpPart);
|
||
|
END
|
||
|
|
||
|
static Boolean IsDef_6804(void)
|
||
|
BEGIN
|
||
|
return (Memo("SFR"));
|
||
|
END
|
||
|
|
||
|
static void SwitchFrom_6804(void)
|
||
|
BEGIN
|
||
|
DeinitFields();
|
||
|
END
|
||
|
|
||
|
static void SwitchTo_6804(void)
|
||
|
BEGIN
|
||
|
TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=False;
|
||
|
|
||
|
PCSymbol="PC"; HeaderID=0x64; NOPCode=0x20;
|
||
|
DivideChars=","; HasAttrs=False;
|
||
|
|
||
|
ValidSegs=(1<<SegCode)|(1<<SegData);
|
||
|
Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
|
||
|
SegLimits[SegCode] = 0xfff;
|
||
|
Grans[SegData]=1; ListGrans[SegData]=1; SegInits[SegData]=0;
|
||
|
SegLimits[SegData] = 0xff;
|
||
|
|
||
|
MakeCode=MakeCode_6804; IsDef=IsDef_6804;
|
||
|
SwitchFrom=SwitchFrom_6804; InitFields();
|
||
|
END
|
||
|
|
||
|
void code6804_init(void)
|
||
|
BEGIN
|
||
|
CPU6804=AddCPU("6804",SwitchTo_6804);
|
||
|
END
|