/* code6805.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator 68(HC)05/08 */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmpars.h"
#include "asmsub.h"
#include "asmitree.h"
#include "motpseudo.h"
#include "codevars.h"
#include "errmsg.h"
#include "code6805.h"
typedef struct
{
CPUVar MinCPU;
Byte Code;
} BaseOrder;
typedef struct
{
CPUVar MinCPU;
Byte Code;
Word Mask;
tSymbolSize Size;
} ALUOrder;
typedef struct
{
CPUVar MinCPU;
Byte Code;
Word Mask;
} RMWOrder;
enum
{
ModNone = -1,
ModImm = 0,
ModDir = 1,
ModExt = 2,
ModIx2 = 3,
ModIx1 = 4,
ModIx = 5,
ModSP2 = 6,
ModSP1 = 7,
ModIxP = 8
};
#define MModImm (1 << ModImm)
#define MModDir (1 << ModDir)
#define MModExt (1 << ModExt)
#define MModIx2 (1 << ModIx2)
#define MModIx1 (1 << ModIx1)
#define MModIx (1 << ModIx)
#define MModSP2 (1 << ModSP2)
#define MModSP1 (1 << ModSP1)
#define MModIxP (1 << ModIxP)
#define MMod05 (MModImm | MModDir | MModExt | MModIx2 | MModIx1 | MModIx)
#define MMod08 (MModSP2 | MModSP1 | MModIxP)
static ShortInt AdrMode;
static tSymbolSize OpSize;
static Byte AdrVals[2];
static IntType AdrIntType;
static CPUVar CPU6805, CPU68HC05, CPU68HC08, CPU68HCS08;
static BaseOrder *FixedOrders;
static BaseOrder *RelOrders;
static RMWOrder *RMWOrders;
static ALUOrder *ALUOrders;
/*--------------------------------------------------------------------------*/
/* address parser */
static unsigned ChkZero(char *s, Byte *pErg)
{
if (*s == '<')
{
*pErg = 2;
return 1;
}
else if (*s == '>')
{
*pErg = 1;
return 1;
}
else
{
*pErg = 0;
return 0;
}
}
static void DecodeAdr(Byte Start, Byte Stop, Word Mask)
{
Boolean OK;
tSymbolFlags Flags;
Word AdrWord, Mask08;
Byte ZeroMode;
unsigned Offset;
ShortInt tmode1, tmode2;
AdrMode = ModNone;
AdrCnt = 0;
Mask08 = Mask & MMod08;
if (MomCPU == CPU6805)
Mask &= MMod05;
if (Stop - Start == 1)
{
if (!as_strcasecmp(ArgStr[Stop].str.p_str, "X"))
{
tmode1 = ModIx1;
tmode2 = ModIx2;
}
else if (!as_strcasecmp(ArgStr[Stop].str.p_str,"SP"))
{
tmode1 = ModSP1;
tmode2 = ModSP2;
if (MomCPU < CPU68HC08)
{
WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
goto chk;
}
}
else
{
WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
goto chk;
}
Offset = ChkZero(ArgStr[Start].str.p_str, &ZeroMode);
AdrWord = EvalStrIntExpressionOffsWithFlags(&ArgStr[Start], Offset, (ZeroMode == 2) ? Int8 : Int16, &OK, &Flags);
if (OK)
{
if ((ZeroMode == 0) && (AdrWord == 0) && (Mask & MModIx) && (tmode1 == ModIx1))
AdrMode = ModIx;
else if (((Mask & (1 << tmode2)) == 0) || (ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrWord) == 0)))
{
if (mFirstPassUnknown(Flags))
AdrWord &= 0xff;
if (Hi(AdrWord) != 0) WrError(ErrNum_NoShortAddr);
else
{
AdrCnt = 1;
AdrVals[0] = Lo(AdrWord);
AdrMode = tmode1;
}
}
else
{
AdrVals[0] = Hi(AdrWord);
AdrVals[1] = Lo(AdrWord);
AdrCnt = 2;
AdrMode = tmode2;
}
}
}
else if (Stop == Start)
{
/* Postinkrement */
if (!as_strcasecmp(ArgStr[Start].str.p_str, "X+"))
{
AdrMode = ModIxP;
goto chk;
}
/* X-indirekt */
if (!as_strcasecmp(ArgStr[Start].str.p_str, "X"))
{
WrError(ErrNum_ConvIndX);
AdrMode = ModIx;
goto chk;
}
/* immediate */
if (*ArgStr[Start].str.p_str == '#')
{
switch (OpSize)
{
case eSymbolSizeUnknown:
WrError(ErrNum_UndefOpSizes);
break;
case eSymbolSize8Bit:
AdrVals[0] = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int8, &OK);
if (OK)
{
AdrCnt = 1;
AdrMode = ModImm;
}
break;
case eSymbolSize16Bit:
AdrWord = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int16, &OK);
if (OK)
{
AdrVals[0] = Hi(AdrWord);
AdrVals[1] = Lo(AdrWord);
AdrCnt = 2;
AdrMode = ModImm;
}
break;
default:
break;
}
goto chk;
}
/* absolut */
Offset = ChkZero(ArgStr[Start].str.p_str, &ZeroMode);
AdrWord = EvalStrIntExpressionOffsWithFlags(&ArgStr[Start], Offset, (ZeroMode == 2) ? UInt8 : AdrIntType, &OK, &Flags);
if (OK)
{
if (((Mask & MModExt) == 0) || (ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrWord) == 0)))
{
if (mFirstPassUnknown(Flags))
AdrWord &= 0xff;
if (Hi(AdrWord) != 0) WrError(ErrNum_NoShortAddr);
else
{
AdrCnt = 1;
AdrVals[0] = Lo(AdrWord);
AdrMode = ModDir;
}
}
else
{
AdrVals[0] = Hi(AdrWord);
AdrVals[1] = Lo(AdrWord);
AdrCnt = 2;
AdrMode = ModExt;
}
goto chk;
}
}
else
(void)ChkArgCnt(Start, Start + 1);
chk:
if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
{
if ((1 << AdrMode) & Mask08)
(void)ChkMinCPUExt(CPU68HC08, ErrNum_AddrModeNotSupported);
else
WrError(ErrNum_InvAddrMode);
AdrMode = ModNone;
AdrCnt = 0;
}
}
/*--------------------------------------------------------------------------*/
/* instruction parsers */
static void DecodeFixed(Word Index)
{
const BaseOrder *pOrder = FixedOrders + Index;
if (ChkArgCnt(0, 0)
&& ChkMinCPU(pOrder->MinCPU))
{
CodeLen = 1;
BAsmCode[0] = pOrder->Code;
}
}
static void DecodeMOV(Word Index)
{
UNUSED(Index);
if (ChkArgCnt(2, 2)
&& ChkMinCPU(CPU68HC08))
{
OpSize = eSymbolSize8Bit;
DecodeAdr(1, 1, MModImm | MModDir | MModIxP);
switch (AdrMode)
{
case ModImm:
BAsmCode[1] = AdrVals[0];
DecodeAdr(2, 2, MModDir);
if (AdrMode == ModDir)
{
BAsmCode[0] = 0x6e;
BAsmCode[2] = AdrVals[0];
CodeLen = 3;
}
break;
case ModDir:
BAsmCode[1] = AdrVals[0];
DecodeAdr(2, 2, MModDir | MModIxP);
switch (AdrMode)
{
case ModDir:
BAsmCode[0] = 0x4e;
BAsmCode[2] = AdrVals[0];
CodeLen = 3;
break;
case ModIxP:
BAsmCode[0] = 0x5e;
CodeLen = 2;
break;
}
break;
case ModIxP:
DecodeAdr(2, 2, MModDir);
if (AdrMode == ModDir)
{
BAsmCode[0] = 0x7e;
BAsmCode[1] = AdrVals[0];
CodeLen = 2;
}
break;
}
}
}
static void DecodeRel(Word Index)
{
BaseOrder *pOrder = RelOrders + Index;
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
if (ChkArgCnt(1, 1)
&& ChkMinCPU(pOrder->MinCPU))
{
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrIntType, &OK, &Flags) - (EProgCounter() + 2);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
CodeLen = 2;
BAsmCode[0] = pOrder->Code;
BAsmCode[1] = Lo(AdrInt);
}
}
}
}
static void DecodeCBEQx(Word Index)
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
if (ChkArgCnt(2, 2)
&& ChkMinCPU(CPU68HC08))
{
OpSize = eSymbolSize8Bit; DecodeAdr(1, 1, MModImm);
if (AdrMode == ModImm)
{
BAsmCode[1] = AdrVals[0];
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], AdrIntType, &OK, &Flags) - (EProgCounter() + 3);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
BAsmCode[0] = 0x41 | Index;
BAsmCode[2] = AdrInt & 0xff;
CodeLen = 3;
}
}
}
}
}
static void DecodeCBEQ(Word Index)
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
Byte Disp = 0;
UNUSED(Index);
if (!ChkMinCPU(CPU68HC08));
else if (ArgCnt == 2)
{
DecodeAdr(1, 1, MModDir | MModIxP);
switch (AdrMode)
{
case ModDir:
BAsmCode[0] = 0x31;
BAsmCode[1] = AdrVals[0];
Disp = 3;
break;
case ModIxP:
BAsmCode[0]=0x71;
Disp = 2;
break;
}
if (AdrMode != ModNone)
{
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], AdrIntType, &OK, &Flags) - (EProgCounter() + Disp);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
BAsmCode[Disp - 1] = AdrInt & 0xff;
CodeLen = Disp;
}
}
}
}
else if (ArgCnt == 3)
{
OK = True;
if (!as_strcasecmp(ArgStr[2].str.p_str, "X+")) Disp = 3;
else if (!as_strcasecmp(ArgStr[2].str.p_str,"SP"))
{
BAsmCode[0] = 0x9e;
Disp = 4;
}
else
{
WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
OK = False;
}
if (OK)
{
BAsmCode[Disp - 3] = 0x61;
BAsmCode[Disp - 2] = EvalStrIntExpression(&ArgStr[1], UInt8, &OK);
if (OK)
{
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], AdrIntType, &OK, &Flags) - (EProgCounter() + Disp);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
BAsmCode[Disp - 1] = AdrInt & 0xff;
CodeLen = Disp;
}
}
}
}
}
else
(void)ChkArgCnt(2, 3);
}
static void DecodeDBNZx(Word Index)
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU68HC08))
{
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrIntType, &OK, &Flags) - (EProgCounter() + 2);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
BAsmCode[0] = 0x4b | Index;
BAsmCode[1] = AdrInt & 0xff;
CodeLen = 2;
}
}
}
}
static void DecodeDBNZ(Word Index)
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
Byte Disp = 0;
UNUSED(Index);
if (ChkArgCnt(2, 3)
&& ChkMinCPU(CPU68HC08))
{
DecodeAdr(1, ArgCnt - 1, MModDir | MModIx | MModIx1 | MModSP1);
switch (AdrMode)
{
case ModDir:
BAsmCode[0] = 0x3b;
BAsmCode[1] = AdrVals[0];
Disp = 3;
break;
case ModIx:
BAsmCode[0] = 0x7b;
Disp = 2;
break;
case ModIx1:
BAsmCode[0] = 0x6b;
BAsmCode[1] = AdrVals[0];
Disp = 3;
break;
case ModSP1:
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0x6b;
BAsmCode[2] = AdrVals[0];
Disp = 4;
break;
}
if (AdrMode != ModNone)
{
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], AdrIntType, &OK, &Flags) - (EProgCounter() + Disp);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
BAsmCode[Disp - 1] = AdrInt & 0xff;
CodeLen = Disp;
}
}
}
}
}
static void DecodeALU(Word Index)
{
const ALUOrder *pOrder = ALUOrders + Index;
if (ChkMinCPU(pOrder->MinCPU))
{
OpSize = pOrder->Size;
DecodeAdr(1, ArgCnt, pOrder->Mask);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModImm:
BAsmCode[0] = 0xa0 + pOrder->Code;
CodeLen = 1; /* leave for CPHX */
break;
case ModDir:
BAsmCode[0] = 0xb0 + pOrder->Code;
CodeLen = 1;
break;
case ModExt:
BAsmCode[0] = 0xc0 | pOrder->Code;
CodeLen = 1;
break;
case ModIx:
BAsmCode[0] = 0xf0 | pOrder->Code;
CodeLen = 1;
break;
case ModIx1:
BAsmCode[0] = 0xe0 | pOrder->Code;
CodeLen = 1;
break;
case ModIx2:
BAsmCode[0] = 0xd0 | pOrder->Code;
CodeLen = 1;
break;
case ModSP1:
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xe0| pOrder->Code;
CodeLen = 2;
break;
case ModSP2:
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xd0 | pOrder->Code;
CodeLen = 2;
break;
}
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen += AdrCnt;
}
}
}
static void DecodeCPHX(Word Index)
{
UNUSED(Index);
if (ChkMinCPU(CPU68HC08))
{
Word Mask = MModImm | MModDir;
if (MomCPU >= CPU68HCS08)
Mask |= MModExt| MModSP1;
OpSize = eSymbolSize16Bit;
DecodeAdr(1, ArgCnt, Mask);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModImm:
BAsmCode[0] = 0x65;
CodeLen = 1;
break;
case ModDir:
BAsmCode[0] = 0x75;
CodeLen = 1;
break;
case ModExt:
BAsmCode[0] = 0x3e;
CodeLen = 1;
break;
case ModSP1:
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xf3;
CodeLen = 2;
break;
}
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen += AdrCnt;
}
}
}
static void DecodeSTHX(Word Index)
{
UNUSED(Index);
if (ChkMinCPU(CPU68HC08))
{
Word Mask = MModDir;
if (MomCPU >= CPU68HCS08)
Mask |= MModExt| MModSP1;
DecodeAdr(1, ArgCnt, Mask);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModDir:
BAsmCode[0] = 0x35;
CodeLen = 1;
break;
case ModExt:
BAsmCode[0] = 0x96;
CodeLen = 1;
break;
case ModSP1:
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xff;
CodeLen = 2;
break;
}
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen += AdrCnt;
}
}
}
static void DecodeLDHX(Word Index)
{
UNUSED(Index);
if (ChkMinCPU(CPU68HC08))
{
Word Mask = MModImm | MModDir;
if (MomCPU >= CPU68HCS08)
Mask |= MModExt| MModIx | MModIx1 | MModIx2 | MModSP1;
OpSize = eSymbolSize16Bit;
DecodeAdr(1, ArgCnt, Mask);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModImm:
BAsmCode[0] = 0x45;
CodeLen = 1;
break;
case ModDir:
BAsmCode[0] = 0x55;
CodeLen = 1;
break;
case ModExt:
BAsmCode[0] = 0x32;
CodeLen = 1;
break;
case ModIx :
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xae;
CodeLen = 2;
break;
case ModIx1 :
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xce;
CodeLen = 2;
break;
case ModIx2 :
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xbe;
CodeLen = 2;
break;
case ModSP1:
BAsmCode[0] = 0x9e;
BAsmCode[1] = 0xfe;
CodeLen = 2;
break;
}
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen += AdrCnt;
}
}
}
static void DecodeAIx(Word Index)
{
Boolean OK;
if (!ChkArgCnt(1, 1));
else if (!ChkMinCPU(CPU68HC08));
else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
else
{
BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, SInt8, &OK);
if (OK)
{
BAsmCode[0] = 0xa7 | Index;
CodeLen = 2;
}
}
}
static void DecodeRMW(Word Index)
{
const RMWOrder *pOrder = RMWOrders + Index;
if (ChkMinCPU(pOrder->MinCPU))
{
DecodeAdr(1, ArgCnt, pOrder->Mask);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModDir :
BAsmCode[0] = 0x30 | pOrder->Code;
CodeLen = 1;
break;
case ModIx :
BAsmCode[0] = 0x70 | pOrder->Code;
CodeLen = 1;
break;
case ModIx1 :
BAsmCode[0] = 0x60 | pOrder->Code;
CodeLen = 1;
break;
case ModSP1 :
BAsmCode[0] = 0x9e; BAsmCode[1] = 0x60 | pOrder->Code;
CodeLen = 2;
break;
}
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen += AdrCnt;
}
}
}
static void decode_bset_bclr_core(Word code, int arg_index)
{
Boolean ok;
BAsmCode[1] = EvalStrIntExpression(&ArgStr[arg_index], Int8, &ok);
if (ok)
{
BAsmCode[0] = 0x10 | code;
CodeLen = 2;
}
}
static void decode_bset_bclr_1(Word code)
{
if (ChkArgCnt(1, 1))
decode_bset_bclr_core(code, 1);
}
static void decode_bset_bclr_2(Word code)
{
if (ChkArgCnt(2, 2))
{
Boolean ok;
code |= EvalStrIntExpression(&ArgStr[1], UInt3, &ok) << 1;
if (ok)
decode_bset_bclr_core(code, 2);
}
}
static void decode_brset_brclr_core(Word code, int arg_index)
{
Boolean ok;
BAsmCode[1] = EvalStrIntExpression(&ArgStr[arg_index], Int8, &ok);
if (ok)
{
tSymbolFlags flags;
LongInt address;
address = EvalStrIntExpressionWithFlags(&ArgStr[arg_index + 1], AdrIntType, &ok, &flags) - (EProgCounter() + 3);
if (ok)
{
if (!mSymbolQuestionable(flags) && ((address < -128) || (address > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
CodeLen = 3;
BAsmCode[0] = code;
BAsmCode[2] = Lo(address);
}
}
}
}
static void decode_brset_brclr_2(Word code)
{
if (ChkArgCnt(2, 2))
decode_brset_brclr_core(code, 1);
}
static void decode_brset_brclr_3(Word code)
{
if (ChkArgCnt(3, 3))
{
Boolean ok;
code |= EvalStrIntExpression(&ArgStr[1], UInt3, &ok) << 1;
if (ok)
decode_brset_brclr_core(code, 2);
}
}
/*--------------------------------------------------------------------------*/
/* dynamic code table handling */
static void AddFixed(const char *NName, CPUVar NMin, Byte NCode)
{
order_array_rsv_end(FixedOrders, BaseOrder);
FixedOrders[InstrZ].MinCPU = NMin;
FixedOrders[InstrZ].Code = NCode;
AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
}
static void AddRel(const char *NName, CPUVar NMin, Byte NCode)
{
order_array_rsv_end(RelOrders, BaseOrder);
RelOrders[InstrZ].MinCPU = NMin;
RelOrders[InstrZ].Code = NCode;
AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
}
static void AddALU(const char *NName, CPUVar NMin, Byte NCode, Word NMask, tSymbolSize NSize)
{
order_array_rsv_end(ALUOrders, ALUOrder);
ALUOrders[InstrZ].MinCPU = NMin;
ALUOrders[InstrZ].Code = NCode;
ALUOrders[InstrZ].Mask = NMask;
ALUOrders[InstrZ].Size = NSize;
AddInstTable(InstTable, NName, InstrZ++, DecodeALU);
}
static void AddRMW(const char *NName, CPUVar NMin, Byte NCode ,Word NMask)
{
order_array_rsv_end(RMWOrders, RMWOrder);
RMWOrders[InstrZ].MinCPU = NMin;
RMWOrders[InstrZ].Code = NCode;
RMWOrders[InstrZ].Mask = NMask;
AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
}
static void add_bset_bclr(const char *p_name, Word code)
{
char name[10];
unsigned bit;
AddInstTable(InstTable, p_name, code, decode_bset_bclr_2);
for (bit = 0; bit < 8; bit++)
{
as_snprintf(name, sizeof(name), "%s%c", p_name, bit + '0');
AddInstTable(InstTable, name, code | (bit << 1), decode_bset_bclr_1);
}
}
static void add_brset_brclr(const char *p_name, Word code)
{
char name[10];
unsigned bit;
AddInstTable(InstTable, p_name, code, decode_brset_brclr_3);
for (bit = 0; bit < 8; bit++)
{
as_snprintf(name, sizeof(name), "%s%c", p_name, bit + '0');
AddInstTable(InstTable, name, code | (bit << 1), decode_brset_brclr_2);
}
}
static void InitFields(void)
{
InstTable = CreateInstTable(247);
SetDynamicInstTable(InstTable);
InstrZ = 0;
AddFixed("RTI" , CPU6805 , 0x80); AddFixed("RTS" , CPU6805 , 0x81);
AddFixed("SWI" , CPU6805 , 0x83); AddFixed("TAX" , CPU6805 , 0x97);
AddFixed("CLC" , CPU6805 , 0x98); AddFixed("SEC" , CPU6805 , 0x99);
AddFixed("CLI" , CPU6805 , 0x9a); AddFixed("SEI" , CPU6805 , 0x9b);
AddFixed("RSP" , CPU6805 , 0x9c); AddFixed("NOP" , CPU6805 , 0x9d);
AddFixed("TXA" , CPU6805 , 0x9f); AddFixed("NEGA", CPU6805 , 0x40);
AddFixed("NEGX", CPU6805 , 0x50); AddFixed("COMA", CPU6805 , 0x43);
AddFixed("COMX", CPU6805 , 0x53); AddFixed("LSRA", CPU6805 , 0x44);
AddFixed("LSRX", CPU6805 , 0x54); AddFixed("RORA", CPU6805 , 0x46);
AddFixed("RORX", CPU6805 , 0x56); AddFixed("ASRA", CPU6805 , 0x47);
AddFixed("ASRX", CPU6805 , 0x57); AddFixed("ASLA", CPU6805 , 0x48);
AddFixed("ASLX", CPU6805 , 0x58); AddFixed("LSLA", CPU6805 , 0x48);
AddFixed("LSLX", CPU6805 , 0x58); AddFixed("ROLA", CPU6805 , 0x49);
AddFixed("ROLX", CPU6805 , 0x59); AddFixed("DECA", CPU6805 , 0x4a);
AddFixed("DECX", CPU6805 , 0x5a); AddFixed("INCA", CPU6805 , 0x4c);
AddFixed("INCX", CPU6805 , 0x5c); AddFixed("TSTA", CPU6805 , 0x4d);
AddFixed("TSTX", CPU6805 , 0x5d); AddFixed("CLRA", CPU6805 , 0x4f);
AddFixed("CLRX", CPU6805 , 0x5f); AddFixed("CLRH", CPU68HC08 , 0x8c);
AddFixed("DAA" , CPU68HC08 , 0x72); AddFixed("DIV" , CPU68HC08 , 0x52);
AddFixed("MUL" , CPU68HC05 , 0x42); AddFixed("NSA" , CPU68HC08 , 0x62);
AddFixed("PSHA", CPU68HC08 , 0x87); AddFixed("PSHH", CPU68HC08 , 0x8b);
AddFixed("PSHX", CPU68HC08 , 0x89); AddFixed("PULA", CPU68HC08 , 0x86);
AddFixed("PULH", CPU68HC08 , 0x8a); AddFixed("PULX", CPU68HC08 , 0x88);
AddFixed("STOP", CPU68HC05 , 0x8e); AddFixed("TAP" , CPU68HC08 , 0x84);
AddFixed("TPA" , CPU68HC08 , 0x85); AddFixed("TSX" , CPU68HC08 , 0x95);
AddFixed("TXS" , CPU68HC08 , 0x94); AddFixed("WAIT", CPU68HC05 , 0x8f);
AddFixed("INX" , CPU6805 , 0x5c); AddFixed("BGND", CPU68HCS08, 0x82);
AddInstTable(InstTable, "MOV", 0, DecodeMOV);
InstrZ = 0;
AddRel("BRA" , CPU6805 , 0x20); AddRel("BRN" , CPU6805 , 0x21);
AddRel("BHI" , CPU6805 , 0x22); AddRel("BLS" , CPU6805 , 0x23);
AddRel("BCC" , CPU6805 , 0x24); AddRel("BCS" , CPU6805 , 0x25);
AddRel("BNE" , CPU6805 , 0x26); AddRel("BEQ" , CPU6805 , 0x27);
AddRel("BHCC", CPU6805 , 0x28); AddRel("BHCS", CPU6805 , 0x29);
AddRel("BPL" , CPU6805 , 0x2a); AddRel("BMI" , CPU6805 , 0x2b);
AddRel("BMC" , CPU6805 , 0x2c); AddRel("BMS" , CPU6805 , 0x2d);
AddRel("BIL" , CPU6805 , 0x2e); AddRel("BIH" , CPU6805 , 0x2f);
AddRel("BSR" , CPU6805 , 0xad); AddRel("BGE" , CPU68HC08 , 0x90);
AddRel("BGT" , CPU68HC08 , 0x92); AddRel("BHS" , CPU6805 , 0x24);
AddRel("BLE" , CPU68HC08 , 0x93); AddRel("BLO" , CPU6805 , 0x25);
AddRel("BLT" , CPU68HC08 , 0x91);
AddInstTable(InstTable, "CBEQA", 0x00, DecodeCBEQx);
AddInstTable(InstTable, "CBEQX", 0x10, DecodeCBEQx);
AddInstTable(InstTable, "CBEQ", 0, DecodeCBEQ);
AddInstTable(InstTable, "DBNZA", 0x00, DecodeDBNZx);
AddInstTable(InstTable, "DBNZX", 0x10, DecodeDBNZx);
AddInstTable(InstTable, "DBNZ", 0, DecodeDBNZ);
InstrZ = 0;
AddALU("SUB" , CPU6805 , 0x00, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("CMP" , CPU6805 , 0x01, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("SBC" , CPU6805 , 0x02, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("CPX" , CPU6805 , 0x03, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("AND" , CPU6805 , 0x04, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("BIT" , CPU6805 , 0x05, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("LDA" , CPU6805 , 0x06, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("STA" , CPU6805 , 0x07, MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("EOR" , CPU6805 , 0x08, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("ADC" , CPU6805 , 0x09, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("ORA" , CPU6805 , 0x0a, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("ADD" , CPU6805 , 0x0b, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("JMP" , CPU6805 , 0x0c, MModDir | MModExt | MModIx | MModIx1 | MModIx2 , eSymbolSizeUnknown);
AddALU("JSR" , CPU6805 , 0x0d, MModDir | MModExt | MModIx | MModIx1 | MModIx2 , eSymbolSizeUnknown);
AddALU("LDX" , CPU6805 , 0x0e, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddALU("STX" , CPU6805 , 0x0f, MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
AddInstTable(InstTable, "CPHX", 0, DecodeCPHX);
AddInstTable(InstTable, "LDHX", 0, DecodeLDHX);
AddInstTable(InstTable, "STHX", 0, DecodeSTHX);
AddInstTable(InstTable, "AIS", 0x00, DecodeAIx);
AddInstTable(InstTable, "AIX", 0x08, DecodeAIx);
InstrZ = 0;
AddRMW("NEG", CPU6805, 0x00, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("COM", CPU6805, 0x03, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("LSR", CPU6805, 0x04, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("ROR", CPU6805, 0x06, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("ASR", CPU6805, 0x07, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("ASL", CPU6805, 0x08, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("LSL", CPU6805, 0x08, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("ROL", CPU6805, 0x09, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("DEC", CPU6805, 0x0a, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("INC", CPU6805, 0x0c, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("TST", CPU6805, 0x0d, MModDir | MModIx | MModIx1 | MModSP1 );
AddRMW("CLR", CPU6805, 0x0f, MModDir | MModIx | MModIx1 | MModSP1 );
add_bset_bclr("BCLR", 0x01);
add_bset_bclr("BSET", 0x00);
add_brset_brclr("BRCLR", 0x01);
add_brset_brclr("BRSET", 0x00);
init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw);
}
static void DeinitFields(void)
{
DestroyInstTable(InstTable);
order_array_free(FixedOrders);
order_array_free(RelOrders);
order_array_free(ALUOrders);
order_array_free(RMWOrders);
}
/*--------------------------------------------------------------------------*/
/* Main Functions */
static Boolean DecodeAttrPart_6805(void)
{
if (strlen(AttrPart.
str.
p_str) > 1)
{
WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
return False;
}
/* deduce operand size - no size is zero-length string -> '\0' */
return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
}
static void MakeCode_6805(void)
{
CodeLen = 0;
DontPrint = False;
OpSize = AttrPartOpSize[0];
/* zu ignorierendes */
if (Memo(""))
return;
/* Pseudoanweisungen */
if (DecodeMoto16Pseudo(OpSize, True))
return;
if (!LookupInstTable(InstTable, OpPart.str.p_str))
WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}
static Boolean IsDef_6805(void)
{
return False;
}
static void SwitchFrom_6805(void)
{
DeinitFields();
}
static void SwitchTo_6805(void)
{
TurnWords = False;
SetIntConstMode(eIntConstModeMoto);
PCSymbol = "*";
HeaderID = 0x62;
NOPCode = 0x9d;
DivideChars = ",";
HasAttrs = True;
AttrChars = ".";
ValidSegs = (1 << SegCode);
Grans[SegCode] = 1;
ListGrans[SegCode] = 1;
SegInits[SegCode] = 0;
SegLimits[SegCode] = (MomCPU >= CPU68HC08) ? 0xffff : 0x1fff;
AdrIntType = (MomCPU >= CPU68HC08) ? UInt16 : UInt13;
DecodeAttrPart = DecodeAttrPart_6805;
MakeCode = MakeCode_6805;
IsDef = IsDef_6805;
SwitchFrom = SwitchFrom_6805;
InitFields();
AddMoto16PseudoONOFF(False);
}
void code6805_init(void)
{
CPU6805 = AddCPU("6805", SwitchTo_6805);
CPU68HC05 = AddCPU("68HC05", SwitchTo_6805);
CPU68HC08 = AddCPU("68HC08", SwitchTo_6805);
CPU68HCS08 = AddCPU("68HCS08", SwitchTo_6805);
}