/* code6809.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Code Generator 6809/6309 */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "nls.h"
#include "strutil.h"
#include "bpemu.h"
#include "asmdef.h"
#include "asmpars.h"
#include "asmsub.h"
#include "asmallg.h"
#include "asmitree.h"
#include "codepseudo.h"
#include "motpseudo.h"
#include "codevars.h"
#include "errmsg.h"
#include "cmdarg.h"
#include "code6809.h"
#define plain_base_mode_sym_name "PLAINBASE"
#define plain_base_mode_cmd_name "PLAINBASE"
typedef struct
{
char *Name;
Word Code;
CPUVar MinCPU;
} BaseOrder;
typedef struct
{
char *Name;
Word Code;
Boolean Inv;
CPUVar MinCPU;
} FlagOrder;
typedef struct
{
char *Name;
Word Code8;
Word Code16;
CPUVar MinCPU;
} RelOrder;
typedef struct
{
char *Name;
Word Code;
tSymbolSize OpSize;
Boolean MayImm;
CPUVar MinCPU;
} ALUOrder;
typedef enum
{
e_adr_mode_none = -1,
e_adr_mode_imm = 1,
e_adr_mode_dir = 2,
e_adr_mode_ind = 3,
e_adr_mode_ext = 4
} adr_mode_t;
#define adr_mode_mask_imm (1 << e_adr_mode_imm)
#define adr_mode_mask_dir (1 << e_adr_mode_dir)
#define adr_mode_mask_ind (1 << e_adr_mode_ind)
#define adr_mode_mask_ext (1 << e_adr_mode_ext)
#define adr_mode_mask_no_imm (adr_mode_mask_dir | adr_mode_mask_ind | adr_mode_mask_ext)
#define adr_mode_mask_all (adr_mode_mask_imm | adr_mode_mask_no_imm)
typedef struct
{
adr_mode_t mode;
int cnt;
Byte vals[5];
} adr_vals_t;
#define StackRegCnt 12
static char StackRegNames[StackRegCnt][4] =
{
"CCR", "A", "B","DPR", "X", "Y","S/U", "PC", "CC", "DP", "S", "D"
};
static Byte StackRegMasks[StackRegCnt] =
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x08, 0x40, 0x06
};
static const char FlagChars[] = "CVZNIHFE";
static LongInt DPRValue;
static Boolean target_used,
plain_base_mode,
def_plain_base_mode,
def_plain_base_mode_set;
static BaseOrder *FixedOrders;
static RelOrder *RelOrders;
static ALUOrder *ALUOrders;
static BaseOrder *RMWOrders;
static FlagOrder *FlagOrders;
static BaseOrder *LEAOrders;
static BaseOrder *ImmOrders;
static CPUVar CPU6809, CPU6309;
/*-------------------------------------------------------------------------*/
static Boolean CodeReg(char *ChIn, Byte *erg)
{
static char Regs[5] = "XYUS", *p;
return False;
else
{
p
= strchr(Regs
, as_toupper
(*ChIn
));
if (!p)
return False;
*erg = p - Regs;
return True;
}
}
static unsigned ChkZero(const char *s, Byte *Erg)
{
if (*s == '>')
{
*Erg = 1;
return 1;
}
else if (*s == '<')
{
if (1[s] == '<')
{
*Erg = 3;
return 2;
}
else
{
*Erg = 2;
return 1;
}
}
else
{
*Erg = 0;
return 0;
}
}
static Boolean MayShort(Integer Arg)
{
return ((Arg >= -128) && (Arg < 127));
}
static Boolean IsZeroOrEmpty(const tStrComp *pArg)
{
Boolean OK;
LongInt Value;
if (!*pArg->str.p_str)
return True;
Value = EvalStrIntExpression(pArg, Int32, &OK);
return OK && !Value;
}
static void reset_adr_vals(adr_vals_t *p_vals)
{
p_vals->mode = e_adr_mode_none;
p_vals->cnt = 0;
}
static Boolean check_plain_base_arg(int adr_arg_cnt, const tStrComp *p_start_arg)
{
switch (adr_arg_cnt)
{
case 1:
if (!plain_base_mode)
WrStrErrorPos(ErrNum_WrongArgCnt, p_start_arg);
return plain_base_mode;
case 2:
{
Boolean ret = IsZeroOrEmpty(p_start_arg);
if (!ret)
WrStrErrorPos(ErrNum_InvAddrMode, p_start_arg);
return ret;
}
default:
WrError(ErrNum_WrongArgCnt);
return False;
}
}
static adr_mode_t DecodeAdr(int ArgStartIdx, int ArgEndIdx,
unsigned OpcodeLen, tSymbolSize op_size,
unsigned mode_mask, adr_vals_t *p_vals)
{
tStrComp *pStartArg, *pEndArg, IndirComps[2];
String temp;
LongInt AdrLong;
Word AdrWord;
Boolean IndFlag, OK;
Byte EReg, ZeroMode;
char *p;
unsigned Offset;
Integer AdrInt;
int AdrArgCnt = ArgEndIdx - ArgStartIdx + 1;
const Boolean allow_6309 = (MomCPU >= CPU6309);
reset_adr_vals(p_vals);
pStartArg = &ArgStr[ArgStartIdx];
pEndArg = &ArgStr[ArgEndIdx];
/* immediate */
if ((*pStartArg->str.p_str == '#') && (AdrArgCnt == 1))
{
switch (op_size)
{
case eSymbolSize32Bit:
AdrLong = EvalStrIntExpressionOffs(pStartArg, 1, Int32, &OK);
if (OK)
{
p_vals->vals[0] = Lo(AdrLong >> 24);
p_vals->vals[1] = Lo(AdrLong >> 16);
p_vals->vals[2] = Lo(AdrLong >> 8);
p_vals->vals[3] = Lo(AdrLong);
p_vals->cnt = 4;
}
break;
case eSymbolSize16Bit:
AdrWord = EvalStrIntExpressionOffs(pStartArg, 1, Int16, &OK);
if (OK)
{
p_vals->vals[0] = Hi(AdrWord);
p_vals->vals[1] = Lo(AdrWord);
p_vals->cnt = 2;
}
break;
case eSymbolSize8Bit:
p_vals->vals[0] = EvalStrIntExpressionOffs(pStartArg, 1, Int8, &OK);
if (OK)
p_vals->cnt = 1;
break;
default:
OK = False;
break;
}
if (OK)
p_vals->mode = e_adr_mode_imm;
goto chk_mode;
}
/* indirekter Ausdruck ? */
if ((*pStartArg
->str.
p_str == '[') && (pStartArg
->str.
p_str[strlen(pStartArg
->str.
p_str) - 1] == ']'))
{
tStrComp Arg, Remainder;
IndFlag = True;
StrCompRefRight(&Arg, pStartArg, 1);
StrCompShorten(&Arg, 1);
AdrArgCnt = 0;
do
{
p = QuotPos(Arg.str.p_str, ',');
if (p)
StrCompSplitRef(&IndirComps[AdrArgCnt], &Remainder, &Arg, p);
else
IndirComps[AdrArgCnt] = Arg;
KillPrefBlanksStrCompRef(&IndirComps[AdrArgCnt]);
KillPostBlanksStrComp(&IndirComps[AdrArgCnt]);
AdrArgCnt++;
if (p)
Arg = Remainder;
}
while (p && (AdrArgCnt < 2));
pStartArg = &IndirComps[0];
pEndArg = &IndirComps[AdrArgCnt - 1];
}
else
IndFlag = False;
/* Predekrement ? */
if ((AdrArgCnt
>= 1) && (AdrArgCnt
<= 2) && (strlen(pEndArg
->str.
p_str) == 2) && (*pEndArg
->str.
p_str == '-') && (CodeReg
(pEndArg
->str.
p_str + 1, &EReg
)))
{
if (check_plain_base_arg(AdrArgCnt, pStartArg))
{
p_vals->cnt = 1;
p_vals->vals[0] = 0x82 + (EReg << 5) + (Ord(IndFlag) << 4);
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
if ((AdrArgCnt
>= 1) && (AdrArgCnt
<= 2) && (strlen(pEndArg
->str.
p_str) == 3) && (!strncmp(pEndArg
->str.
p_str, "--", 2)) && (CodeReg
(pEndArg
->str.
p_str + 2, &EReg
)))
{
if (check_plain_base_arg(AdrArgCnt, pStartArg))
{
p_vals->cnt = 1;
p_vals->vals[0] = 0x83 + (EReg << 5) + (Ord(IndFlag) << 4);
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (!as_strcasecmp(pEndArg->str.p_str, "--W")))
{
if (!check_plain_base_arg(AdrArgCnt, pStartArg));
else if (!allow_6309) WrError(ErrNum_AddrModeNotSupported);
else
{
p_vals->cnt = 1;
p_vals->vals[0] = 0xef + Ord(IndFlag);
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
/* Postinkrement ? */
if ((AdrArgCnt
>= 1) && (AdrArgCnt
<= 2) && (strlen(pEndArg
->str.
p_str) == 2) && (pEndArg
->str.
p_str[1] == '+'))
{
temp[0] = *pEndArg->str.p_str;
temp[1] = '\0';
if (CodeReg(temp, &EReg))
{
if (check_plain_base_arg(AdrArgCnt, pStartArg))
{
p_vals->cnt = 1;
p_vals->vals[0] = 0x80 + (EReg << 5) + (Ord(IndFlag) << 4);
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
}
if ((AdrArgCnt
>= 1) && (AdrArgCnt
<= 2) && (strlen(pEndArg
->str.
p_str) == 3) && (!strncmp(pEndArg
->str.
p_str + 1, "++", 2)))
{
temp[0] = *pEndArg->str.p_str;
temp[1] = '\0';
if (CodeReg(temp, &EReg))
{
if (check_plain_base_arg(AdrArgCnt, pStartArg))
{
p_vals->cnt = 1;
p_vals->vals[0] = 0x81 + (EReg << 5) + (Ord(IndFlag) << 4);
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
}
if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (!as_strcasecmp(pEndArg->str.p_str, "W++")))
{
if (!check_plain_base_arg(AdrArgCnt, pStartArg));
else if (!allow_6309) WrError(ErrNum_AddrModeNotSupported);
else
{
p_vals->cnt = 1;
p_vals->vals[0] = 0xcf + Ord(IndFlag);
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
/* 16-Bit-Register (mit Index) ? */
if ((AdrArgCnt <= 2) && (AdrArgCnt >= 1) && (CodeReg(pEndArg->str.p_str, &EReg)))
{
p_vals->vals[0] = (EReg << 5) + (Ord(IndFlag) << 4);
/* nur 16-Bit-Register */
if (AdrArgCnt == 1)
{
if (!plain_base_mode) WrStrErrorPos(ErrNum_WrongArgCnt, pEndArg);
else
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x84;
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
/* mit Index */
if (!as_strcasecmp(pStartArg->str.p_str, "A"))
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x86;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
if (!as_strcasecmp(pStartArg->str.p_str, "B"))
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x85;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
if (!as_strcasecmp(pStartArg->str.p_str, "D"))
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x8b;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
if ((!as_strcasecmp(pStartArg->str.p_str, "E")) && allow_6309)
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x87;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
if ((!as_strcasecmp(pStartArg->str.p_str, "F")) && allow_6309)
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x8a;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
if ((!as_strcasecmp(pStartArg->str.p_str, "W")) && allow_6309)
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x8e;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
/* Displacement auswerten */
Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
if (ZeroMode > 1)
{
tSymbolFlags Flags;
AdrInt = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, Int8, &OK, &Flags);
if (mFirstPassUnknown(Flags) && (ZeroMode == 3))
AdrInt &= 0x0f;
}
else
AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, Int16, &OK);
if (!OK)
goto chk_mode;
/* Displacement 0 ? */
if ((ZeroMode == 0) && (AdrInt == 0))
{
p_vals->cnt = 1;
p_vals->vals[0] += 0x84;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
/* 5-Bit-Displacement */
else if ((ZeroMode == 3) || ((ZeroMode == 0) && (!IndFlag) && (AdrInt >= -16) && (AdrInt <= 15)))
{
if ((AdrInt < -16) || (AdrInt > 15)) WrError(ErrNum_NoShortAddr);
else if (IndFlag) WrError(ErrNum_InvAddrMode);
else
{
p_vals->mode = e_adr_mode_ind;
p_vals->cnt = 1;
p_vals->vals[0] += AdrInt & 0x1f;
}
goto chk_mode;
}
/* 8-Bit-Displacement */
else if ((ZeroMode == 2) || ((ZeroMode == 0) && (MayShort(AdrInt))))
{
if (!MayShort(AdrInt)) WrError(ErrNum_NoShortAddr);
else
{
p_vals->mode = e_adr_mode_ind;
p_vals->cnt = 2;
p_vals->vals[0] += 0x88;
p_vals->vals[1] = Lo(AdrInt);
}
goto chk_mode;
}
/* 16-Bit-Displacement */
else
{
p_vals->mode = e_adr_mode_ind;
p_vals->cnt = 3;
p_vals->vals[0] += 0x89;
p_vals->vals[1] = Hi(AdrInt);
p_vals->vals[2] = Lo(AdrInt);
goto chk_mode;
}
}
if ((AdrArgCnt <= 2) && (AdrArgCnt >= 1) && allow_6309 && (!as_strcasecmp(pEndArg->str.p_str, "W")))
{
p_vals->vals[0] = 0x8f + Ord(IndFlag);
/* nur W-Register */
if (AdrArgCnt == 1)
{
if (!plain_base_mode) WrStrErrorPos(ErrNum_WrongArgCnt, pEndArg);
else
{
p_vals->cnt = 1;
p_vals->mode = e_adr_mode_ind;
}
goto chk_mode;
}
/* Displacement auswerten */
Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, Int16, &OK);
/* Displacement 0 ? */
if ((ZeroMode == 0) && (AdrInt == 0))
{
p_vals->cnt = 1;
p_vals->mode = e_adr_mode_ind;
goto chk_mode;
}
/* 16-Bit-Displacement */
else
{
p_vals->mode = e_adr_mode_ind;
p_vals->cnt = 3;
p_vals->vals[0] += 0x20;
p_vals->vals[1] = Hi(AdrInt);
p_vals->vals[2] = Lo(AdrInt);
goto chk_mode;
}
}
/* PC-relativ ? */
if ((AdrArgCnt == 2) && (!as_strcasecmp(pEndArg->str.p_str, "PCR") || !as_strcasecmp(pEndArg->str.p_str, "PC")))
{
p_vals->vals[0] = Ord(IndFlag) << 4;
Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, Int16, &OK);
if (OK)
{
AdrInt -= EProgCounter() + 2 + OpcodeLen;
if (ZeroMode == 3) WrError(ErrNum_InvAddrMode);
else if ((ZeroMode == 2) || ((ZeroMode == 0) && MayShort(AdrInt)))
{
if (!MayShort(AdrInt)) WrError(ErrNum_OverRange);
else
{
p_vals->cnt = 2;
p_vals->vals[0] += 0x8c;
p_vals->vals[1] = Lo(AdrInt);
p_vals->mode = e_adr_mode_ind;
}
}
else
{
AdrInt--;
p_vals->cnt = 3;
p_vals->vals[0] += 0x8d;
p_vals->vals[1] = Hi(AdrInt);
p_vals->vals[2] = Lo(AdrInt);
p_vals->mode = e_adr_mode_ind;
}
}
goto chk_mode;
}
if (AdrArgCnt == 1)
{
tSymbolFlags Flags;
Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
AdrInt = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, Int16, &OK, &Flags);
if (mFirstPassUnknown(Flags) && (ZeroMode == 2))
AdrInt = (AdrInt & 0xff) | (DPRValue << 8);
if (OK)
{
if (ZeroMode == 3) WrError(ErrNum_InvAddrMode);
else if ((ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrInt) == DPRValue) && (!IndFlag)))
{
if (IndFlag) WrError(ErrNum_NoIndir);
else if (Hi(AdrInt) != DPRValue) WrError(ErrNum_NoShortAddr);
else
{
p_vals->cnt = 1;
p_vals->mode = e_adr_mode_dir;
p_vals->vals[0] = Lo(AdrInt);
}
}
else
{
if (IndFlag)
{
p_vals->mode = e_adr_mode_ind;
p_vals->cnt = 3;
p_vals->vals[0] = 0x9f;
p_vals->vals[1] = Hi(AdrInt);
p_vals->vals[2] = Lo(AdrInt);
}
else
{
p_vals->mode = e_adr_mode_ext;
p_vals->cnt = 2;
p_vals->vals[0] = Hi(AdrInt);
p_vals->vals[1] = Lo(AdrInt);
}
}
}
goto chk_mode;
}
if (p_vals->mode == e_adr_mode_none)
WrError(ErrNum_InvAddrMode);
chk_mode:
if ((p_vals->mode != e_adr_mode_none) && !((mode_mask >> p_vals->mode) & 1))
{
WrError(ErrNum_InvAddrMode);
reset_adr_vals(p_vals);
}
return p_vals->mode;
}
static Boolean CodeCPUReg(const char *Asc, Byte *Erg)
{
#define RegCnt (sizeof(RegNames) / sizeof(*RegNames))
static const char RegNames[][4] =
{
"D", "X", "Y", "U", "S", "SP", "PC", "W", "V", "A", "B", "CCR", "DPR", "CC", "DP", "Z", "E", "F"
};
static const Byte RegVals[RegCnt] =
{
0 , 1 , 2 , 3 , 4 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 10 , 11 , 13 , 14 , 15
};
unsigned z;
String Asc_N;
strmaxcpy(Asc_N, Asc, STRINGSIZE); NLS_UpString(Asc_N); Asc = Asc_N;
for (z = 0; z < RegCnt; z++)
if (!strcmp(Asc
, RegNames
[z
]))
{
if (((RegVals[z] & 6) == 6) && !ChkMinCPUExt(CPU6309, ErrNum_AddrModeNotSupported));
else
{
*Erg = RegVals[z];
return True;
}
}
return False;
}
static void SplitIncDec(char *s, int *Erg)
{
if (l == 0)
*Erg = 0;
else if (s[l - 1] == '+')
{
s[l - 1] = '\0';
*Erg = 1;
}
else if (s[l - 1] == '-')
{
s[l - 1] = '\0';
*Erg = -1;
}
else
*Erg = 0;
}
static Boolean SplitBit(tStrComp *pArg, int *Erg)
{
char *p;
Boolean OK;
tStrComp BitArg;
p = QuotPos(pArg->str.p_str, '.');
if (!p)
{
WrError(ErrNum_InvBitPos);
return False;
}
StrCompSplitRef(pArg, &BitArg, pArg, p);
*Erg = EvalStrIntExpression(&BitArg, UInt3, &OK);
if (!OK)
return False;
*p = '\0';
return True;
}
static void append_adr_vals(const adr_vals_t *p_vals)
{
memcpy(&BAsmCode
[CodeLen
], p_vals
->vals
, p_vals
->cnt
);
CodeLen += p_vals->cnt;
}
/*-------------------------------------------------------------------------*/
/* Anweisungen ohne Argument */
static void DecodeFixed(Word Index)
{
const BaseOrder *pOrder = FixedOrders + Index;
if (!ChkArgCnt(0, 0));
else if (!ChkMinCPU(pOrder->MinCPU));
else if (Hi(pOrder->Code) == 0)
{
BAsmCode[0] = Lo(pOrder->Code);
CodeLen = 1;
}
else
{
BAsmCode[0] = Hi(pOrder->Code);
BAsmCode[1] = Lo(pOrder->Code);
CodeLen = 2;
}
}
/* Specials... */
static void DecodeSWI(Word Code)
{
UNUSED(Code);
if (ArgCnt == 0)
{
BAsmCode[0] = 0x3f;
CodeLen = 1;
}
else if (ChkArgCnt(1, 1))
{
Boolean OK;
tSymbolFlags Flags;
Byte Num;
Num = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
if (OK && mFirstPassUnknown(Flags) && (Num < 2))
Num = 2;
if (OK && ChkRange(Num, 2, 3))
{
BAsmCode[0] = 0x10 | (Num & 1);
BAsmCode[1] = 0x3f;
CodeLen = 2;
}
}
}
/* relative Spruenge */
static void DecodeRel(Word Index)
{
Boolean LongFlag = (Index & 0x8000) || False;
const RelOrder *pOrder = RelOrders + (Index & 0x7fff);
if (ChkArgCnt(1, 1))
{
Boolean ExtFlag = (LongFlag) && (Hi(pOrder->Code16) != 0), OK;
tSymbolFlags Flags;
Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
if (OK)
{
AdrInt -= EProgCounter() + 2 + Ord(LongFlag) + Ord(ExtFlag);
if (!mSymbolQuestionable(Flags) && !LongFlag && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
CodeLen = 1 + Ord(ExtFlag);
if (LongFlag)
{
if (ExtFlag)
{
BAsmCode[0] = Hi(pOrder->Code16);
BAsmCode[1] = Lo(pOrder->Code16);
}
else
BAsmCode[0] = Lo(pOrder->Code16);
}
else
BAsmCode[0] = Lo(pOrder->Code8);
if (LongFlag)
{
BAsmCode[CodeLen] = Hi(AdrInt);
BAsmCode[CodeLen + 1] = Lo(AdrInt);
CodeLen += 2;
}
else
{
BAsmCode[CodeLen] = Lo(AdrInt);
CodeLen++;
}
}
}
}
}
/* ALU-Operationen */
static void DecodeALU(Word Index)
{
const ALUOrder *pOrder = ALUOrders + Index;
if (ChkArgCnt(1, 2)
&& ChkMinCPU(pOrder->MinCPU))
{
adr_vals_t vals;
if (DecodeAdr(1, ArgCnt, 1 + !!Hi(pOrder->Code), pOrder->OpSize, pOrder->MayImm ? adr_mode_mask_all : adr_mode_mask_no_imm, &vals) != e_adr_mode_none)
{
if (Hi(pOrder->Code))
BAsmCode[CodeLen++] = Hi(pOrder->Code);
BAsmCode[CodeLen++] = Lo(pOrder->Code) + ((vals.mode - 1) << 4);
append_adr_vals(&vals);
}
}
}
static void DecodeLDQ(Word Index)
{
UNUSED(Index);
if (ChkArgCnt(1, 2)
&& ChkMinCPU(CPU6309))
{
adr_vals_t vals;
if (DecodeAdr(1, ArgCnt, 2, eSymbolSize32Bit, adr_mode_mask_all, &vals) == e_adr_mode_imm)
{
BAsmCode[CodeLen++] = 0xcd;
append_adr_vals(&vals);
}
else
{
BAsmCode[CodeLen++] = 0x10;
BAsmCode[CodeLen++] = 0xcc + ((vals.mode - 1) << 4);
append_adr_vals(&vals);
}
}
}
/* Read-Modify-Write-Operationen */
static void DecodeRMW(Word Index)
{
const BaseOrder *pOrder = RMWOrders + Index;
if (ChkArgCnt(1, 2)
&& ChkMinCPU(pOrder->MinCPU))
{
adr_vals_t vals;
switch (DecodeAdr(1, ArgCnt, 1, eSymbolSizeUnknown, adr_mode_mask_no_imm, &vals))
{
case e_adr_mode_dir:
BAsmCode[CodeLen++] = pOrder->Code;
goto append;
case e_adr_mode_ind:
BAsmCode[CodeLen++] = pOrder->Code + 0x60;
goto append;
case e_adr_mode_ext:
BAsmCode[CodeLen++] = pOrder->Code + 0x70;
goto append;
append:
append_adr_vals(&vals);
break;
default:
return;
}
}
}
/* Anweisungen mit Flag-Operand */
static void DecodeFlag(Word Index)
{
const FlagOrder *pOrder = FlagOrders + Index;
Boolean OK;
const char *p;
int z2, z3;
if (ChkArgCnt(1, ArgCntMax))
{
OK = True;
BAsmCode[1] = (pOrder->Inv) ? 0xff : 0x00;
for (z2 = 1; z2 <= ArgCnt; z2++)
if (OK)
{
p
= (strlen(ArgStr
[z2
].
str.
p_str) == 1) ? strchr(FlagChars
, as_toupper
(*ArgStr
[z2
].
str.
p_str)) : NULL
;
if (p)
{
z3 = p - FlagChars;
if (pOrder->Inv)
BAsmCode[1] &= (0xff ^ (1 << z3));
else
BAsmCode[1] |= (1 << z3);
}
else if (*ArgStr[z2].str.p_str != '#')
{
WrError(ErrNum_OnlyImmAddr);
OK = False;
}
else
{
BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[z2], 1, Int8, &OK);
if (OK)
{
if (pOrder->Inv)
BAsmCode[1] &= BAsmCode[2];
else
BAsmCode[1] |= BAsmCode[2];
}
}
}
if (OK)
{
CodeLen = 2;
BAsmCode[0] = pOrder->Code;
}
}
}
/* Bit-Befehle */
static void DecodeImm(Word Index)
{
const BaseOrder *pOrder = ImmOrders + Index;
if (!ChkArgCnt(2, 3));
else if (!ChkMinCPU(pOrder->MinCPU));
else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
else
{
Boolean OK;
BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int8, &OK);
if (OK)
{
adr_vals_t vals;
switch (DecodeAdr(2, ArgCnt, 2, eSymbolSizeUnknown, adr_mode_mask_no_imm, &vals))
{
case e_adr_mode_dir:
BAsmCode[0] = pOrder->Code;
goto append;
case e_adr_mode_ext:
BAsmCode[0] = pOrder->Code + 0x70;
goto append;
case e_adr_mode_ind:
BAsmCode[0] = pOrder->Code + 0x60;
goto append;
append:
CodeLen = 2;
append_adr_vals(&vals);
break;
default:
return;
}
}
}
}
static void DecodeBit(Word Code)
{
int z2, z3;
if (ChkArgCnt(2, 2)
&& ChkMinCPU(CPU6309)
&& SplitBit(&ArgStr[1], &z2) && SplitBit(&ArgStr[2], &z3))
{
if (!CodeCPUReg(ArgStr[1].str.p_str, BAsmCode + 2)) WrError(ErrNum_InvRegName);
else if ((BAsmCode[2] < 8) || (BAsmCode[2] > 11)) WrError(ErrNum_InvRegName);
else
{
adr_vals_t vals;
if (DecodeAdr(2, 2, 3, eSymbolSizeUnknown, adr_mode_mask_dir, &vals) != e_adr_mode_none)
{
BAsmCode[2] -= 7;
if (BAsmCode[2] == 3)
BAsmCode[2] = 0;
BAsmCode[0] = 0x11;
BAsmCode[1] = 0x30 + Code;
BAsmCode[2] = (BAsmCode[2] << 6) + (z3 << 3) + z2;
BAsmCode[3] = vals.vals[0];
CodeLen = 4;
}
}
}
}
/* Register-Register-Operationen */
void DecodeTFR_TFM_EXG_6809(Word code, Boolean allow_inc_dec, reg_decoder_6809_t reg_decoder, Boolean reverse)
{
if (ChkArgCnt(2, 2))
{
int Inc1, Inc2;
SplitIncDec(ArgStr[1].str.p_str, &Inc1);
SplitIncDec(ArgStr[2].str.p_str, &Inc2);
if ((Inc1 != 0) || (Inc2 != 0))
{
if (!allow_inc_dec) WrError(ErrNum_InvAddrMode);
else if (!reg_decoder(ArgStr[1].str.p_str, BAsmCode + 3) || (BAsmCode[3] > 4)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
else if (!reg_decoder(ArgStr[2].str.p_str, BAsmCode + 2) || (BAsmCode[2] > 4)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
else
{
BAsmCode[0] = 0x11;
BAsmCode[1] = 0;
if (reverse)
BAsmCode[2] = (BAsmCode[2] << 4) | (BAsmCode[3] & 0x0f);
else
BAsmCode[2] |= BAsmCode[3] << 4;
if ((Inc1 == 1) && (Inc2 == 1))
BAsmCode[1] = 0x38;
else if ((Inc1 == -1) && (Inc2 == -1))
BAsmCode[1] = 0x39;
else if ((Inc1 == 1) && (Inc2 == 0))
BAsmCode[1] = 0x3a;
else if ((Inc1 == 0) && (Inc2 == 1))
BAsmCode[1] = 0x3b;
if (BAsmCode[1] == 0) WrError(ErrNum_InvAddrMode);
else
CodeLen = 3;
}
}
else if (Memo("TFM")) WrError(ErrNum_InvAddrMode);
else if (!reg_decoder(ArgStr[1].str.p_str, BAsmCode + 2)) WrError(ErrNum_InvRegName);
else if (!reg_decoder(ArgStr[2].str.p_str, BAsmCode + 1)) WrError(ErrNum_InvRegName);
else if ((BAsmCode[1] != 13) && (BAsmCode[2] != 13) /* Z Register compatible to all other registers */
&& (((BAsmCode[1] ^ BAsmCode[2]) & 0x08) != 0)) WrError(ErrNum_ConfOpSizes);
else
{
CodeLen = 2;
BAsmCode[0] = code;
if (reverse)
BAsmCode[1] = (BAsmCode[1] << 4) | (BAsmCode[2] & 0x0f);
else
BAsmCode[1] |= BAsmCode[2] << 4;
}
}
}
static void DecodeTFR_TFM(Word code)
{
DecodeTFR_TFM_EXG_6809(code, MomCPU == CPU6309, CodeCPUReg, False);
}
static void DecodeEXG(Word code)
{
DecodeTFR_TFM_EXG_6809(code, False, CodeCPUReg, False);
}
static void DecodeALU2(Word Code)
{
if (!ChkArgCnt(2, 2));
else if (!CodeCPUReg(ArgStr[1].str.p_str, &BAsmCode[3])) WrError(ErrNum_InvRegName);
else if (!CodeCPUReg(ArgStr[2].str.p_str, &BAsmCode[2])) WrError(ErrNum_InvRegName);
else if ((BAsmCode[2] != 13) && (BAsmCode[3] != 13) /* Z Register compatible to all other registers */
&& (((BAsmCode[2] ^ BAsmCode[3]) & 0x08) != 0)) WrError(ErrNum_ConfOpSizes);
else
{
CodeLen = 3;
BAsmCode[0] = 0x10;
BAsmCode[1] = 0x30 + Code;
BAsmCode[2] += BAsmCode[3] << 4;
}
}
/* Berechnung effektiver Adressen */
static void DecodeLEA(Word Index)
{
const BaseOrder *pOrder = LEAOrders + Index;
if (ChkArgCnt(1, 2))
{
adr_vals_t vals;
if (DecodeAdr(1, ArgCnt, 1, eSymbolSizeUnknown, adr_mode_mask_ind, &vals) != e_adr_mode_none)
{
BAsmCode[CodeLen++] = pOrder->Code;
append_adr_vals(&vals);
}
}
}
/* Push/Pull */
void DecodeStack_6809(Word code)
{
Boolean OK = True, Extent = False;
int z2, z3;
Boolean has_w = !!Hi(code);
BAsmCode[1] = 0;
/* S oder U einsetzen, entsprechend Opcode */
*StackRegNames
[StackRegCnt
- 2] = OpPart.
str.
p_str[strlen(OpPart.
str.
p_str) - 1] ^ ('S' ^ 'U');
for (z2 = 1; z2 <= ArgCnt; z2++)
if (OK)
{
if (!as_strcasecmp(ArgStr[z2].str.p_str, "W"))
{
if (!has_w)
OK = False;
else if (ArgCnt != 1)
{
WrError(ErrNum_InAccReg);
OK = False;
}
else
Extent = True;
}
else
{
for (z3 = 0; z3 < StackRegCnt; z3++)
if (!as_strcasecmp(ArgStr[z2].str.p_str, StackRegNames[z3]))
{
BAsmCode[1] |= StackRegMasks[z3];
break;
}
if (z3 >= StackRegCnt)
{
if (!as_strcasecmp(ArgStr[z2].str.p_str, "ALL"))
BAsmCode[1] = 0xff;
else if (*ArgStr[z2].str.p_str != '#') OK = False;
else
{
BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[z2], 1, Int8, &OK);
if (OK)
BAsmCode[1] |= BAsmCode[2];
}
}
}
}
if (OK)
{
if (Extent)
{
CodeLen = 2;
BAsmCode[0] = 0x10;
BAsmCode[1] = Lo(code) + 4;
}
else
{
CodeLen = 2;
BAsmCode[0] = code;
}
}
else
WrStrErrorPos(ErrNum_InvRegName, &ArgStr[z2 - 1]);
}
static void DecodeBITMD_LDMD(Word Code)
{
if (!ChkArgCnt(1, 1));
else if (!ChkMinCPU(CPU6309));
else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
else
{
Boolean OK;
BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[1], 1,Int8, &OK);
if (OK)
{
BAsmCode[0] = 0x11;
BAsmCode[1] = Code;
CodeLen = 3;
}
}
}
/*-------------------------------------------------------------------------*/
/* Erzeugung/Aufloesung Codetabellen */
static void AddFixed(const char *NName, Word NCode, CPUVar NCPU)
{
order_array_rsv_end(FixedOrders, BaseOrder);
FixedOrders[InstrZ].Code = NCode;
FixedOrders[InstrZ].MinCPU = NCPU;
AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
}
static void AddRel(const char *NName, Word NCode8, Word NCode16)
{
char LongName[30];
order_array_rsv_end(RelOrders, RelOrder);
RelOrders[InstrZ].Code8 = NCode8;
RelOrders[InstrZ].Code16 = NCode16;
AddInstTable(InstTable, NName, InstrZ, DecodeRel);
as_snprintf(LongName, sizeof(LongName), "L%s", NName);
AddInstTable(InstTable, LongName, InstrZ | 0x8000, DecodeRel);
InstrZ++;
}
static void AddALU(const char *NName, Word NCode, tSymbolSize NSize, Boolean NImm, CPUVar NCPU)
{
order_array_rsv_end(ALUOrders, ALUOrder);
ALUOrders[InstrZ].Code = NCode;
ALUOrders[InstrZ].OpSize = NSize;
ALUOrders[InstrZ].MayImm = NImm;
ALUOrders[InstrZ].MinCPU = NCPU;
AddInstTable(InstTable, NName, InstrZ++, DecodeALU);
}
static void AddALU2(const char *NName)
{
char RName[30];
AddInstTable(InstTable, NName, InstrZ, DecodeALU2);
as_snprintf(RName, sizeof(RName), "%sR", NName);
AddInstTable(InstTable, RName, InstrZ, DecodeALU2);
InstrZ++;
}
static void AddRMW(const char *NName, Word NCode, CPUVar NCPU)
{
order_array_rsv_end(RMWOrders, BaseOrder);
RMWOrders[InstrZ].Code = NCode;
RMWOrders[InstrZ].MinCPU = NCPU;
AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
}
static void AddFlag(const char *NName, Word NCode, Boolean NInv, CPUVar NCPU)
{
order_array_rsv_end(FlagOrders, FlagOrder);
FlagOrders[InstrZ].Code = NCode;
FlagOrders[InstrZ].Inv = NInv;
FlagOrders[InstrZ].MinCPU = NCPU;
AddInstTable(InstTable, NName, InstrZ++, DecodeFlag);
}
static void AddLEA(const char *NName, Word NCode, CPUVar NCPU)
{
order_array_rsv_end(LEAOrders, BaseOrder);
LEAOrders[InstrZ].Code = NCode;
LEAOrders[InstrZ].MinCPU = NCPU;
AddInstTable(InstTable, NName, InstrZ++, DecodeLEA);
}
static void AddImm(const char *NName, Word NCode, CPUVar NCPU)
{
order_array_rsv_end(ImmOrders, BaseOrder);
ImmOrders[InstrZ].Code = NCode;
ImmOrders[InstrZ].MinCPU = NCPU;
AddInstTable(InstTable, NName, InstrZ++, DecodeImm);
}
static void InitFields(void)
{
InstTable = CreateInstTable(307);
SetDynamicInstTable(InstTable);
AddInstTable(InstTable, "SWI", 0, DecodeSWI);
AddInstTable(InstTable, "LDQ", 0, DecodeLDQ);
AddInstTable(InstTable, "TFR", 0x1f, DecodeTFR_TFM);
AddInstTable(InstTable, "TFM", 0x1138, DecodeTFR_TFM);
AddInstTable(InstTable, "EXG", 0x1e, DecodeEXG);
AddInstTable(InstTable, "BITMD", 0x3c, DecodeBITMD_LDMD);
AddInstTable(InstTable, "LDMD", 0x3d, DecodeBITMD_LDMD);
InstrZ = 0;
AddFixed("NOP" , 0x0012, CPU6809); AddFixed("SYNC" , 0x0013, CPU6809);
AddFixed("DAA" , 0x0019, CPU6809); AddFixed("SEX" , 0x001d, CPU6809);
AddFixed("RTS" , 0x0039, CPU6809); AddFixed("ABX" , 0x003a, CPU6809);
AddFixed("RTI" , 0x003b, CPU6809); AddFixed("MUL" , 0x003d, CPU6809);
AddFixed("SWI2" , 0x103f, CPU6809); AddFixed("SWI3" , 0x113f, CPU6809);
AddFixed("NEGA" , 0x0040, CPU6809); AddFixed("COMA" , 0x0043, CPU6809);
AddFixed("LSRA" , 0x0044, CPU6809); AddFixed("RORA" , 0x0046, CPU6809);
AddFixed("ASRA" , 0x0047, CPU6809); AddFixed("ASLA" , 0x0048, CPU6809);
AddFixed("LSLA" , 0x0048, CPU6809); AddFixed("ROLA" , 0x0049, CPU6809);
AddFixed("DECA" , 0x004a, CPU6809); AddFixed("INCA" , 0x004c, CPU6809);
AddFixed("TSTA" , 0x004d, CPU6809); AddFixed("CLRA" , 0x004f, CPU6809);
AddFixed("NEGB" , 0x0050, CPU6809); AddFixed("COMB" , 0x0053, CPU6809);
AddFixed("LSRB" , 0x0054, CPU6809); AddFixed("RORB" , 0x0056, CPU6809);
AddFixed("ASRB" , 0x0057, CPU6809); AddFixed("ASLB" , 0x0058, CPU6809);
AddFixed("LSLB" , 0x0058, CPU6809); AddFixed("ROLB" , 0x0059, CPU6809);
AddFixed("DECB" , 0x005a, CPU6809); AddFixed("INCB" , 0x005c, CPU6809);
AddFixed("TSTB" , 0x005d, CPU6809); AddFixed("CLRB" , 0x005f, CPU6809);
AddFixed("PSHSW", 0x1038, CPU6309); AddFixed("PULSW", 0x1039, CPU6309);
AddFixed("PSHUW", 0x103a, CPU6309); AddFixed("PULUW", 0x103b, CPU6309);
AddFixed("SEXW" , 0x0014, CPU6309); AddFixed("NEGD" , 0x1040, CPU6309);
AddFixed("COMD" , 0x1043, CPU6309); AddFixed("LSRD" , 0x1044, CPU6309);
AddFixed("RORD" , 0x1046, CPU6309); AddFixed("ASRD" , 0x1047, CPU6309);
AddFixed("ASLD" , 0x1048, CPU6309); AddFixed("LSLD" , 0x1048, CPU6309);
AddFixed("ROLD" , 0x1049, CPU6309); AddFixed("DECD" , 0x104a, CPU6309);
AddFixed("INCD" , 0x104c, CPU6309); AddFixed("TSTD" , 0x104d, CPU6309);
AddFixed("CLRD" , 0x104f, CPU6309); AddFixed("COMW" , 0x1053, CPU6309);
AddFixed("LSRW" , 0x1054, CPU6309); AddFixed("RORW" , 0x1056, CPU6309);
AddFixed("ROLW" , 0x1059, CPU6309); AddFixed("DECW" , 0x105a, CPU6309);
AddFixed("INCW" , 0x105c, CPU6309); AddFixed("TSTW" , 0x105d, CPU6309);
AddFixed("CLRW" , 0x105f, CPU6309); AddFixed("COME" , 0x1143, CPU6309);
AddFixed("DECE" , 0x114a, CPU6309); AddFixed("INCE" , 0x114c, CPU6309);
AddFixed("TSTE" , 0x114d, CPU6309); AddFixed("CLRE" , 0x114f, CPU6309);
AddFixed("COMF" , 0x1153, CPU6309); AddFixed("DECF" , 0x115a, CPU6309);
AddFixed("INCF" , 0x115c, CPU6309); AddFixed("TSTF" , 0x115d, CPU6309);
AddFixed("CLRF" , 0x115f, CPU6309); AddFixed("CLRS" , 0x1fd4, CPU6309);
AddFixed("CLRV" , 0x1fd7, CPU6309); AddFixed("CLRX" , 0x1fd1, CPU6309);
AddFixed("CLRY" , 0x1fd2, CPU6309);
InstrZ = 0;
AddRel("BRA", 0x0020, 0x0016); AddRel("BRN", 0x0021, 0x1021);
AddRel("BHI", 0x0022, 0x1022); AddRel("BLS", 0x0023, 0x1023);
AddRel("BHS", 0x0024, 0x1024); AddRel("BCC", 0x0024, 0x1024);
AddRel("BLO", 0x0025, 0x1025); AddRel("BCS", 0x0025, 0x1025);
AddRel("BNE", 0x0026, 0x1026); AddRel("BEQ", 0x0027, 0x1027);
AddRel("BVC", 0x0028, 0x1028); AddRel("BVS", 0x0029, 0x1029);
AddRel("BPL", 0x002a, 0x102a); AddRel("BMI", 0x002b, 0x102b);
AddRel("BGE", 0x002c, 0x102c); AddRel("BLT", 0x002d, 0x102d);
AddRel("BGT", 0x002e, 0x102e); AddRel("BLE", 0x002f, 0x102f);
AddRel("BSR", 0x008d, 0x0017);
InstrZ = 0;
AddALU("LDA" , 0x0086, eSymbolSize8Bit , True , CPU6809);
AddALU("STA" , 0x0087, eSymbolSize8Bit , False, CPU6809);
AddALU("CMPA", 0x0081, eSymbolSize8Bit , True , CPU6809);
AddALU("ADDA", 0x008b, eSymbolSize8Bit , True , CPU6809);
AddALU("ADCA", 0x0089, eSymbolSize8Bit , True , CPU6809);
AddALU("SUBA", 0x0080, eSymbolSize8Bit , True , CPU6809);
AddALU("SBCA", 0x0082, eSymbolSize8Bit , True , CPU6809);
AddALU("ANDA", 0x0084, eSymbolSize8Bit , True , CPU6809);
AddALU("ORA" , 0x008a, eSymbolSize8Bit , True , CPU6809);
AddALU("EORA", 0x0088, eSymbolSize8Bit , True , CPU6809);
AddALU("BITA", 0x0085, eSymbolSize8Bit , True , CPU6809);
AddALU("LDB" , 0x00c6, eSymbolSize8Bit , True , CPU6809);
AddALU("STB" , 0x00c7, eSymbolSize8Bit , False, CPU6809);
AddALU("CMPB", 0x00c1, eSymbolSize8Bit , True , CPU6809);
AddALU("ADDB", 0x00cb, eSymbolSize8Bit , True , CPU6809);
AddALU("ADCB", 0x00c9, eSymbolSize8Bit , True , CPU6809);
AddALU("SUBB", 0x00c0, eSymbolSize8Bit , True , CPU6809);
AddALU("SBCB", 0x00c2, eSymbolSize8Bit , True , CPU6809);
AddALU("ANDB", 0x00c4, eSymbolSize8Bit , True , CPU6809);
AddALU("ORB" , 0x00ca, eSymbolSize8Bit , True , CPU6809);
AddALU("EORB", 0x00c8, eSymbolSize8Bit , True , CPU6809);
AddALU("BITB", 0x00c5, eSymbolSize8Bit , True , CPU6809);
AddALU("LDD" , 0x00cc, eSymbolSize16Bit, True , CPU6809);
AddALU("STD" , 0x00cd, eSymbolSize16Bit, False, CPU6809);
AddALU("CMPD", 0x1083, eSymbolSize16Bit, True , CPU6809);
AddALU("ADDD", 0x00c3, eSymbolSize16Bit, True , CPU6809);
AddALU("ADCD", 0x1089, eSymbolSize16Bit, True , CPU6309);
AddALU("SUBD", 0x0083, eSymbolSize16Bit, True , CPU6809);
AddALU("SBCD", 0x1082, eSymbolSize16Bit, True , CPU6309);
AddALU("MULD", 0x118f, eSymbolSize16Bit, True , CPU6309);
AddALU("DIVD", 0x118d, eSymbolSize16Bit, True , CPU6309);
AddALU("ANDD", 0x1084, eSymbolSize16Bit, True , CPU6309);
AddALU("ORD" , 0x108a, eSymbolSize16Bit, True , CPU6309);
AddALU("EORD", 0x1088, eSymbolSize16Bit, True , CPU6309);
AddALU("BITD", 0x1085, eSymbolSize16Bit, True , CPU6309);
AddALU("LDW" , 0x1086, eSymbolSize16Bit, True , CPU6309);
AddALU("STW" , 0x1087, eSymbolSize16Bit, False, CPU6309);
AddALU("CMPW", 0x1081, eSymbolSize16Bit, True , CPU6309);
AddALU("ADDW", 0x108b, eSymbolSize16Bit, True , CPU6309);
AddALU("SUBW", 0x1080, eSymbolSize16Bit, True , CPU6309);
AddALU("STQ" , 0x10cd, eSymbolSize16Bit, True , CPU6309);
AddALU("DIVQ", 0x118e, eSymbolSize16Bit, True , CPU6309);
AddALU("LDE" , 0x1186, eSymbolSize8Bit , True , CPU6309);
AddALU("STE" , 0x1187, eSymbolSize8Bit , False, CPU6309);
AddALU("CMPE", 0x1181, eSymbolSize8Bit , True , CPU6309);
AddALU("ADDE", 0x118b, eSymbolSize8Bit , True , CPU6309);
AddALU("SUBE", 0x1180, eSymbolSize8Bit , True , CPU6309);
AddALU("LDF" , 0x11c6, eSymbolSize8Bit , True , CPU6309);
AddALU("STF" , 0x11c7, eSymbolSize8Bit , False, CPU6309);
AddALU("CMPF", 0x11c1, eSymbolSize8Bit , True , CPU6309);
AddALU("ADDF", 0x11cb, eSymbolSize8Bit , True , CPU6309);
AddALU("SUBF", 0x11c0, eSymbolSize8Bit , True , CPU6309);
AddALU("LDX" , 0x008e, eSymbolSize16Bit, True , CPU6809);
AddALU("STX" , 0x008f, eSymbolSize16Bit, False, CPU6809);
AddALU("CMPX", 0x008c, eSymbolSize16Bit, True , CPU6809);
AddALU("LDY" , 0x108e, eSymbolSize16Bit, True , CPU6809);
AddALU("STY" , 0x108f, eSymbolSize16Bit, False, CPU6809);
AddALU("CMPY", 0x108c, eSymbolSize16Bit, True , CPU6809);
AddALU("LDU" , 0x00ce, eSymbolSize16Bit, True , CPU6809);
AddALU("STU" , 0x00cf, eSymbolSize16Bit, False, CPU6809);
AddALU("CMPU", 0x1183, eSymbolSize16Bit, True , CPU6809);
AddALU("LDS" , 0x10ce, eSymbolSize16Bit, True , CPU6809);
AddALU("STS" , 0x10cf, eSymbolSize16Bit, False, CPU6809);
AddALU("CMPS", 0x118c, eSymbolSize16Bit, True , CPU6809);
AddALU("JSR" , 0x008d, eSymbolSize16Bit, False, CPU6809);
InstrZ = 0;
AddALU2("ADD"); AddALU2("ADC");
AddALU2("SUB"); AddALU2("SBC");
AddALU2("AND"); AddALU2("OR" );
AddALU2("EOR"); AddALU2("CMP");
InstrZ = 0;
AddRMW("NEG", 0x00, CPU6809);
AddRMW("COM", 0x03, CPU6809);
AddRMW("LSR", 0x04, CPU6809);
AddRMW("ROR", 0x06, CPU6809);
AddRMW("ASR", 0x07, CPU6809);
AddRMW("ASL", 0x08, CPU6809);
AddRMW("LSL", 0x08, CPU6809);
AddRMW("ROL", 0x09, CPU6809);
AddRMW("DEC", 0x0a, CPU6809);
AddRMW("INC", 0x0c, CPU6809);
AddRMW("TST", 0x0d, CPU6809);
AddRMW("JMP", 0x0e, CPU6809);
AddRMW("CLR", 0x0f, CPU6809);
InstrZ = 0;
AddFlag("CWAI" , 0x3c, True , CPU6809);
AddFlag("ANDCC", 0x1c, True , CPU6809);
AddFlag("ORCC" , 0x1a, False, CPU6809);
InstrZ = 0;
AddLEA("LEAX", 0x30, CPU6809);
AddLEA("LEAY", 0x31, CPU6809);
AddLEA("LEAS", 0x32, CPU6809);
AddLEA("LEAU", 0x33, CPU6809);
InstrZ = 0;
AddImm("AIM", 0x02, CPU6309);
AddImm("OIM", 0x01, CPU6309);
AddImm("EIM", 0x05, CPU6309);
AddImm("TIM", 0x0b, CPU6309);
AddInstTable(InstTable, "PSHS", 0x34 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
AddInstTable(InstTable, "PULS", 0x35 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
AddInstTable(InstTable, "PSHU", 0x36 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
AddInstTable(InstTable, "PULU", 0x37 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
InstrZ = 0;
AddInstTable(InstTable, "BAND" , InstrZ++, DecodeBit);
AddInstTable(InstTable, "BIAND", InstrZ++, DecodeBit);
AddInstTable(InstTable, "BOR" , InstrZ++, DecodeBit);
AddInstTable(InstTable, "BIOR" , InstrZ++, DecodeBit);
AddInstTable(InstTable, "BEOR" , InstrZ++, DecodeBit);
AddInstTable(InstTable, "BIEOR", InstrZ++, DecodeBit);
AddInstTable(InstTable, "LDBT" , InstrZ++, DecodeBit);
AddInstTable(InstTable, "STBT" , InstrZ++, DecodeBit);
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);
order_array_free(FlagOrders);
order_array_free(LEAOrders);
order_array_free(ImmOrders);
}
/*-------------------------------------------------------------------------*/
static Boolean DecodeAttrPart_6809(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_6809(void)
{
tSymbolSize OpSize;
CodeLen = 0;
DontPrint = False;
OpSize = (AttrPartOpSize[0] != eSymbolSizeUnknown) ? AttrPartOpSize[0] : eSymbolSize8Bit;
/* zu ignorierendes */
if (Memo(""))
return;
/* Pseudoanweisungen */
if (DecodeMoto16Pseudo(OpSize, True))
return;
if (!LookupInstTable(InstTable, OpPart.str.p_str))
WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}
static void InitCode_6809(void)
{
DPRValue = 0;
target_used = False;
}
static Boolean IsDef_6809(void)
{
return False;
}
static void SwitchTo_6809(void)
{
#define ASSUME09Count (sizeof(ASSUME09s) / sizeof(*ASSUME09s))
static const ASSUMERec ASSUME09s[] =
{
{ "DPR", &DPRValue, 0, 0xff, 0x100, NULL }
};
TurnWords = False;
SetIntConstMode(eIntConstModeMoto);
PCSymbol = "*";
HeaderID = 0x63;
NOPCode = 0x12;
DivideChars = ",";
HasAttrs = True;
AttrChars = ".";
ValidSegs = (1 << SegCode);
Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
SegLimits[SegCode] = 0xffff;
DecodeAttrPart = DecodeAttrPart_6809;
MakeCode = MakeCode_6809;
IsDef = IsDef_6809;
SwitchFrom = DeinitFields;
InitFields();
AddMoto16PseudoONOFF(False);
if (!target_used)
SetFlag(&plain_base_mode, plain_base_mode_sym_name, def_plain_base_mode_set ? def_plain_base_mode : False);
AddONOFF(plain_base_mode_cmd_name, &plain_base_mode, plain_base_mode_sym_name, False);
target_used = True;
pASSUMERecs = ASSUME09s;
ASSUMERecCnt = ASSUME09Count;
}
static as_cmd_result_t cmd_plain_base(Boolean negate, const char *p_arg)
{
UNUSED(p_arg);
def_plain_base_mode = !negate;
def_plain_base_mode_set = True;
return e_cmd_ok;
}
static const as_cmd_rec_t onoff_params[] =
{
{ plain_base_mode_cmd_name, cmd_plain_base }
};
void code6809_init(void)
{
CPU6809 = AddCPU("6809", SwitchTo_6809);
CPU6309 = AddCPU("6309", SwitchTo_6809);
as_cmd_register(onoff_params, as_array_size(onoff_params));
AddInitPassProc(InitCode_6809);
}