/* codefmc16.c */
/****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS, C-Version */
/* */
/* Codegenerator fuer Fujitsu-F2MC16L-Prozessoren */
/* */
/****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmpars.h"
#include "asmsub.h"
#include "asmallg.h"
#include "onoff_common.h"
#include "errmsg.h"
#include "codepseudo.h"
#include "intpseudo.h"
#include "asmitree.h"
#include "codevars.h"
#include "headids.h"
#include "errmsg.h"
#include "codefmc16.h"
/*--------------------------------------------------------------------------*/
/* Definitionen */
#define AccOrderCnt 2
#define MulDivOrderCnt 8
typedef struct
{
Byte Code
;
Word AccCode
;
} MulDivOrder
;
#define ModNone (-1)
#define ModAcc 0
#define MModAcc (1 << ModAcc)
#define ModReg 1
#define MModReg (1 << ModReg)
#define ModMem 2
#define MModMem (1 << ModMem)
#define ModDir 3
#define MModDir (1 << ModDir)
#define ModImm 4
#define MModImm (1 << ModImm)
#define ModCCR 5
#define MModCCR (1 << ModCCR)
#define ModIO 6
#define MModIO (1 << ModIO)
#define ModSeg 7
#define MModSeg (1 << ModSeg)
#define ModIAcc 8
#define MModIAcc (1 << ModIAcc)
#define ModRDisp 9
#define MModRDisp (1 << ModRDisp)
#define ModSpec 10
#define MModSpec (1 << ModSpec)
#define ModRP 11
#define MModRP (1 << ModRP)
#define ModILM 12
#define MModILM (1 << ModILM)
#define ModSP 13
#define MModSP (1 << ModSP)
#define ABSMODE 0x1f
static CPUVar CPU90500
;
static MulDivOrder
*MulDivOrders
;
static const char BankNames
[4][4] =
{
"PCB", "DTB", "ADB", "SPB"
};
static Byte AdrVals
[5], AdrPart
, NextDataSeg
;
static LongWord CurrBank
;
static ShortInt AdrMode
, OpSize
;
static LongInt Reg_PCB
, Reg_DTB
, Reg_ADB
, Reg_USB
, Reg_SSB
, Reg_DPR
;
#define ASSUMEF2MC16Count 6
static ASSUMERec ASSUMEF2MC16s
[ASSUMEF2MC16Count
] =
{
{ "PCB" , &Reg_PCB
, 0x00, 0xff, 0x100, NULL
},
{ "DTB" , &Reg_DTB
, 0x00, 0xff, 0x100, NULL
},
{ "ADB" , &Reg_ADB
, 0x00, 0xff, 0x100, NULL
},
{ "USB" , &Reg_USB
, 0x00, 0xff, 0x100, NULL
},
{ "SSB" , &Reg_SSB
, 0x00, 0xff, 0x100, NULL
},
{ "DPR" , &Reg_DPR
, 0x00, 0xff, 0x100, NULL
}
};
/*--------------------------------------------------------------------------*/
/* Adressdekoder */
static void SetOpSize
(ShortInt NewSize
)
{
if (OpSize
== -1)
OpSize
= NewSize
;
else if (OpSize
!= NewSize
)
{
WrError
(ErrNum_ConfOpSizes
);
AdrMode
= ModNone
; AdrCnt
= 0;
}
}
static Boolean DecodeAdr
(const tStrComp
*pArg
, int Mask
)
{
Integer AdrVal
;
LongWord ImmVal
;
Boolean OK
;
unsigned Index
;
static const char SpecNames
[7][4] = {"DTB", "ADB", "SSB", "USB", "DPR", "\a", "PCB"};
AdrMode
= ModNone
; AdrCnt
= 0;
/* 1. Sonderregister: */
if (!as_strcasecmp
(pArg
->str.
p_str, "A"))
{
AdrMode
= ModAcc
;
goto found
;
}
if (!as_strcasecmp
(pArg
->str.
p_str, "CCR"))
{
AdrMode
= ModCCR
;
goto found
;
}
if (!as_strcasecmp
(pArg
->str.
p_str, "ILM"))
{
AdrMode
= ModILM
;
goto found
;
}
if (!as_strcasecmp
(pArg
->str.
p_str, "RP"))
{
AdrMode
= ModRP
;
goto found
;
}
if (!as_strcasecmp
(pArg
->str.
p_str, "SP"))
{
AdrMode
= ModSP
;
goto found
;
}
if (Mask
& MModSeg
)
{
for (Index
= 0; Index
< sizeof(BankNames
) / sizeof(BankNames
[0]); Index
++)
if (!as_strcasecmp
(pArg
->str.
p_str, BankNames
[Index
]))
{
AdrMode
= ModSeg
;
AdrPart
= Index
;
goto found
;
}
}
if (Mask
& MModSpec
)
{
for (Index
= 0; Index
< sizeof(SpecNames
) / sizeof(SpecNames
[0]); Index
++)
if (as_strcasecmp
(pArg
->str.
p_str, SpecNames
[Index
]) == 0)
{
AdrMode
= ModSpec
;
AdrPart
= Index
;
goto found
;
}
}
/* 2. Register: */
if (as_toupper
(*pArg
->str.
p_str) == 'R')
{
switch(as_toupper
(pArg
->str.
p_str[1]))
{
case 'W':
if ((pArg
->str.
p_str[3] == '\0') && (pArg
->str.
p_str[2] >= '0') && (pArg
->str.
p_str[2] <= '7'))
{
AdrPart
= pArg
->str.
p_str[2] - '0';
AdrMode
= ModReg
;
SetOpSize
(1);
goto found
;
}
break;
case 'L':
if ((pArg
->str.
p_str[3] == '\0') && (pArg
->str.
p_str[2] >= '0') && (pArg
->str.
p_str[2] <= '3'))
{
AdrPart
= (pArg
->str.
p_str[2] - '0') << 1;
AdrMode
= ModReg
;
SetOpSize
(2);
goto found
;
}
break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
if (pArg
->str.
p_str[2] == '\0')
{
AdrPart
= pArg
->str.
p_str[1] - '0';
AdrMode
= ModReg
;
SetOpSize
(0);
goto found
;
}
}
}
/* 3. 32-Bit-Register indirekt: */
if ((*pArg
->str.
p_str == '(')
&& (as_toupper
(pArg
->str.
p_str[1]) == 'R')
&& (as_toupper
(pArg
->str.
p_str[2]) == 'L')
&& (pArg
->str.
p_str[3] >= '0') && (pArg
->str.
p_str[3] <= '3')
&& (pArg
->str.
p_str[4] == ')')
&& (pArg
->str.
p_str[5] == '\0'))
{
AdrPart
= ((pArg
->str.
p_str[3] - '0') << 1) + 1;
AdrMode
= ModMem
;
goto found
;
}
/* 4. immediate: */
else if (*pArg
->str.
p_str == '#')
{
if (OpSize
== -1) WrError
(ErrNum_UndefOpSizes
);
else
{
ImmVal
= EvalStrIntExpressionOffs
(pArg
, 1, (OpSize
== 2) ? Int32
: ((OpSize
== 1) ? Int16
: Int8
), &OK
);
if (OK
)
{
AdrMode
= ModImm
;
AdrVals
[AdrCnt
++] = ImmVal
& 0xff;
if (OpSize
>= 1)
AdrVals
[AdrCnt
++] = (ImmVal
>> 8) & 0xff;
if (OpSize
>= 2)
{
AdrVals
[AdrCnt
++] = (ImmVal
>> 16) & 0xff;
AdrVals
[AdrCnt
++] = (ImmVal
>> 24) & 0xff;
}
}
}
goto found
;
}
/* 5. indirekt: */
if (*pArg
->str.
p_str == '@')
{
tStrComp Arg
;
StrCompRefRight
(&Arg
, pArg
, 1);
/* Akku-indirekt: */
if (!as_strcasecmp
(Arg.
str.
p_str, "A"))
{
AdrMode
= ModIAcc
;
}
/* PC-relativ: */
else if (as_strncasecmp
(Arg.
str.
p_str, "PC", 2) == 0)
{
tStrComp RegComp
;
StrCompRefRight
(&RegComp
, &Arg
, 2);
AdrPart
= 0x1e;
if ((*RegComp.
str.
p_str == '+') || (*RegComp.
str.
p_str == '-') || (as_isspace
(*RegComp.
str.
p_str)))
{
AdrVal
= EvalStrIntExpression
(&RegComp
, SInt16
, &OK
);
if (OK
)
{
AdrVals
[0] = AdrVal
& 0xff;
AdrVals
[1] = (AdrVal
>> 8) & 0xff;
AdrCnt
= 2;
AdrMode
= ModMem
;
}
}
else if (*RegComp.
str.
p_str == '\0')
{
AdrVals
[0] = AdrVals
[1] = 0;
AdrCnt
= 2;
AdrMode
= ModMem
;
}
else
WrStrErrorPos
(ErrNum_InvReg
, &Arg
);
}
/* base register, 32 bit: */
else if ((as_toupper
(*Arg.
str.
p_str) == 'R')
&& (as_toupper
(Arg.
str.
p_str[1]) == 'L')
&& (Arg.
str.
p_str[2] >= '0') && (Arg.
str.
p_str[2] <= '3'))
{
AdrVal
= EvalStrIntExpressionOffs
(&Arg
, 3, SInt8
, &OK
);
if (OK
)
{
AdrVals
[0] = AdrVal
& 0xff;
AdrCnt
= 1;
AdrPart
= Arg.
str.
p_str[2] - '0';
AdrMode
= ModRDisp
;
}
}
/* base register, 16 bit: */
else if ((as_toupper
(*Arg.
str.
p_str) == 'R') && (as_toupper
(Arg.
str.
p_str[1]) == 'W') &&
(Arg.
str.
p_str[2] >= '0') && (Arg.
str.
p_str[2] <= '7'))
{
tStrComp IComp
;
AdrPart
= Arg.
str.
p_str[2] - '0';
StrCompRefRight
(&IComp
, &Arg
, 3);
switch (*IComp.
str.
p_str)
{
case '\0': /* no displacement */
if (AdrPart
< 4) /* RW0..RW3 directly available */
{
AdrPart
+= 8;
AdrMode
= ModMem
;
}
else /* dummy disp for RW4..RW7 */
{
AdrPart
+= 0x10;
AdrVals
[0] = 0; AdrCnt
= 1;
AdrMode
= ModMem
;
}
break;
case '+':
if (IComp.
str.
p_str[1] == '\0') /* postincrement */
{
if (AdrPart
> 3) WrError
(ErrNum_InvReg
); /* only allowed for RW0..RW3 */
else
{
AdrPart
+= 0x0c;
AdrMode
= ModMem
;
}
break;
} /* run into disp part otherwise*/
/* else fall-through */
case ' ':
case '\t':
case '-':
while (as_isspace
(*IComp.
str.
p_str)) /* skip leading spaces */
StrCompIncRefLeft
(&IComp
, 1);
if (!as_strcasecmp
(IComp.
str.
p_str, "+RW7")) /* base + RW7 as index */
{
if (AdrPart
> 1) WrError
(ErrNum_InvReg
);
else
{
AdrPart
+= 0x1c;
AdrMode
= ModMem
;
}
}
else /* numeric index */
{
AdrVal
= /* max length depends on base */
EvalStrIntExpression
(&IComp
, (AdrPart
> 3) ? SInt8
: SInt16
, &OK
);
if (OK
)
{ /* optimize length */
AdrVals
[0] = AdrVal
& 0xff;
AdrCnt
= 1;
AdrMode
= ModMem
;
AdrPart
|= 0x10;
if ((AdrVal
< -0x80) || (AdrVal
> 0x7f))
{
AdrVals
[AdrCnt
++] = (AdrVal
>> 8) & 0xff;
AdrPart
|= 0x08;
}
}
}
break;
default:
WrError
(ErrNum_InvAddrMode
);
}
}
else
WrStrErrorPos
(ErrNum_InvReg
, &Arg
);
goto found
;
}
/* 6. dann direkt: */
ImmVal
= EvalStrIntExpression
(pArg
, UInt24
, &OK
);
if (OK
)
{
AdrVals
[AdrCnt
++] = ImmVal
& 0xff;
if (((ImmVal
>> 8) == 0) && (Mask
& MModIO
))
AdrMode
= ModIO
;
else if ((Lo
(ImmVal
>> 8) == Reg_DPR
) && ((ImmVal
& 0xffff0000) == CurrBank
) && (Mask
& MModDir
))
AdrMode
= ModDir
;
else
{
AdrVals
[AdrCnt
++] = (ImmVal
>> 8) & 0xff;
AdrPart
= ABSMODE
;
AdrMode
= ModMem
;
if ((ImmVal
& 0xffff0000) != CurrBank
) WrError
(ErrNum_InAccPage
);
}
}
found
:
if ((AdrMode
!= ModNone
) && ((Mask
& (1 << AdrMode
)) == 0))
{
WrError
(ErrNum_InvAddrMode
);
AdrMode
= ModNone
; AdrCnt
= 0;
}
return (AdrMode
!= ModNone
);
}
static Boolean SplitBit
(tStrComp
*pArg
, Byte
*Result
)
{
char *pos
;
Boolean Res
= FALSE
;
pos
= RQuotPos
(pArg
->str.
p_str, ':');
if (pos
== NULL
)
{
*Result
= 0;
WrError
(ErrNum_InvBitPos
);
}
else
{
tStrComp BitArg
;
StrCompSplitRef
(pArg
, &BitArg
, pArg
, pos
);
*Result
= EvalStrIntExpression
(&BitArg
, UInt3
, &Res
);
}
return Res
;
}
static void CopyVals
(int Offset
)
{
memcpy(BAsmCode
+ Offset
, AdrVals
, AdrCnt
);
CodeLen
= Offset
+ AdrCnt
;
}
/*--------------------------------------------------------------------------*/
/* Dekoder fuer einzelne Instruktionen */
static void DecodeFixed
(Word Code
)
{
if (ChkArgCnt
(0, 0))
{
BAsmCode
[0] = Code
;
CodeLen
= 1;
}
}
static void DecodeALU8
(Word Code
)
{
int HCnt
;
if (ChkArgCnt
(2, 2))
{
SetOpSize
(0);
DecodeAdr
(&ArgStr
[1], MModAcc
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
DecodeAdr
(&ArgStr
[2], MModReg
| MModMem
| MModImm
| MModDir
);
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x30 + Code
;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
case ModDir
:
BAsmCode
[0] = 0x20 + Code
;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
case ModReg
:
case ModMem
:
{
BAsmCode
[0] = 0x74;
BAsmCode
[1] = (Code
<< 5) | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
break;
case ModReg
:
case ModMem
:
HCnt
= AdrCnt
;
BAsmCode
[1] = (Code
<< 5) | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
if (DecodeAdr
(&ArgStr
[2], MModAcc
))
{
BAsmCode
[0] = 0x75;
CodeLen
= 2 + HCnt
;
}
break;
}
}
}
static void DecodeLog8
(Word Code
)
{
int HCnt
;
if (ChkArgCnt
(2, 2))
{
SetOpSize
(0);
DecodeAdr
(&ArgStr
[1], MModAcc
| MModReg
| MModMem
| ((Code
< 6) ? MModCCR
: 0));
switch (AdrMode
)
{
case ModAcc
:
DecodeAdr
(&ArgStr
[2], MModReg
| MModMem
| MModImm
);
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x30 + Code
;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
case ModReg
:
case ModMem
:
{
BAsmCode
[0] = 0x74;
BAsmCode
[1] = (Code
<< 5) | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
break;
case ModReg
:
case ModMem
:
HCnt
= AdrCnt
;
BAsmCode
[1] = (Code
<< 5) | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
if (DecodeAdr
(&ArgStr
[2], MModAcc
))
{
BAsmCode
[0] = 0x75;
CodeLen
= 2 + HCnt
;
}
break;
case ModCCR
:
if (DecodeAdr
(&ArgStr
[2], MModImm
))
{
BAsmCode
[0] = 0x20 + Code
;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
}
break;
}
}
}
static void DecodeCarry8
(Word Index
)
{
if (ChkArgCnt
(1, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
if (ArgCnt
== 1)
{
BAsmCode
[0] = 0x22 + (Index
<< 4);
CodeLen
= 1;
}
else if (DecodeAdr
(&ArgStr
[2], MModReg
| MModMem
))
{
BAsmCode
[0] = 0x74 + Index
;
BAsmCode
[1] = AdrPart
| 0x40;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
}
static void DecodeCarry16
(Word Index
)
{
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
)
&& DecodeAdr
(&ArgStr
[2], MModReg
| MModMem
))
{
BAsmCode
[0] = 0x76 + Index
;
BAsmCode
[1] = AdrPart
| 0x40;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
static void DecodeAcc
(Word Code
)
{
if (ChkArgCnt
(1, 1)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
BAsmCode
[0] = Code
;
CodeLen
= 1;
}
}
static void DecodeShift
(Word Code
)
{
if (ChkArgCnt
(Hi
(Code
) ? 1 : 2, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
if (ArgCnt
== 1)
{
BAsmCode
[0] = Lo
(Code
);
CodeLen
= 1;
}
else
{
SetOpSize
(0);
if (DecodeAdr
(&ArgStr
[2], MModReg
))
{
if (AdrPart
!= 0) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
else
{
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = Lo
(Code
);
CodeLen
= 2;
}
}
}
}
}
static void DecodeAdd32
(Word Index
)
{
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
SetOpSize
(2);
if (DecodeAdr
(&ArgStr
[2], MModImm
| MModMem
| MModReg
))
{
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x18 + Index
;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
break;
case ModReg
:
case ModMem
:
BAsmCode
[0] = 0x70;
BAsmCode
[1] = AdrPart
| (Index
<< 5);
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
break;
}
}
}
}
static void DecodeLog32
(Word Index
)
{
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
if (DecodeAdr
(&ArgStr
[2], MModMem
| MModReg
))
{
BAsmCode
[0] = 0x70;
BAsmCode
[1] = AdrPart
| (Index
<< 5);
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
}
static void DecodeADDSP
(Word Index
)
{
Integer Val
;
Boolean OK
;
UNUSED
(Index
);
if (!ChkArgCnt
(1, 1));
else if (*ArgStr
[1].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
Val
= EvalStrIntExpressionOffs
(&ArgStr
[1], 1, Int16
, &OK
);
if (OK
)
{
BAsmCode
[CodeLen
++] = 0x17;
BAsmCode
[CodeLen
++] = Val
& 0xff;
if ((Val
> 127) || (Val
< -128))
{
BAsmCode
[CodeLen
++] = (Val
>> 8) & 0xff;
BAsmCode
[0] |= 8;
}
}
}
}
static void DecodeAdd16
(Word Index
)
{
int HCnt
;
if (!ChkArgCnt
(1, 2));
else if (ArgCnt
== 1)
{
if (DecodeAdr
(&ArgStr
[1], MModAcc
))
{
BAsmCode
[0] = 0x28 | Index
;
CodeLen
= 1;
}
}
else
{
SetOpSize
(1);
DecodeAdr
(&ArgStr
[1], MModAcc
| ((Index
!= 3) ? (MModMem
| MModReg
) : 0));
switch (AdrMode
)
{
case ModAcc
:
DecodeAdr
(&ArgStr
[2], MModImm
| MModMem
| MModReg
);
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x38 | Index
;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
break;
case ModMem
:
case ModReg
:
BAsmCode
[0] = 0x76;
BAsmCode
[1] = AdrPart
| (Index
<< 5);
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
break;
}
break;
case ModMem
:
case ModReg
:
BAsmCode
[0] = 0x77;
BAsmCode
[1] = AdrPart
| (Index
<< 5);
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
HCnt
= 2 + AdrCnt
;
if (DecodeAdr
(&ArgStr
[2], MModAcc
))
CodeLen
= HCnt
;
break;
}
}
}
static void DecodeBBcc
(Word Index
)
{
Byte BitPos
, HLen
;
LongInt Addr
;
Boolean OK
;
if ((ChkArgCnt
(2, 2))
&& (SplitBit
(&ArgStr
[1], &BitPos
)))
{
HLen
= 0;
DecodeAdr
(&ArgStr
[1], MModMem
| MModDir
| MModIO
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[HLen
++] = 0x6c;
switch (AdrMode
)
{
case ModDir
:
BAsmCode
[HLen
++] = Index
+ 8 + BitPos
;
BAsmCode
[HLen
++] = AdrVals
[0];
break;
case ModIO
:
BAsmCode
[HLen
++] = Index
+ BitPos
;
BAsmCode
[HLen
++] = AdrVals
[0];
break;
case ModMem
:
if (AdrPart
!= ABSMODE
) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[HLen
++] = Index
+ 16 + BitPos
;
memcpy(BAsmCode
+ HLen
, AdrVals
, AdrCnt
);
HLen
+= AdrCnt
;
}
break;
}
if (HLen
> 1)
{
tSymbolFlags Flags
;
Addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[2], UInt24
, &OK
, &Flags
) - (EProgCounter
() + HLen
+ 1);
if (OK
)
{
if (!mSymbolQuestionable
(Flags
) && ((Addr
< -128) || (Addr
> 127))) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[HLen
++] = Addr
& 0xff;
CodeLen
= HLen
;
}
}
}
}
}
}
static void DecodeBranch
(Word Code
)
{
LongInt Addr
;
Boolean OK
;
if (ChkArgCnt
(1, 1))
{
tSymbolFlags Flags
;
Addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt24
, &OK
, &Flags
) - (EProgCounter
() + 2);
if (OK
)
{
if (!mSymbolQuestionable
(Flags
) && ((Addr
< -128) || (Addr
> 127))) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[0] = Code
;
BAsmCode
[1] = Addr
& 0xff;
CodeLen
= 2;
}
}
}
}
static void DecodeJmp16
(Word Index
)
{
LongWord Addr
;
Boolean OK
;
if (!ChkArgCnt
(1, 1));
else if (*ArgStr
[1].
str.
p_str == '@')
{
tStrComp Arg1
;
SetOpSize
(1);
StrCompRefRight
(&Arg1
, &ArgStr
[1], 1);
DecodeAdr
(&Arg1
, MModReg
| ((Index
== 0) ? MModAcc
: 0) | MModMem
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x61;
CodeLen
= 1;
break;
case ModReg
:
case ModMem
:
BAsmCode
[0] = 0x73;
BAsmCode
[1] = (Index
<< 4) | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
break;
}
}
else
{
Addr
= EvalStrIntExpression
(&ArgStr
[1], UInt24
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x62 + Index
;
BAsmCode
[1] = Addr
& 0xff;
BAsmCode
[2] = (Addr
>> 8) & 0xff;
CodeLen
= 3;
if (((Addr
>> 16) & 0xff) != (LongWord
)Reg_PCB
)
WrError
(ErrNum_InAccSegment
);
}
}
}
static void DecodeJmp24
(Word Index
)
{
LongWord Addr
;
Boolean OK
;
if (!ChkArgCnt
(1, 1));
else if (*ArgStr
[1].
str.
p_str == '@')
{
tStrComp Arg1
;
SetOpSize
(2);
StrCompRefRight
(&Arg1
, &ArgStr
[1], 1);
if (DecodeAdr
(&Arg1
, MModReg
| MModMem
))
{
BAsmCode
[0] = 0x71;
BAsmCode
[1] = (Index
<< 4) | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
else
{
Addr
= EvalStrIntExpression
(&ArgStr
[1], UInt24
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x63 + Index
;
BAsmCode
[1] = Addr
& 0xff;
BAsmCode
[2] = (Addr
>> 8) & 0xff;
BAsmCode
[3] = (Addr
>> 16) & 0xff;
CodeLen
= 4;
}
}
}
static void DecodeCALLV
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (!ChkArgCnt
(1, 1));
else if (*ArgStr
[1].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
BAsmCode
[0] = 0xe0 + EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt4
, &OK
);
if (OK
) CodeLen
= 1;
}
}
static void DecodeCmpBranch
(Word Index
)
{
LongInt Addr
;
int HCnt
;
Boolean OK
;
if (ChkArgCnt
(3, 3))
{
SetOpSize
(Index
); HCnt
= 0;
if (DecodeAdr
(&ArgStr
[1], MModMem
| MModReg
| MModAcc
))
{
OK
= TRUE
;
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[HCnt
++] = 0x2a + (Index
<< 4);
break;
case ModReg
:
case ModMem
:
if ((AdrPart
>= 0x0c) && (AdrPart
<= 0x0f))
{
WrError
(ErrNum_InvAddrMode
); OK
= FALSE
;
}
BAsmCode
[HCnt
++] = 0x70;
BAsmCode
[HCnt
++] = 0xe0 - (Index
* 0xa0) + AdrPart
;
memcpy(BAsmCode
+ HCnt
, AdrVals
, AdrCnt
);
HCnt
+= AdrCnt
;
break;
}
if ((OK
) && (DecodeAdr
(&ArgStr
[2], MModImm
)))
{
tSymbolFlags Flags
;
memcpy(BAsmCode
+ HCnt
, AdrVals
, AdrCnt
);
HCnt
+= AdrCnt
;
Addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[3], UInt24
, &OK
, &Flags
) - (EProgCounter
() + HCnt
+ 1);
if (OK
)
{
if (!mSymbolQuestionable
(Flags
) && ((Addr
> 127) || (Addr
< -128))) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[HCnt
++] = Addr
& 0xff;
CodeLen
= HCnt
;
}
}
}
}
}
}
static void DecodeBit
(Word Index
)
{
Byte BitPos
;
if ((ChkArgCnt
(1, 1))
&& (SplitBit
(&ArgStr
[1], &BitPos
)))
{
DecodeAdr
(&ArgStr
[1], MModMem
| MModDir
| MModIO
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[CodeLen
++] = 0x6c;
switch (AdrMode
)
{
case ModDir
:
BAsmCode
[CodeLen
++] = Index
+ 8 + BitPos
;
BAsmCode
[CodeLen
++] = AdrVals
[0];
break;
case ModIO
:
BAsmCode
[CodeLen
++] = Index
+ BitPos
;
BAsmCode
[CodeLen
++] = AdrVals
[0];
break;
case ModMem
:
if (AdrPart
!= ABSMODE
) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[CodeLen
++] = Index
+ 16 + BitPos
;
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen
+= AdrCnt
;
}
break;
}
}
}
}
static void DecodeCMP
(Word Index
)
{
UNUSED
(Index
);
if (ChkArgCnt
(1, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
if (ArgCnt
== 1)
{
BAsmCode
[0] = 0x23;
CodeLen
= 1;
}
else
{
SetOpSize
(0);
DecodeAdr
(&ArgStr
[2], MModMem
| MModReg
| MModImm
);
switch (AdrMode
)
{
case ModMem
:
case ModReg
:
BAsmCode
[0] = 0x74;
BAsmCode
[1] = AdrPart
| 0x40;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
break;
case ModImm
:
BAsmCode
[0] = 0x33;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
}
}
}
}
static void DecodeDBNZ
(Word Index
)
{
LongInt Addr
;
Boolean OK
;
if (ChkArgCnt
(2, 2))
{
SetOpSize
(Index
);
if (DecodeAdr
(&ArgStr
[1], MModReg
| MModMem
))
{
tSymbolFlags Flags
;
Addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[2], UInt16
, &OK
, &Flags
) - (EProgCounter
() + 3 + AdrCnt
);
if (OK
)
{
if (!mSymbolQuestionable
(Flags
) && ((Addr
< -128) || (Addr
> 127))) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[0] = 0x74 + (Index
<< 1);
BAsmCode
[1] = 0xe0 | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
BAsmCode
[2 + AdrCnt
] = Addr
& 0xff;
CodeLen
= 3 + AdrCnt
;
}
}
}
}
}
static void DecodeIncDec
(Word Code
)
{
static Byte Sizes
[3] = {2, 0, 1};
if (ChkArgCnt
(1, 1))
{
SetOpSize
(Sizes
[(Code
& 3) - 1]);
if (DecodeAdr
(&ArgStr
[1], MModMem
| MModReg
))
{
BAsmCode
[0] = 0x70 | (Code
& 15);
BAsmCode
[1] = (Code
& 0xf0) | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
}
static void DecodeMulDiv
(Word Index
)
{
MulDivOrder
*POrder
= MulDivOrders
+ Index
;
if (ChkArgCnt
(1, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
if (ArgCnt
== 1)
{
if (POrder
->AccCode
== 0xfff) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[CodeLen
++] = Lo
(POrder
->AccCode
);
if (Hi
(POrder
->AccCode
) != 0)
BAsmCode
[CodeLen
++] = Hi
(POrder
->AccCode
);
}
}
else
{
SetOpSize
((POrder
->Code
>> 5) & 1);
if (DecodeAdr
(&ArgStr
[2], MModMem
| MModReg
))
{
BAsmCode
[0] = 0x78;
BAsmCode
[1] = POrder
->Code
| AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
}
}
static void DecodeSeg
(Word Code
)
{
if (ChkArgCnt
(1, 1)
&& DecodeAdr
(&ArgStr
[1], MModSeg
))
{
BAsmCode
[0] = 0x6e;
BAsmCode
[1] = Code
+ AdrPart
;
CodeLen
= 2;
}
}
static void DecodeString
(Word Code
)
{
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[1], MModSeg
))
{
BAsmCode
[1] = AdrPart
<< 2;
if (DecodeAdr
(&ArgStr
[2], MModSeg
))
{
BAsmCode
[1] += Code
+ AdrPart
;
BAsmCode
[0] = 0x6e;
CodeLen
= 2;
}
}
}
static void DecodeINT
(Word Index
)
{
Boolean OK
;
LongWord Addr
;
UNUSED
(Index
);
if (!ChkArgCnt
(1, 1));
else if (*ArgStr
[1].
str.
p_str == '#')
{
BAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt8
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x68;
CodeLen
= 2;
}
}
else
{
tSymbolFlags Flags
;
Addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt24
, &OK
, &Flags
);
if (OK
)
{
if (!mSymbolQuestionable
(Flags
) && ((Addr
& 0xff0000) != 0xff0000))
WrError
(ErrNum_InAccPage
);
BAsmCode
[0] = 0x69;
BAsmCode
[1] = Addr
& 0xff;
BAsmCode
[2] = (Addr
>> 8) & 0xff;
CodeLen
= 3;
}
}
}
static void DecodeINTP
(Word Index
)
{
Boolean OK
;
LongWord Addr
;
UNUSED
(Index
);
if (ChkArgCnt
(1, 1))
{
Addr
= EvalStrIntExpression
(&ArgStr
[1], UInt24
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x6a;
BAsmCode
[1] = Addr
& 0xff;
BAsmCode
[2] = (Addr
>> 8) & 0xff;
BAsmCode
[3] = (Addr
>> 16) & 0xff;
CodeLen
= 4;
}
}
}
static void DecodeJCTX
(Word Index
)
{
UNUSED
(Index
);
if (!ChkArgCnt
(1, 1));
else if (*ArgStr
[1].
str.
p_str != '@') WrError
(ErrNum_InvAddrMode
);
else
{
tStrComp Arg1
;
StrCompRefRight
(&Arg1
, &ArgStr
[1], 1);
if (DecodeAdr
(&Arg1
, MModAcc
))
{
BAsmCode
[0] = 0x13;
CodeLen
= 1;
}
}
}
static void DecodeLINK
(Word Index
)
{
UNUSED
(Index
);
if (ChkArgCnt
(1, 1))
{
SetOpSize
(0);
if (DecodeAdr
(&ArgStr
[1], MModImm
))
{
BAsmCode
[0] = 0x08;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
}
}
}
static void DecodeMOV
(Word Index
)
{
Byte HPart
, HCnt
;
UNUSED
(Index
);
if (!ChkArgCnt
(2, 2));
else if (((!as_strcasecmp
(ArgStr
[1].
str.
p_str, "@AL")) || (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "@A")))
&& ((!as_strcasecmp
(ArgStr
[2].
str.
p_str, "AH" )) || (!as_strcasecmp
(ArgStr
[2].
str.
p_str, "T" ))))
{
BAsmCode
[0] = 0x6f; BAsmCode
[1] = 0x15;
CodeLen
= 2;
}
else
{
SetOpSize
(0);
DecodeAdr
(&ArgStr
[1], MModRP
| MModILM
| MModAcc
| MModDir
| MModRDisp
| MModIO
| MModSpec
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModRP
:
{
if (DecodeAdr
(&ArgStr
[2], MModImm
))
{
BAsmCode
[0] = 0x0a;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
}
break;
} /* 1 = ModRP */
case ModILM
:
{
if (DecodeAdr
(&ArgStr
[2], MModImm
))
{
BAsmCode
[0] = 0x1a;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
}
break;
} /* 1 = ModILM */
case ModAcc
:
{
DecodeAdr
(&ArgStr
[2], MModImm
| MModIAcc
| MModRDisp
| MModIO
| MModMem
| MModReg
| MModDir
| MModSpec
);
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x42;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
case ModIAcc
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x05;
CodeLen
= 2;
break;
case ModRDisp
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x40 | (AdrPart
<< 1);
BAsmCode
[2] = AdrVals
[0];
CodeLen
= 3;
break;
case ModIO
:
BAsmCode
[0] = 0x50;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
case ModMem
:
if (AdrPart
== ABSMODE
) /* 16 bit absolute */
{
BAsmCode
[0] = 0x52;
CodeLen
= 1;
}
else
{
BAsmCode
[0] = 0x72;
BAsmCode
[1] = 0x80 + AdrPart
;
CodeLen
= 2;
}
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen
+= AdrCnt
;
break;
case ModReg
:
BAsmCode
[0] = 0x80 | AdrPart
;
CodeLen
= 1;
break;
case ModDir
:
BAsmCode
[0] = 0x40;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
case ModSpec
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x00 + AdrPart
;
CodeLen
= 2;
break;
}
break;
} /* 1 = ModAcc */
case ModDir
:
{
BAsmCode
[1] = AdrVals
[0];
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x41;
CodeLen
= 2;
break;
case ModImm
:
BAsmCode
[0] = 0x44;
BAsmCode
[2] = AdrVals
[0];
CodeLen
= 3;
break;
case ModReg
: /* extend to 16 bits */
BAsmCode
[0] = 0x7c;
BAsmCode
[2] = BAsmCode
[1];
BAsmCode
[1] = (AdrPart
<< 5) | ABSMODE
;
BAsmCode
[3] = Reg_DPR
;
CodeLen
= 4;
break;
}
break;
} /* 1 = ModDir */
case ModRDisp
:
{
BAsmCode
[2] = AdrVals
[0];
DecodeAdr
(&ArgStr
[2], MModAcc
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x30 | (AdrPart
<< 1);
CodeLen
= 3;
break;
}
break;
} /* 1 = ModRDisp */
case ModIO
:
{
BAsmCode
[1] = AdrVals
[0];
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x51;
CodeLen
= 2;
break;
case ModImm
:
BAsmCode
[0] = 0x54;
BAsmCode
[2] = AdrVals
[0];
CodeLen
= 3;
break;
case ModReg
: /* extend to 16 bits - will only work when in Bank 0 */
BAsmCode
[0] = 0x7c;
BAsmCode
[2] = BAsmCode
[1];
BAsmCode
[1] = (AdrPart
<< 5) | ABSMODE
;
BAsmCode
[3] = 0;
if (CurrBank
!= 0) WrError
(ErrNum_InAccPage
);
CodeLen
= 4;
break;
}
break;
} /* 1 = ModIO */
case ModSpec
:
if (AdrPart
== 6) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[1] = 0x10 + AdrPart
;
DecodeAdr
(&ArgStr
[2], MModAcc
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x6f;
CodeLen
= 2;
break;
}
} /* 1 = ModSpec */
break;
case ModReg
:
{
BAsmCode
[0] = AdrPart
;
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] += 0x90;
CodeLen
= 1;
break;
case ModImm
:
BAsmCode
[0] += 0xa0;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
break;
case ModReg
:
case ModMem
:
BAsmCode
[1] = (BAsmCode
[0] << 5) | AdrPart
;
BAsmCode
[0] = 0x7a;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
break;
}
break;
} /* 1 = ModReg */
case ModMem
:
{
HPart
= AdrPart
; HCnt
= AdrCnt
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
if (HPart
== ABSMODE
)
{
memmove(BAsmCode
+ 1, BAsmCode
+ 2, 2);
BAsmCode
[0] = 0x53;
CodeLen
= 3;
}
else
{
BAsmCode
[0] = 0x72;
BAsmCode
[1] = 0xa0 | HPart
;
CodeLen
= 2 + HCnt
;
}
break;
case ModImm
:
BAsmCode
[0] = 0x71;
BAsmCode
[1] = 0xc0 | HPart
;
BAsmCode
[2 + HCnt
] = AdrVals
[0];
CodeLen
= 3 + HCnt
;
break;
case ModReg
:
BAsmCode
[0] = 0x7c;
BAsmCode
[1] = (AdrPart
<< 5) | HPart
;
CodeLen
= 2 + HCnt
;
}
break;
} /* 1 = ModMem */
}
}
}
static void DecodeMOVB
(Word Index
)
{
if (ChkArgCnt
(2, 2))
{
if (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "A"))
Index
= 2;
else if (!as_strcasecmp
(ArgStr
[2].
str.
p_str, "A"))
Index
= 1;
else
WrError
(ErrNum_InvAddrMode
);
if ((Index
> 0)
&& SplitBit
(&ArgStr
[Index
], BAsmCode
+ 1)
&& DecodeAdr
(&ArgStr
[Index
], MModDir
| MModIO
| MModMem
))
{
BAsmCode
[0] = 0x6c;
BAsmCode
[1] += (2 - Index
) << 5;
switch (AdrMode
)
{
case ModDir
:
BAsmCode
[1] += 0x08;
break;
case ModMem
:
BAsmCode
[1] += 0x18;
if (AdrPart
!= ABSMODE
)
{
WrError
(ErrNum_InvAddrMode
);
AdrCnt
= 0;
}
break;
}
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
}
static void DecodeMOVEA
(Word Index
)
{
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
SetOpSize
(1);
DecodeAdr
(&ArgStr
[1], MModAcc
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
if (DecodeAdr
(&ArgStr
[2], MModMem
| MModReg
))
{
BAsmCode
[0] = 0x71;
BAsmCode
[1] = 0xe0 | AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
break;
case ModReg
:
BAsmCode
[1] = AdrPart
<< 5;
if (DecodeAdr
(&ArgStr
[2], MModMem
| MModReg
))
{
BAsmCode
[0] = 0x79;
BAsmCode
[1] += AdrPart
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
break;
}
}
}
static void DecodeMOVL
(Word Index
)
{
Byte HCnt
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
SetOpSize
(2);
DecodeAdr
(&ArgStr
[1], MModAcc
| MModMem
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
DecodeAdr
(&ArgStr
[2], MModMem
| MModReg
| MModImm
);
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x4b;
CopyVals
(1);
break;
case ModReg
:
case ModMem
:
BAsmCode
[0] = 0x71;
BAsmCode
[1] = 0x80 | AdrPart
;
CopyVals
(2);
}
break;
case ModReg
:
case ModMem
:
BAsmCode
[1] = 0xa0 | AdrPart
;
HCnt
= AdrCnt
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
if (DecodeAdr
(&ArgStr
[2], MModAcc
))
{
BAsmCode
[0] = 0x71;
CodeLen
= 2 + HCnt
;
}
break;
}
}
}
static void DecodeMOVN
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
if (*ArgStr
[2].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
BAsmCode
[0] = 0xd0 + EvalStrIntExpressionOffs
(&ArgStr
[2], 1, UInt4
, &OK
);
if (OK
)
CodeLen
= 1;
}
}
}
static void DecodeMOVW
(Word Index
)
{
Byte HPart
, HCnt
;
UNUSED
(Index
);
if (!ChkArgCnt
(2, 2));
else if (((!as_strcasecmp
(ArgStr
[1].
str.
p_str, "@AL")) || (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "@A")))
&& ((!as_strcasecmp
(ArgStr
[2].
str.
p_str, "AH" )) || (!as_strcasecmp
(ArgStr
[2].
str.
p_str, "T" ))))
{
BAsmCode
[0] = 0x6f; BAsmCode
[1] = 0x1d;
CodeLen
= 2;
}
else
{
SetOpSize
(1);
DecodeAdr
(&ArgStr
[1], MModAcc
| MModRDisp
| MModSP
| MModDir
| MModIO
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
DecodeAdr
(&ArgStr
[2], MModImm
| MModIAcc
| MModRDisp
| MModSP
| MModIO
| MModMem
| MModReg
| MModDir
);
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x4a;
CopyVals
(1);
break;
case ModIAcc
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x0d;
CodeLen
= 2;
break;
case ModRDisp
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x48 + (AdrPart
<< 1);
CopyVals
(2);
break;
case ModSP
:
BAsmCode
[0] = 0x46;
CodeLen
= 1;
break;
case ModIO
:
BAsmCode
[0] = 0x58;
CopyVals
(1);
break;
case ModDir
:
BAsmCode
[0] = 0x48;
CopyVals
(1);
break;
case ModReg
:
BAsmCode
[0] = 0x88 + AdrPart
;
CodeLen
= 1;
break;
case ModMem
:
if (AdrPart
== ABSMODE
)
{
BAsmCode
[0] = 0x5a;
CopyVals
(1);
}
else if ((AdrPart
>= 0x10) && (AdrPart
<= 0x17))
{
BAsmCode
[0] = 0xa8 + AdrPart
;
CopyVals
(1);
}
else
{
BAsmCode
[0] = 0x73;
BAsmCode
[1] = 0x80 + AdrPart
;
CopyVals
(2);
}
break;
}
break; /* 1 = ModAcc */
case ModRDisp
:
BAsmCode
[1] = 0x38 + (AdrPart
<< 1);
BAsmCode
[2] = AdrVals
[0];
if (DecodeAdr
(&ArgStr
[2], MModAcc
))
{
BAsmCode
[0] = 0x6f;
CodeLen
= 3;
}
break; /* 1 = ModRDisp */
case ModSP
:
if (DecodeAdr
(&ArgStr
[2], MModAcc
))
{
BAsmCode
[0] = 0x47;
CodeLen
= 1;
}
break; /* 1 = ModSP */
case ModDir
:
BAsmCode
[1] = AdrVals
[0];
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x49;
CodeLen
= 2;
break;
case ModImm
: /* extend to 16 bits */
BAsmCode
[0] = 0x73;
BAsmCode
[2] = BAsmCode
[1];
BAsmCode
[1] = 0xc0 | ABSMODE
;
BAsmCode
[3] = Reg_DPR
;
CopyVals
(4);
break;
case ModReg
: /* extend to 16 bits */
BAsmCode
[0] = 0x7d;
BAsmCode
[2] = BAsmCode
[1];
BAsmCode
[1] = (AdrPart
<< 5) | ABSMODE
;
BAsmCode
[3] = Reg_DPR
;
CodeLen
= 4;
break;
}
break; /* 1 = ModDir */
case ModIO
:
BAsmCode
[1] = AdrVals
[0];
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x59;
CodeLen
= 2;
break;
case ModImm
:
BAsmCode
[0] = 0x56;
CopyVals
(1);
break;
case ModReg
: /* extend to 16 bits - will only work when in Bank 0 */
BAsmCode
[0] = 0x7d;
BAsmCode
[2] = BAsmCode
[1];
BAsmCode
[1] = (AdrPart
<< 5) | ABSMODE
;
BAsmCode
[3] = 0;
if (CurrBank
!= 0) WrError
(ErrNum_InAccPage
);
CodeLen
= 4;
break;
}
break; /* 1 = ModIO */
case ModReg
:
HPart
= AdrPart
;
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x98 | HPart
;
CodeLen
= 1;
break;
case ModImm
:
BAsmCode
[0] = 0x98 | HPart
;
CopyVals
(1);
break;
case ModReg
:
case ModMem
:
BAsmCode
[0] = 0x7b;
BAsmCode
[1] = (HPart
<< 5) | AdrPart
;
CopyVals
(2);
break;
}
break; /* 1 = ModReg */
case ModMem
:
HPart
= AdrPart
; HCnt
= AdrCnt
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
DecodeAdr
(&ArgStr
[2], MModAcc
| MModImm
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
if (HPart
== ABSMODE
)
{
BAsmCode
[0] = 0x5b;
memmove(BAsmCode
+ 1, BAsmCode
+ 2, HCnt
);
CodeLen
= 1 + HCnt
;
}
else if ((HPart
>= 0x10) && (HPart
<= 0x17))
{
BAsmCode
[0] = 0xb8 + AdrPart
;
memmove(BAsmCode
+ 1, BAsmCode
+ 2, HCnt
);
CodeLen
= 1 + HCnt
;
}
else
{
BAsmCode
[0] = 0x73;
BAsmCode
[1] = 0xa0 | AdrPart
;
CodeLen
= 2 + HCnt
;
}
break;
case ModImm
:
BAsmCode
[0] = 0x73;
BAsmCode
[1] = 0xc0 | HPart
;
CopyVals
(2 + HCnt
);
break;
case ModReg
:
BAsmCode
[0] = 0x7d;
BAsmCode
[1] = (AdrPart
<< 5) | HPart
;
CodeLen
= 2 + HCnt
;
}
break; /* 1 = ModMem */
}
}
}
static void DecodeMOVX
(Word Index
)
{
UNUSED
(Index
);
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
SetOpSize
(0);
DecodeAdr
(&ArgStr
[2], MModImm
| MModIAcc
| MModRDisp
| MModDir
| MModIO
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModImm
:
BAsmCode
[0] = 0x43;
CopyVals
(1);
break;
case ModIAcc
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x16;
CodeLen
= 2;
break;
case ModRDisp
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x20 | (AdrPart
<< 1);
CopyVals
(2);
break;
case ModDir
:
BAsmCode
[0] = 0x45;
CopyVals
(1);
break;
case ModIO
:
BAsmCode
[0] = 0x55;
CopyVals
(1);
break;
case ModReg
:
BAsmCode
[0] = 0xb0 + AdrPart
;
CodeLen
= 1;
break;
case ModMem
:
if (AdrPart
== ABSMODE
)
{
BAsmCode
[0] = 0x57;
CopyVals
(1);
}
else if ((AdrPart
>= 0x10) && (AdrPart
<= 0x17))
{
BAsmCode
[0] = 0xb0 + AdrPart
;
CopyVals
(1);
}
else
{
BAsmCode
[0] = 0x72;
BAsmCode
[1] = 0xc0 | AdrPart
;
CopyVals
(2);
}
break;
}
}
}
static void DecodeNEGNOT
(Word Index
)
{
if (ChkArgCnt
(1, 1))
{
SetOpSize
((OpPart.
str.
p_str[3] == 'W') ? 1 : 0);
DecodeAdr
(&ArgStr
[1], MModAcc
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = Lo
(Index
);
CodeLen
= 1;
break;
case ModReg
:
case ModMem
:
BAsmCode
[0] = 0x75 + (OpSize
<< 1);
BAsmCode
[1] = Hi
(Index
) + AdrPart
;
CopyVals
(2);
break;
}
}
}
static void DecodeNRML
(Word Index
)
{
UNUSED
(Index
);
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[1], MModAcc
))
{
SetOpSize
(0);
if (DecodeAdr
(&ArgStr
[2], MModReg
))
{
if (AdrPart
!= 0) WrError
(ErrNum_InvAddrMode
);
else
{
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x2d;
CodeLen
= 2;
}
}
}
}
static void DecodeStack
(Word Index
)
{
int z
, z2
;
Byte HReg
;
char *p
;
if (!ChkArgCnt
(1, ArgCntMax
));
else if ((ArgCnt
== 1) && (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "A")))
{
BAsmCode
[0] = Index
;
CodeLen
= 1;
}
else if ((ArgCnt
== 1) && (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "AH")))
{
BAsmCode
[0] = Index
+ 1;
CodeLen
= 1;
}
else if ((ArgCnt
== 1) && (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "PS")))
{
BAsmCode
[0] = Index
+ 2;
CodeLen
= 1;
}
else
{
tStrComp From
, To
;
BAsmCode
[1] = 0; SetOpSize
(1);
for (z
= 1; z
<= ArgCnt
; z
++)
if ((p
= strchr(ArgStr
[z
].
str.
p_str, '-')) != NULL
)
{
StrCompSplitRef
(&From
, &To
, &ArgStr
[z
], p
);
if (!DecodeAdr
(&From
, MModReg
)) break;
HReg
= AdrPart
;
if (!DecodeAdr
(&To
, MModReg
)) break;
if (AdrPart
>= HReg
)
{
for (z2
= HReg
; z2
<= AdrPart
; z2
++)
BAsmCode
[1] |= (1 << z2
);
}
else
{
for (z2
= HReg
; z2
<= 7; z2
++)
BAsmCode
[1] |= (1 << z2
);
for (z2
= 0; z2
<= AdrPart
; z2
++)
BAsmCode
[1] |= (1 << z2
);
}
}
else
{
if (!DecodeAdr
(&ArgStr
[z
], MModReg
)) break;
BAsmCode
[1] |= (1 << AdrPart
);
}
if (z
> ArgCnt
)
{
BAsmCode
[0] = Index
+ 3;
CodeLen
= 2;
}
}
}
static void DecodeRotate
(Word Index
)
{
if (ChkArgCnt
(1, 1))
{
DecodeAdr
(&ArgStr
[1], MModAcc
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x6f;
BAsmCode
[1] = 0x07 | (Index
<< 4);
CodeLen
= 2;
break;
case ModReg
:
case ModMem
:
BAsmCode
[0] = 0x72;
BAsmCode
[1] = (Index
<< 5) | AdrPart
;
CopyVals
(2);
break;
}
}
}
static void DecodeSBBS
(Word Index
)
{
LongInt Adr
;
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2)
&& SplitBit
(&ArgStr
[1], BAsmCode
+ 1)
&& DecodeAdr
(&ArgStr
[1], MModMem
))
{
if (AdrPart
!= ABSMODE
) WrError
(ErrNum_InvAddrMode
);
else
{
tSymbolFlags Flags
;
Adr
= EvalStrIntExpressionWithFlags
(&ArgStr
[2], UInt24
, &OK
, &Flags
) - (EProgCounter
() + 5);
if (OK
)
{
if (!mSymbolQuestionable
(Flags
) && ((Adr
< -128) || (Adr
> 127))) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[0] = 0x6c;
BAsmCode
[1] += 0xf8;
CopyVals
(2);
BAsmCode
[CodeLen
++] = Adr
& 0xff;
}
}
}
}
}
static void DecodeWBit
(Word Index
)
{
if (ChkArgCnt
(1, 1)
&& SplitBit
(&ArgStr
[1], BAsmCode
+ 1)
&& DecodeAdr
(&ArgStr
[1], MModIO
))
{
BAsmCode
[0] = 0x6c;
BAsmCode
[1] += Index
;
CopyVals
(2);
}
}
static void DecodeExchange
(Word Index
)
{
Byte HPart
, HCnt
;
if (ChkArgCnt
(2, 2))
{
SetOpSize
(Index
);
DecodeAdr
(&ArgStr
[1], MModAcc
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
if (DecodeAdr
(&ArgStr
[2], MModReg
| MModMem
))
{
BAsmCode
[0] = 0x72 + Index
;
BAsmCode
[1] = 0xe0 | AdrPart
;
CopyVals
(2);
}
break;
case ModReg
:
HPart
= AdrPart
;
DecodeAdr
(&ArgStr
[2], MModAcc
| MModReg
| MModMem
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x72 + Index
;
BAsmCode
[1] = 0xe0 | HPart
;
CodeLen
= 2;
break;
case ModReg
:
case ModMem
:
BAsmCode
[0] = 0x7e + Index
;
BAsmCode
[1] = (HPart
<< 5) | AdrPart
;
CopyVals
(2);
break;
}
break;
case ModMem
:
HPart
= AdrPart
; HCnt
= AdrCnt
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
DecodeAdr
(&ArgStr
[2], MModAcc
| MModReg
);
switch (AdrMode
)
{
case ModAcc
:
BAsmCode
[0] = 0x72 + Index
;
BAsmCode
[1] = 0xe0 | HPart
;
CodeLen
= 2 + HCnt
;
break;
case ModReg
:
BAsmCode
[0] = 0x7e + Index
;
BAsmCode
[1] = (AdrPart
<< 5) | HPart
;
CodeLen
= 2 + HCnt
;
break;
}
break;
}
}
}
static void DecodeBank
(Word Index
)
{
if (ChkArgCnt
(0, 0))
{
BAsmCode
[0] = Index
+ 4;
CodeLen
= 1;
NextDataSeg
= Index
;
}
}
/*--------------------------------------------------------------------------*/
/* Codetabellen */
static void AddFixed
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeFixed
);
}
static void AddALU8
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeALU8
);
}
static void AddLog8
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeLog8
);
}
static void AddAcc
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeAcc
);
}
static void AddShift
(const char *NName
, Word NCode
, Word NMay
)
{
AddInstTable
(InstTable
, NName
, NCode
| (NMay
<< 8), DecodeShift
);
}
static void AddBranch
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBranch
);
}
static void AddIncDec
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeIncDec
);
}
static void AddMulDiv
(const char *NName
, Byte NCode
, Word NAccCode
)
{
MulDivOrders
[InstrZ
].
Code = NCode
;
MulDivOrders
[InstrZ
].
AccCode = NAccCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeMulDiv
);
}
static void AddSeg
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeSeg
);
}
static void AddString
(const char *NName
, Byte NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeString
);
}
static void InitFields
(void)
{
unsigned z
;
InstTable
= CreateInstTable
(201);
AddFixed
("EXT" , 0x14); AddFixed
("EXTW" , 0x1c);
AddFixed
("INT9" , 0x01); AddFixed
("NOP" , 0x00);
AddFixed
("RET" , 0x67); AddFixed
("RETI" , 0x6b);
AddFixed
("RETP" , 0x66); AddFixed
("SWAP" , 0x16);
AddFixed
("SWAPW" , 0x1e); AddFixed
("UNLINK" , 0x09);
AddFixed
("ZEXT" , 0x15); AddFixed
("ZEXTW" , 0x1d);
AddFixed
("CMR" , 0x10); AddFixed
("NCC" , 0x11);
AddALU8
("ADD" , 0); AddALU8
("SUB" , 1);
AddLog8
("AND" , 4); AddLog8
("OR" , 5);
AddLog8
("XOR" , 6);
AddAcc
("ADDDC" , 0x02);
AddAcc
("SUBDC" , 0x12);
AddShift
("ASR" , 0x2e, FALSE
); AddShift
("ASRL" , 0x1e, FALSE
);
AddShift
("ASRW" , 0x0e, TRUE
); AddShift
("LSLW" , 0x0c, TRUE
);
AddShift
("LSRW" , 0x0f, TRUE
); AddShift
("LSL" , 0x2c, FALSE
);
AddShift
("LSR" , 0x2f, FALSE
); AddShift
("LSLL" , 0x1c, FALSE
);
AddShift
("LSRL" , 0x1f, FALSE
); AddShift
("SHLW" , 0x0c, TRUE
);
AddShift
("SHRW" , 0x0f, TRUE
);
AddBranch
("BZ" , 0xf0); AddBranch
("BEQ" , 0xf0); AddBranch
("BNZ" , 0xf1);
AddBranch
("BNE" , 0xf1); AddBranch
("BC" , 0xf2); AddBranch
("BLO" , 0xf2);
AddBranch
("BNC" , 0xf3); AddBranch
("BHS" , 0xf3); AddBranch
("BN" , 0xf4);
AddBranch
("BP" , 0xf5); AddBranch
("BV" , 0xf6); AddBranch
("BNV" , 0xf7);
AddBranch
("BT" , 0xf8); AddBranch
("BNT" , 0xf9); AddBranch
("BLT" , 0xfa);
AddBranch
("BGE" , 0xfb); AddBranch
("BLE" , 0xfc); AddBranch
("BGT" , 0xfd);
AddBranch
("BLS" , 0xfe); AddBranch
("BHI" , 0xff); AddBranch
("BRA" , 0x60);
AddIncDec
("INC" , 0x42); AddIncDec
("INCW" , 0x43); AddIncDec
("INCL" , 0x41);
AddIncDec
("DEC" , 0x62); AddIncDec
("DECW" , 0x63); AddIncDec
("DECL" , 0x61);
MulDivOrders
= (MulDivOrder
*) malloc(sizeof(MulDivOrder
) * MulDivOrderCnt
);
InstrZ
= 0;
AddMulDiv
("MULU", 0x00, 0x0027); AddMulDiv
("MULUW", 0x20, 0x002f);
AddMulDiv
("MUL" , 0x40, 0x786f); AddMulDiv
("MULW" , 0x60, 0x796f);
AddMulDiv
("DIVU", 0x80, 0x0026); AddMulDiv
("DIVUW", 0xa0, 0xffff);
AddMulDiv
("DIV" , 0xc0, 0x7a6f); AddMulDiv
("DIVW" , 0xe0, 0xffff);
AddSeg
("SCEQI" , 0x80); AddSeg
("SCEQD" , 0x90);
AddSeg
("SCWEQI", 0xa0); AddSeg
("SCWEQD", 0xb0);
AddSeg
("FILSI" , 0xc0); AddSeg
("FILS" , 0xc0);
AddSeg
("FILSWI", 0xe0); AddSeg
("FILSW" , 0xe0);
AddSeg
("SCEQ" , 0x80); AddSeg
("SCWEQ" , 0xa0);
AddString
("MOVS" , 0x00); AddString
("MOVSI" , 0x00); AddString
("MOVSD" , 0x10);
AddString
("MOVSW", 0x20); AddString
("MOVSWI", 0x20); AddString
("MOVSWD", 0x30);
for (z
= 0; z
< (int)sizeof(BankNames
) / sizeof(*BankNames
); z
++)
AddInstTable
(InstTable
, BankNames
[z
], z
, DecodeBank
);
AddInstTable
(InstTable
, "ADDC", 0, DecodeCarry8
);
AddInstTable
(InstTable
, "SUBC", 1, DecodeCarry8
);
AddInstTable
(InstTable
, "ADDCW",0, DecodeCarry16
);
AddInstTable
(InstTable
, "SUBCW",1, DecodeCarry16
);
AddInstTable
(InstTable
, "ADDL", 0, DecodeAdd32
);
AddInstTable
(InstTable
, "SUBL", 1, DecodeAdd32
);
AddInstTable
(InstTable
, "CMPL", 3, DecodeAdd32
);
AddInstTable
(InstTable
, "ADDSP",0, DecodeADDSP
);
AddInstTable
(InstTable
, "ADDW", 0, DecodeAdd16
);
AddInstTable
(InstTable
, "SUBW", 1, DecodeAdd16
);
AddInstTable
(InstTable
, "CMPW", 3, DecodeAdd16
);
AddInstTable
(InstTable
, "ANDW", 4, DecodeAdd16
);
AddInstTable
(InstTable
, "ORW" , 5, DecodeAdd16
);
AddInstTable
(InstTable
, "XORW", 6, DecodeAdd16
);
AddInstTable
(InstTable
, "ANDL", 4, DecodeLog32
);
AddInstTable
(InstTable
, "ORL", 5, DecodeLog32
);
AddInstTable
(InstTable
, "XORL", 6, DecodeLog32
);
AddInstTable
(InstTable
, "BBC", 0x80, DecodeBBcc
);
AddInstTable
(InstTable
, "BBS", 0xa0, DecodeBBcc
);
AddInstTable
(InstTable
, "CALL", 2, DecodeJmp16
);
AddInstTable
(InstTable
, "JMP", 0, DecodeJmp16
);
AddInstTable
(InstTable
, "CALLP", 2, DecodeJmp24
);
AddInstTable
(InstTable
, "JMPP", 0, DecodeJmp24
);
AddInstTable
(InstTable
, "CALLV", 0, DecodeCALLV
);
AddInstTable
(InstTable
, "CBNE", 0, DecodeCmpBranch
);
AddInstTable
(InstTable
, "CWBNE", 1, DecodeCmpBranch
);
AddInstTable
(InstTable
, "CLRB", 0x40, DecodeBit
);
AddInstTable
(InstTable
, "SETB", 0x60, DecodeBit
);
AddInstTable
(InstTable
, "CMP" , 0, DecodeCMP
);
AddInstTable
(InstTable
, "DBNZ" , 0, DecodeDBNZ
);
AddInstTable
(InstTable
, "DWBNZ" , 1, DecodeDBNZ
);
AddInstTable
(InstTable
, "INT", 0, DecodeINT
);
AddInstTable
(InstTable
, "INTP", 0, DecodeINTP
);
AddInstTable
(InstTable
, "JCTX", 0, DecodeJCTX
);
AddInstTable
(InstTable
, "LINK", 0, DecodeLINK
);
AddInstTable
(InstTable
, "MOV", 0, DecodeMOV
);
AddInstTable
(InstTable
, "MOVB", 0, DecodeMOVB
);
AddInstTable
(InstTable
, "MOVEA", 0, DecodeMOVEA
);
AddInstTable
(InstTable
, "MOVL", 0, DecodeMOVL
);
AddInstTable
(InstTable
, "MOVN", 0, DecodeMOVN
);
AddInstTable
(InstTable
, "MOVW", 0, DecodeMOVW
);
AddInstTable
(InstTable
, "MOVX", 0, DecodeMOVX
);
AddInstTable
(InstTable
, "NOT" , 0xe037, DecodeNEGNOT
);
AddInstTable
(InstTable
, "NEG" , 0x6003, DecodeNEGNOT
);
AddInstTable
(InstTable
, "NOTW", 0xe03f, DecodeNEGNOT
);
AddInstTable
(InstTable
, "NEGW", 0x600b, DecodeNEGNOT
);
AddInstTable
(InstTable
, "NRML", 0, DecodeNRML
);
AddInstTable
(InstTable
, "PUSHW", 0x40, DecodeStack
);
AddInstTable
(InstTable
, "POPW", 0x50, DecodeStack
);
AddInstTable
(InstTable
, "ROLC", 0, DecodeRotate
);
AddInstTable
(InstTable
, "RORC", 1, DecodeRotate
);
AddInstTable
(InstTable
, "SBBS", 1, DecodeSBBS
);
AddInstTable
(InstTable
, "WBTS", 0xc0, DecodeWBit
);
AddInstTable
(InstTable
, "WBTC", 0xe0, DecodeWBit
);
AddInstTable
(InstTable
, "XCH", 0, DecodeExchange
);
AddInstTable
(InstTable
, "XCHW", 1, DecodeExchange
);
}
static void DeinitFields
(void)
{
DestroyInstTable
(InstTable
);
free(MulDivOrders
);
}
/*--------------------------------------------------------------------------*/
/* Interface zu AS */
static void MakeCode_F2MC16
(void)
{
/* Leeranweisung ignorieren */
if (Memo
(""))
return;
/* Pseudoanweisungen */
if (DecodeIntelPseudo
(False
))
return;
/* akt. Datensegment */
switch (NextDataSeg
)
{
case 0:
CurrBank
= Reg_PCB
;
break;
case 1:
CurrBank
= Reg_DTB
;
break;
case 2:
CurrBank
= Reg_ADB
;
break;
case 3:
CurrBank
= SupAllowed
? Reg_SSB
: Reg_USB
;
break;
}
CurrBank
<<= 16;
NextDataSeg
= 1; /* = DTB */
OpSize
= -1;
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
}
static Boolean IsDef_F2MC16
(void)
{
return FALSE
;
}
static void InitCode_F2MC16
(void)
{
Reg_PCB
= 0xff;
Reg_DTB
= 0x00;
Reg_USB
= 0x00;
Reg_SSB
= 0x00;
Reg_ADB
= 0x00;
Reg_DPR
= 0x01;
}
static void SwitchTo_F2MC16
(void)
{
const TFamilyDescr
*FoundDescr
;
FoundDescr
= FindFamilyByName
("F2MC16");
TurnWords
= False
;
SetIntConstMode
(eIntConstModeIntel
);
PCSymbol
= "$";
HeaderID
= FoundDescr
->Id
;
NOPCode
=0x00;
DivideChars
= ",";
HasAttrs
= False
;
ValidSegs
= 1 << SegCode
;
Grans
[SegCode
] = 1;
ListGrans
[SegCode
] = 1;
SegInits
[SegCode
] = 0;
SegLimits
[SegCode
] = 0xffffff;
MakeCode
= MakeCode_F2MC16
;
IsDef
= IsDef_F2MC16
;
SwitchFrom
= DeinitFields
;
InitFields
();
onoff_supmode_add
();
pASSUMERecs
= ASSUMEF2MC16s
;
ASSUMERecCnt
= ASSUMEF2MC16Count
;
NextDataSeg
= 1; /* DTB */
}
/*--------------------------------------------------------------------------*/
/* Initialisierung */
void codef2mc16_init
(void)
{
CPU90500
= AddCPU
("MB90500", SwitchTo_F2MC16
);
AddInitPassProc
(InitCode_F2MC16
);
}