/* codeh8_5.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* AS-Codegenerator H8/500 */
/* */
/*****************************************************************************/
#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 "asmitree.h"
#include "asmstructs.h"
#include "codepseudo.h"
#include "motpseudo.h"
#include "codevars.h"
#include "errmsg.h"
#include "codeh8_5.h"
#define REG_SP 7
#define REG_FP 6
#define ModNone (-1)
#define ModReg 0
#define MModReg (1 << ModReg)
#define ModIReg 1
#define MModIReg (1 << ModIReg)
#define ModDisp8 2
#define MModDisp8 (1 << ModDisp8)
#define ModDisp16 3
#define MModDisp16 (1 << ModDisp16)
#define ModPredec 4
#define MModPredec (1 << ModPredec)
#define ModPostInc 5
#define MModPostInc (1 << ModPostInc)
#define ModAbs8 6
#define MModAbs8 (1 << ModAbs8)
#define ModAbs16 7
#define MModAbs16 (1 << ModAbs16)
#define ModImm 8
#define MModImm (1 << ModImm)
#define MModImmVariable (1 << 9)
#define MModAll (MModReg|MModIReg|MModDisp8|MModDisp16|MModPredec|MModPostInc|MModAbs8|MModAbs16|MModImm)
#define MModNoImm (MModAll & ~MModImm)
typedef struct
{
char *Name
;
Word Code
;
Byte SizeMask
;
tSymbolSize DefSize
;
} OneOrder
;
static CPUVar CPU532
,CPU534
,CPU536
,CPU538
;
static tSymbolSize OpSize
;
static char *Format
;
static ShortInt AdrMode
;
static Byte AdrByte
,FormatCode
;
static Byte AdrVals
[3];
static Byte AbsBank
;
static tSymbolSize ImmSize
;
static ShortInt Adr2Mode
;
static Byte Adr2Byte
, Adr2Cnt
;
static Byte Adr2Vals
[3];
static tSymbolSize Imm2Size
;
static LongInt Reg_DP
,Reg_EP
,Reg_TP
,Reg_BR
;
static OneOrder
*OneOrders
;
static OneOrder
*OneRegOrders
;
static OneOrder
*RegEAOrders
;
static OneOrder
*TwoRegOrders
;
#define ASSUMEH8_5Count 4
static ASSUMERec ASSUMEH8_5s
[ASSUMEH8_5Count
] =
{
{"DP", &Reg_DP
, 0, 0xff, -1, NULL
},
{"EP", &Reg_EP
, 0, 0xff, -1, NULL
},
{"TP", &Reg_TP
, 0, 0xff, -1, NULL
},
{"BR", &Reg_BR
, 0, 0xff, -1, NULL
}
};
/*-------------------------------------------------------------------------*/
/* Adressparsing */
static void SetOpSize
(tSymbolSize NSize
)
{
if (OpSize
== eSymbolSizeUnknown
) OpSize
= NSize
;
else if (OpSize
!= NSize
) WrError
(ErrNum_ConfOpSizes
);
}
/*!------------------------------------------------------------------------
* \fn DecodeRegCore(const char *pArg, Byte *pResult)
* \brief check whether argument is a CPU register
* \param pArg source argument
* \param pResult register # if yes
* \return True if yes
* ------------------------------------------------------------------------ */
static Boolean DecodeRegCore
(const char *pArg
, Byte
*pResult
)
{
if (!as_strcasecmp
(pArg
, "SP")) *pResult
= REG_SP
| REGSYM_FLAG_ALIAS
;
else if (!as_strcasecmp
(pArg
, "FP")) *pResult
= REG_FP
| REGSYM_FLAG_ALIAS
;
else if ((strlen(pArg
) == 2) && (as_toupper
(*pArg
) == 'R') && (pArg
[1] >= '0') && (pArg
[1] <= '7'))
*pResult
= pArg
[1] - '0';
else
return False
;
return True
;
}
/*!------------------------------------------------------------------------
* \fn DissectReg_H8_5(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
* \brief dissect register symbols - H8/500 variant
* \param pDest destination buffer
* \param DestSize destination buffer size
* \param Value numeric register value
* \param InpSize register size
* ------------------------------------------------------------------------ */
static void DissectReg_H8_5
(char *pDest
, size_t DestSize
, tRegInt Value
, tSymbolSize InpSize
)
{
switch (InpSize
)
{
case eSymbolSize16Bit
:
if (Value
== (REG_SP
| REGSYM_FLAG_ALIAS
))
as_snprintf
(pDest
, DestSize
, "SP");
else if (Value
== (REG_FP
| REGSYM_FLAG_ALIAS
))
as_snprintf
(pDest
, DestSize
, "FP");
else
as_snprintf
(pDest
, DestSize
, "R%u", (unsigned)Value
);
break;
default:
as_snprintf
(pDest
, DestSize
, "%d-%u", (int)InpSize
, (unsigned)Value
);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
* \brief check whether argument is a CPU register or CPU alias
* \param pArg source argument
* \param pResult register # if yes
* \param MustBeReg True if argument must be a register
* \return EvalResult
* ------------------------------------------------------------------------ */
static tRegEvalResult DecodeReg
(const tStrComp
*pArg
, Byte
*pResult
, Boolean MustBeReg
)
{
tRegDescr RegDescr
;
tEvalResult EvalResult
;
tRegEvalResult RegEvalResult
;
if (DecodeRegCore
(pArg
->str.
p_str, pResult
))
{
*pResult
&= ~REGSYM_FLAG_ALIAS
;
return eIsReg
;
}
RegEvalResult
= EvalStrRegExpressionAsOperand
(pArg
, &RegDescr
, &EvalResult
, eSymbolSize16Bit
, MustBeReg
);
*pResult
= RegDescr.
Reg;
return RegEvalResult
;
}
static Boolean DecodeRegList
(tStrComp
*pArg
, Byte
*pResult
)
{
tStrComp Arg
, Remainder
;
Byte Reg1
, Reg2
, z
;
char *p
, *p2
;
StrCompRefRight
(&Arg
, pArg
, 0);
if (IsIndirect
(Arg.
str.
p_str))
{
StrCompIncRefLeft
(&Arg
, 1);
StrCompShorten
(&Arg
, 1);
KillPrefBlanksStrCompRef
(&Arg
);
KillPostBlanksStrComp
(&Arg
);
}
*pResult
= 0;
do
{
p
= QuotPos
(Arg.
str.
p_str, ',');
if (p
)
StrCompSplitRef
(&Arg
, &Remainder
, &Arg
, p
);
p2
= strchr(Arg.
str.
p_str, '-');
if (p2
)
{
tStrComp Left
, Right
;
StrCompSplitRef
(&Left
, &Right
, &Arg
, p2
);
if (DecodeReg
(&Left
, &Reg1
, True
) != eIsReg
) return False
;
if (DecodeReg
(&Right
, &Reg2
, True
) != eIsReg
) return False
;
if (Reg1
> Reg2
) Reg2
+= 8;
for (z
= Reg1
; z
<= Reg2
; z
++) *pResult
|= (1 << (z
& 7));
}
else
{
if (DecodeReg
(&Arg
, &Reg1
, True
) != eIsReg
) return False
;
*pResult
|= (1 << Reg1
);
}
if (p
)
Arg
= Remainder
;
}
while (p
);
return True
;
}
static Boolean DecodeCReg
(char *Asc
, Byte
*pErg
)
{
if (!as_strcasecmp
(Asc
, "SR"))
{
*pErg
= 0; SetOpSize
(eSymbolSize16Bit
);
}
else if (!as_strcasecmp
(Asc
, "CCR"))
{
*pErg
= 1; SetOpSize
(eSymbolSize8Bit
);
}
else if (!as_strcasecmp
(Asc
, "BR"))
{
*pErg
= 3; SetOpSize
(eSymbolSize8Bit
);
}
else if (!as_strcasecmp
(Asc
, "EP"))
{
*pErg
= 4; SetOpSize
(eSymbolSize8Bit
);
}
else if (!as_strcasecmp
(Asc
, "DP"))
{
*pErg
= 5; SetOpSize
(eSymbolSize8Bit
);
}
else if (!as_strcasecmp
(Asc
, "TP"))
{
*pErg
= 7; SetOpSize
(eSymbolSize8Bit
);
}
else
return False
;
return True
;
}
static void SplitDisp
(tStrComp
*pArg
, tSymbolSize
*pSize
)
{
int l
= strlen(pArg
->str.
p_str);
if ((l
> 2) && !strcmp(pArg
->str.
p_str + l
- 2, ":8"))
{
StrCompShorten
(pArg
, 2);
*pSize
= eSymbolSize8Bit
;
}
else if ((l
> 3) && !strcmp(pArg
->str.
p_str + l
- 3, ":16"))
{
StrCompShorten
(pArg
, 3);
*pSize
= eSymbolSize16Bit
;
}
}
static void DecideAbsolute
(LongInt Value
, tSymbolSize Size
, Boolean Unknown
, Word Mask
)
{
LongInt Base
;
if (Size
== eSymbolSizeUnknown
)
{
if (((Value
>> 8) == Reg_BR
) && (Mask
& MModAbs8
)) Size
= eSymbolSize8Bit
;
else Size
= eSymbolSize16Bit
;
}
AdrMode
= ModNone
;
AdrCnt
= 0;
switch (Size
)
{
case eSymbolSize8Bit
:
if (Unknown
) Value
= (Value
& 0xff) | (Reg_BR
<< 8);
if ((Value
>> 8) != Reg_BR
) WrError
(ErrNum_InAccPage
);
AdrMode
= ModAbs8
; AdrByte
= 0x05;
AdrVals
[0] = Value
& 0xff; AdrCnt
= 1;
break;
case eSymbolSize16Bit
:
if (MaxMode
)
{
Base
= AbsBank
;
Base
<<= 16;
}
else
Base
= 0;
if (Unknown
) Value
= (Value
& 0xffff) | Base
;
if ((Value
>> 16) != (Base
>> 16)) WrError
(ErrNum_InAccPage
);
AdrMode
= ModAbs16
; AdrByte
= 0x15;
AdrVals
[0] = (Value
>> 8) & 0xff;
AdrVals
[1] = Value
& 0xff;
AdrCnt
= 2;
break;
default:
break;
}
}
static void ChkAdr
(Word Mask
)
{
if ((AdrMode
!= ModNone
) && (!(Mask
& (1 << AdrMode
))))
{
WrError
(ErrNum_InvAddrMode
); AdrMode
= ModNone
; AdrCnt
= 0;
}
}
static void DecodeAdr
(tStrComp
*pArg
, Word Mask
)
{
Word AdrWord
;
Boolean OK
, Unknown
;
tSymbolFlags Flags
;
LongInt DispAcc
;
Byte HReg
;
tSymbolSize DispSize
;
ShortInt RegPart
;
char *p
;
AdrMode
= ModNone
; AdrCnt
= 0;
ImmSize
= eSymbolSizeUnknown
;
/* einfaches Register ? */
switch (DecodeReg
(pArg
, &AdrByte
, False
))
{
case eIsReg
:
AdrMode
= ModReg
; AdrByte
|= 0xa0;
ChkAdr
(Mask
); return;
case eRegAbort
:
return;
case eIsNoReg
:
break;
}
/* immediate ? */
if (*pArg
->str.
p_str == '#')
{
SplitDisp
(pArg
, &ImmSize
);
if (ImmSize
== eSymbolSizeUnknown
)
{
if (!(Mask
& MModImmVariable
))
ImmSize
= OpSize
;
}
else if ((ImmSize
!= OpSize
) && !(Mask
& MModImmVariable
))
{
WrStrErrorPos
(ErrNum_ConfOpSizes
, pArg
);
return;
}
switch (OpSize
)
{
case eSymbolSizeUnknown
:
OK
= False
; WrError
(ErrNum_UndefOpSizes
);
break;
case eSymbolSize8Bit
:
AdrVals
[0] = EvalStrIntExpressionOffs
(pArg
, 1, Int8
, &OK
);
break;
case eSymbolSize16Bit
:
AdrWord
= EvalStrIntExpressionOffs
(pArg
, 1, Int16
, &OK
);
AdrVals
[0] = Hi
(AdrWord
); AdrVals
[1] = Lo
(AdrWord
);
break;
default:
OK
= False
;
break;
}
if (OK
)
{
AdrMode
= ModImm
; AdrByte
= 0x04; AdrCnt
= OpSize
+ 1;
}
ChkAdr
(Mask
); return;
}
/* indirekt ? */
if (*pArg
->str.
p_str == '@')
{
tStrComp Arg
, Remainder
;
StrCompRefRight
(&Arg
, pArg
, 1);
if (IsIndirect
(Arg.
str.
p_str))
{
StrCompIncRefLeft
(&Arg
, 1);
StrCompShorten
(&Arg
, 1);
}
/* Predekrement ? */
if (*Arg.
str.
p_str == '-')
{
tStrComp RegArg
;
StrCompRefRight
(&RegArg
, &Arg
, 1);
if (DecodeReg
(&RegArg
, &AdrByte
, True
) == eIsReg
)
{
AdrMode
= ModPredec
; AdrByte
|= 0xb0;
ChkAdr
(Mask
); return;
}
}
/* Postinkrement ? */
if ((*Arg.
str.
p_str) && (Arg.
str.
p_str[strlen(Arg.
str.
p_str) - 1] == '+'))
{
StrCompShorten
(&Arg
, 1);
if (DecodeReg
(&Arg
, &AdrByte
, True
) == eIsReg
)
{
AdrMode
= ModPostInc
; AdrByte
|= 0xc0;
ChkAdr
(Mask
); return;
}
}
/* zusammengesetzt */
DispAcc
= 0; DispSize
= eSymbolSizeUnknown
; RegPart
= -1; OK
= True
; Unknown
= False
;
do
{
p
= QuotPos
(Arg.
str.
p_str, ',');
if (p
)
StrCompSplitRef
(&Arg
, &Remainder
, &Arg
, p
);
switch (DecodeReg
(&Arg
, &HReg
, False
))
{
case eIsReg
:
if (RegPart
!= -1)
{
WrStrErrorPos
(ErrNum_InvAddrMode
, &Arg
); OK
= False
;
}
else
RegPart
= HReg
;
break;
case eIsNoReg
:
SplitDisp
(&Arg
, &DispSize
);
DispAcc
+= EvalStrIntExpressionOffsWithFlags
(&Arg
, !!(*Arg.
str.
p_str == '#'), Int32
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
)) Unknown
= True
;
break;
default:
OK
= False
;
}
if (p
)
Arg
= Remainder
;
}
while (p
&& OK
);
if (OK
)
{
if (RegPart
== -1) DecideAbsolute
(DispAcc
, DispSize
, Unknown
, Mask
);
else if (DispAcc
== 0)
{
switch (DispSize
)
{
case eSymbolSizeUnknown
:
AdrMode
= ModIReg
; AdrByte
= 0xd0 | RegPart
;
break;
case eSymbolSize8Bit
:
AdrMode
= ModDisp8
; AdrByte
= 0xe0 | RegPart
;
AdrVals
[0] = 0; AdrCnt
= 1;
break;
case eSymbolSize16Bit
:
AdrMode
= ModDisp16
; AdrByte
= 0xf0 | RegPart
;
AdrVals
[0] = 0; AdrVals
[1] = 0; AdrCnt
= 2;
break;
default:
break;
}
}
else
{
if (DispSize
== eSymbolSizeUnknown
)
{
if ((DispAcc
>= -128) && (DispAcc
< 127)) DispSize
= eSymbolSize8Bit
;
else DispSize
= eSymbolSize16Bit
;
}
switch (DispSize
)
{
case eSymbolSize8Bit
:
if (Unknown
) DispAcc
&= 0x7f;
if (ChkRange
(DispAcc
, -128, 127))
{
AdrMode
= ModDisp8
; AdrByte
= 0xe0 | RegPart
;
AdrVals
[0] = DispAcc
& 0xff; AdrCnt
= 1;
}
break;
case eSymbolSize16Bit
:
if (Unknown
) DispAcc
&= 0x7fff;
if (ChkRange
(DispAcc
, -0x8000l
, 0xffffl
))
{
AdrMode
= ModDisp16
; AdrByte
= 0xf0 | RegPart
;
AdrVals
[1] = DispAcc
& 0xff;
AdrVals
[0] = (DispAcc
>> 8) & 0xff;
AdrCnt
= 2;
}
break;
default:
break;
}
}
}
ChkAdr
(Mask
); return;
}
/* absolut */
DispSize
= eSymbolSizeUnknown
; SplitDisp
(pArg
, &DispSize
);
DispAcc
= EvalStrIntExpressionWithFlags
(pArg
, UInt24
, &OK
, &Flags
);
DecideAbsolute
(DispAcc
, DispSize
, mFirstPassUnknown
(Flags
), Mask
);
ChkAdr
(Mask
);
}
static LongInt ImmVal
(void)
{
LongInt t
;
switch (OpSize
)
{
case eSymbolSize8Bit
:
t
= AdrVals
[0]; if (t
> 127) t
-= 256;
break;
case eSymbolSize16Bit
:
t
= (((Word
)AdrVals
[0]) << 8) + AdrVals
[1];
if (t
> 0x7fff) t
-= 0x10000;
break;
default:
t
= 0; WrError
(ErrNum_InternalError
);
}
return t
;
}
/*!------------------------------------------------------------------------
* \fn AdaptImmSize(const tStrComp *pArg)
* \brief necessary post-processing if immediate operand size may differ from insn size
* \param pArg immediate argument
* \return True if adaption succeeded
* ------------------------------------------------------------------------ */
static Boolean AdaptImmSize
(const tStrComp
*pArg
)
{
LongInt ImmV
= ImmVal
();
Boolean ImmValShort
= CompMode
? ((ImmV
>= 0) && (ImmV
<= 255)) : ((ImmV
>= -128) && (ImmV
<= 127));
switch (OpSize
)
{
/* no AdrVals adaptions needed for pure 8 bit: */
case eSymbolSize8Bit
:
if (ImmSize
== eSymbolSize16Bit
)
{
WrStrErrorPos
(ErrNum_ConfOpSizes
, pArg
);
return False
;
}
else
{
ImmSize
= eSymbolSize8Bit
;
return True
;
}
case eSymbolSize16Bit
:
switch (ImmSize
)
{
case eSymbolSize16Bit
:
return True
;
case eSymbolSize8Bit
:
if (!ImmValShort
)
{
WrStrErrorPos
(ErrNum_OverRange
, pArg
);
return False
;
}
else
goto Make8
;
case eSymbolSizeUnknown
:
if (ImmValShort
)
{
ImmSize
= eSymbolSize8Bit
;
goto Make8
;
}
else
{
ImmSize
= eSymbolSize16Bit
;
return True
;
}
default:
WrStrErrorPos
(ErrNum_InternalError
, pArg
);
return False
;
Make8
:
AdrVals
[0] = AdrVals
[1];
AdrCnt
--;
return True
;
}
default:
WrStrErrorPos
(ErrNum_InternalError
, pArg
);
return False
;
}
}
/*--------------------------------------------------------------------------*/
/* Bit Symbol Handling */
/*
* Compact representation of bits in symbol table:
* Bit 31/30: Operand size (00 = unknown, 10=8, 11=16 bits)
* Bit 29/28: address field size (00 = unknown, 10=8, 11=16 bits)
* Bits 27...4 or 26..3: Absolute address
* Bits 0..2 or 0..3: Bit position
*/
static LongWord CodeOpSize
(tSymbolSize Size
)
{
return (Size
== eSymbolSizeUnknown
)
? 0
: ((Size
== eSymbolSize16Bit
) ? 3 : 2);
}
static tSymbolSize DecodeOpSize
(Byte SizeCode
)
{
return (SizeCode
& 2)
? ((SizeCode
& 1) ? eSymbolSize16Bit
: eSymbolSize8Bit
)
: eSymbolSizeUnknown
;
}
/*!------------------------------------------------------------------------
* \fn EvalBitPosition(const tStrComp *pArg, tSymbolSize Size, Boolean *pOK)
* \brief evaluate bit position
* \param bit position argument (with or without #)
* \param Size operand size (8/16/unknown)
* \param pOK parsing OK?
* \return numeric bit position
* ------------------------------------------------------------------------ */
static LongWord EvalBitPosition
(const tStrComp
*pArg
, tSymbolSize Size
, Boolean
*pOK
)
{
return EvalStrIntExpressionOffs
(pArg
, !!(*pArg
->str.
p_str == '#'), (Size
== eSymbolSize16Bit
) ? UInt4
: UInt3
, pOK
);
}
/*!------------------------------------------------------------------------
* \fn AssembleBitSymbol(Byte BitPos, LongWord Address, tSymbolSize OpSize, tSymbolSize AddrSize)
* \brief build the compact internal representation of a bit symbol
* \param BitPos bit position in word
* \param Address register address
* \param OpSize memory operand size
* \param AddrSize address length
* \return compact representation
* ------------------------------------------------------------------------ */
static LongWord AssembleBitSymbol
(Byte BitPos
, Word Address
, tSymbolSize OpSize
, tSymbolSize AddrSize
)
{
return
(CodeOpSize
(OpSize
) << 30)
| (CodeOpSize
(AddrSize
) << 28)
| (Address
<< ((OpSize
== eSymbolSize8Bit
) ? 3 : 4))
| (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 Addr
, BitPos
;
tSymbolSize AddrSize
= eSymbolSizeUnknown
;
BitPos
= EvalBitPosition
(pBitArg
, (OpSize
== eSymbolSizeUnknown
) ? eSymbolSize16Bit
: OpSize
, &OK
);
if (!OK
)
return False
;
SplitDisp
(pRegArg
, &AddrSize
);
Addr
= EvalStrIntExpression
(pRegArg
, UInt24
, &OK
);
if (!OK
)
return False
;
*pResult
= AssembleBitSymbol
(BitPos
, Addr
, OpSize
, AddrSize
);
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, tSymbolSize *pOpSize, tSymbolSize *pAddrSize)
* \brief transform compact representation of bit (field) symbol into components
* \param BitSymbol compact storage
* \param pAddress register address
* \param pBitPos bit position
* \param pOpSize operand size
* \param pAddrSize address length
* \return constant True
* ------------------------------------------------------------------------ */
static Boolean DissectBitSymbol
(LongWord BitSymbol
, LongWord
*pAddress
, Byte
*pBitPos
, tSymbolSize
*pOpSize
, tSymbolSize
*pAddrSize
)
{
*pOpSize
= DecodeOpSize
(BitSymbol
>> 30);
*pAddrSize
= DecodeOpSize
(BitSymbol
>> 28);
*pAddress
= (BitSymbol
>> ((*pOpSize
== eSymbolSize8Bit
) ? 3 : 4)) & 0xfffffful
;
*pBitPos
= BitSymbol
& (*pOpSize
? 15 : 7);
return True
;
}
/*!------------------------------------------------------------------------
* \fn DissectBit_H8_5(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_5
(char *pDest
, size_t DestSize
, LargeWord Inp
)
{
Byte BitPos
;
LongWord Address
;
tSymbolSize OpSize
, AddrSize
;
DissectBitSymbol
(Inp
, &Address
, &BitPos
, &OpSize
, &AddrSize
);
as_snprintf
(pDest
, DestSize
, "#%u,$%llx", BitPos
, (LargeWord
)Address
);
if (AddrSize
!= eSymbolSizeUnknown
)
as_snprcatf
(pDest
, DestSize
, ":%u", AddrSize
? 16 : 8);
if (OpSize
!= eSymbolSizeUnknown
)
as_snprcatf
(pDest
, DestSize
, ".%c", "BW"[OpSize
]);
}
/*!------------------------------------------------------------------------
* \fn ExpandBit_H8_5(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_5
(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
{
tSymbolSize OpSize
= (pStructElem
->OpSize
< 0) ? eSymbolSize8Bit
: pStructElem
->OpSize
;
if (!ChkRange
(Address
, 0, 0xffffff)
|| !ChkRange
(pStructElem
->BitPos
, 0, (8 << OpSize
) - 1))
return;
PushLocHandle
(-1);
EnterIntSymbol
(pVarName
, AssembleBitSymbol
(pStructElem
->BitPos
, Address
, OpSize
, eSymbolSizeUnknown
), SegBData
, False
);
PopLocHandle
();
/* TODO: MakeUseList? */
}
}
/*-------------------------------------------------------------------------*/
static Boolean CheckFormat
(const char *FSet
)
{
const char *p
;
if (!strcmp(Format
, " "))
FormatCode
= 0;
else
{
p
= strchr(FSet
, *Format
);
if (!p
)
{
WrError
(ErrNum_InvFormat
);
return False
;
}
else
FormatCode
= p
- FSet
+ 1;
}
return True
;
}
static Boolean FormatToBranchSize
(const char *pFormat
, tSymbolSize
*pOpSize
)
{
if (!strcmp(pFormat
, " "));
else if (!strcmp(pFormat
, "16")) /* treat like .L */
{
if (*pOpSize
== eSymbolSizeUnknown
) *pOpSize
= eSymbolSize32Bit
;
else if (*pOpSize
!= eSymbolSize32Bit
)
{
WrXError
(ErrNum_ConfOpSizes
, Format
);
return False
;
}
}
else if (!strcmp(pFormat
, "8")) /* treat like .S */
{
if (*pOpSize
== eSymbolSizeUnknown
) *pOpSize
= eSymbolSizeFloat32Bit
;
else if (*pOpSize
!= eSymbolSizeFloat32Bit
)
{
WrXError
(ErrNum_ConfOpSizes
, Format
);
return False
;
}
}
else
{
WrXError
(ErrNum_InvFormat
, Format
);
return False
;
}
return True
;
}
static void CopyAdr
(void)
{
Adr2Mode
= AdrMode
;
Adr2Byte
= AdrByte
;
Adr2Cnt
= AdrCnt
;
Imm2Size
= ImmSize
;
memcpy(Adr2Vals
, AdrVals
, AdrCnt
);
}
/*-------------------------------------------------------------------------*/
/* Instruction Decoders */
static void DecodeFixed
(Word Code
)
{
if (!ChkArgCnt
(0, 0));
else if (OpSize
!= eSymbolSizeUnknown
) WrError
(ErrNum_UseLessAttr
);
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else
{
CodeLen
= 0;
if (Hi
(Code
) != 0)
BAsmCode
[CodeLen
++] = Hi
(Code
);
BAsmCode
[CodeLen
++] = Lo
(Code
);
}
}
static void DecodeMOV
(Word Dummy
)
{
UNUSED
(Dummy
);
if (!ChkArgCnt
(2, 2));
else if (CheckFormat
("GEIFLS"))
{
if (OpSize
== eSymbolSizeUnknown
)
SetOpSize
((FormatCode
== 2) ? eSymbolSize8Bit
: eSymbolSize16Bit
);
if ((OpSize
!= eSymbolSize8Bit
) && (OpSize
!= eSymbolSize16Bit
)) WrError
(ErrNum_InvOpSize
);
else
{
DecodeAdr
(&ArgStr
[2], MModNoImm
);
if (AdrMode
!= ModNone
)
{
CopyAdr
();
DecodeAdr
(&ArgStr
[1], MModAll
| MModImmVariable
);
if (AdrMode
!= ModNone
)
{
if (FormatCode
== 0)
{
if ((AdrMode
== ModImm
) && ((ImmSize
== OpSize
) || (ImmSize
== eSymbolSizeUnknown
)) && (Adr2Mode
== ModReg
)) FormatCode
= 2 + OpSize
;
else if ((AdrMode
== ModReg
) && (Adr2Byte
== 0xe6)) FormatCode
= 4;
else if ((Adr2Mode
== ModReg
) && (AdrByte
== 0xe6)) FormatCode
= 4;
else if ((AdrMode
== ModReg
) && (Adr2Mode
== ModAbs8
)) FormatCode
= 6;
else if ((AdrMode
== ModAbs8
) && (Adr2Mode
== ModReg
)) FormatCode
= 5;
else FormatCode
= 1;
}
switch (FormatCode
)
{
case 1:
if ((AdrMode
== ModReg
) && (Adr2Mode
== ModReg
))
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
BAsmCode
[1] = 0x80 | (Adr2Byte
& 7);
CodeLen
= 2;
}
else if (AdrMode
== ModReg
)
{
BAsmCode
[0] = Adr2Byte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, Adr2Vals
, Adr2Cnt
);
BAsmCode
[1 + Adr2Cnt
] = 0x90 | (AdrByte
& 7);
CodeLen
= 2 + Adr2Cnt
;
}
else if (Adr2Mode
== ModReg
)
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = 0x80 | (Adr2Byte
& 7);
CodeLen
= 2 + AdrCnt
;
}
else if (AdrMode
== ModImm
)
{
BAsmCode
[0] = Adr2Byte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, Adr2Vals
, Adr2Cnt
);
if (AdaptImmSize
(&ArgStr
[1]))
{
BAsmCode
[1 + Adr2Cnt
] = 0x06 + ImmSize
;
memcpy(BAsmCode
+ 1 + Adr2Cnt
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + Adr2Cnt
+ 1 + AdrCnt
;
}
}
else WrError
(ErrNum_InvAddrMode
);
break;
case 2:
if ((AdrMode
!= ModImm
) || (Adr2Mode
!= ModReg
)) WrError
(ErrNum_InvAddrMode
);
else if (OpSize
!= eSymbolSize8Bit
) WrError
(ErrNum_InvOpSize
);
else
{
BAsmCode
[0] = 0x50 | (Adr2Byte
& 7);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
break;
case 3:
if ((AdrMode
!= ModImm
) || (Adr2Mode
!= ModReg
)) WrError
(ErrNum_InvAddrMode
);
else if (OpSize
!= eSymbolSize16Bit
) WrError
(ErrNum_InvOpSize
);
else
{
BAsmCode
[0] = 0x58 | (Adr2Byte
& 7);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
break;
case 4:
if ((AdrMode
== ModReg
) && (Adr2Byte
== 0xe6))
{
BAsmCode
[0] = 0x90 | (OpSize
<< 3) | (AdrByte
& 7);
memcpy(BAsmCode
+ 1, Adr2Vals
, Adr2Cnt
);
CodeLen
=1 + Adr2Cnt
;
}
else if ((Adr2Mode
== ModReg
) && (AdrByte
== 0xe6))
{
BAsmCode
[0] = 0x80 | (OpSize
<< 3) | (Adr2Byte
& 7);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
else WrError
(ErrNum_InvAddrMode
);
break;
case 5:
if ((AdrMode
!= ModAbs8
) || (Adr2Mode
!= ModReg
)) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[0] = 0x60 | (OpSize
<< 3) | (Adr2Byte
& 7);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
break;
case 6:
if ((Adr2Mode
!= ModAbs8
) || (AdrMode
!= ModReg
)) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[0] = 0x70 | (OpSize
<< 3) | (AdrByte
& 7);
memcpy(BAsmCode
+ 1, Adr2Vals
, Adr2Cnt
);
CodeLen
= 1 + Adr2Cnt
;
}
break;
}
}
}
}
}
}
static void DecodeLDC_STC
(Word IsSTC_16
)
{
Byte HReg
;
int CRegIdx
= 2, AdrIdx
= 1;
if (!ChkArgCnt
(2, 2));
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else
{
if (IsSTC_16
)
{
CRegIdx
= 1;
AdrIdx
= 2;
}
if (!DecodeCReg
(ArgStr
[CRegIdx
].
str.
p_str, &HReg
)) WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[2]);
else
{
DecodeAdr
(&ArgStr
[AdrIdx
], IsSTC_16
? MModNoImm
: MModAll
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = 0x88 | IsSTC_16
| HReg
;
CodeLen
= 2 + AdrCnt
;
}
}
}
}
static void DecodeLDM
(Word Dummy
)
{
UNUSED
(Dummy
);
if (OpSize
== eSymbolSizeUnknown
) OpSize
= eSymbolSize16Bit
;
if (!ChkArgCnt
(2, 2));
else if (OpSize
!= eSymbolSize16Bit
) WrError
(ErrNum_InvOpSize
);
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (!DecodeRegList
(&ArgStr
[2], BAsmCode
+ 1)) WrError
(ErrNum_InvRegList
);
else
{
DecodeAdr
(&ArgStr
[1], MModPostInc
);
if (AdrMode
!= ModNone
)
{
if ((AdrByte
& 7) != 7) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[0] = 0x02; CodeLen
= 2;
}
}
}
}
static void DecodeSTM
(Word Dummy
)
{
UNUSED
(Dummy
);
if (OpSize
== eSymbolSizeUnknown
) OpSize
= eSymbolSize16Bit
;
if (!ChkArgCnt
(2, 2));
else if (OpSize
!= eSymbolSize16Bit
) WrError
(ErrNum_InvOpSize
);
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (!DecodeRegList
(&ArgStr
[1], BAsmCode
+ 1)) WrError
(ErrNum_InvRegList
);
else
{
DecodeAdr
(&ArgStr
[2], MModPredec
);
if (AdrMode
!= ModNone
)
{
if ((AdrByte
& 7) != 7) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[0] = 0x12; CodeLen
= 2;
}
}
}
}
static void DecodeMOVTPE_MOVFPE
(Word IsMOVTPE_16
)
{
Byte HReg
;
int RegIdx
= 2, AdrIdx
= 1;
if (ChkArgCnt
(2, 2)
&& CheckFormat
("G"))
{
if (IsMOVTPE_16
)
{
RegIdx
= 1;
AdrIdx
= 2;
}
if (OpSize
== eSymbolSizeUnknown
) SetOpSize
(eSymbolSize8Bit
);
if (OpSize
!= eSymbolSize8Bit
) WrError
(ErrNum_InvOpSize
);
else if (DecodeReg
(&ArgStr
[RegIdx
], &HReg
, True
))
{
DecodeAdr
(&ArgStr
[AdrIdx
], MModNoImm
& (~MModReg
));
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = 0;
BAsmCode
[2 + AdrCnt
] = 0x80 | HReg
| IsMOVTPE_16
;
CodeLen
=3 + AdrCnt
;
}
}
}
}
static void DecodeADD_SUB
(Word IsSUB_16
)
{
LongInt AdrLong
;
if (ChkArgCnt
(2, 2)
&& CheckFormat
("GQ"))
{
if (OpSize
== eSymbolSizeUnknown
) SetOpSize
(eSymbolSize16Bit
);
if ((OpSize
!= eSymbolSize8Bit
) && (OpSize
!= eSymbolSize16Bit
)) WrError
(ErrNum_InvOpSize
);
else
{
DecodeAdr
(&ArgStr
[2], MModNoImm
);
if (AdrMode
!= ModNone
)
{
CopyAdr
();
DecodeAdr
(&ArgStr
[1], MModAll
);
if (AdrMode
!= ModNone
)
{
AdrLong
= ImmVal
();
if (FormatCode
== 0)
{
if ((AdrMode
== ModImm
) && (abs(AdrLong
) >= 1) && (abs(AdrLong
) <= 2) && !IsSUB_16
) FormatCode
= 2;
else FormatCode
= 1;
}
switch (FormatCode
)
{
case 1:
if (Adr2Mode
!= ModReg
) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = 0x20 | IsSUB_16
| (Adr2Byte
& 7);
CodeLen
= 2 + AdrCnt
;
}
break;
case 2:
if (ChkRange
(AdrLong
, -2, 2))
{
if (AdrLong
== 0) WrError
(ErrNum_UnderRange
);
else
{
if (IsSUB_16
) AdrLong
= (-AdrLong
);
BAsmCode
[0] = Adr2Byte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, Adr2Vals
, Adr2Cnt
);
BAsmCode
[1 + Adr2Cnt
] = 0x08 | (abs(AdrLong
) - 1);
if (AdrLong
< 0) BAsmCode
[1 + Adr2Cnt
] |= 4;
CodeLen
= 2 + Adr2Cnt
;
}
}
break;
}
}
}
}
}
}
/* NOTE: though the length of immediate data im G format is explicitly
coded and independent of the operand size, the manual seems to suggest
that it is not allowed for CMP to use an 8-bit immediate value with a
16-bit operand, assuming the immediate value will be sign-extended.
This mechanism is described e.g. for MOV:G, but not for CMP:G. So
we omit this optimization here: */
#define CMP_IMMVARIABLE 0
static void DecodeCMP
(Word Dummy
)
{
UNUSED
(Dummy
);
if (ChkArgCnt
(2, 2)
&& CheckFormat
("GEI"))
{
if (OpSize
== eSymbolSizeUnknown
)
SetOpSize
((FormatCode
== 2) ? eSymbolSize8Bit
: eSymbolSize16Bit
);
if ((OpSize
!= 0) && (OpSize
!= 1)) WrError
(ErrNum_InvOpSize
);
else
{
DecodeAdr
(&ArgStr
[2], MModNoImm
);
if (AdrMode
!= ModNone
)
{
CopyAdr
();
DecodeAdr
(&ArgStr
[1], MModAll
#if CMP_IMMVARIABLE
| MModImmVariable
#endif
);
if (AdrMode
!= ModNone
)
{
if (FormatCode
== 0)
{
if ((AdrMode
== ModImm
) && ((ImmSize
== OpSize
) || (ImmSize
== eSymbolSizeUnknown
)) && (Adr2Mode
== ModReg
)) FormatCode
= 2 + OpSize
;
else FormatCode
= 1;
}
switch (FormatCode
)
{
case 1:
if (Adr2Mode
== ModReg
)
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = 0x70 | (Adr2Byte
& 7);
CodeLen
= 2 + AdrCnt
;
}
else if (AdrMode
== ModImm
)
{
#if CMP_IMMVARIABLE
if (AdaptImmSize
(&ArgStr
[1]))
#endif
{
BAsmCode
[0] = Adr2Byte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, Adr2Vals
, Adr2Cnt
);
BAsmCode
[1 + Adr2Cnt
] = 0x04 | ImmSize
;
memcpy(BAsmCode
+ 2 + Adr2Cnt
, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
+ Adr2Cnt
;
}
}
else WrError
(ErrNum_InvAddrMode
);
break;
case 2:
if ((AdrMode
!= ModImm
) || (Adr2Mode
!= ModReg
)) WrError
(ErrNum_InvAddrMode
);
else if (OpSize
!= eSymbolSize8Bit
) WrError
(ErrNum_InvOpSize
);
else
{
BAsmCode
[0] = 0x40 | (Adr2Byte
& 7);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
break;
case 3:
if ((AdrMode
!= ModImm
) || (Adr2Mode
!= ModReg
)) WrError
(ErrNum_InvAddrMode
);
else if (OpSize
!= eSymbolSize16Bit
) WrError
(ErrNum_InvOpSize
);
else
{
BAsmCode
[0] = 0x48 + (Adr2Byte
& 7);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
break;
}
}
}
}
}
}
static void DecodeRegEA
(Word Index
)
{
Byte HReg
;
OneOrder
*pOrder
= RegEAOrders
+ Index
;
if (ChkArgCnt
(2, 2)
&& CheckFormat
("G"))
{
if (OpSize
== eSymbolSizeUnknown
) SetOpSize
(pOrder
->DefSize
);
if (!((1 << OpSize
) & pOrder
->SizeMask
)) WrError
(ErrNum_InvOpSize
);
else if (DecodeReg
(&ArgStr
[2], &HReg
, True
))
{
DecodeAdr
(&ArgStr
[1], MModAll
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = pOrder
->Code
| HReg
;
CodeLen
= 2 + AdrCnt
;
}
}
}
}
static void DecodeTwoReg
(Word Index
)
{
Byte HReg
;
OneOrder
*pOrder
= TwoRegOrders
+ Index
;
if (!ChkArgCnt
(2, 2));
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (DecodeReg
(&ArgStr
[1], &HReg
, True
)
&& DecodeReg
(&ArgStr
[2], &AdrByte
, True
))
{
if (OpSize
== eSymbolSizeUnknown
) SetOpSize
(pOrder
->DefSize
);
if (!((1 << OpSize
) & pOrder
->SizeMask
)) WrError
(ErrNum_InvOpSize
);
else
{
BAsmCode
[0] = 0xa0 | HReg
| (OpSize
<< 3);
if (Hi
(pOrder
->Code
))
{
BAsmCode
[1] = Lo
(pOrder
->Code
);
BAsmCode
[2] = Hi
(pOrder
->Code
) | AdrByte
;
CodeLen
= 3;
}
else
{
BAsmCode
[1] = pOrder
->Code
| AdrByte
;
CodeLen
= 2;
}
}
}
}
static void DecodeLog
(Word Code
)
{
Byte HReg
;
if (!ChkArgCnt
(2, 2));
else if (!DecodeCReg
(ArgStr
[2].
str.
p_str, &HReg
)) WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[2]);
else
{
DecodeAdr
(&ArgStr
[1], MModImm
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1,AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = Code
| HReg
;
CodeLen
= 2 + AdrCnt
;
}
}
}
static void DecodeOne
(Word Index
)
{
OneOrder
*pOrder
= OneOrders
+ Index
;
if (!ChkArgCnt
(1, 1));
else if (CheckFormat
("G"))
{
if (OpSize
== eSymbolSizeUnknown
) SetOpSize
(pOrder
->DefSize
);
if (!((1 << OpSize
) & pOrder
->SizeMask
)) WrError
(ErrNum_InvOpSize
);
else
{
DecodeAdr
(&ArgStr
[1], MModNoImm
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = pOrder
->Code
;
CodeLen
= 2 + AdrCnt
;
}
}
}
}
static void DecodeOneReg
(Word Index
)
{
Byte HReg
;
OneOrder
*pOrder
= OneRegOrders
+ Index
;
if (!ChkArgCnt
(1, 1));
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (DecodeReg
(&ArgStr
[1], &HReg
, True
))
{
if (OpSize
== -1) SetOpSize
(pOrder
->DefSize
);
if (!((1 << OpSize
) & pOrder
->SizeMask
)) WrError
(ErrNum_InvOpSize
);
else
{
BAsmCode
[0] = 0xa0 | HReg
| (OpSize
<< 3);
BAsmCode
[1] = pOrder
->Code
;
CodeLen
= 2;
}
}
}
static void DecodeBit
(Word Code
)
{
Boolean OK
;
Byte BitPos
;
switch (ArgCnt
)
{
case 1:
{
LongWord BitSpec
;
if (DecodeBitArg
(&BitSpec
, 1, 1))
{
LongWord Addr
;
tSymbolSize ThisOpSize
, ThisAddrSize
;
DissectBitSymbol
(BitSpec
, &Addr
, &BitPos
, &ThisOpSize
, &ThisAddrSize
);
if (OpSize
== eSymbolSizeUnknown
)
OpSize
= ThisOpSize
;
else if (OpSize
!= ThisOpSize
)
{
WrStrErrorPos
(ErrNum_ConfOpSizes
, &ArgStr
[1]);
return;
}
if (OpSize
== eSymbolSizeUnknown
)
OpSize
= eSymbolSize8Bit
;
BitPos
|= 0x80;
DecideAbsolute
(Addr
, ThisAddrSize
, False
, MModAbs8
| MModAbs16
);
if (AdrMode
!= ModNone
)
goto common
;
}
break;
}
case 2:
{
DecodeAdr
(&ArgStr
[2], MModNoImm
);
if (AdrMode
!= ModNone
)
{
if (OpSize
== eSymbolSizeUnknown
)
OpSize
= (AdrMode
== ModReg
) ? eSymbolSize16Bit
: eSymbolSize8Bit
;
if ((OpSize
!= 0) && (OpSize
!= 1)) WrError
(ErrNum_InvOpSize
);
else
{
switch (DecodeReg
(&ArgStr
[1], &BitPos
, False
))
{
case eIsReg
:
OK
= True
; BitPos
+= 8;
break;
case eIsNoReg
:
BitPos
= EvalStrIntExpressionOffs
(&ArgStr
[1], !!(*ArgStr
[1].
str.
p_str == '#'), (OpSize
== eSymbolSize8Bit
) ? UInt3
: UInt4
, &OK
);
if (OK
) BitPos
|= 0x80;
break;
default:
OK
= False
;
}
if (OK
)
goto common
;
}
}
break;
}
common
:
BAsmCode
[0] = AdrByte
| (OpSize
<< 3);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = Code
| BitPos
;
CodeLen
= 2 + AdrCnt
;
break;
default:
(void)ChkArgCnt
(1, 2);
}
}
static void DecodeRel
(Word Code
)
{
Boolean OK
;
tSymbolFlags Flags
;
LongInt AdrLong
;
if (ChkArgCnt
(1, 1)
&& FormatToBranchSize
(Format
, &OpSize
))
{
AdrLong
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt24
, &OK
, &Flags
);
if (OK
)
{
if (!ChkSamePage
(AdrLong
, EProgCounter
(), 16, Flags
));
else if ((EProgCounter
() & 0xffff) >= 0xfffc) WrError
(ErrNum_NotFromThisAddress
);
else
{
AdrLong
-= EProgCounter
() + 2;
if (AdrLong
> 0x7fff) AdrLong
-= 0x10000;
else if (AdrLong
< -0x8000l
) AdrLong
+= 0x10000;
if (OpSize
== eSymbolSizeUnknown
)
{
if ((AdrLong
<= 127) && (AdrLong
>= -128)) OpSize
= eSymbolSizeFloat32Bit
;
else OpSize
= eSymbolSize32Bit
;
}
switch (OpSize
)
{
case eSymbolSize32Bit
:
AdrLong
--;
BAsmCode
[0] = Code
| 0x10;
BAsmCode
[1] = (AdrLong
>> 8) & 0xff;
BAsmCode
[2] = AdrLong
& 0xff;
CodeLen
= 3;
break;
case eSymbolSizeFloat32Bit
:
if (((AdrLong
< -128) || (AdrLong
> 127)) && !mSymbolQuestionable
(Flags
)) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[0] = Code
;
BAsmCode
[1] = AdrLong
& 0xff;
CodeLen
= 2;
}
break;
default:
WrError
(ErrNum_InvOpSize
);
}
}
}
}
}
static void DecodeJMP_JSR
(Word IsJSR_8
)
{
if (ChkArgCnt
(1, 1)
&& CheckFormat
("G"))
{
AbsBank
= EProgCounter
() >> 16;
DecodeAdr
(&ArgStr
[1], MModIReg
| MModReg
| MModDisp8
| MModDisp16
| MModAbs16
);
switch (AdrMode
)
{
case ModReg
:
case ModIReg
:
BAsmCode
[0] = 0x11; BAsmCode
[1] = 0xd0 | IsJSR_8
| (AdrByte
& 7);
CodeLen
= 2;
break;
case ModDisp8
:
case ModDisp16
:
BAsmCode
[0] = 0x11; BAsmCode
[1] = AdrByte
| IsJSR_8
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
break;
case ModAbs16
:
BAsmCode
[0] = 0x10 | IsJSR_8
; memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
break;
}
}
}
static void DecodePJMP_PJSR
(Word IsPJMP
)
{
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (!MaxMode
) WrError
(ErrNum_OnlyInMaxmode
);
else
{
tStrComp
*pArg
= &ArgStr
[1], Arg
;
unsigned ArgOffs
= !!(*pArg
->str.
p_str == '@');
Byte HReg
;
StrCompRefRight
(&Arg
, pArg
, ArgOffs
);
switch (DecodeReg
(&Arg
, &HReg
, False
))
{
case eIsReg
:
BAsmCode
[0] = 0x11; BAsmCode
[1] = 0xc0 | ((1 - IsPJMP
) << 3) | HReg
;
CodeLen
= 2;
break;
case eIsNoReg
:
{
Boolean OK
;
LongInt AdrLong
= EvalStrIntExpressionOffs
(pArg
, ArgOffs
, UInt24
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x03 | (IsPJMP
<< 4);
BAsmCode
[1] = (AdrLong
>> 16) & 0xff;
BAsmCode
[2] = (AdrLong
>> 8) & 0xff;
BAsmCode
[3] = AdrLong
& 0xff;
CodeLen
= 4;
}
break;
}
default:
break;
}
}
}
static void DecodeSCB
(Word Code
)
{
Byte HReg
;
LongInt AdrLong
;
Boolean OK
;
tSymbolFlags Flags
;
if (!ChkArgCnt
(2, 2));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (DecodeReg
(&ArgStr
[1], &HReg
, True
))
{
AdrLong
= EvalStrIntExpressionWithFlags
(&ArgStr
[2], UInt24
, &OK
, &Flags
);
if (OK
)
{
if (!ChkSamePage
(AdrLong
, EProgCounter
(), 16, Flags
));
else if ((EProgCounter
() & 0xffff) >= 0xfffc) WrError
(ErrNum_NotFromThisAddress
);
else
{
AdrLong
-= EProgCounter
() + 3;
if (!mSymbolQuestionable
(Flags
) && ((AdrLong
> 127) || (AdrLong
< -128))) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[0] = Code
;
BAsmCode
[1] = 0xb8 | HReg
;
BAsmCode
[2] = AdrLong
& 0xff;
CodeLen
= 3;
}
}
}
}
}
static void DecodePRTD_RTD
(Word IsPRTD
)
{
tSymbolSize HSize
;
Integer AdrInt
;
if (!ChkArgCnt
(1, 1));
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (*ArgStr
[1].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
tStrComp Arg
;
Boolean OK
;
tSymbolFlags Flags
;
StrCompRefRight
(&Arg
, &ArgStr
[1], 1);
HSize
= eSymbolSizeUnknown
; SplitDisp
(&Arg
, &HSize
);
if (HSize
!= eSymbolSizeUnknown
) SetOpSize
(HSize
);
AdrInt
= EvalStrIntExpressionWithFlags
(&Arg
, SInt16
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
)) AdrInt
&= 127;
if (OK
)
{
if (OpSize
== eSymbolSizeUnknown
)
{
if ((AdrInt
< 127) && (AdrInt
> -128)) OpSize
= eSymbolSize8Bit
;
else OpSize
= eSymbolSize16Bit
;
}
if (IsPRTD
) BAsmCode
[0] = 0x11;
switch (OpSize
)
{
case eSymbolSize8Bit
:
if (ChkRange
(AdrInt
, -128, 127))
{
BAsmCode
[IsPRTD
] = 0x14;
BAsmCode
[1 + IsPRTD
] = AdrInt
& 0xff;
CodeLen
= 2 + IsPRTD
;
}
break;
case eSymbolSize16Bit
:
BAsmCode
[IsPRTD
] = 0x1c;
BAsmCode
[1 + IsPRTD
] = (AdrInt
>> 8) & 0xff;
BAsmCode
[2 + IsPRTD
] = AdrInt
& 0xff;
CodeLen
= 3 + IsPRTD
;
break;
default:
WrError
(ErrNum_InvOpSize
);
}
}
}
}
static void DecodeLINK
(Word Dummy
)
{
UNUSED
(Dummy
);
if (!ChkArgCnt
(2, 2));
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else
{
DecodeAdr
(&ArgStr
[1], MModReg
);
if (AdrMode
!= ModNone
)
{
if ((AdrByte
& 7) != 6) WrError
(ErrNum_InvAddrMode
);
else if (*ArgStr
[2].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
tStrComp Arg
;
tSymbolSize HSize
;
Integer AdrInt
;
Boolean OK
;
tSymbolFlags Flags
;
StrCompRefRight
(&Arg
, &ArgStr
[2], 1);
HSize
= eSymbolSizeUnknown
; SplitDisp
(&Arg
, &HSize
);
if (HSize
!= eSymbolSizeUnknown
) SetOpSize
(HSize
);
AdrInt
= EvalStrIntExpressionWithFlags
(&Arg
, SInt16
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
)) AdrInt
&= 127;
if (OK
)
{
if (OpSize
== eSymbolSizeUnknown
)
{
if ((AdrInt
< 127) && (AdrInt
> -128)) OpSize
= eSymbolSize8Bit
;
else OpSize
= eSymbolSize16Bit
;
}
switch (OpSize
)
{
case eSymbolSize8Bit
:
if (ChkRange
(AdrInt
, -128, 127))
{
BAsmCode
[0] = 0x17;
BAsmCode
[1] = AdrInt
& 0xff;
CodeLen
= 2;
}
break;
case eSymbolSize16Bit
:
BAsmCode
[0] = 0x1f;
BAsmCode
[1] = (AdrInt
>> 8) & 0xff;
BAsmCode
[2] = AdrInt
& 0xff;
CodeLen
= 3;
break;
default:
WrError
(ErrNum_InvOpSize
);
}
}
}
}
}
}
static void DecodeUNLK
(Word Dummy
)
{
UNUSED
(Dummy
);
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else
{
DecodeAdr
(&ArgStr
[1], MModReg
);
if (AdrMode
!= ModNone
)
{
if ((AdrByte
& 7) != 6) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[0] = 0x0f; CodeLen
= 1;
}
}
}
}
static void DecodeTRAPA
(Word Dummy
)
{
UNUSED
(Dummy
);
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (strcmp(Format
, " ")) WrError
(ErrNum_InvFormat
);
else if (*ArgStr
[1].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
Boolean OK
;
BAsmCode
[1] = 0x10 | EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt4
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x08; CodeLen
= 2;
}
}
}
static void DecodeDATA
(Word Dummy
)
{
UNUSED
(Dummy
);
DecodeMotoDC
(OpSize
, True
);
}
static void DecodeBIT
(Word Code
)
{
UNUSED
(Code
);
/* if in structure definition, add special element to structure */
if (OpSize
> eSymbolSize16Bit
)
{
WrError
(ErrNum_InvOpSize
);
return;
}
if (ActPC
== StructSeg
)
{
Boolean OK
;
Byte BitPos
;
PStructElem pElement
;
if (!ChkArgCnt
(2, 2))
return;
BitPos
= EvalBitPosition
(&ArgStr
[1], OpSize
, &OK
);
if (!OK
)
return;
pElement
= CreateStructElem
(&LabPart
);
if (!pElement
)
return;
pElement
->pRefElemName
= as_strdup
(ArgStr
[2].
str.
p_str);
pElement
->OpSize
= OpSize
;
pElement
->BitPos
= BitPos
;
pElement
->ExpandFnc
= ExpandBit_H8_5
;
AddStructElem
(pInnermostNamedStruct
->StructRec
, pElement
);
}
else
{
LongWord BitSpec
;
if (DecodeBitArg
(&BitSpec
, 1, ArgCnt
))
{
*ListLine
= '=';
DissectBit_H8_5
(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 AddRel
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeRel
);
}
static void AddOne
(const char *NName
, Word NCode
, Byte NMask
, tSymbolSize NDef
)
{
order_array_rsv_end
(OneOrders
, OneOrder
);
OneOrders
[InstrZ
].
Code = NCode
;
OneOrders
[InstrZ
].
SizeMask = NMask
;
OneOrders
[InstrZ
].
DefSize = NDef
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeOne
);
}
static void AddOneReg
(const char *NName
, Word NCode
, Byte NMask
, tSymbolSize NDef
)
{
order_array_rsv_end
(OneRegOrders
, OneOrder
);
OneRegOrders
[InstrZ
].
Code=NCode
;
OneRegOrders
[InstrZ
].
SizeMask = NMask
;
OneRegOrders
[InstrZ
].
DefSize = NDef
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeOneReg
);
}
static void AddRegEA
(const char *NName
, Word NCode
, Byte NMask
, tSymbolSize NDef
)
{
order_array_rsv_end
(RegEAOrders
, OneOrder
);
RegEAOrders
[InstrZ
].
Code = NCode
;
RegEAOrders
[InstrZ
].
SizeMask = NMask
;
RegEAOrders
[InstrZ
].
DefSize = NDef
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeRegEA
);
}
static void AddTwoReg
(const char *NName
, Word NCode
, Byte NMask
, tSymbolSize NDef
)
{
order_array_rsv_end
(TwoRegOrders
, OneOrder
);
TwoRegOrders
[InstrZ
].
Code = NCode
;
TwoRegOrders
[InstrZ
].
SizeMask = NMask
;
TwoRegOrders
[InstrZ
].
DefSize = NDef
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeTwoReg
);
}
static void AddLog
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeLog
);
}
static void AddBit
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBit
);
}
static void InitFields
(void)
{
Format
= (char*)malloc(sizeof(char) * STRINGSIZE
);
InstTable
= CreateInstTable
(302);
AddFixed
("NOP" , 0x0000); AddFixed
("PRTS" , 0x1119);
AddFixed
("RTE" , 0x000a); AddFixed
("RTS" , 0x0019);
AddFixed
("SLEEP", 0x001a); AddFixed
("TRAP/VS", 0x0009);
AddInstTable
(InstTable
, "MOV" , 0 , DecodeMOV
);
AddInstTable
(InstTable
, "LDC" , 0 , DecodeLDC_STC
);
AddInstTable
(InstTable
, "STC" , 16 , DecodeLDC_STC
);
AddInstTable
(InstTable
, "LDM" , 0 , DecodeLDM
);
AddInstTable
(InstTable
, "STM" , 0 , DecodeSTM
);
AddInstTable
(InstTable
, "MOVTPE", 16 , DecodeMOVTPE_MOVFPE
);
AddInstTable
(InstTable
, "MOVFPE", 0 , DecodeMOVTPE_MOVFPE
);
AddInstTable
(InstTable
, "ADD" , 0 , DecodeADD_SUB
);
AddInstTable
(InstTable
, "SUB" , 16 , DecodeADD_SUB
);
AddInstTable
(InstTable
, "CMP" , 0 , DecodeCMP
);
AddInstTable
(InstTable
, "JMP" , 0 , DecodeJMP_JSR
);
AddInstTable
(InstTable
, "JSR" , 8 , DecodeJMP_JSR
);
AddInstTable
(InstTable
, "PJMP" , 1 , DecodePJMP_PJSR
);
AddInstTable
(InstTable
, "PJSR" , 0 , DecodePJMP_PJSR
);
AddInstTable
(InstTable
, "SCB/F" , 0x01, DecodeSCB
);
AddInstTable
(InstTable
, "SCB/NE", 0x06, DecodeSCB
);
AddInstTable
(InstTable
, "SCB/EQ", 0x07, DecodeSCB
);
AddInstTable
(InstTable
, "RTD" , 0 , DecodePRTD_RTD
);
AddInstTable
(InstTable
, "PRTD" , 1 , DecodePRTD_RTD
);
AddInstTable
(InstTable
, "LINK" , 0 , DecodeLINK
);
AddInstTable
(InstTable
, "UNLK" , 0 , DecodeUNLK
);
AddInstTable
(InstTable
, "TRAPA" , 0 , DecodeTRAPA
);
AddRel
("BRA", 0x20); AddRel
("BT" , 0x20); AddRel
("BRN", 0x21);
AddRel
("BF" , 0x21); AddRel
("BHI", 0x22); AddRel
("BLS", 0x23);
AddRel
("BCC", 0x24); AddRel
("BHS", 0x24); AddRel
("BCS", 0x25);
AddRel
("BLO", 0x25); AddRel
("BNE", 0x26); AddRel
("BEQ", 0x27);
AddRel
("BVC", 0x28); AddRel
("BVS", 0x29); AddRel
("BPL", 0x2a);
AddRel
("BMI", 0x2b); AddRel
("BGE", 0x2c); AddRel
("BLT", 0x2d);
AddRel
("BGT", 0x2e); AddRel
("BLE", 0x2f); AddRel
("BSR", 0x0e);
InstrZ
= 0;
AddOne
("CLR" , 0x13, 3, eSymbolSize16Bit
); AddOne
("NEG" , 0x14, 3, eSymbolSize16Bit
);
AddOne
("NOT" , 0x15, 3, eSymbolSize16Bit
); AddOne
("ROTL" , 0x1c, 3, eSymbolSize16Bit
);
AddOne
("ROTR" , 0x1d, 3, eSymbolSize16Bit
); AddOne
("ROTXL", 0x1e, 3, eSymbolSize16Bit
);
AddOne
("ROTXR", 0x1f, 3, eSymbolSize16Bit
); AddOne
("SHAL" , 0x18, 3, eSymbolSize16Bit
);
AddOne
("SHAR" , 0x19, 3, eSymbolSize16Bit
); AddOne
("SHLL" , 0x1a, 3, eSymbolSize16Bit
);
AddOne
("SHLR" , 0x1b, 3, eSymbolSize16Bit
); AddOne
("TAS" , 0x17, 1, eSymbolSize8Bit
);
AddOne
("TST" , 0x16, 3, eSymbolSize16Bit
);
InstrZ
= 0;
AddOneReg
("EXTS", 0x11, 1, eSymbolSize8Bit
);
AddOneReg
("EXTU", 0x12, 1, eSymbolSize8Bit
);
AddOneReg
("SWAP", 0x10, 1, eSymbolSize8Bit
);
InstrZ
= 0;
AddRegEA
("ADDS" , 0x28, 3, eSymbolSize16Bit
); AddRegEA
("ADDX" , 0xa0, 3, eSymbolSize16Bit
);
AddRegEA
("AND" , 0x50, 3, eSymbolSize16Bit
); AddRegEA
("DIVXU", 0xb8, 3, eSymbolSize16Bit
);
AddRegEA
("MULXU", 0xa8, 3, eSymbolSize16Bit
); AddRegEA
("OR" , 0x40, 3, eSymbolSize16Bit
);
AddRegEA
("SUBS" , 0x38, 3, eSymbolSize16Bit
); AddRegEA
("SUBX" , 0xb0, 3, eSymbolSize16Bit
);
AddRegEA
("XOR" , 0x60, 3, eSymbolSize16Bit
);
InstrZ
= 0;
AddTwoReg
("DADD", 0xa000, 1, eSymbolSize8Bit
);
AddTwoReg
("DSUB", 0xb000, 1, eSymbolSize8Bit
);
AddTwoReg
("XCH" , 0x90, 2, eSymbolSize16Bit
);
AddLog
("ANDC", 0x58); AddLog
("ORC", 0x48); AddLog
("XORC", 0x68);
AddBit
("BCLR", 0x50); AddBit
("BNOT", 0x60);
AddBit
("BSET", 0x40); AddBit
("BTST", 0x70);
AddInstTable
(InstTable
, "REG", 0, CodeREG
);
AddInstTable
(InstTable
, "DATA", 0, DecodeDATA
);
AddInstTable
(InstTable
, "BIT", 0, DecodeBIT
);
}
static void DeinitFields
(void)
{
free(Format
);
order_array_free
(OneOrders
);
order_array_free
(OneRegOrders
);
order_array_free
(RegEAOrders
);
order_array_free
(TwoRegOrders
);
DestroyInstTable
(InstTable
);
}
/*!------------------------------------------------------------------------
* \fn InternSymbol_H8_5(char *pArg, TempResult *pResult)
* \brief handle built-in symbols on H8/500
* \param pArg source argument
* \param pResult result buffer
* ------------------------------------------------------------------------ */
static void InternSymbol_H8_5
(char *pArg
, TempResult
*pResult
)
{
Byte Erg
;
if (DecodeRegCore
(pArg
, &Erg
))
{
pResult
->Typ
= TempReg
;
pResult
->DataSize
= eSymbolSize16Bit
;
pResult
->Contents.
RegDescr.
Reg = Erg
;
pResult
->Contents.
RegDescr.
Dissect = DissectReg_H8_5
;
pResult
->Contents.
RegDescr.
compare = NULL
;
}
}
static Boolean DecodeAttrPart_H8_5
(void)
{
char *p
;
/* Formatangabe abspalten */
switch (AttrSplit
)
{
case '.':
p
= strchr(AttrPart.
str.
p_str, ':');
if (p
)
{
if (p
< AttrPart.
str.
p_str + strlen(AttrPart.
str.
p_str) - 1)
strmaxcpy
(Format
, p
+ 1, STRINGSIZE
- 1);
else
strcpy(Format
, " ");
*p
= '\0';
}
else
strcpy(Format
, " ");
break;
case ':':
p
= strchr(AttrPart.
str.
p_str, '.');
if (!p
)
{
strmaxcpy
(Format
, AttrPart.
str.
p_str, STRINGSIZE
- 1);
*AttrPart.
str.
p_str = '\0';
}
else
{
*p
= '\0';
if (p
== AttrPart.
str.
p_str)
strcpy(Format
, " ");
else
strmaxcpy
(Format
, AttrPart.
str.
p_str, STRINGSIZE
- 1);
strcpy(AttrPart.
str.
p_str, p
+ 1);
}
break;
default:
strcpy(Format
, " ");
}
NLS_UpString
(Format
);
if (*AttrPart.
str.
p_str)
{
if (!DecodeMoto16AttrSize
(*AttrPart.
str.
p_str, &AttrPartOpSize
[0], False
))
return False
;
}
return True
;
}
static void MakeCode_H8_5
(void)
{
CodeLen
= 0; DontPrint
= False
; AbsBank
= Reg_DP
;
/* to be ignored */
if (Memo
("")) return;
OpSize
= eSymbolSizeUnknown
;
if (*AttrPart.
str.
p_str)
SetOpSize
(AttrPartOpSize
[0]);
if (DecodeMoto16Pseudo
(OpSize
, True
)) return;
/* Sonderfaelle */
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
}
static Boolean ChkPC_H8_5
(LargeWord Addr
)
{
if (ActPC
== SegCode
)
return (Addr
< (MaxMode
? 0x1000000u
: 0x10000u
));
else
return False
;
}
static Boolean IsDef_H8_5
(void)
{
return Memo
("REG")
|| Memo
("BIT");
}
static void InitCode_H8_5
(void)
{
Reg_DP
= -1;
Reg_EP
= -1;
Reg_TP
= -1;
Reg_BR
= -1;
}
static void SwitchTo_H8_5
(void)
{
TurnWords
= True
;
SetIntConstMode
(eIntConstModeMoto
);
PCSymbol
= "*"; HeaderID
= 0x69; NOPCode
= 0x00;
DivideChars
= ","; HasAttrs
= True
; AttrChars
= ".:";
ValidSegs
= 1 << SegCode
;
Grans
[SegCode
] = 1; ListGrans
[SegCode
] = 1; SegInits
[SegCode
] = 0;
DecodeAttrPart
= DecodeAttrPart_H8_5
;
MakeCode
= MakeCode_H8_5
;
ChkPC
= ChkPC_H8_5
;
IsDef
= IsDef_H8_5
;
SwitchFrom
= DeinitFields
;
InternSymbol
= InternSymbol_H8_5
;
DissectReg
= DissectReg_H8_5
;
DissectBit
= DissectBit_H8_5
;
QualifyQuote
= QualifyQuote_SingleQuoteConstant
;
IntConstModeIBMNoTerm
= True
;
InitFields
();
onoff_maxmode_add
();
onoff_compmode_add
();
AddMoto16PseudoONOFF
(False
);
pASSUMERecs
= ASSUMEH8_5s
;
ASSUMERecCnt
= ASSUMEH8_5Count
;
}
void codeh8_5_init
(void)
{
CPU532
= AddCPU
("HD6475328", SwitchTo_H8_5
);
CPU534
= AddCPU
("HD6475348", SwitchTo_H8_5
);
CPU536
= AddCPU
("HD6475368", SwitchTo_H8_5
);
CPU538
= AddCPU
("HD6475388", SwitchTo_H8_5
);
AddInitPassProc
(InitCode_H8_5
);
}