/* codeh8_3.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator H8/300(L/H) */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "nls.h"
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "onoff_common.h"
#include "asmstructs.h"
#include "asmitree.h"
#include "codepseudo.h"
#include "motpseudo.h"
#include "codevars.h"
#include "errmsg.h"
#include "codeh8_3.h"
#define ModNone (-1)
#define ModReg 0
#define MModReg (1 << ModReg)
#define ModImm 1
#define MModImm (1 << ModImm)
#define ModAbs8 2
#define MModAbs8 (1 << ModAbs8)
#define ModAbs16 3
#define MModAbs16 (1 << ModAbs16)
#define ModAbs24 4
#define MModAbs24 (1 << ModAbs24)
#define MModAbs (MModAbs8 | MModAbs16 | MModAbs24)
#define ModIReg 5
#define MModIReg (1 << ModIReg)
#define ModPreDec 6
#define MModPreDec (1 << ModPreDec)
#define ModPostInc 7
#define MModPostInc (1 << ModPostInc)
#define ModInd16 8
#define MModInd16 (1 << ModInd16)
#define ModInd24 9
#define MModInd24 (1 << ModInd24)
#define ModIIAbs 10
#define MModIIAbs (1 << ModIIAbs)
#define MModInd (MModInd16 | MModInd24)
/* keep in the same order as in registration */
#define M_CPUH8_300L (1 << 0)
#define M_CPU6413308 (1 << 1)
#define M_CPUH8_300 (1 << 2)
#define M_CPU6413309 (1 << 3)
#define M_CPUH8_300H (1 << 4)
#define REG_SP 7
static tSymbolSize OpSize, MomSize;
static ShortInt AdrMode; /* Ergebnisadressmodus */
static Byte AdrPart; /* Adressierungsmodusbits im Opcode */
static Word AdrVals[6]; /* Adressargument */
static CPUVar CPUH8_300L;
static CPUVar CPU6413308,CPUH8_300;
static CPUVar CPU6413309,CPUH8_300H;
static Boolean CPU16; /* keine 32-Bit-Register */
/*-------------------------------------------------------------------------*/
/* Adressparsing */
static void SetOpSize(tSymbolSize Size)
{
if (OpSize == eSymbolSizeUnknown)
OpSize = Size;
else if (Size != OpSize)
{
WrError(ErrNum_ConfOpSizes);
AdrMode = ModNone;
AdrCnt = 0;
}
}
static Boolean IsNum(char Inp, Byte *Erg)
{
if ((Inp < '0') || (Inp > '7'))
return False;
else
{
*Erg = Inp - AscOfs;
return True;
}
}
/*!------------------------------------------------------------------------
* \fn DecodeRegCore(char *pArg, Byte *pResult, tSymbolSize *pSize)
* \brief check whether argument is a CPU register
* \param pArg source argument
* \param pResult register # if yes
* \param pSize register size if yes
* \return True if it is a register
* ------------------------------------------------------------------------ */
static Boolean DecodeRegCore(char *pArg, Byte *pResult, tSymbolSize *pSize)
{
if (!as_strcasecmp(pArg, "SP"))
{
*pResult = REG_SP | REGSYM_FLAG_ALIAS;
*pSize = MaxMode ? eSymbolSize32Bit : eSymbolSize16Bit;
return True;
}
{
case 2:
if (IsNum(pArg[1], pResult))
{
if (as_toupper(*pArg) == 'R')
{
*pSize = eSymbolSize16Bit;
return True;
}
else if (as_toupper(*pArg) == 'E')
{
*pResult += 8;
*pSize = eSymbolSize16Bit;
return True;
}
}
break;
case 3:
if ((as_toupper(*pArg) == 'R') && IsNum(pArg[1], pResult))
{
if (as_toupper(pArg[2]) == 'L')
{
*pResult += 8;
*pSize = eSymbolSize8Bit;
return True;
}
else if (as_toupper(pArg[2]) == 'H')
{
*pSize = eSymbolSize8Bit;
return True;
}
}
else if ((as_toupper(*pArg) == 'E') && (as_toupper(pArg[1]) == 'R') && IsNum(pArg[2], pResult))
{
*pSize = eSymbolSize32Bit;
return True;
}
}
*pSize = eSymbolSizeUnknown;
return False;
}
/*!------------------------------------------------------------------------
* \fn DissectReg_H8_3(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
* \brief dissect register symbols - C16x variant
* \param pDest destination buffer
* \param DestSize destination buffer size
* \param Value numeric register value
* \param InpSize register size
* ------------------------------------------------------------------------ */
static void DissectReg_H8_3(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
{
switch (InpSize)
{
case eSymbolSize8Bit:
as_snprintf(pDest, DestSize, "R%u%c", (unsigned)(Value & 7), "HL"[(Value >> 3) & 1]);
break;
case eSymbolSize16Bit:
if (Value == (REG_SP | REGSYM_FLAG_ALIAS))
as_snprintf(pDest, DestSize, "SP");
else
as_snprintf(pDest, DestSize, "%c%u", "RE"[(Value >> 3) & 1], (unsigned)(Value & 7));
break;
case eSymbolSize32Bit:
if (Value == (REG_SP | REGSYM_FLAG_ALIAS))
as_snprintf(pDest, DestSize, "SP");
else
as_snprintf(pDest, DestSize, "ER%u", (unsigned)Value);
break;
default:
as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize ReqSize, tSymbolSize *pSize)
* \brief check whether argument is a CPU register or register alias
* \param pArg source argument
* \param pResult register # if yes
* \param SizeMask requested register size(s)
* \param pSize register size if yes
* \return reg eval result
* ------------------------------------------------------------------------ */
static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, unsigned SizeMask, tSymbolSize *pSize, Boolean MustBeReg)
{
tRegDescr RegDescr;
tEvalResult EvalResult;
tRegEvalResult RegEvalResult;
if (DecodeRegCore(pArg->str.p_str, pResult, pSize))
{
RegEvalResult = eIsReg;
*pResult &= ~REGSYM_FLAG_ALIAS;
}
else
{
RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
*pSize = EvalResult.DataSize;
*pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
}
if ((RegEvalResult == eIsReg)
&& !((SizeMask >> *pSize) & 1))
{
WrStrErrorPos(ErrNum_InvOpSize, pArg);
return MustBeReg ? eIsNoReg : eRegAbort;
}
return RegEvalResult;
}
static void CutSize(tStrComp *pArg)
{
int ArgLen
= strlen(pArg
->str.
p_str);
if ((ArgLen
>= 2) && !strcmp(pArg
->str.
p_str + ArgLen
- 2, ":8"))
{
StrCompShorten(pArg, 2);
MomSize = eSymbolSize8Bit;
}
else if ((ArgLen
>= 3) && !strcmp(pArg
->str.
p_str + ArgLen
- 3, ":16"))
{
StrCompShorten(pArg, 3);
MomSize = eSymbolSize16Bit;
}
else if ((ArgLen
>= 3) && !strcmp(pArg
->str.
p_str + ArgLen
- 3, ":24"))
{
StrCompShorten(pArg, 3);
MomSize = eSymbolSize24Bit;
}
}
static Boolean ChkCPU32(tErrorNum ErrorNum)
{
return ChkMinCPUExt(CPU6413309, ErrorNum);
}
static Byte DecodeBaseReg(const tStrComp *pArg, Byte *Erg, Boolean MustBeReg)
{
tSymbolSize HSize;
Word Mask;
switch (DecodeReg(pArg, Erg, (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), &HSize, MustBeReg))
{
case eIsNoReg:
return 0;
case eRegAbort:
return 1;
default:
break;
}
if ((HSize == eSymbolSize16Bit) && (*Erg > 7))
{
WrStrErrorPos(ErrNum_InvReg, pArg);
return 1;
}
Mask = (HSize == eSymbolSize16Bit) ? (M_CPUH8_300L | M_CPU6413308 | M_CPUH8_300) : (M_CPU6413309 | M_CPUH8_300H);
if (ChkExactCPUMaskExt(Mask, CPUH8_300L, ErrNum_AddrModeNotSupported) < 0)
return 1;
return 2;
}
static Boolean Is8(LongInt Address)
{
if (CPU16)
return (((Address >> 8) & 0xff) == 0xff);
else
return (((Address >> 8) & 0xffff) == 0xffff);
}
static Boolean Is16(LongInt Address)
{
return (CPU16) ? (True) : (((Address >= 0) && (Address <= 0x7fff)) || ((Address >= 0xff8000) && (Address <= 0xffffff)));
}
static void DecideVAbsolute(LongInt Address, Word Mask)
{
/* bei Automatik Operandengroesse festlegen */
if (MomSize == eSymbolSizeUnknown)
{
if (Is8(Address))
MomSize = eSymbolSize8Bit;
else if (Is16(Address))
MomSize = eSymbolSize16Bit;
else
MomSize = eSymbolSize24Bit;
}
/* wenn nicht vorhanden, eins rauf */
if ((MomSize == eSymbolSize8Bit) && ((Mask & MModAbs8) == 0))
MomSize = eSymbolSize16Bit;
if ((MomSize == eSymbolSize16Bit) && ((Mask & MModAbs16) == 0))
MomSize = eSymbolSize24Bit;
/* entsprechend Modus Bytes ablegen */
switch (MomSize)
{
case eSymbolSize8Bit:
if (!Is8(Address)) WrError(ErrNum_AdrOverflow);
else
{
AdrCnt = 2;
AdrVals[0] = Address & 0xff;
AdrMode = ModAbs8;
}
break;
case eSymbolSize16Bit:
if (!Is16(Address)) WrError(ErrNum_AdrOverflow);
else
{
AdrCnt = 2;
AdrVals[0] = Address & 0xffff;
AdrMode = ModAbs16;
}
break;
case eSymbolSize24Bit:
AdrCnt = 4;
AdrVals[1] = Address & 0xffff;
AdrVals[0] = Lo(Address >> 16);
AdrMode = ModAbs24;
break;
default:
WrError(ErrNum_InternalError);
}
}
static void DecideAbsolute(const tStrComp *pArg, Word Mask)
{
LongInt Addr;
Boolean OK;
Addr = EvalStrIntExpression(pArg, Int32, &OK);
if (OK)
DecideVAbsolute(Addr, Mask);
}
static void DecodeAdr(tStrComp *pArg, Word Mask)
{
tSymbolSize HSize;
Byte HReg;
LongInt HLong;
Boolean OK;
char *p;
LongInt DispAcc;
int ArgLen;
AdrMode = ModNone;
AdrCnt = 0;
MomSize = eSymbolSizeUnknown;
/* immediate ? */
if (*pArg->str.p_str == '#')
{
switch (OpSize)
{
case eSymbolSizeUnknown:
WrError(ErrNum_UndefOpSizes);
break;
case eSymbolSize8Bit:
HReg = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
if (OK)
{
AdrCnt = 2;
AdrVals[0] = HReg;
AdrMode = ModImm;
}
break;
case eSymbolSize16Bit:
AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
if (OK)
{
AdrCnt = 2;
AdrMode = ModImm;
}
break;
case eSymbolSize32Bit:
HLong = EvalStrIntExpressionOffs(pArg, 1, Int32, &OK);
if (OK)
{
AdrCnt = 4;
AdrVals[0] = HLong >> 16;
AdrVals[1] = HLong & 0xffff;
AdrMode = ModImm;
}
break;
default:
WrError(ErrNum_InvOpSize);
}
goto chk;
}
/* Register ? */
switch (DecodeReg(pArg, &HReg, (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), &HSize, False))
{
case eIsReg:
AdrMode = ModReg;
AdrPart = HReg;
SetOpSize(HSize);
goto chk;
case eRegAbort:
return;
case eIsNoReg:
break;
}
/* indirekt ? */
if (*pArg->str.p_str == '@')
{
tStrComp Arg;
StrCompRefRight(&Arg, pArg, 1);
if (*Arg.str.p_str == '@')
{
AdrVals[0] = EvalStrIntExpressionOffs(&Arg, 1, UInt8, &OK) & 0xff;
if (OK)
{
AdrCnt = 1;
AdrMode = ModIIAbs;
}
goto chk;
}
switch (DecodeBaseReg(&Arg, &AdrPart, False))
{
case 1:
goto chk;
case 2:
AdrMode = ModIReg;
goto chk;
}
if (*Arg.str.p_str == '-')
{
tStrComp Reg;
StrCompRefRight(&Reg, &Arg, 1);
switch (DecodeBaseReg(&Reg, &AdrPart, True))
{
case 1:
goto chk;
case 2:
AdrMode = ModPreDec;
goto chk;
}
}
ArgLen
= strlen(Arg.
str.
p_str);
if (*Arg.str.p_str && (Arg.str.p_str[ArgLen - 1] == '+'))
{
StrCompShorten(&Arg, 1);
switch (DecodeBaseReg(&Arg, &AdrPart, True))
{
case 1:
goto chk;
case 2:
AdrMode = ModPostInc;
goto chk;
}
Arg.str.p_str[ArgLen - 1] = '+'; Arg.Pos.Len++;
}
if (IsIndirect(Arg.str.p_str))
{
tStrComp Part, Remainder;
StrCompRefRight(&Part, &Arg, 1);
StrCompShorten(&Part, 1);
AdrPart = 0xff;
DispAcc = 0;
do
{
p = QuotPos(Part.str.p_str, ',');
if (p)
StrCompSplitRef(&Part, &Remainder, &Part, p);
switch (DecodeBaseReg(&Part, &HReg, False))
{
case 2:
if (AdrPart != 0xff)
{
WrError(ErrNum_InvAddrMode);
goto chk;
}
else
AdrPart = HReg;
break;
case 1:
goto chk;
case 0:
CutSize(&Part);
DispAcc += EvalStrIntExpression(&Part, Int32, &OK);
if (!OK)
{
goto chk;
}
break;
}
if (p)
Part = Remainder;
}
while (p);
if (AdrPart == 0xff)
DecideVAbsolute(DispAcc, Mask);
else
{
if ((CPU16) && ((DispAcc & 0xffff8000) == 0x8000))
DispAcc += 0xffff0000;
if (MomSize == eSymbolSizeUnknown)
MomSize = ((DispAcc >= -32768) && (DispAcc <= 32767)) ? eSymbolSize16Bit : eSymbolSize24Bit;
switch (MomSize)
{
case eSymbolSize8Bit:
WrError(ErrNum_InvOpSize);
break;
case eSymbolSize16Bit:
if (ChkRange(DispAcc, -32768, 32767))
{
AdrCnt = 2;
AdrVals[0] = DispAcc & 0xffff;
AdrMode = ModInd16;
}
break;
case eSymbolSize24Bit:
AdrVals[1] = DispAcc & 0xffff;
AdrVals[0] = Lo(DispAcc >> 16);
AdrCnt = 4;
AdrMode = ModInd24;
break;
default:
WrError(ErrNum_InternalError);
}
}
}
else
{
CutSize(&Arg);
DecideAbsolute(&Arg, Mask);
}
goto chk;
}
CutSize(pArg);
DecideAbsolute(pArg, Mask);
chk:
if (((AdrMode == ModReg) && (OpSize == eSymbolSize32Bit))
|| ((AdrMode == ModReg) && (OpSize == eSymbolSize16Bit) && (AdrPart > 7))
|| (AdrMode == ModAbs24)
|| (AdrMode == ModInd24))
{
if (!ChkMinCPUExt(CPU6413309, ErrNum_AddrModeNotSupported))
{
AdrMode = ModNone;
AdrCnt = 0;
}
}
if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
{
WrError(ErrNum_InvAddrMode);
AdrMode = ModNone;
AdrCnt = 0;
}
}
static LongInt ImmVal(void)
{
switch (OpSize)
{
case eSymbolSize8Bit:
return Lo(AdrVals[0]);
case eSymbolSize16Bit:
return AdrVals[0];
case eSymbolSize32Bit:
return (((LongInt)AdrVals[0]) << 16) + AdrVals[1];
default:
WrError(ErrNum_InternalError);
return 0;
}
}
/*--------------------------------------------------------------------------*/
/* Bit Symbol Handling */
/*
* Compact representation of bits in symbol table:
* Bits 10...3: Absolute address (8-bit value for range $FFxx or $FFFFxx)
* Bits 0..2: Bit position
*/
/*!------------------------------------------------------------------------
* \fn EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
* \brief evaluate bit position
* \param bit position argument (with or without #)
* \param pOK parsing OK?
* \return numeric bit position
* ------------------------------------------------------------------------ */
static LongWord EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
{
return EvalStrIntExpressionOffs(pArg, !!(*pArg->str.p_str == '#'), UInt3, pOK);
}
/*!------------------------------------------------------------------------
* \fn AssembleBitSymbol(Byte BitPos, LongWord Address)
* \brief build the compact internal representation of a bit symbol
* \param BitPos bit position in byte
* \param Address register address
* \return compact representation
* ------------------------------------------------------------------------ */
static LongWord AssembleBitSymbol(Byte BitPos, Word Address)
{
return
(Address << 3)
| (BitPos << 0);
}
/*!------------------------------------------------------------------------
* \fn DecodeBitArg2(LongWord *pResult, const tStrComp *pBitArg, tStrComp *pRegArg)
* \brief encode a bit symbol, address & bit position separated
* \param pResult resulting encoded bit
* \param pRegArg register argument
* \param pBitArg bit argument
* \return True if success
* ------------------------------------------------------------------------ */
static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pBitArg, tStrComp *pRegArg)
{
Boolean OK;
LongWord BitPos;
BitPos = EvalBitPosition(pBitArg, &OK);
if (!OK)
return False;
DecideAbsolute(pRegArg, MModAbs8);
if (AdrMode != ModAbs8)
return False;
*pResult = AssembleBitSymbol(BitPos, AdrVals[0]);
return True;
}
/*!------------------------------------------------------------------------
* \fn DecodeBitArg(LongWord *pResult, int Start, int Stop)
* \brief encode a bit symbol from instruction argument(s)
* \param pResult resulting encoded bit
* \param Start first argument
* \param Stop last argument
* \return True if success
* ------------------------------------------------------------------------ */
static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop)
{
*pResult = 0;
/* Just one argument -> parse as bit argument */
if (Start == Stop)
{
tEvalResult EvalResult;
*pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
if (EvalResult.OK)
ChkSpace(SegBData, EvalResult.AddrSpaceMask);
return EvalResult.OK;
}
/* register & bit position are given as separate arguments */
else if (Stop == Start + 1)
return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop]);
/* other # of arguments not allowed */
else
{
WrError(ErrNum_WrongArgCnt);
return False;
}
}
/*!------------------------------------------------------------------------
* \fn DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos)
* \brief transform compact representation of bit (field) symbol into components
* \param BitSymbol compact storage
* \param pAddress register address
* \param pBitPos bit position
* \return constant True
* ------------------------------------------------------------------------ */
static Boolean DissectBitSymbol(LongWord BitSymbol, LongWord *pAddress, Byte *pBitPos)
{
*pAddress = (BitSymbol >> 3) & 0xfful;
*pBitPos = BitSymbol & 7;
return True;
}
/*!------------------------------------------------------------------------
* \fn DissectBit_H8_3(char *pDest, size_t DestSize, LargeWord Inp)
* \brief dissect compact storage of bit (field) into readable form for listing
* \param pDest destination for ASCII representation
* \param DestSize destination buffer size
* \param Inp compact storage
* ------------------------------------------------------------------------ */
static void DissectBit_H8_3(char *pDest, size_t DestSize, LargeWord Inp)
{
Byte BitPos;
LongWord Address;
DissectBitSymbol(Inp, &Address, &BitPos);
as_snprintf(pDest, DestSize, "#%u,$%s%x", BitPos,
(HexStartCharacter == 'A') ? (CPU16 ? "FF" : "FFFF") : (CPU16 ? "ff" : "ffff"),
(unsigned)Address);
}
/*!------------------------------------------------------------------------
* \fn ExpandBit_H8_3(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
* \brief expands bit definition when a structure is instantiated
* \param pVarName desired symbol name
* \param pStructElem element definition
* \param Base base address of instantiated structure
* ------------------------------------------------------------------------ */
static void ExpandBit_H8_3(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
{
LongWord Address = Base + pStructElem->Offset;
if (pInnermostNamedStruct)
{
PStructElem pElem = CloneStructElem(pVarName, pStructElem);
if (!pElem)
return;
pElem->Offset = Address;
AddStructElem(pInnermostNamedStruct->StructRec, pElem);
}
else
{
if (!ChkRange(Address, SegLimits[SegCode] - 0xff, SegLimits[SegCode])
|| !ChkRange(pStructElem->BitPos, 0, 7))
return;
PushLocHandle(-1);
EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, Address), SegBData, False);
PopLocHandle();
/* TODO: MakeUseList? */
}
}
/*-------------------------------------------------------------------------*/
/* Code Generators */
static void DecodeFixed(Word Code)
{
if (!ChkArgCnt(0, 0));
else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
else
{
CodeLen = 2;
WAsmCode[0] = Code;
}
}
static void DecodeEEPMOV(Word Code)
{
UNUSED(Code);
if (OpSize == eSymbolSizeUnknown)
OpSize = CPU16 ? eSymbolSize8Bit : eSymbolSize16Bit;
if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
else if (!ChkArgCnt(0, 0));
else if ((OpSize == eSymbolSize16Bit) && !ChkCPU32(ErrNum_AddrModeNotSupported));
else
{
CodeLen = 4;
WAsmCode[0] = (OpSize == eSymbolSize8Bit) ? 0x7b5c : 0x7bd4;
WAsmCode[1] = 0x598f;
}
}
static void DecodeMOV(Word Code)
{
Byte HReg;
UNUSED(Code);
if (ChkArgCnt(2, 2))
{
DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPreDec | MModInd | MModAbs);
switch (AdrMode)
{
case ModReg:
HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModPostInc | MModInd | MModImm | ((OpSize == eSymbolSize8Bit) ? MModAbs : (MModAbs16 | MModAbs24)));
switch (AdrMode)
{
case ModReg:
{
int z = (OpSize == eSymbolSize32Bit) ? 3 : OpSize;
CodeLen = 2;
WAsmCode[0] = 0x0c00 + (z << 8) + (AdrPart << 4) + HReg;
if (OpSize == eSymbolSize32Bit)
WAsmCode[0] += 0x80;
break;
}
case ModIReg:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0x6800 + (AdrPart << 4) + HReg;
break;
case eSymbolSize16Bit:
CodeLen = 2;
WAsmCode[0] = 0x6900 + (AdrPart << 4) + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 4;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x6900 + (AdrPart << 4) + HReg;
break;
default:
break;
}
break;
case ModPostInc:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0x6c00 + (AdrPart << 4) + HReg;
break;
case eSymbolSize16Bit:
CodeLen = 2;
WAsmCode[0] = 0x6d00 + (AdrPart << 4) + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 4;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x6d00 + (AdrPart << 4) + HReg;
break;
default:
break;
}
break;
case ModInd16:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 4;
WAsmCode[0] = 0x6e00 + (AdrPart << 4) + HReg;
WAsmCode[1] = AdrVals[0];
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[0] = 0x6f00 + (AdrPart << 4) + HReg;
WAsmCode[1] = AdrVals[0];
break;
case eSymbolSize32Bit:
CodeLen = 6;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x6f00 + (AdrPart << 4) + HReg;
WAsmCode[2] = AdrVals[0];
break;
default:
break;
}
break;
case ModInd24:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 8;
WAsmCode[0] = 0x7800 + (AdrPart << 4);
WAsmCode[1] = 0x6a20 + HReg;
memcpy(WAsmCode
+ 2, AdrVals
, AdrCnt
);
break;
case eSymbolSize16Bit:
CodeLen = 8;
WAsmCode[0] = 0x7800 + (AdrPart << 4);
WAsmCode[1] = 0x6b20 + HReg;
memcpy(WAsmCode
+ 2, AdrVals
, AdrCnt
);
break;
case eSymbolSize32Bit:
CodeLen = 10;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x7800 + (AdrPart << 4);
WAsmCode[2] = 0x6b20 + HReg;
memcpy(WAsmCode
+ 3, AdrVals
, AdrCnt
);
break;
default:
break;
}
break;
case ModAbs8:
CodeLen = 2;
WAsmCode[0] = 0x2000 + (((Word)HReg) << 8) + Lo(AdrVals[0]);
break;
case ModAbs16:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 4;
WAsmCode[0] = 0x6a00 + HReg;
WAsmCode[1] = AdrVals[0];
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[0] = 0x6b00 + HReg;
WAsmCode[1] = AdrVals[0];
break;
case eSymbolSize32Bit:
CodeLen = 6;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x6b00 + HReg;
WAsmCode[2] = AdrVals[0];
break;
default:
break;
}
break;
case ModAbs24:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 6;
WAsmCode[0] = 0x6a20 + HReg;
memcpy(WAsmCode
+ 1, AdrVals
, AdrCnt
);
break;
case eSymbolSize16Bit:
CodeLen = 6;
WAsmCode[0] = 0x6b20 + HReg;
memcpy(WAsmCode
+ 1, AdrVals
, AdrCnt
);
break;
case eSymbolSize32Bit:
CodeLen = 8;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x6b20 + HReg;
memcpy(WAsmCode
+ 2, AdrVals
, AdrCnt
);
break;
default:
break;
}
break;
case ModImm:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0xf000 + (((Word)HReg) << 8) + Lo(AdrVals[0]);
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[0] = 0x7900 + HReg;
WAsmCode[1] = AdrVals[0];
break;
case eSymbolSize32Bit:
CodeLen = 6;
WAsmCode[0] = 0x7a00 + HReg;
memcpy(WAsmCode
+ 1, AdrVals
, AdrCnt
);
break;
default:
break;
}
break;
}
break;
case ModIReg:
HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0x6880 + (HReg << 4) + AdrPart;
break;
case eSymbolSize16Bit:
CodeLen = 2;
WAsmCode[0] = 0x6980 + (HReg << 4) + AdrPart;
break;
case eSymbolSize32Bit:
CodeLen = 4;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x6980 + (HReg << 4) + AdrPart;
break;
default:
break;
}
}
break;
case ModPreDec:
HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen=2; WAsmCode[0]=0x6c80+(HReg << 4)+AdrPart;
break;
case eSymbolSize16Bit:
CodeLen=2; WAsmCode[0]=0x6d80+(HReg << 4)+AdrPart;
break;
case eSymbolSize32Bit:
CodeLen=4; WAsmCode[0]=0x0100;
WAsmCode[1]=0x6d80+(HReg << 4)+AdrPart;
break;
default:
break;
}
}
break;
case ModInd16:
HReg = AdrPart;
WAsmCode[1] = AdrVals[0];
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode!=ModNone)
{
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 4;
WAsmCode[0] = 0x6e80 + (HReg << 4) + AdrPart;
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[0] = 0x6f80 + (HReg << 4) + AdrPart;
break;
case eSymbolSize32Bit:
CodeLen = 6;
WAsmCode[0] = 0x0100;
WAsmCode[2] = WAsmCode[1];
WAsmCode[1] = 0x6f80 + (HReg << 4) + AdrPart;
break;
default:
break;
}
}
break;
case ModInd24:
HReg = AdrPart;
memcpy(WAsmCode
+ 2, AdrVals
, 4);
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 8;
WAsmCode[0] = 0x7800 + (HReg << 4);
WAsmCode[1] = 0x6aa0 + AdrPart;
break;
case eSymbolSize16Bit:
CodeLen = 8;
WAsmCode[0] = 0x7800 + (HReg << 4);
WAsmCode[1] = 0x6ba0 + AdrPart;
break;
case eSymbolSize32Bit:
CodeLen = 10;
WAsmCode[0] = 0x0100;
WAsmCode[4] = WAsmCode[3];
WAsmCode[3] = WAsmCode[2];
WAsmCode[1] = 0x7800 + (HReg << 4);
WAsmCode[2] = 0x6ba0 + AdrPart;
break;
default:
break;
}
}
break;
case ModAbs8:
HReg = Lo(AdrVals[0]);
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0x3000 + (((Word)AdrPart) << 8) + HReg;
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[0] = 0x6b80 + AdrPart;
WAsmCode[1] = 0xff00 + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 6;
WAsmCode[0] = 0x0100;
WAsmCode[1] = 0x6b80 + AdrPart;
WAsmCode[2] = 0xff00 + HReg;
break;
default:
break;
}
}
break;
case ModAbs16:
WAsmCode[1] = AdrVals[0];
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 4;
WAsmCode[0] = 0x6a80 + AdrPart;
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[0] = 0x6b80 + AdrPart;
break;
case eSymbolSize32Bit:
CodeLen = 6;
WAsmCode[0] = 0x0100;
WAsmCode[2] = WAsmCode[1];
WAsmCode[1] = 0x6b80 + AdrPart;
break;
default:
break;
}
}
break;
case ModAbs24:
memcpy(WAsmCode
+ 1, AdrVals
, 4);
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 6;
WAsmCode[0] = 0x6aa0 + AdrPart;
break;
case eSymbolSize16Bit:
CodeLen = 6;
WAsmCode[0] = 0x6ba0 + AdrPart;
break;
case eSymbolSize32Bit:
CodeLen = 8;
WAsmCode[0] = 0x0100;
WAsmCode[3] = WAsmCode[2];
WAsmCode[2] = WAsmCode[1];
WAsmCode[1] = 0x6ba0 + AdrPart;
break;
default:
break;
}
}
break;
}
}
}
static void DecodeMOVTPE_MOVFPE(Word CodeTPE)
{
if (ChkArgCnt(2, 2)
&& ChkMinCPU(CPU6413308))
{
tStrComp *pRegArg = CodeTPE ? &ArgStr[1] : &ArgStr[2],
*pMemArg = CodeTPE ? &ArgStr[2] : &ArgStr[1];
DecodeAdr(pRegArg, MModReg);
if (AdrMode != ModNone)
{
if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
else
{
Byte HReg = AdrPart;
DecodeAdr(pMemArg, MModAbs16);
if (AdrMode != ModNone)
{
CodeLen = 4;
WAsmCode[0] = 0x6a40 + CodeTPE + HReg;
WAsmCode[1] = AdrVals[0];
}
}
}
}
}
static void DecodePUSH_POP(Word Code)
{
if (ChkArgCnt(1, 1))
{
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
if (OpSize == eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
else if ((OpSize != eSymbolSize32Bit) || ChkCPU32(ErrNum_AddrModeNotSupported))
{
if (OpSize == eSymbolSize32Bit)
WAsmCode[0] = 0x0100;
CodeLen = 2 * OpSize;
WAsmCode[(CodeLen - 2) >> 1] = Code + AdrPart;
}
}
}
}
static void DecodeLDC_STC(Word CodeIsSTC)
{
if (ChkArgCnt(2, 2))
{
tStrComp *pRegArg = CodeIsSTC ? &ArgStr[1] : &ArgStr[2],
*pMemArg = CodeIsSTC ? &ArgStr[2] : &ArgStr[1];
if (as_strcasecmp(pRegArg->str.p_str, "CCR")) WrError(ErrNum_InvAddrMode);
else
{
SetOpSize(eSymbolSize8Bit);
DecodeAdr(pMemArg, MModReg | MModIReg | MModInd | MModAbs16 | MModAbs24 | (CodeIsSTC ? MModPreDec : (MModImm | MModPostInc)));
switch (AdrMode)
{
case ModReg:
CodeLen = 2;
WAsmCode[0] = 0x0300 + AdrPart - (CodeIsSTC << 1);
break;
case ModIReg:
CodeLen = 4;
WAsmCode[0] = 0x0140;
WAsmCode[1] = 0x6900 + CodeIsSTC + (AdrPart << 4);
break;
case ModPostInc:
case ModPreDec:
CodeLen = 4;
WAsmCode[0] = 0x0140;
WAsmCode[1] = 0x6d00 + CodeIsSTC + (AdrPart << 4);
break;
case ModInd16:
CodeLen = 6;
WAsmCode[0] = 0x0140;
WAsmCode[2] = AdrVals[0];
WAsmCode[1] = 0x6f00 + CodeIsSTC + (AdrPart << 4);
break;
case ModInd24:
CodeLen = 10;
WAsmCode[0] = 0x0140;
WAsmCode[1] = 0x7800 + (AdrPart << 4);
WAsmCode[2] = 0x6b20 + CodeIsSTC;
memcpy(WAsmCode
+ 3, AdrVals
, AdrCnt
);
break;
case ModAbs16:
CodeLen = 6;
WAsmCode[0] = 0x0140;
WAsmCode[2] = AdrVals[0];
WAsmCode[1] = 0x6b00 + CodeIsSTC;
break;
case ModAbs24:
CodeLen = 8;
WAsmCode[0] = 0x0140;
WAsmCode[1] = 0x6b20 + CodeIsSTC;
memcpy(WAsmCode
+ 2, AdrVals
, AdrCnt
);
break;
case ModImm:
CodeLen = 2;
WAsmCode[0] = 0x0700 + Lo(AdrVals[0]);
break;
}
}
}
}
static void DecodeADD_SUB(Word IsSUB)
{
if (ChkArgCnt(2, 2))
{
DecodeAdr(&ArgStr[2], MModReg);
if (AdrMode != ModNone)
{
Byte HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModReg | MModImm);
if (AdrMode != ModNone)
{
if (((OpSize > eSymbolSize16Bit) || ((OpSize == eSymbolSize16Bit) && (AdrMode == ModImm))) && !ChkCPU32(ErrNum_AddrModeNotSupported));
else
{
switch (AdrMode)
{
case ModImm:
switch (OpSize)
{
case eSymbolSize8Bit:
if (IsSUB) WrError(ErrNum_InvAddrMode);
else
{
CodeLen = 2;
WAsmCode[0] = 0x8000 + (((Word)HReg) << 8) + Lo(AdrVals[0]);
}
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[1] = AdrVals[0];
WAsmCode[0] = 0x7910 + (IsSUB << 5) + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 6;
memcpy(WAsmCode
+ 1, AdrVals
, 4);
WAsmCode[0] = 0x7a10 + (IsSUB << 5) + HReg;
break;
default:
break;
}
break;
case ModReg:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0x0800 + (IsSUB << 12) + (AdrPart << 4) + HReg;
break;
case eSymbolSize16Bit:
CodeLen = 2;
WAsmCode[0] = 0x0900 + (IsSUB << 12) + (AdrPart << 4) + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 2;
WAsmCode[0] = 0x0a00 + (IsSUB << 12) + 0x80 + (AdrPart << 4) + HReg;
break;
default:
break;
}
break;
}
}
}
}
}
}
static void DecodeCMP(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(2, 2))
{
DecodeAdr(&ArgStr[2], MModReg);
if (AdrMode != ModNone)
{
Byte HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModReg | MModImm);
if (AdrMode != ModNone)
{
if (((OpSize > eSymbolSize16Bit) || ((OpSize == eSymbolSize16Bit) && (AdrMode == ModImm))) && !ChkCPU32(ErrNum_AddrModeNotSupported));
else
{
switch (AdrMode)
{
case ModImm:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0xa000 + (((Word)HReg) << 8) + Lo(AdrVals[0]);
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[1] = AdrVals[0];
WAsmCode[0] = 0x7920 + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 6;
memcpy(WAsmCode
+ 1, AdrVals
, 4);
WAsmCode[0] = 0x7a20 + HReg;
default:
break;
}
break;
case ModReg:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0x1c00 + (AdrPart << 4) + HReg;
break;
case eSymbolSize16Bit:
CodeLen = 2;
WAsmCode[0] = 0x1d00 + (AdrPart << 4) + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 2;
WAsmCode[0] = 0x1f80 + (AdrPart << 4) + HReg;
break;
default:
break;
}
break;
}
}
}
}
}
}
static void DecodeLogic(Word Code)
{
if (ChkArgCnt(2, 2))
{
DecodeAdr(&ArgStr[2], MModReg);
if (AdrMode != ModNone)
{
if ((OpSize <= eSymbolSize8Bit) || ChkCPU32(ErrNum_AddrModeNotSupported))
{
Byte HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModImm | MModReg);
switch (AdrMode)
{
case ModImm:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0xc000 + (Code << 12) + (((Word)HReg) << 8) + Lo(AdrVals[0]);
break;
case eSymbolSize16Bit:
CodeLen = 4;
WAsmCode[1] = AdrVals[0];
WAsmCode[0] = 0x7940 + (Code << 4) + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 6;
memcpy(WAsmCode
+ 1, AdrVals
, AdrCnt
);
WAsmCode[0] = 0x7a40 + (Code << 4) + HReg;
break;
default:
break;
}
break;
case ModReg:
switch (OpSize)
{
case eSymbolSize8Bit:
CodeLen = 2;
WAsmCode[0] = 0x1400 + (Code << 8) + (AdrPart << 4) + HReg;
break;
case eSymbolSize16Bit:
CodeLen = 2;
WAsmCode[0] = 0x6400 + (Code << 8) + (AdrPart << 4) + HReg;
break;
case eSymbolSize32Bit:
CodeLen = 4;
WAsmCode[0] = 0x01f0;
WAsmCode[1] = 0x6400 + (Code << 8) + (AdrPart << 4) + HReg;
break;
default:
break;
}
break;
}
}
}
}
}
static void DecodeLogicBit(Word Code)
{
SetOpSize(eSymbolSize8Bit);
if (!ChkArgCnt(2, 2));
else if (as_strcasecmp(ArgStr[2].str.p_str, "CCR")) WrError(ErrNum_InvAddrMode);
else
{
DecodeAdr(&ArgStr[1], MModImm);
if (AdrMode != ModNone)
{
CodeLen = 2;
WAsmCode[0] = 0x0400 + (Code << 8) + Lo(AdrVals[0]);
}
}
}
static void DecodeADDX_SUBX(Word IsSUBX)
{
if (ChkArgCnt(2, 2))
{
DecodeAdr(&ArgStr[2], MModReg);
if (AdrMode != ModNone)
{
if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
else
{
Byte HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModImm | MModReg);
switch (AdrMode)
{
case ModImm:
CodeLen = 2;
WAsmCode[0] = 0x9000 + (((Word)HReg) << 8) + Lo(AdrVals[0]) + (IsSUBX << 13);
break;
case ModReg:
CodeLen = 2;
WAsmCode[0] = 0x0e00 + (AdrPart << 4) + HReg + (IsSUBX << 12);
break;
}
}
}
}
}
static void DecodeADDS_SUBS(Word IsSUBS)
{
if (ChkArgCnt(2, 2))
{
DecodeAdr(&ArgStr[2], MModReg);
if (AdrMode != ModNone)
{
if (((CPU16) && (OpSize != eSymbolSize16Bit)) || ((!CPU16) && (OpSize != eSymbolSize32Bit))) WrError(ErrNum_InvOpSize);
else
{
Byte HReg = AdrPart;
DecodeAdr(&ArgStr[1], MModImm);
if (AdrMode != ModNone)
{
LongInt AdrLong = ImmVal();
if ((AdrLong != 1) && (AdrLong != 2) && (AdrLong != 4)) WrError(ErrNum_OverRange);
else
{
switch (AdrLong)
{
case 1: WAsmCode[0] = 0x0b00; break;
case 2: WAsmCode[0] = 0x0b80; break;
case 4: WAsmCode[0] = 0x0b90; break;
}
CodeLen = 2;
WAsmCode[0] += HReg + IsSUBS;
}
}
}
}
}
}
static void DecodeMul(Word Code)
{
if (ChkArgCnt(2, 2))
{
if (OpSize != eSymbolSizeUnknown) OpSize++;
DecodeAdr(&ArgStr[2], MModReg);
if (AdrMode != ModNone)
{
if (OpSize == eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
else if ((OpSize != eSymbolSize32Bit) || ChkCPU32(ErrNum_AddrModeNotSupported))
{
Byte HReg = AdrPart;
OpSize--;
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
if ((Code & 2) == 2)
{
CodeLen = 4;
WAsmCode[0] = 0x01c0;
if ((Code & 1) == 1)
WAsmCode[0] += 0x10;
}
else
CodeLen=2;
WAsmCode[CodeLen >> 2] = 0x5000
+ (((Word)OpSize) << 9)
+ ((Code & 1) << 8)
+ (AdrPart << 4) + HReg;
}
}
}
}
}
static void DecodeBit1(Word Code)
{
Word OpCode = 0x60 + (Code & 0x7f);
Byte BitPos;
switch (ArgCnt)
{
case 1:
{
LongWord BitSpec;
if (DecodeBitArg(&BitSpec, 1, 1))
{
LongWord Addr;
DissectBitSymbol(BitSpec, &Addr, &BitPos);
AdrMode = ModAbs8;
AdrVals[0] = Addr & 0xff;
AdrCnt = 2;
goto common;
}
break;
}
case 2:
{
Boolean OK;
BitPos = EvalBitPosition(&ArgStr[1], &OK);
if (OK)
{
DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModAbs8);
if (AdrMode != ModNone)
goto common;
}
break;
}
common:
if (OpSize > eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
else switch (AdrMode)
{
case ModReg:
CodeLen = 2;
WAsmCode[0] = (OpCode << 8) + (Code & 0x80) + (BitPos << 4) + AdrPart;
break;
case ModIReg:
CodeLen = 4;
WAsmCode[0] = 0x7c00 + (AdrPart << 4);
WAsmCode[1] = (OpCode << 8) + (Code & 0x80) + (BitPos << 4);
if (OpCode < 0x70)
WAsmCode[0] += 0x100;
break;
case ModAbs8:
CodeLen = 4;
WAsmCode[0] = 0x7e00 + Lo(AdrVals[0]);
WAsmCode[1] = (OpCode << 8) + (Code & 0x80) + (BitPos << 4);
if (OpCode < 0x70)
WAsmCode[0] += 0x100;
break;
}
break;
default:
(void)ChkArgCnt(1, 2);
}
}
static void DecodeBit2(Word Code)
{
Word OpCode;
Byte Bit;
Boolean OK;
tSymbolSize HSize;
switch (ArgCnt)
{
case 1:
{
LongWord BitSpec;
if (DecodeBitArg(&BitSpec, 1, 1))
{
LongWord Addr;
DissectBitSymbol(BitSpec, &Addr, &Bit);
OpCode = Code + 0x70;
AdrMode = ModAbs8;
AdrVals[0] = Addr & 0xff;
AdrCnt = 2;
goto common;
}
break;
}
case 2:
switch (DecodeReg(&ArgStr[1], &Bit, 1 << eSymbolSize8Bit, &HSize, False))
{
case eIsReg:
OpCode = Code + 0x60;
OK = True;
break;
case eIsNoReg:
OpCode = Code + 0x70;
Bit = EvalBitPosition(&ArgStr[1], &OK);
break;
default: /* eRegAbort */
return;
}
if (OK)
{
DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModAbs8);
if (AdrMode != ModNone)
goto common;
break;
}
common:
if (OpSize > eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
else
{
switch (AdrMode)
{
case ModReg:
CodeLen = 2;
WAsmCode[0] = (OpCode << 8) + (Bit << 4) + AdrPart;
break;
case ModIReg:
CodeLen = 4;
WAsmCode[0] = 0x7d00 + (AdrPart << 4);
WAsmCode[1] = (OpCode << 8) + (Bit << 4);
if (Code == 3)
WAsmCode[0] -= 0x100;
break;
case ModAbs8:
CodeLen = 4;
WAsmCode[0] = 0x7f00 + Lo(AdrVals[0]);
WAsmCode[1] = (OpCode << 8) + (Bit << 4);
if (Code == 3)
WAsmCode[0] -= 0x100;
break;
}
}
break;
default:
(void)ChkArgCnt(1, 2);
}
}
static void DecodeINC_DEC(Word Code)
{
Boolean OK;
int z;
Byte HReg;
if (ChkArgCnt(1, 2))
{
DecodeAdr(&ArgStr[ArgCnt], MModReg);
if (AdrMode != ModNone)
{
if ((OpSize <= eSymbolSize8Bit) || ChkCPU32(ErrNum_AddrModeNotSupported))
{
HReg = AdrPart;
if (ArgCnt == 1)
{
OK = True;
z = 1;
}
else
{
DecodeAdr(&ArgStr[1], MModImm);
OK = (AdrMode == ModImm);
if (OK)
{
z = ImmVal();
if (z < 1)
{
WrError(ErrNum_UnderRange);
OK = False;
}
else if (((OpSize == eSymbolSize8Bit) && (z > 1)) || (z > 2))
{
WrError(ErrNum_OverRange);
OK = False;
}
}
}
if (OK)
{
CodeLen = 2;
z--;
switch (OpSize)
{
case eSymbolSize8Bit:
WAsmCode[0] = Code + 0x0a00 + HReg;
break;
case eSymbolSize16Bit:
WAsmCode[0] = Code + 0x0b50 + HReg + (z << 7);
break;
case eSymbolSize32Bit:
WAsmCode[0] = Code + 0x0b70 + HReg + (z << 7);
break;
default:
break;
}
}
}
}
}
}
static void DecodeShift(Word Code)
{
if (ChkArgCnt(1, 1))
{
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
if ((OpSize <= eSymbolSize8Bit) || ChkCPU32(ErrNum_AddrModeNotSupported))
{
CodeLen = 2;
switch (OpSize)
{
case eSymbolSize8Bit:
WAsmCode[0] = Code + AdrPart;
break;
case eSymbolSize16Bit:
WAsmCode[0] = Code + AdrPart + 0x10;
break;
case eSymbolSize32Bit:
WAsmCode[0] = Code + AdrPart + 0x30;
break;
default:
break;
}
}
}
}
}
static void DecodeNEG_NOT(Word Code)
{
if (ChkArgCnt(1, 1))
{
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
if ((OpSize <= eSymbolSize8Bit) || ChkCPU32(ErrNum_AddrModeNotSupported))
{
CodeLen = 2;
switch (OpSize)
{
case eSymbolSize8Bit:
WAsmCode[0] = Code + 0x1700 + AdrPart;
break;
case eSymbolSize16Bit:
WAsmCode[0] = Code + 0x1710 + AdrPart;
break;
case eSymbolSize32Bit:
WAsmCode[0] = Code + 0x1730 + AdrPart;
break;
default:
break;
}
}
}
}
}
static void DecodeEXTS_EXTU(Word IsEXTS)
{
if (ChkArgCnt(1, 1)
&& ChkCPU32(ErrNum_InstructionNotSupported))
{
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
if ((OpSize != eSymbolSize16Bit) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
else
{
CodeLen = 2;
switch (OpSize)
{
case eSymbolSize16Bit:
WAsmCode[0] = IsEXTS ? 0x17d0 : 0x1750;
break;
case eSymbolSize32Bit:
WAsmCode[0] = IsEXTS ? 0x17f0 : 0x1770;
break;
default:
break;
}
WAsmCode[0] += AdrPart;
}
}
}
}
static void DecodeDAA_DAS(Word Code)
{
if (ChkArgCnt(1, 1))
{
DecodeAdr(&ArgStr[1], MModReg);
if (AdrMode != ModNone)
{
if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
else
{
CodeLen = 2;
WAsmCode[0] = Code + AdrPart;
}
}
}
}
static void DecodeCond(Word Code)
{
if (!ChkArgCnt(1, 1));
else if ((OpSize != eSymbolSizeUnknown) && (OpSize != eSymbolSizeFloat32Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
else
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], Int24, &OK, &Flags) - (EProgCounter() + 2);
if (OK)
{
if (OpSize == eSymbolSizeUnknown)
{
if ((AdrLong >= -128) && (AdrLong <= 127))
OpSize = eSymbolSizeFloat32Bit;
else
{
OpSize = eSymbolSize32Bit;
AdrLong -= 2;
}
}
else if (OpSize == eSymbolSize32Bit)
AdrLong -= 2;
if (OpSize == eSymbolSize32Bit)
{
if (!mSymbolQuestionable(Flags) && ((AdrLong < -32768) || (AdrLong > 32767))) WrError(ErrNum_JmpDistTooBig);
else if (ChkCPU32(ErrNum_AddrModeNotSupported))
{
CodeLen = 4;
WAsmCode[0] = 0x5800 + (Code << 4);
WAsmCode[1] = AdrLong & 0xffff;
}
}
else
{
if (!mSymbolQuestionable(Flags) && ((AdrLong < -128) || (AdrLong > 127))) WrError(ErrNum_JmpDistTooBig);
else
{
CodeLen = 2;
WAsmCode[0] = 0x4000 + (Code << 8) + (AdrLong & 0xff);
}
}
}
}
}
static void DecodeJMP_JSR(Word Code)
{
if (ChkArgCnt(1, 1))
{
DecodeAdr(&ArgStr[1], MModIReg | ((CPU16) ? MModAbs16 : MModAbs24) | MModIIAbs);
switch (AdrMode)
{
case ModIReg:
CodeLen = 2;
WAsmCode[0] = 0x5900 + Code + (AdrPart << 4);
break;
case ModAbs16:
CodeLen = 4;
WAsmCode[0] = 0x5a00 + Code;
WAsmCode[1] = AdrVals[0];
break;
case ModAbs24:
CodeLen = 4;
WAsmCode[0] = 0x5a00 + Code + Lo(AdrVals[0]);
WAsmCode[1] = AdrVals[1];
break;
case ModIIAbs:
CodeLen = 2;
WAsmCode[0] = 0x5b00 + Code + Lo(AdrVals[0]);
break;
}
}
}
static void DecodeBSR(Word Code)
{
UNUSED(Code);
if (!ChkArgCnt(1, 1));
else if ((OpSize != eSymbolSizeUnknown) && (OpSize != eSymbolSizeFloat32Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
else
{
Boolean OK;
tSymbolFlags Flags;
LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], Int24, &OK, &Flags) - (EProgCounter() + 2);
if (OK)
{
if (OpSize == eSymbolSizeUnknown)
{
if ((AdrLong >= -128) && (AdrLong <= 127))
OpSize = eSymbolSizeFloat32Bit;
else
{
OpSize = eSymbolSize32Bit;
AdrLong -= 2;
}
}
else
{
if (OpSize == eSymbolSize32Bit)
AdrLong -= 2;
}
if (OpSize == eSymbolSize32Bit)
{
if (!mSymbolQuestionable(Flags) && ((AdrLong < -32768) || (AdrLong > 32767))) WrError(ErrNum_JmpDistTooBig);
else if (ChkCPU32(ErrNum_AddrModeNotSupported))
{
CodeLen = 4;
WAsmCode[0] = 0x5c00;
WAsmCode[1] = AdrLong & 0xffff;
}
}
else
{
if ((AdrLong < -128) || (AdrLong > 127)) WrError(ErrNum_JmpDistTooBig);
else
{
CodeLen = 2;
WAsmCode[0] = 0x5500 + (AdrLong & 0xff);
}
}
}
}
}
static void DecodeTRAPA(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU6413309))
{
Boolean OK;
WAsmCode[0] = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt2, &OK) << 4;
if (OK)
{
WAsmCode[0] += 0x5700;
CodeLen = 2;
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeBIT(Word Code)
* \brief handle BIT instruction
* ------------------------------------------------------------------------ */
static void DecodeBIT(Word Code)
{
UNUSED(Code);
/* if in structure definition, add special element to structure */
if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSizeUnknown))
{
WrError(ErrNum_InvOpSize);
return;
}
if (ActPC == StructSeg)
{
Boolean OK;
Byte BitPos;
PStructElem pElement;
if (!ChkArgCnt(2, 2))
return;
BitPos = EvalBitPosition(&ArgStr[1], &OK);
if (!OK)
return;
pElement = CreateStructElem(&LabPart);
if (!pElement)
return;
pElement->pRefElemName = as_strdup(ArgStr[2].str.p_str);
pElement->OpSize = eSymbolSize8Bit;
pElement->BitPos = BitPos;
pElement->ExpandFnc = ExpandBit_H8_3;
AddStructElem(pInnermostNamedStruct->StructRec, pElement);
}
else
{
LongWord BitSpec;
if (DecodeBitArg(&BitSpec, 1, ArgCnt))
{
*ListLine = '=';
DissectBit_H8_3(ListLine + 1, STRINGSIZE - 3, BitSpec);
PushLocHandle(-1);
EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
PopLocHandle();
/* TODO: MakeUseList? */
}
}
}
/*-------------------------------------------------------------------------*/
/* dynamische Belegung/Freigabe Codetabellen */
static void AddFixed(const char *NName, Word NCode)
{
AddInstTable(InstTable, NName, NCode, DecodeFixed);
}
static void AddCond(const char *NName, Byte NCode)
{
AddInstTable(InstTable, NName, NCode, DecodeCond);
}
static void AddShift(const char *NName, Word NCode)
{
AddInstTable(InstTable, NName, NCode, DecodeShift);
}
static void AddLogic(const char *NName, const char *NNameBit, Word NCode)
{
AddInstTable(InstTable, NName, NCode, DecodeLogic);
AddInstTable(InstTable, NNameBit, NCode, DecodeLogicBit);
}
static void AddMul(const char *NName, Word NCode)
{
AddInstTable(InstTable, NName, NCode, DecodeMul);
}
static void AddBit1(const char *NName, Word NCode)
{
AddInstTable(InstTable, NName, NCode, DecodeBit1);
}
static void AddBit2(const char *NName, Word NCode)
{
AddInstTable(InstTable, NName, NCode, DecodeBit2);
}
static void InitFields(void)
{
InstTable = CreateInstTable(203);
AddInstTable(InstTable, "EEPMOV", 0, DecodeEEPMOV);
AddInstTable(InstTable, "MOV", 0, DecodeMOV);
AddInstTable(InstTable, "MOVTPE", 0x80, DecodeMOVTPE_MOVFPE);
AddInstTable(InstTable, "MOVFPE", 0x00, DecodeMOVTPE_MOVFPE);
AddInstTable(InstTable, "PUSH", 0x6df0, DecodePUSH_POP);
AddInstTable(InstTable, "POP", 0x6d70, DecodePUSH_POP);
AddInstTable(InstTable, "LDC", 0x00, DecodeLDC_STC);
AddInstTable(InstTable, "STC", 0x80, DecodeLDC_STC);
AddInstTable(InstTable, "ADD", 0, DecodeADD_SUB);
AddInstTable(InstTable, "SUB", 1, DecodeADD_SUB);
AddInstTable(InstTable, "CMP", 0, DecodeCMP);
AddInstTable(InstTable, "ADDX", 0, DecodeADDX_SUBX);
AddInstTable(InstTable, "SUBX", 1, DecodeADDX_SUBX);
AddInstTable(InstTable, "ADDS", 0x0000, DecodeADDS_SUBS);
AddInstTable(InstTable, "SUBS", 0x1000, DecodeADDS_SUBS);
AddInstTable(InstTable, "INC", 0x0000, DecodeINC_DEC);
AddInstTable(InstTable, "DEC", 0x1000, DecodeINC_DEC);
AddInstTable(InstTable, "NEG", 0x80, DecodeNEG_NOT);
AddInstTable(InstTable, "NOT", 0x00, DecodeNEG_NOT);
AddInstTable(InstTable, "EXTS", 1, DecodeEXTS_EXTU);
AddInstTable(InstTable, "EXTU", 0, DecodeEXTS_EXTU);
AddInstTable(InstTable, "DAA", 0x0f00, DecodeDAA_DAS);
AddInstTable(InstTable, "DAS", 0x1f00, DecodeDAA_DAS);
AddInstTable(InstTable, "JMP", 0x0000, DecodeJMP_JSR);
AddInstTable(InstTable, "JSR", 0x0400, DecodeJMP_JSR);
AddInstTable(InstTable, "BSR", 0, DecodeBSR);
AddInstTable(InstTable, "TRAPA", 0, DecodeTRAPA);
AddFixed("NOP", 0x0000); AddFixed("RTE" , 0x5670);
AddFixed("RTS", 0x5470); AddFixed("SLEEP", 0x0180);
AddCond("BRA", 0x0); AddCond("BT" , 0x0);
AddCond("BRN", 0x1); AddCond("BF" , 0x1);
AddCond("BHI", 0x2); AddCond("BLS", 0x3);
AddCond("BCC", 0x4); AddCond("BHS", 0x4);
AddCond("BCS", 0x5); AddCond("BLO", 0x5);
AddCond("BNE", 0x6); AddCond("BEQ", 0x7);
AddCond("BVC", 0x8); AddCond("BVS", 0x9);
AddCond("BPL", 0xa); AddCond("BMI", 0xb);
AddCond("BGE", 0xc); AddCond("BLT", 0xd);
AddCond("BGT", 0xe); AddCond("BLE", 0xf);
AddShift("ROTL" , 0x1280); AddShift("ROTR" , 0x1380);
AddShift("ROTXL", 0x1200); AddShift("ROTXR", 0x1300);
AddShift("SHAL" , 0x1080); AddShift("SHAR" , 0x1180);
AddShift("SHLL" , 0x1000); AddShift("SHLR" , 0x1100);
AddLogic("OR", "ORC", 0);
AddLogic("XOR", "XORC", 1);
AddLogic("AND", "ANDC", 2);
AddMul("DIVXS", 3);
AddMul("DIVXU", 1);
AddMul("MULXS", 2);
AddMul("MULXU", 0);
AddBit1("BAND", 0x16); AddBit1("BIAND", 0x96);
AddBit1("BOR" , 0x14); AddBit1("BIOR" , 0x94);
AddBit1("BXOR", 0x15); AddBit1("BIXOR", 0x95);
AddBit1("BLD" , 0x17); AddBit1("BILD" , 0x97);
AddBit1("BST" , 0x07); AddBit1("BIST" , 0x87);
AddBit2("BCLR", 2);
AddBit2("BNOT", 1);
AddBit2("BSET", 0);
AddBit2("BTST", 3);
AddInstTable(InstTable, "REG", 0, CodeREG);
AddInstTable(InstTable, "BIT", 0, DecodeBIT);
}
static void DeinitFields(void)
{
DestroyInstTable(InstTable);
}
/*-------------------------------------------------------------------------*/
/*!------------------------------------------------------------------------
* \fn InternSymbol_H8_3(char *pArg, TempResult *pResult)
* \brief handle built-in symbols on H8/300
* \param pArg source argument
* \param pResult result buffer
* ------------------------------------------------------------------------ */
static void InternSymbol_H8_3(char *pArg, TempResult *pResult)
{
Byte Result;
tSymbolSize Size;
if (DecodeRegCore(pArg, &Result, &Size))
{
pResult->Typ = TempReg;
pResult->DataSize = Size;
pResult->Contents.RegDescr.Reg = Result;
pResult->Contents.RegDescr.Dissect = DissectReg_H8_3;
pResult->Contents.RegDescr.compare = NULL;
}
}
static Boolean DecodeAttrPart_H8_3(void)
{
if (*AttrPart.str.p_str)
{
if (strlen(AttrPart.
str.
p_str) != 1)
{
WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
return False;
}
if (!DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False))
return False;
}
return True;
}
static void MakeCode_H8_3(void)
{
CodeLen = 0; DontPrint = False;
/* zu ignorierendes */
if (Memo("")) return;
OpSize = eSymbolSizeUnknown;
if (AttrPartOpSize[0] != eSymbolSizeUnknown)
SetOpSize(AttrPartOpSize[0]);
if (DecodeMoto16Pseudo(OpSize, True)) return;
if (!LookupInstTable(InstTable, OpPart.str.p_str))
WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}
static Boolean IsDef_H8_3(void)
{
return Memo("REG")
|| Memo("BIT");
}
static void SwitchTo_H8_3(void)
{
TurnWords = True;
SetIntConstMode(eIntConstModeMoto);
PCSymbol = "*";
HeaderID = 0x68;
NOPCode = 0x0000;
DivideChars = ",";
HasAttrs = True;
AttrChars = ".";
ValidSegs = 1 << SegCode;
Grans[SegCode] = 1;
ListGrans[SegCode] = 2;
SegInits[SegCode] = 0;
SegLimits[SegCode] = (MomCPU <= CPUH8_300) ? 0xffff : 0xffffffl;
DecodeAttrPart = DecodeAttrPart_H8_3;
MakeCode = MakeCode_H8_3;
IsDef = IsDef_H8_3;
InternSymbol = InternSymbol_H8_3;
DissectReg = DissectReg_H8_3;
DissectBit = DissectBit_H8_3;
QualifyQuote = QualifyQuote_SingleQuoteConstant;
IntConstModeIBMNoTerm = True;
SwitchFrom = DeinitFields;
InitFields();
onoff_maxmode_add();
AddMoto16PseudoONOFF(False);
CPU16 = (MomCPU <= CPUH8_300);
}
void codeh8_3_init(void)
{
CPUH8_300L = AddCPU("H8/300L" , SwitchTo_H8_3);
CPU6413308 = AddCPU("HD6413308" , SwitchTo_H8_3);
CPUH8_300 = AddCPU("H8/300" , SwitchTo_H8_3);
CPU6413309 = AddCPU("HD6413309" , SwitchTo_H8_3);
CPUH8_300H = AddCPU("H8/300H" , SwitchTo_H8_3);
}