/* code68rs08.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator 68RS08 */
/* */
/*****************************************************************************/
#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 "code68rs08.h"
typedef struct
{
char *Name;
CPUVar MinCPU;
Byte Code;
} BaseOrder;
typedef struct
{
char *Name;
CPUVar MinCPU;
Byte Code;
Word Mask;
} ALUOrder;
typedef struct
{
char *Name;
CPUVar MinCPU;
Byte Code;
Byte DCode;
Word Mask;
} RMWOrder;
enum
{
ModNone = -1,
ModImm = 0,
ModDir = 1,
ModExt = 2,
ModSrt = 3,
ModTny = 4,
ModIX = 5,
ModX = 6
};
#define MModImm (1 << ModImm)
#define MModDir (1 << ModDir)
#define MModExt (1 << ModExt)
#define MModSrt (1 << ModSrt)
#define MModTny (1 << ModTny)
#define MModIX (1 << ModIX)
#define MModX (1 << ModX)
static ShortInt AdrMode;
static tSymbolSize OpSize;
static Byte AdrVals[2];
static IntType AdrIntType;
static CPUVar CPU68RS08;
static BaseOrder *FixedOrders;
static BaseOrder *RelOrders;
static RMWOrder *RMWOrders;
static ALUOrder *ALUOrders;
/*--------------------------------------------------------------------------*/
/* address parser */
static unsigned ChkZero(char *s, Byte *pErg)
{
if (*s == '<') /* short / tiny */
{
*pErg = 2;
return 1;
}
else if (*s == '>') /* direct */
{
*pErg = 1;
return 1;
}
else /* let the assembler make the choice */
{
*pErg = 0;
return 0;
}
}
static void DecodeAdr(Byte Start, Byte Stop, Word Mask)
{
Boolean OK;
tSymbolFlags Flags;
Word AdrWord;
Byte ZeroMode;
unsigned Offset;
AdrMode = ModNone;
AdrCnt = 0;
if (Stop - Start == 1)
{
if (*(ArgStr[Start].str.p_str) == 0 && (!as_strcasecmp(ArgStr[Stop].str.p_str, "X")))
{
AdrMode = ModIX;
}
else
{
WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
goto chk;
}
}
else if (Stop == Start)
{
/* X-indirekt */
if (!as_strcasecmp(ArgStr[Start].str.p_str, "X"))
{
AdrMode = ModX;
goto chk;
}
if (!as_strcasecmp(ArgStr[Start].str.p_str, "D[X]"))
{
AdrMode = ModIX;
goto chk;
}
/* immediate */
if (*ArgStr[Start].str.p_str == '#')
{
AdrVals[0] = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int8, &OK);
if (OK)
{
AdrCnt = 1;
AdrMode = ModImm;
}
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;
if (ZeroMode == 0)
{
if ((Mask & MModTny) && (AdrVals[0] <= 0x0f))
AdrMode = ModTny;
if ((Mask & MModSrt) && (AdrVals[0] <= 0x1f))
AdrMode = ModSrt;
}
if (ZeroMode == 2)
{
if (Mask & MModTny)
{
if (AdrVals[0] <= 0x0f)
AdrMode = ModTny;
else
WrError(ErrNum_ConfOpSizes);
return;
}
else if (Mask & MModSrt)
{
if (AdrVals[0] <= 0x1f)
AdrMode = ModSrt;
else
WrError(ErrNum_ConfOpSizes);
return;
}
else
{
AdrMode = ModNone;
WrError(ErrNum_NoShortAddr);
return;
}
}
}
}
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))))
{
WrError(ErrNum_InvAddrMode);
AdrMode = ModNone;
AdrCnt = 0;
}
}
/*--------------------------------------------------------------------------*/
/* instruction parsers */
static void DecodeFixed(Word Index)
{
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))
{
OpSize = eSymbolSize8Bit;
DecodeAdr(1, 1, MModImm | MModDir | MModIX);
switch (AdrMode)
{
case ModImm:
BAsmCode[1] = AdrVals[0];
DecodeAdr(2, 2, MModDir | MModIX);
switch (AdrMode)
{
case ModDir:
BAsmCode[0] = 0x3e;
BAsmCode[2] = AdrVals[0];
CodeLen = 3;
break;
case ModIX:
BAsmCode[0] = 0x3e;
BAsmCode[2] = 0x0e;
CodeLen = 3;
break;
}
break;
case ModDir:
BAsmCode[1] = AdrVals[0];
DecodeAdr(2, 2, MModDir | MModIX);
switch (AdrMode)
{
case ModDir:
BAsmCode[0] = 0x4e;
BAsmCode[2] = AdrVals[0];
CodeLen = 3;
break;
case ModIX:
BAsmCode[0] = 0x4e;
BAsmCode[2] = 0x0e;
CodeLen = 3;
break;
}
break;
case ModIX:
DecodeAdr(2, 2, MModDir);
if (AdrMode == ModDir)
{
BAsmCode[0] = 0x4e;
BAsmCode[1] = 0x0e;
BAsmCode[2] = AdrVals[0];
CodeLen = 3;
}
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);
if (BAsmCode[0] == 0x00) /* BRN pseudo op */
{
BAsmCode[0] = 0x30;
BAsmCode[1] = 0x00;
}
}
}
}
}
static void DecodeCBEQx(Word Index)
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
UNUSED(Index);
if (ChkArgCnt(2, 2))
{
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;
BAsmCode[2] = AdrInt & 0xff;
CodeLen = 3;
}
}
}
}
}
static void DecodeCBEQ(Word Index)
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
UNUSED(Index);
if (ArgCnt == 2)
{
DecodeAdr(1, 1, MModDir | MModX);
switch (AdrMode)
{
case ModDir:
BAsmCode[1] = AdrVals[0];
break;
case ModX:
BAsmCode[1] = 0x0f;
break;
}
if (AdrMode != ModNone)
{
BAsmCode[0] = 0x31;
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], AdrIntType, &OK, &Flags) - (EProgCounter() + 3);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
BAsmCode[2] = AdrInt & 0xff;
CodeLen = 3;
}
}
}
}
else if (ArgCnt == 3)
{
if ((*(ArgStr[1].str.p_str) != 0) || (as_strcasecmp(ArgStr[2].str.p_str, "X"))) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
else
{
BAsmCode[0] = 0x31; BAsmCode[1] = 0x0e;
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], AdrIntType, &OK, &Flags) - (EProgCounter() + 3);
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
BAsmCode[2] = AdrInt & 0xff;
CodeLen = 3;
}
}
}
}
else
(void)ChkArgCnt(2, 3);
}
static void DecodeDBNZx(Word Index)
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrInt;
if (ChkArgCnt(1, 1))
{
AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrIntType, &OK, &Flags) - (EProgCounter() + ((Index == 0) ? 3 : 2));
if (OK)
{
if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else if (Index == 0)
{
BAsmCode[0] = 0x3b;
BAsmCode[1] = 0x0f;
BAsmCode[2] = AdrInt & 0xff;
CodeLen = 3;
}
else
{
BAsmCode[0] = 0x4b;
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))
{
DecodeAdr(1, ArgCnt - 1, MModDir | MModIX);
switch (AdrMode)
{
case ModDir:
BAsmCode[0] = 0x3b;
BAsmCode[1] = AdrVals[0];
Disp = 3;
break;
case ModIX:
BAsmCode[0] = 0x3b;
BAsmCode[1] = 0x0e;
Disp = 3;
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 DecodeLDX(Word Index)
{
BAsmCode[0] = 0x4e;
if (ChkArgCnt(1, 2))
{
DecodeAdr(1, ArgCnt, (Index == 0) ? (MModImm | MModDir | MModIX) : MModDir);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModImm:
BAsmCode[0] = 0x3e;
BAsmCode[1] = AdrVals[0];
BAsmCode[2] = 0x0f;
break;
case ModDir:
if (Index == 0)
{
BAsmCode[1] = AdrVals[0];
BAsmCode[2] = 0x0f;
}
else
{
BAsmCode[1] = 0x0f;
BAsmCode[2] = AdrVals[0];
}
break;
case ModIX:
BAsmCode[1] = 0x0e;
BAsmCode[2] = 0x0e;
break;
}
CodeLen = 3;
}
}
}
static void DecodeTST(Word Index)
{
BAsmCode[0] = 0x4e;
if (Index == 1)
{
if (ChkArgCnt(0, 0))
{
BAsmCode[1] = 0x0f;
BAsmCode[2] = 0x0f;
CodeLen = 3;
}
}
else if (Index == 2)
{
BAsmCode[0] = 0xaa;
BAsmCode[1] = 0x00;
CodeLen = 2;
}
else
{
DecodeAdr(1, ArgCnt, MModDir | MModX | MModIX);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModDir:
BAsmCode[1] = AdrVals[0];
BAsmCode[2] = AdrVals[0];
break;
case ModIX:
BAsmCode[1] = 0x0e;
BAsmCode[2] = 0x0e;
break;
case ModX:
BAsmCode[1] = 0x0f;
BAsmCode[2] = 0x0f;
break;
}
CodeLen = 3;
}
}
}
static void DecodeALU(Word Index)
{
ALUOrder *pOrder = ALUOrders + Index;
if (ChkMinCPU(pOrder->MinCPU))
{
DecodeAdr(1, ArgCnt, pOrder->Mask);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModImm:
BAsmCode[0] = 0xa0 | pOrder->Code;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen = 1 + AdrCnt;
break;
case ModDir:
BAsmCode[0] = 0xb0 | pOrder->Code;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen = 1 + AdrCnt;
break;
case ModIX:
BAsmCode[0] = 0xb0 | pOrder->Code;
BAsmCode[1] = 0x0e;
CodeLen = 2;
break;
case ModX:
BAsmCode[0] = 0xb0 | pOrder->Code;
BAsmCode[1] = 0x0f;
CodeLen = 2;
break;
case ModExt:
BAsmCode[0] = pOrder->Code;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen = 1 + AdrCnt;
}
}
}
}
static void DecodeRMW(Word Index)
{
RMWOrder *pOrder = RMWOrders + Index;
if (ChkMinCPU(pOrder->MinCPU))
{
DecodeAdr(1, ArgCnt, pOrder->Mask);
if (AdrMode != ModNone)
{
switch (AdrMode)
{
case ModImm :
BAsmCode[0] = 0xa0 | pOrder->Code;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen = 1 + AdrCnt;
break;
case ModDir :
BAsmCode[0] = 0xb0 ^ pOrder->Code;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen = 1+ AdrCnt;
break;
case ModTny :
BAsmCode[0] = AdrVals[0] | pOrder->DCode;
CodeLen = 1;
break;
case ModSrt :
BAsmCode[0] = AdrVals[0] | pOrder->DCode;
CodeLen = 1;
break;
case ModIX :
BAsmCode[0] = 0x0e | pOrder->DCode;
CodeLen = 1;
break;
case ModX :
BAsmCode[0] = 0x0f | pOrder->DCode;
CodeLen = 1;
break;
}
}
}
}
static void decode_bset_bclr_core(Word code, int arg_index)
{
Boolean ok = True;
if (!as_strcasecmp(ArgStr[arg_index].str.p_str, "D[X]")) BAsmCode[1] = 0x0e;
else if (!as_strcasecmp(ArgStr[arg_index].str.p_str, "X")) BAsmCode[1] = 0x0f;
else BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &ok);
if (ok)
{
CodeLen = 2;
BAsmCode[0] = 0x10 | code;
}
}
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 = True;
if (!as_strcasecmp(ArgStr[2].str.p_str, "D[X]"))
BAsmCode[1] = 0x0e;
else if (!as_strcasecmp(ArgStr[2].str.p_str, "X"))
BAsmCode[1] = 0x0f;
else
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)
{
order_array_rsv_end(ALUOrders, ALUOrder);
ALUOrders[InstrZ].MinCPU = NMin;
ALUOrders[InstrZ].Code = NCode;
ALUOrders[InstrZ].Mask = NMask;
AddInstTable(InstTable, NName, InstrZ++, DecodeALU);
}
static void AddRMW(const char *NName, CPUVar NMin, Byte NCode, Byte DCode, Word NMask)
{
order_array_rsv_end(RMWOrders, RMWOrder);
RMWOrders[InstrZ].MinCPU = NMin;
RMWOrders[InstrZ].Code = NCode;
RMWOrders[InstrZ].DCode = DCode;
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(177);
SetDynamicInstTable(InstTable);
InstrZ = 0;
AddFixed("SHA" , CPU68RS08, 0x45); AddFixed("SLA" , CPU68RS08, 0x42);
AddFixed("RTS" , CPU68RS08, 0xbe); AddFixed("TAX" , CPU68RS08, 0xef);
AddFixed("CLC" , CPU68RS08, 0x38); AddFixed("SEC" , CPU68RS08, 0x39);
AddFixed("NOP" , CPU68RS08, 0xac); AddFixed("TXA" , CPU68RS08, 0xcf);
AddFixed("COMA", CPU68RS08, 0x43); AddFixed("LSRA", CPU68RS08, 0x44);
AddFixed("RORA", CPU68RS08, 0x46); AddFixed("ASLA", CPU68RS08, 0x48);
AddFixed("LSLA", CPU68RS08, 0x48); AddFixed("ROLA", CPU68RS08, 0x49);
AddFixed("DECA", CPU68RS08, 0x4a); AddFixed("DECX", CPU68RS08, 0x5f);
AddFixed("INCA", CPU68RS08, 0x4c); AddFixed("INCX", CPU68RS08, 0x2f);
AddFixed("CLRA", CPU68RS08, 0x4f); AddFixed("CLRX", CPU68RS08, 0x8f);
AddFixed("STOP", CPU68RS08, 0xae); AddFixed("WAIT", CPU68RS08, 0xaf);
AddFixed("BGND", CPU68RS08, 0xbf);
InstrZ = 0;
AddRel("BRA" , CPU68RS08, 0x30); AddRel("BRN" , CPU68RS08, 0x00);
AddRel("BCC" , CPU68RS08, 0x34); AddRel("BCS" , CPU68RS08, 0x35);
AddRel("BHS" , CPU68RS08, 0x34); AddRel("BLO" , CPU68RS08, 0x35);
AddRel("BNE" , CPU68RS08, 0x36); AddRel("BEQ" , CPU68RS08, 0x37);
AddRel("BSR" , CPU68RS08, 0xad);
InstrZ = 0;
AddALU("ADC" , CPU68RS08, 0x09, MModImm | MModDir | MModIX | MModX);
AddALU("AND" , CPU68RS08, 0x04, MModImm | MModDir | MModIX | MModX);
AddALU("CMP" , CPU68RS08, 0x01, MModImm | MModDir | MModIX | MModX);
AddALU("EOR" , CPU68RS08, 0x08, MModImm | MModDir | MModIX | MModX);
AddALU("ORA" , CPU68RS08, 0x0a, MModImm | MModDir | MModIX | MModX);
AddALU("SBC" , CPU68RS08, 0x02, MModImm | MModDir | MModIX | MModX);
AddALU("JMP" , CPU68RS08, 0xbc, MModExt);
AddALU("JSR" , CPU68RS08, 0xbd, MModExt);
InstrZ = 0;
AddRMW("ADD" , CPU68RS08, 0x0b, 0x60, MModImm | MModDir | MModTny | MModIX | MModX );
AddRMW("SUB" , CPU68RS08, 0x00, 0x70, MModImm | MModDir | MModTny | MModIX | MModX );
AddRMW("DEC" , CPU68RS08, 0x8a, 0x50, MModDir | MModTny | MModIX | MModX );
AddRMW("INC" , CPU68RS08, 0x8c, 0x20, MModDir | MModTny | MModIX | MModX );
AddRMW("CLR" , CPU68RS08, 0x8f, 0x80, MModDir | MModSrt | MModIX | MModX );
AddRMW("LDA" , CPU68RS08, 0x06, 0xc0, MModImm | MModDir | MModSrt | MModIX | MModX );
AddRMW("STA" , CPU68RS08, 0x07, 0xe0, MModDir | MModSrt | MModIX | MModX );
AddInstTable(InstTable, "CBEQA", 1, DecodeCBEQx);
AddInstTable(InstTable, "CBEQ" , 0, DecodeCBEQ);
AddInstTable(InstTable, "DBNZA", 1, DecodeDBNZx);
AddInstTable(InstTable, "DBNZX", 0, DecodeDBNZx);
AddInstTable(InstTable, "DBNZ" , 0, DecodeDBNZ);
AddInstTable(InstTable, "MOV" , 0, DecodeMOV);
AddInstTable(InstTable, "TST" , 0, DecodeTST);
AddInstTable(InstTable, "TSTX" , 1, DecodeTST);
AddInstTable(InstTable, "TSTA" , 2, DecodeTST);
AddInstTable(InstTable, "LDX" , 0, DecodeLDX);
AddInstTable(InstTable, "STX" , 1, DecodeLDX);
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_68rs08(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_68rs08(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_68rs08(void)
{
return False;
}
static void SwitchFrom_68rs08(void)
{
DeinitFields();
}
static void SwitchTo_68rs08(void)
{
TurnWords = False;
SetIntConstMode(eIntConstModeMoto);
PCSymbol = "*";
HeaderID = 0x5e;
NOPCode = 0xac;
DivideChars = ",";
HasAttrs = True;
AttrChars = ".";
ValidSegs = (1 << SegCode);
Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
SegLimits[SegCode] = 0x3fff;
AdrIntType = UInt14;
DecodeAttrPart = DecodeAttrPart_68rs08;
MakeCode = MakeCode_68rs08;
IsDef = IsDef_68rs08;
SwitchFrom = SwitchFrom_68rs08;
InitFields();
AddMoto16PseudoONOFF(False);
}
void code68rs08_init(void)
{
CPU68RS08 = AddCPU("68RS08", SwitchTo_68rs08);
AddCopyright("68RS08-Generator (C) 2006 Andreas Bolsch");
}