/* code6812.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegeneratormodul CPU12 */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "strutil.h"
#include "bpemu.h"
#include "asmdef.h"
#include "asmpars.h"
#include "asmsub.h"
#include "asmallg.h"
#include "asmitree.h"
#include "codepseudo.h"
#include "motpseudo.h"
#include "codevars.h"
#include "errmsg.h"
#include "code6812.h"
typedef struct
{
Word Code
;
CPUVar MinCPU
;
} FixedOrder
;
typedef struct
{
Word Code
;
CPUVar MinCPU
;
Boolean MayImm
, MayDir
, MayExt
;
tSymbolSize ThisOpSize
;
} GenOrder
;
typedef struct
{
Word Code
;
Boolean MayDir
;
} JmpOrder
;
typedef struct
{
Word Code
;
Byte OpSize
;
CPUVar MinCPU
;
} Reg
;
enum
{
eShortModeAuto
= 0,
eShortModeNo
= 1,
eShortModeYes
= 2,
eShortModeExtreme
= 3
};
enum
{
ModNone
= -1,
ModImm
= 0,
ModDir
= 1,
ModExt
= 2,
ModIdx
= 3,
ModIdx1
= 4,
ModIdx2
= 5,
ModDIdx
= 6,
ModIIdx2
= 7,
ModExtPg
= 8
};
#define MModImm (1 << ModImm)
#define MModDir (1 << ModDir)
#define MModExt (1 << ModExt)
#define MModIdx (1 << ModIdx)
#define MModIdx1 (1 << ModIdx1)
#define MModIdx2 (1 << ModIdx2)
#define MModDIdx (1 << ModDIdx)
#define MModIIdx2 (1 << ModIIdx2)
#define MModExtPg (1 << ModExtPg)
#define MModAllIdx (MModIdx | MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2)
static tSymbolSize OpSize
;
static ShortInt AdrMode
;
static ShortInt ExPos
;
static Byte AdrVals
[4];
static Byte ActReg
, ActRegSize
;
static CPUVar CPU6812
, CPU6812X
;
static IntType AddrInt
;
static LongInt Reg_Direct
, Reg_GPage
;
static FixedOrder
*FixedOrders
;
static FixedOrder
*BranchOrders
;
static GenOrder
*GenOrders
;
static FixedOrder
*LoopOrders
;
static FixedOrder
*LEAOrders
;
static JmpOrder
*JmpOrders
;
static Reg
*Regs
;
static PInstTable RegTable
;
/*---------------------------------------------------------------------------*/
/* Address Expression Decoder */
enum
{
eRegA
= 0,
eRegB
= 1,
eRegCCRL
= 2,
eRegD
= 4,
eRegX
= 5,
eRegY
= 6,
eRegSP
= 7,
eRegPC
= 8,
eRegHalf
= 0x40,
eRegUpper
= 0x80,
eRegWord
= 0xc0,
eRegXL
= eRegHalf
| eRegX
,
eRegXH
= eRegHalf
| eRegUpper
| eRegX
,
eRegYL
= eRegHalf
| eRegY
,
eRegYH
= eRegHalf
| eRegUpper
| eRegY
,
eRegSPL
= eRegHalf
| eRegSP
,
eRegSPH
= eRegHalf
| eRegUpper
| eRegSP
,
eRegCCRH
= eRegCCRL
| eRegUpper
,
eRegCCRW
= eRegCCRL
| eRegWord
,
eNoReg
= 0xff
};
static Boolean DecodeReg
(const char *pAsc
, Byte
*pErg
)
{
Boolean Result
;
String Reg
;
strmaxcpy
(Reg
, pAsc
, STRINGSIZE
);
UpString
(Reg
);
Result
= LookupInstTable
(RegTable
, Reg
) && (ActReg
!= eNoReg
);
if (Result
)
*pErg
= ActReg
;
return Result
;
}
enum
{
eBaseRegX
= 0,
eBaseRegY
= 1,
eBaseRegSP
= 2,
eBaseRegPC
= 3
};
static Boolean DecodeBaseReg
(const char *pAsc
, Byte
*pErg
)
{
Boolean Result
= DecodeReg
(pAsc
, pErg
);
if (Result
)
{
switch (*pErg
)
{
case eRegX
:
*pErg
= eBaseRegX
;
break;
case eRegY
:
*pErg
= eBaseRegY
;
break;
case eRegSP
:
*pErg
= eBaseRegSP
;
break;
case eRegPC
:
*pErg
= eBaseRegPC
;
break;
default:
Result
= FALSE
;
}
}
return Result
;
}
static Boolean ValidReg
(const char *Asc_o
)
{
Byte Dummy
;
String Asc
;
int l
= strlen(Asc_o
);
if ((*Asc_o
== '-') || (*Asc_o
== '+'))
strcpy(Asc
, Asc_o
+ 1);
else
{
strcpy(Asc
, Asc_o
);
if ((l
> 0) && ((Asc_o
[l
- 1] == '-') || (Asc_o
[l
- 1] == '+')))
Asc
[l
- 1] = '\0';
}
return DecodeBaseReg
(Asc
, &Dummy
);
}
enum
{
eIdxRegA
= 0,
eIdxRegB
= 1,
eIdxRegD
= 2
};
static Boolean DecodeIdxReg
(const char *pAsc
, Byte
*pErg
)
{
Boolean Result
= DecodeReg
(pAsc
, pErg
);
if (Result
)
{
switch (*pErg
)
{
case eRegA
:
*pErg
= eIdxRegA
;
break;
case eRegB
:
*pErg
= eIdxRegB
;
break;
case eRegD
:
*pErg
= eIdxRegD
;
break;
default:
Result
= FALSE
;
}
}
return Result
;
}
static Boolean ChkRegPair
(Byte SrcReg
, Byte DestReg
, Byte
*pExtMask
)
{
Boolean Result
= TRUE
;
switch (SrcReg
)
{
case eRegA
:
if ((DestReg
<= eRegCCRL
) || ((DestReg
>= eRegD
) && (DestReg
<= eRegSP
)))
*pExtMask
= 0;
else if ((DestReg
== eRegCCRH
) || (DestReg
== eRegXH
) || (DestReg
== eRegYH
) || (DestReg
== eRegSPH
))
*pExtMask
= 8;
else
Result
= False
;
break;
case eRegB
:
if ((DestReg
<= eRegCCRL
) || ((DestReg
>= eRegD
) && (DestReg
<= eRegSP
)))
*pExtMask
= 0;
else if ((DestReg
== eRegXL
) || (DestReg
== eRegYL
) || (DestReg
== eRegSPL
))
*pExtMask
= 8;
else
Result
= False
;
break;
case eRegCCRL
:
if ((DestReg
<= eRegCCRL
) || ((DestReg
>= eRegD
) && (DestReg
<= eRegSP
)))
*pExtMask
= 0;
else
Result
= False
;
break;
case eRegD
:
case eRegX
:
case eRegY
:
case eRegSP
:
if ((DestReg
<= eRegCCRL
) || ((DestReg
>= eRegD
) && (DestReg
<= eRegSP
)))
*pExtMask
= 0;
else if (DestReg
== eRegCCRW
)
*pExtMask
= 8;
else
Result
= False
;
break;
case eRegXL
:
case eRegYL
:
case eRegSPL
:
if (DestReg
<= eRegCCRL
)
*pExtMask
= 0;
else
Result
= False
;
break;
case eRegXH
:
case eRegYH
:
case eRegSPH
:
case eRegCCRH
:
if (DestReg
== eRegA
)
*pExtMask
= 8;
else
Result
= False
;
break;
case eRegCCRW
:
if ((DestReg
== eRegCCRW
) || ((DestReg
>= eRegD
) && (DestReg
<= eRegSP
)))
*pExtMask
= 8;
else
Result
= False
;
break;
default:
Result
= False
;
}
if ((Result
) && (*pExtMask
) && (MomCPU
< CPU6812X
))
Result
= FALSE
;
return Result
;
}
static void CutShort
(char *Asc
, Integer
*ShortMode
)
{
if (*Asc
== '>')
{
*ShortMode
= eShortModeNo
;
strmov
(Asc
, Asc
+ 1);
}
else if (*Asc
== '<')
{
if (Asc
[1] == '<')
{
*ShortMode
= eShortModeExtreme
;
strmov
(Asc
, Asc
+ 2);
}
else
{
*ShortMode
= eShortModeYes
;
strmov
(Asc
,Asc
+ 1);
}
}
else
*ShortMode
= eShortModeAuto
;
}
static Boolean DistFits
(Byte Reg
, Integer Dist
, Integer Offs
, LongInt Min
, LongInt Max
, tSymbolFlags Flags
)
{
if (Reg
== eBaseRegPC
)
Dist
-= Offs
;
return (((Dist
>= Min
) && (Dist
<= Max
)) || ((Reg
== eBaseRegPC
) && mSymbolQuestionable
(Flags
)));
}
static void DecodeAdr
(int Start
, int Stop
, Word Mask
)
{
Integer ShortMode
;
LongInt AdrWord
;
int l
;
char *p
;
Boolean OK
;
tSymbolFlags Flags
;
Boolean DecFlag
, AutoFlag
, PostFlag
;
AdrMode
= ModNone
;
AdrCnt
= 0;
/* one argument? */
if (Stop
- Start
== 0)
{
/* immediate */
if (*ArgStr
[Start
].
str.
p_str == '#')
{
switch (OpSize
)
{
case eSymbolSizeUnknown
:
WrError
(ErrNum_UndefOpSizes
);
break;
case eSymbolSize8Bit
:
AdrVals
[0] = EvalStrIntExpressionOffs
(&ArgStr
[Start
], 1, Int8
, &OK
);
if (OK
)
{
AdrCnt
= 1;
AdrMode
= ModImm
;
}
break;
case eSymbolSize16Bit
:
AdrWord
= EvalStrIntExpressionOffs
(&ArgStr
[Start
], 1, Int16
, &OK
);
if (OK
)
{
AdrVals
[0] = AdrWord
>> 8;
AdrVals
[1] = AdrWord
& 0xff;
AdrCnt
= 2;
AdrMode
= ModImm
;
}
break;
default:
break;
}
goto chk
;
}
/* indirekt */
if ((*ArgStr
[Start
].
str.
p_str == '[') && (ArgStr
[Start
].
str.
p_str[strlen(ArgStr
[Start
].
str.
p_str) - 1] == ']'))
{
strmov
(ArgStr
[Start
].
str.
p_str, ArgStr
[Start
].
str.
p_str + 1);
ArgStr
[Start
].
str.
p_str[strlen(ArgStr
[Start
].
str.
p_str) - 1] = '\0';
p
= QuotPos
(ArgStr
[Start
].
str.
p_str, ',');
if (p
)
*p
= '\0';
if (!p
) WrError
(ErrNum_InvAddrMode
);
else if (!DecodeBaseReg
(p
+ 1, AdrVals
))
WrXError
(ErrNum_InvReg
, p
+ 1);
else if (!as_strcasecmp
(ArgStr
[Start
].
str.
p_str, "D"))
{
AdrVals
[0] = (AdrVals
[0] << 3) | 0xe7;
AdrCnt
= 1;
AdrMode
= ModDIdx
;
}
else
{
AdrWord
= EvalStrIntExpression
(&ArgStr
[Start
], Int16
, &OK
);
if (OK
)
{
if (AdrVals
[0] == eBaseRegPC
)
AdrWord
-= EProgCounter
() + ExPos
+ 3;
AdrVals
[0] = (AdrVals
[0] << 3) | 0xe3;
AdrVals
[1] = AdrWord
>> 8;
AdrVals
[2] = AdrWord
& 0xff;
AdrCnt
= 3;
AdrMode
= ModIIdx2
;
}
}
goto chk
;
}
/* dann absolut */
CutShort
(ArgStr
[Start
].
str.
p_str, &ShortMode
);
AdrWord
= EvalStrIntExpressionWithFlags
(&ArgStr
[Start
], AddrInt
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
))
{
if ((!(Mask
& (MModExt
| MModExtPg
))) || (ShortMode
== eShortModeYes
))
AdrWord
= (Reg_Direct
<< 8) | Lo
(AdrWord
);
}
if (OK
)
{
if ((ShortMode
!= eShortModeNo
)
&& (Hi
(AdrWord
) == Reg_Direct
)
&& ((Mask
& MModDir
) != 0))
{
AdrMode
= ModDir
;
AdrVals
[0] = AdrWord
& 0xff;
AdrCnt
= 1;
}
else
{
AdrMode
= ModExt
;
AdrVals
[0] = Hi
(AdrWord
);
AdrVals
[1] = Lo
(AdrWord
);
if (Mask
& MModExtPg
)
{
Mask
|= MModExt
;
if ((HiWord
(EProgCounter
()) != HiWord
(AdrWord
))
&& ((AdrWord
& 0xc000) == 0x8000)
&& ((EProgCounter
() & 0xc000) == 0x8000)
&& !mFirstPassUnknown
(Flags
))
WrError
(ErrNum_PageCrossing
);
}
AdrCnt
= 2;
}
}
goto chk
;
}
/* two arguments? */
else if (Stop
- Start
== 1)
{
/* Autoin/-dekrement abspalten */
l
= strlen(ArgStr
[Stop
].
str.
p_str);
if ((*ArgStr
[Stop
].
str.
p_str == '-') || (*ArgStr
[Stop
].
str.
p_str == '+'))
{
DecFlag
= (*ArgStr
[Stop
].
str.
p_str == '-');
AutoFlag
= True
;
PostFlag
= False
;
strmov
(ArgStr
[Stop
].
str.
p_str, ArgStr
[Stop
].
str.
p_str + 1);
}
else if ((ArgStr
[Stop
].
str.
p_str[l
- 1] == '-') || (ArgStr
[Stop
].
str.
p_str[l
- 1] == '+'))
{
DecFlag
= (ArgStr
[Stop
].
str.
p_str[l
- 1] == '-');
AutoFlag
= True
;
PostFlag
= True
;
ArgStr
[Stop
].
str.
p_str[l
- 1] = '\0';
}
else
AutoFlag
= DecFlag
= PostFlag
= False
;
if (AutoFlag
)
{
if (!DecodeBaseReg
(ArgStr
[Stop
].
str.
p_str, AdrVals
)) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[Stop
]);
else if (AdrVals
[0] == eBaseRegPC
) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[Stop
]);
else
{
AdrWord
= EvalStrIntExpressionWithFlags
(&ArgStr
[Start
], SInt8
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
))
AdrWord
= 1;
/* no increment/decrement degenerates to register indirect with zero displacement! */
if (AdrWord
== 0)
{
AdrVals
[0] = (AdrVals
[0] << 6);
AdrCnt
= 1;
AdrMode
= ModIdx
;
}
else if (AdrWord
> 8) WrError
(ErrNum_OverRange
);
else if (AdrWord
< -8) WrError
(ErrNum_UnderRange
);
else
{
if (AdrWord
< 0)
{
DecFlag
= !DecFlag
;
AdrWord
= (-AdrWord
);
}
AdrWord
= DecFlag
? 8 - AdrWord
: AdrWord
- 1;
AdrVals
[0] = (AdrVals
[0] << 6) | 0x20 | (Ord
(PostFlag
) << 4) | (Ord
(DecFlag
) << 3) | (AdrWord
& 7);
AdrCnt
= 1;
AdrMode
= ModIdx
;
}
}
goto chk
;
}
else
{
if (!DecodeBaseReg
(ArgStr
[Stop
].
str.
p_str, AdrVals
)) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[Stop
]);
else if (DecodeIdxReg
(ArgStr
[Start
].
str.
p_str, AdrVals
+ 1))
{
AdrVals
[0] = (AdrVals
[0] << 3) | AdrVals
[1] | 0xe4;
AdrCnt
= 1;
AdrMode
= ModIdx
;
}
else
{
CutShort
(ArgStr
[Start
].
str.
p_str, &ShortMode
);
AdrWord
= EvalStrIntExpressionWithFlags
(&ArgStr
[Start
], Int16
, &OK
, &Flags
);
if (AdrVals
[0] == eBaseRegPC
)
AdrWord
-= EProgCounter
() + ExPos
;
if (OK
)
{
if ((ShortMode
!= eShortModeNo
) && (ShortMode
!= eShortModeYes
) && ((Mask
& MModIdx
) != 0) && (DistFits
(AdrVals
[0], AdrWord
, 1, -16, 15, Flags
)))
{
if (AdrVals
[0] == eBaseRegPC
)
AdrWord
--;
AdrVals
[0] = (AdrVals
[0] << 6) | (AdrWord
& 0x1f);
AdrCnt
= 1;
AdrMode
= ModIdx
;
}
else if ((ShortMode
!= eShortModeNo
) && (ShortMode
!= eShortModeExtreme
) && ((Mask
& MModIdx1
) != 0) && (DistFits
(AdrVals
[0], AdrWord
, 2, -256, 255, Flags
)))
{
if (AdrVals
[0] == eBaseRegPC
)
AdrWord
-= 2;
AdrVals
[0] = 0xe0 | (AdrVals
[0] << 3) | (Hi
(AdrWord
) & 1);
AdrVals
[1] = Lo
(AdrWord
);
AdrCnt
= 2;
AdrMode
= ModIdx1
;
}
else
{
if (AdrVals
[0] == eBaseRegPC
)
AdrWord
-= 3;
AdrVals
[0] = 0xe2 | (AdrVals
[0] << 3);
AdrVals
[1] = Hi
(AdrWord
);
AdrVals
[2] = Lo
(AdrWord
);
AdrCnt
= 3;
AdrMode
= ModIdx2
;
}
}
}
goto chk
;
}
}
else WrError
(ErrNum_InvAddrMode
);
chk
:
if ((AdrMode
!= ModNone
) && (((1 << AdrMode
) & Mask
) == 0))
{
AdrMode
= ModNone
;
AdrCnt
= 0;
WrError
(ErrNum_InvAddrMode
);
}
}
static void Try2Split
(int Src
)
{
char *p
;
int z
;
size_t SrcLen
;
KillPrefBlanksStrComp
(&ArgStr
[Src
]);
KillPostBlanksStrComp
(&ArgStr
[Src
]);
SrcLen
= strlen(ArgStr
[Src
].
str.
p_str);
p
= ArgStr
[Src
].
str.
p_str + SrcLen
- 1;
while ((p
>= ArgStr
[Src
].
str.
p_str) && !as_isspace
(*p
))
p
--;
if (p
>= ArgStr
[Src
].
str.
p_str)
{
InsertArg
(Src
+ 1, SrcLen
);
for (z
= ArgCnt
- 1; z
>= Src
+ 1; z
--)
StrCompCopy
(&ArgStr
[z
+ 1], &ArgStr
[z
]);
StrCompSplitRight
(&ArgStr
[Src
], &ArgStr
[Src
+ 1], p
);
KillPostBlanksStrComp
(&ArgStr
[Src
]);
KillPrefBlanksStrComp
(&ArgStr
[Src
+ 1]);
}
}
/*---------------------------------------------------------------------------*/
/* Instruction Decoders */
static void DecodeFixed
(Word Index
)
{
FixedOrder
*pOrder
= FixedOrders
+ Index
;
if (!ChkArgCnt
(0, 0));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (!ChkMinCPU
(pOrder
->MinCPU
));
else
{
if (Hi
(pOrder
->Code
))
BAsmCode
[CodeLen
++] = Hi
(pOrder
->Code
);
BAsmCode
[CodeLen
++] = Lo
(pOrder
->Code
);
}
}
static void DecodeGen
(Word Index
)
{
GenOrder
*pOrder
= GenOrders
+ Index
;
if (!ChkArgCnt
(1, 2));
else if (!ChkMinCPU
(pOrder
->MinCPU
));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
ExPos
= 1 + Ord
(Hi
(pOrder
->Code
) != 0);
OpSize
= pOrder
->ThisOpSize
;
DecodeAdr
(1, ArgCnt
, MModAllIdx
| (pOrder
->MayImm
? MModImm
: 0) | (pOrder
->MayDir
? MModDir
: 0) | (pOrder
->MayExt
? MModExt
: 0));
if (AdrMode
!= ModNone
)
{
if (Hi
(pOrder
->Code
) == 0)
{
BAsmCode
[0] = pOrder
->Code
;
CodeLen
= 1;
}
else
{
BAsmCode
[0] = Hi
(pOrder
->Code
);
BAsmCode
[1] = Lo
(pOrder
->Code
);
CodeLen
= 2;
}
}
switch (AdrMode
)
{
case ModImm
:
break;
case ModDir
:
BAsmCode
[CodeLen
- 1] += 0x10;
break;
case ModIdx
:
case ModIdx1
:
case ModIdx2
:
case ModDIdx
:
case ModIIdx2
:
BAsmCode
[CodeLen
- 1] += 0x20;
break;
case ModExt
:
BAsmCode
[CodeLen
- 1] += 0x30;
break;
}
if (AdrMode
!= ModNone
)
{
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen
+= AdrCnt
;
}
}
}
static void DecodeLEA
(Word Index
)
{
FixedOrder
*pOrder
= LEAOrders
+ Index
;
if (!ChkArgCnt
(1, 2));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
ExPos
= 1;
DecodeAdr
(1, ArgCnt
, MModIdx
| MModIdx1
| MModIdx2
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = pOrder
->Code
;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
}
}
static void DecodeBranch
(Word Index
)
{
FixedOrder
*pOrder
= BranchOrders
+ Index
;
LongInt Address
;
Boolean OK
;
tSymbolFlags Flags
;
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
Address
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], AddrInt
, &OK
, &Flags
) - EProgCounter
() - 2;
if (OK
)
{
if (((Address
< -128) || (Address
> 127)) && !mSymbolQuestionable
(Flags
)) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[0] = pOrder
->Code
;
BAsmCode
[1] = Lo
(Address
);
CodeLen
= 2;
}
}
}
}
static void DecodeLBranch
(Word Index
)
{
FixedOrder
*pOrder
= BranchOrders
+ Index
;
LongInt Address
;
Boolean OK
;
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
Address
= EvalStrIntExpression
(&ArgStr
[1], AddrInt
, &OK
) - EProgCounter
() - 4;
if (OK
)
{
BAsmCode
[0] = 0x18;
BAsmCode
[1] = pOrder
->Code
;
BAsmCode
[2] = Hi
(Address
);
BAsmCode
[3] = Lo
(Address
);
CodeLen
= 4;
}
}
}
static void DecodeJmp
(Word Index
)
{
JmpOrder
*pOrder
= JmpOrders
+ Index
;
Word Mask
;
if (!ChkArgCnt
(1, 2));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
Mask
= MModAllIdx
| MModExtPg
;
if (pOrder
->MayDir
)
Mask
|= MModDir
;
ExPos
= 1;
DecodeAdr
(1, ArgCnt
, Mask
);
if (AdrMode
!= ModNone
)
{
switch (AdrMode
)
{
case ModExt
:
BAsmCode
[0] = pOrder
->Code
;
break;
case ModDir
:
BAsmCode
[0] = pOrder
->Code
+ 1;
break;
case ModIdx
:
case ModIdx1
:
case ModIdx2
:
case ModDIdx
:
case ModIIdx2
:
BAsmCode
[0] = pOrder
->Code
- 1;
break;
}
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
}
}
static void DecodeLoop
(Word Index
)
{
FixedOrder
*pOrder
= LoopOrders
+ Index
;
Byte HReg
;
LongInt Address
;
Boolean OK
;
tSymbolFlags Flags
;
if (!ChkArgCnt
(2, 2));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (!DecodeReg
(ArgStr
[1].
str.
p_str, &HReg
)) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
else
{
OK
= (HReg
<= eRegB
) || ((HReg
>= eRegD
) && (HReg
<= eRegSP
));
if (!OK
) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
else
{
Address
= EvalStrIntExpressionWithFlags
(&ArgStr
[2], AddrInt
, &OK
, &Flags
) - (EProgCounter
() + 3);
if (OK
)
{
if (((Address
< -256) || (Address
> 255)) && !mSymbolQuestionable
(Flags
)) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[0] = 0x04;
BAsmCode
[1] = pOrder
->Code
| HReg
| ((Address
>> 4) & 0x10);
BAsmCode
[2] = Address
& 0xff;
CodeLen
= 3;
}
}
}
}
}
static void DecodeETBL
(Word Index
)
{
if (!ChkArgCnt
(1, 2));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
ExPos
= 2;
DecodeAdr
(1, ArgCnt
, MModIdx
);
if (AdrMode
== ModIdx
)
{
BAsmCode
[0] = 0x18;
BAsmCode
[1] = Index
;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
CodeLen
= 2 + AdrCnt
;
}
}
}
static void DecodeEMACS
(Word Index
)
{
LongInt Address
;
Boolean OK
;
UNUSED
(Index
);
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
Address
= EvalStrIntExpression
(&ArgStr
[1], UInt16
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x18;
BAsmCode
[1] = 0x12;
BAsmCode
[2] = Hi
(Address
) & 0xff;
BAsmCode
[3] = Lo
(Address
);
CodeLen
= 4;
}
}
}
static void DecodeTransfer
(Word Index
)
{
Byte Reg1
, Reg2
;
Byte ExtMask
;
if (!ChkArgCnt
(2, 2));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (!DecodeReg
(ArgStr
[2].
str.
p_str, &Reg2
)) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
else if (eRegPC
== Reg2
) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
else if (!DecodeReg
(ArgStr
[1].
str.
p_str, &Reg1
)) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
else if (eRegPC
== Reg1
) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
else if (!ChkRegPair
(Reg1
, Reg2
, &ExtMask
)) WrError
(ErrNum_InvRegPair
);
else
{
BAsmCode
[0] = 0xb7;
Reg1
&= 7;
Reg2
&= 7;
BAsmCode
[1] = Index
| (Reg1
<< 4) | Reg2
| ExtMask
;
CodeLen
= 2;
}
}
static void DecodeSEX
(Word Index
)
{
Byte Reg1
, Reg2
;
Byte ExtMask
;
if (!ChkArgCnt
(2, 2));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (!DecodeReg
(ArgStr
[2].
str.
p_str, &Reg2
)) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
else if (ActRegSize
!= 1) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
else if (eRegPC
== Reg2
) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
else if (!DecodeReg
(ArgStr
[1].
str.
p_str, &Reg1
)) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
else if (ActRegSize
!= 0) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
else if (eRegPC
== Reg1
) WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
else if (!ChkRegPair
(Reg1
, Reg2
, &ExtMask
)) WrError
(ErrNum_InvRegPair
);
else
{
BAsmCode
[0] = 0xb7;
BAsmCode
[1] = Index
| (Reg1
<< 4) | Reg2
| ExtMask
;
CodeLen
= 2;
}
}
static void DecodeMOV
(Word Index
)
{
Byte Arg2Start
, HCnt
= 0, HAdrVals
[4];
Word Mask
;
switch (ArgCnt
)
{
case 1:
Try2Split
(1);
break;
case 2:
Try2Split
(1);
if (ArgCnt
== 2)
Try2Split
(2);
break;
case 3:
Try2Split
(2);
break;
}
if (!ChkArgCnt
(2, 4));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
if (ArgCnt
== 2)
Arg2Start
= 2;
else if (ArgCnt
== 4)
Arg2Start
= 3;
else if (ValidReg
(ArgStr
[2].
str.
p_str))
Arg2Start
= 3;
else
Arg2Start
= 2;
OpSize
= (tSymbolSize
)Index
;
ExPos
= 2;
BAsmCode
[0] = 0x18;
BAsmCode
[1] = (1 - Index
) << 3;
Mask
= MModImm
| MModExt
| MModIdx
;
if (MomCPU
>= CPU6812X
)
Mask
|= MModIdx1
| MModIdx2
| MModDIdx
| MModIIdx2
;
/* decode & save source operand */
DecodeAdr
(1, Arg2Start
- 1, Mask
);
if (AdrMode
!= ModNone
)
{
memcpy(HAdrVals
, AdrVals
, AdrCnt
);
HCnt
= AdrCnt
;
}
/* dispatch source address mode */
switch (AdrMode
)
{
case ModImm
:
ExPos
= 4 + 2 * OpSize
;
DecodeAdr
(Arg2Start
, ArgCnt
, MModExt
| MModIdx
| MModIdx1
| MModIdx2
| MModDIdx
| MModIIdx2
);
switch (AdrMode
)
{
case ModExt
:
BAsmCode
[1] |= 3;
memcpy(BAsmCode
+ 2 , HAdrVals
, HCnt
);
memcpy(BAsmCode
+ 2 + HCnt
, AdrVals
, AdrCnt
);
break;
case ModIdx
:
case ModIdx1
:
case ModIdx2
:
case ModDIdx
:
case ModIIdx2
:
memcpy(BAsmCode
+ 2 , AdrVals
, AdrCnt
);
memcpy(BAsmCode
+ 2 + AdrCnt
, HAdrVals
, HCnt
);
break;
}
break;
case ModExt
:
ExPos
= 6;
DecodeAdr
(Arg2Start
, ArgCnt
, MModExt
| MModIdx
| MModIdx1
| MModIdx2
| MModDIdx
| MModIIdx2
);
switch (AdrMode
)
{
case ModExt
:
BAsmCode
[1] |= 4;
memcpy(BAsmCode
+ 2, HAdrVals
, HCnt
);
memcpy(BAsmCode
+ 2 + HCnt
, AdrVals
, AdrCnt
);
break;
case ModIdx
:
case ModIdx1
:
case ModIdx2
:
case ModDIdx
:
case ModIIdx2
:
BAsmCode
[1] |= 1;
memcpy(BAsmCode
+ 2, AdrVals
, AdrCnt
);
memcpy(BAsmCode
+ 2 + AdrCnt
, HAdrVals
, HCnt
);
break;
}
break;
case ModIdx
:
case ModIdx1
:
case ModIdx2
:
case ModDIdx
:
case ModIIdx2
:
ExPos
= 4;
DecodeAdr
(Arg2Start
, ArgCnt
, MModExt
| MModIdx
| MModIdx1
| MModIdx2
| MModDIdx
| MModIIdx2
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[1] |= (AdrMode
== ModExt
) ? 5 : 2;
memcpy(BAsmCode
+ 2, HAdrVals
, HCnt
);
memcpy(BAsmCode
+ 2 + HCnt
, AdrVals
, AdrCnt
);
}
break;
}
if (AdrMode
!= ModNone
)
CodeLen
= 2 + AdrCnt
+ HCnt
;
}
}
static void DecodeLogic
(Word Index
)
{
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
OpSize
= eSymbolSize8Bit
; DecodeAdr
(1, 1, MModImm
);
if (AdrMode
== ModImm
)
{
BAsmCode
[0] = 0x10 | Index
;
BAsmCode
[1] = AdrVals
[0];
CodeLen
= 2;
}
}
}
static void DecodeBit
(Word Index
)
{
Byte HReg
;
Boolean OK
;
if ((ArgCnt
== 1) || (ArgCnt
== 2))
Try2Split
(ArgCnt
);
if (!ChkArgCnt
(2, 3));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
HReg
= EvalStrIntExpressionOffs
(&ArgStr
[ArgCnt
], !!(*ArgStr
[ArgCnt
].
str.
p_str == '#'), UInt8
, &OK
);
if (OK
)
{
ExPos
= 2; /* wg. Masken-Postbyte */
DecodeAdr
(1, ArgCnt
- 1, MModDir
| MModExt
| MModIdx
| MModIdx1
| MModIdx2
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = Index
;
switch (AdrMode
)
{
case ModDir
:
BAsmCode
[0] += 0x40;
break;
case ModExt
:
BAsmCode
[0] += 0x10;
break;
}
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = HReg
;
CodeLen
= 2 + AdrCnt
;
}
}
}
}
static void DecodeCALL
(Word Index
)
{
UNUSED
(Index
);
if (!ChkArgCnt
(1, 3));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else if (*ArgStr
[1].
str.
p_str == '[')
{
if (ChkArgCnt
(1, 1))
{
ExPos
= 1; DecodeAdr
(1, 1, MModDIdx
| MModIIdx2
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = 0x4b;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
CodeLen
= 1 + AdrCnt
;
}
}
}
else
{
if (ChkArgCnt
(2, 3))
{
Boolean OK
;
Byte Page
= EvalStrIntExpression
(&ArgStr
[ArgCnt
], UInt8
, &OK
);
if (OK
)
{
ExPos
= 2; /* wg. Seiten-Byte eins mehr */
DecodeAdr
(1, ArgCnt
- 1, MModExt
| MModIdx
| MModIdx1
| MModIdx2
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = 0x4a | Ord
(AdrMode
!= ModExt
);
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
BAsmCode
[1 + AdrCnt
] = Page
;
CodeLen
= 2 + AdrCnt
;
}
}
}
}
}
static void DecodePCALL
(Word Index
)
{
Boolean OK
;
LongWord Addr
;
UNUSED
(Index
);
if (ChkArgCnt
(1, 1)
&& ChkMinCPU
(CPU6812X
))
{
Addr
= EvalStrIntExpression
(&ArgStr
[1], UInt24
, &OK
);
if (OK
)
{
BAsmCode
[0] = 0x4a;
BAsmCode
[1] = Hi
(Addr
);
BAsmCode
[2] = Lo
(Addr
);
BAsmCode
[3] = (Addr
>> 16) & 0xff;
CodeLen
= 4;
}
}
}
static void DecodeBrBit
(Word Index
)
{
Byte HReg
;
Boolean OK
;
tSymbolFlags Flags
;
LongInt Address
;
if (ArgCnt
== 1)
{
Try2Split
(1);
Try2Split
(1);
}
else if (ArgCnt
== 2)
{
Try2Split
(ArgCnt
);
Try2Split
(2);
}
if (!ChkArgCnt
(3, 4));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
HReg
= EvalStrIntExpressionOffs
(&ArgStr
[ArgCnt
- 1], !!(*ArgStr
[ArgCnt
- 1].
str.
p_str == '#'), UInt8
, &OK
);
if (OK
)
{
Address
= EvalStrIntExpressionWithFlags
(&ArgStr
[ArgCnt
], AddrInt
, &OK
, &Flags
) - EProgCounter
();
if (OK
)
{
ExPos
= 3; /* Opcode, Maske+Distanz */
DecodeAdr
(1, ArgCnt
- 2, MModDir
| MModExt
| MModIdx
| MModIdx1
| MModIdx2
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[0] = 0x0e | Index
;
memcpy(BAsmCode
+ 1, AdrVals
, AdrCnt
);
switch (AdrMode
)
{
case ModDir
:
BAsmCode
[0] += 0x40;
break;
case ModExt
:
BAsmCode
[0] += 0x10;
break;
}
BAsmCode
[1 + AdrCnt
] = HReg
;
Address
-= 3 + AdrCnt
;
if (((Address
< -128) || (Address
> 127)) & !mSymbolQuestionable
(Flags
)) WrError
(ErrNum_JmpDistTooBig
);
else
{
BAsmCode
[2 + AdrCnt
] = Lo
(Address
);
CodeLen
= 3 + AdrCnt
;
}
}
}
}
}
}
static void DecodeTRAP
(Word Index
)
{
Boolean OK
;
tSymbolFlags Flags
;
UNUSED
(Index
);
if (!ChkArgCnt
(1, 1));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
BAsmCode
[1] = EvalStrIntExpressionOffsWithFlags
(&ArgStr
[1], !!(*ArgStr
[1].
str.
p_str == '#'), UInt8
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
))
BAsmCode
[1] = 0x30;
if (OK
)
{
if ((BAsmCode
[1] < 0x30) || ((BAsmCode
[1] > 0x39) && (BAsmCode
[1] < 0x40))) WrError
(ErrNum_OverRange
);
else
{
BAsmCode
[0] = 0x18;
CodeLen
= 2;
}
}
}
}
static void DecodeBTAS
(Word Index
)
{
UNUSED
(Index
);
if (!ChkArgCnt
(2, 3));
else if (!ChkMinCPU
(CPU6812X
));
else if (*AttrPart.
str.
p_str) WrError
(ErrNum_UseLessAttr
);
else
{
ExPos
= 2;
OpSize
= eSymbolSize8Bit
;
DecodeAdr
(1, ArgCnt
- 1, MModDir
| MModExt
| MModIdx
| MModIdx1
| ModIdx2
| ModDIdx
);
if (AdrMode
!= ModNone
)
{
BAsmCode
[CodeLen
++] = 0x18;
switch (AdrMode
)
{
case ModImm
:
break;
case ModDir
:
BAsmCode
[CodeLen
++] = 0x35;
break;
case ModIdx
:
case ModIdx1
:
case ModIdx2
:
case ModDIdx
:
BAsmCode
[CodeLen
++] = 0x37;
break;
case ModExt
:
BAsmCode
[CodeLen
++] = 0x36;
break;
}
memcpy(BAsmCode
+ CodeLen
, AdrVals
, AdrCnt
);
CodeLen
+= AdrCnt
;
DecodeAdr
(ArgCnt
, ArgCnt
, MModImm
);
if (AdrMode
== ModImm
)
BAsmCode
[CodeLen
++] = *AdrVals
;
else
CodeLen
= 0;
}
}
}
static void LookupReg
(Word Index
)
{
Reg
*pReg
= Regs
+ Index
;
ActReg
= (MomCPU
>= pReg
->MinCPU
) ? pReg
->Code
: (Byte
)eNoReg
;
ActRegSize
= pReg
->OpSize
;
}
/*---------------------------------------------------------------------------*/
/* Dynamic Code Table Handling */
static void AddFixed
(const char *NName
, Word NCode
, CPUVar NMin
)
{
order_array_rsv_end
(FixedOrders
, FixedOrder
);
FixedOrders
[InstrZ
].
Code = NCode
;
FixedOrders
[InstrZ
].
MinCPU = NMin
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeFixed
);
}
static void AddBranch
(const char *NName
, Word NCode
)
{
order_array_rsv_end
(BranchOrders
, FixedOrder
);
BranchOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
+ 1, InstrZ
, DecodeBranch
);
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeLBranch
);
}
static void AddGen
(const char *NName
, Word NCode
,
Boolean NMayI
, Boolean NMayD
, Boolean NMayE
,
tSymbolSize NSize
, CPUVar NMin
)
{
order_array_rsv_end
(GenOrders
, GenOrder
);
GenOrders
[InstrZ
].
Code = NCode
;
GenOrders
[InstrZ
].
MayImm = NMayI
;
GenOrders
[InstrZ
].
MayDir = NMayD
;
GenOrders
[InstrZ
].
MayExt = NMayE
;
GenOrders
[InstrZ
].
ThisOpSize = NSize
;
GenOrders
[InstrZ
].
MinCPU = NMin
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeGen
);
}
static void AddLoop
(const char *NName
, Word NCode
)
{
order_array_rsv_end
(LoopOrders
, FixedOrder
);
LoopOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeLoop
);
}
static void AddLEA
(const char *NName
, Word NCode
)
{
order_array_rsv_end
(LEAOrders
, FixedOrder
);
LEAOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeLEA
);
}
static void AddJmp
(const char *NName
, Word NCode
, Boolean NDir
)
{
order_array_rsv_end
(JmpOrders
, JmpOrder
);
JmpOrders
[InstrZ
].
Code = NCode
;
JmpOrders
[InstrZ
].
MayDir = NDir
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeJmp
);
}
static void AddReg
(const char *NName
, Word NCode
, Word NSize
, CPUVar NMin
)
{
order_array_rsv_end
(Regs
, Reg
);
Regs
[InstrZ
].
Code = NCode
;
Regs
[InstrZ
].
OpSize = NSize
;
Regs
[InstrZ
].
MinCPU = NMin
;
AddInstTable
(RegTable
, NName
, InstrZ
++, LookupReg
);
}
static void InitFields
(void)
{
InstTable
= CreateInstTable
(405);
InstrZ
= 0;
AddFixed
("ABA" , 0x1806, CPU6812
); AddFixed
("ABX" , 0x1ae5, CPU6812
);
AddFixed
("ABY" , 0x19ed, CPU6812
); AddFixed
("ASLA" , 0x0048, CPU6812
);
AddFixed
("ASLB" , 0x0058, CPU6812
); AddFixed
("ASLD" , 0x0059, CPU6812
);
AddFixed
("ASLX" , 0x1848, CPU6812X
); AddFixed
("ASLY" , 0x1858, CPU6812X
);
AddFixed
("ASRA" , 0x0047, CPU6812
); AddFixed
("ASRB" , 0x0057, CPU6812
);
AddFixed
("ASRX" , 0x1847, CPU6812X
); AddFixed
("ASRY" , 0x1857, CPU6812X
);
AddFixed
("BGND" , 0x0000, CPU6812
); AddFixed
("CBA" , 0x1817, CPU6812
);
AddFixed
("CLC" , 0x10fe, CPU6812
); AddFixed
("CLI" , 0x10ef, CPU6812
);
AddFixed
("CLRA" , 0x0087, CPU6812
); AddFixed
("CLRB" , 0x00c7, CPU6812
);
AddFixed
("CLRX" , 0x1887, CPU6812X
); AddFixed
("CLRY" , 0x18c7, CPU6812X
);
AddFixed
("CLV" , 0x10fd, CPU6812
); AddFixed
("COMA" , 0x0041, CPU6812
);
AddFixed
("COMB" , 0x0051, CPU6812
); AddFixed
("COMX" , 0x1841, CPU6812X
);
AddFixed
("COMY" , 0x1851, CPU6812X
); AddFixed
("DAA" , 0x1807, CPU6812
);
AddFixed
("DECA" , 0x0043, CPU6812
); AddFixed
("DECB" , 0x0053, CPU6812
);
AddFixed
("DECX" , 0x1843, CPU6812X
); AddFixed
("DECY" , 0x1853, CPU6812X
);
AddFixed
("DES" , 0x1b9f, CPU6812
); AddFixed
("DEX" , 0x0009, CPU6812
);
AddFixed
("DEY" , 0x0003, CPU6812
); AddFixed
("EDIV" , 0x0011, CPU6812
);
AddFixed
("EDIVS", 0x1814, CPU6812
); AddFixed
("EMUL" , 0x0013, CPU6812
);
AddFixed
("EMULS", 0x1813, CPU6812
); AddFixed
("FDIV" , 0x1811, CPU6812
);
AddFixed
("IDIV" , 0x1810, CPU6812
); AddFixed
("IDIVS", 0x1815, CPU6812
);
AddFixed
("INCA" , 0x0042, CPU6812
); AddFixed
("INCB" , 0x0052, CPU6812
);
AddFixed
("INCX" , 0x1842, CPU6812X
); AddFixed
("INCY" , 0x1852, CPU6812X
);
AddFixed
("INS" , 0x1b81, CPU6812
); AddFixed
("INX" , 0x0008, CPU6812
);
AddFixed
("INY" , 0x0002, CPU6812
); AddFixed
("LSLA" , 0x0048, CPU6812
);
AddFixed
("LSLB" , 0x0058, CPU6812
); AddFixed
("LSLX" , 0x1848, CPU6812X
);
AddFixed
("LSLY" , 0x1858, CPU6812X
); AddFixed
("LSLD" , 0x0059, CPU6812
);
AddFixed
("LSRA" , 0x0044, CPU6812
); AddFixed
("LSRB" , 0x0054, CPU6812
);
AddFixed
("LSRX" , 0x1844, CPU6812X
); AddFixed
("LSRY" , 0x1854, CPU6812X
);
AddFixed
("LSRD" , 0x0049, CPU6812
); AddFixed
("MEM" , 0x0001, CPU6812
);
AddFixed
("MUL" , 0x0012, CPU6812
); AddFixed
("NEGA" , 0x0040, CPU6812
);
AddFixed
("NEGB" , 0x0050, CPU6812
); AddFixed
("NEGX" , 0x1840, CPU6812X
);
AddFixed
("NEGY" , 0x1850, CPU6812X
); AddFixed
("NOP" , 0x00a7, CPU6812
);
AddFixed
("PSHA" , 0x0036, CPU6812
); AddFixed
("PSHB" , 0x0037, CPU6812
);
AddFixed
("PSHC" , 0x0039, CPU6812
); AddFixed
("PSHCW", 0x1839, CPU6812X
);
AddFixed
("PSHD" , 0x003b, CPU6812
); AddFixed
("PSHX" , 0x0034, CPU6812
);
AddFixed
("PSHY" , 0x0035, CPU6812
); AddFixed
("PULA" , 0x0032, CPU6812
);
AddFixed
("PULB" , 0x0033, CPU6812
); AddFixed
("PULC" , 0x0038, CPU6812
);
AddFixed
("PULCW", 0x1838, CPU6812X
); AddFixed
("PULD" , 0x003a, CPU6812
);
AddFixed
("PULX" , 0x0030, CPU6812
); AddFixed
("PULY" , 0x0031, CPU6812
);
AddFixed
("REV" , 0x183a, CPU6812
); AddFixed
("REVW" , 0x183b, CPU6812
);
AddFixed
("ROLA" , 0x0045, CPU6812
); AddFixed
("ROLB" , 0x0055, CPU6812
);
AddFixed
("ROLX" , 0x1845, CPU6812X
); AddFixed
("ROLY" , 0x1855, CPU6812X
);
AddFixed
("RORA" , 0x0046, CPU6812
); AddFixed
("RORB" , 0x0056, CPU6812
);
AddFixed
("RORX" , 0x1846, CPU6812X
); AddFixed
("RORY" , 0x1856, CPU6812X
);
AddFixed
("RTC" , 0x000a, CPU6812
); AddFixed
("RTI" , 0x000b, CPU6812
);
AddFixed
("RTS" , 0x003d, CPU6812
); AddFixed
("SBA" , 0x1816, CPU6812
);
AddFixed
("SEC" , 0x1401, CPU6812
); AddFixed
("SEI" , 0x1410, CPU6812
);
AddFixed
("SEV" , 0x1402, CPU6812
); AddFixed
("STOP" , 0x183e, CPU6812
);
AddFixed
("SWI" , 0x003f, CPU6812
); AddFixed
("TAB" , 0x180e, CPU6812
);
AddFixed
("TAP" , 0xb702, CPU6812
); AddFixed
("TBA" , 0x180f, CPU6812
);
AddFixed
("TPA" , 0xb720, CPU6812
); AddFixed
("TSTA" , 0x0097, CPU6812
);
AddFixed
("TSTB" , 0x00d7, CPU6812
); AddFixed
("TSTX" , 0x1897, CPU6812X
);
AddFixed
("TSTY" , 0x18d7, CPU6812X
); AddFixed
("TSX" , 0xb775, CPU6812
);
AddFixed
("TSY" , 0xb776, CPU6812
); AddFixed
("TXS" , 0xb757, CPU6812
);
AddFixed
("TYS" , 0xb767, CPU6812
); AddFixed
("WAI" , 0x003e, CPU6812
);
AddFixed
("WAV" , 0x183c, CPU6812
); AddFixed
("XGDX" , 0xb7c5, CPU6812
);
AddFixed
("XGDY" , 0xb7c6, CPU6812
);
InstrZ
= 0;
AddBranch
("LBGT", 0x2e); AddBranch
("LBGE", 0x2c);
AddBranch
("LBEQ", 0x27); AddBranch
("LBLE", 0x2f);
AddBranch
("LBLT", 0x2d); AddBranch
("LBHI", 0x22);
AddBranch
("LBHS", 0x24); AddBranch
("LBCC", 0x24);
AddBranch
("LBNE", 0x26); AddBranch
("LBLS", 0x23);
AddBranch
("LBLO", 0x25); AddBranch
("LBCS", 0x25);
AddBranch
("LBMI", 0x2b); AddBranch
("LBVS", 0x29);
AddBranch
("LBRA", 0x20); AddBranch
("LBPL", 0x2a);
AddBranch
("LBRN", 0x21); AddBranch
("LBVC", 0x28);
AddBranch
("LBSR", 0x07);
InstrZ
= 0;
AddGen
("ADCA" , 0x0089, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ADCB" , 0x00c9, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ADDA" , 0x008b, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ADDB" , 0x00cb, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ADDD" , 0x00c3, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("ADDX" , 0x188b, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ADDY" , 0x18cb, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ADED" , 0x18c3, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ADEX" , 0x1889, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ADEY" , 0x18c9, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ANDA" , 0x0084, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ANDB" , 0x00c4, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ANDX" , 0x1884, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ANDY" , 0x18c4, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ASL" , 0x0048, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("ASLW" , 0x1848, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("ASR" , 0x0047, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("ASRW" , 0x1847, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("BITA" , 0x0085, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("BITB" , 0x00c5, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("BITX" , 0x1885, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("BITY" , 0x18c5, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("CLR" , 0x0049, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("CLRW" , 0x1849, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("CMPA" , 0x0081, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("CMPB" , 0x00c1, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("COM" , 0x0041, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("COMW" , 0x1841, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("CPED" , 0x188c, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("CPES" , 0x188f, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("CPEX" , 0x188e, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("CPEY" , 0x188d, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("CPD" , 0x008c, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("CPS" , 0x008f, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("CPX" , 0x008e, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("CPY" , 0x008d, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("DEC" , 0x0043, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("DECW" , 0x1843, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("EMAXD", 0x18fa, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("EMAXM", 0x18fe, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("EMIND", 0x18fb, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("EMINM", 0x18ff, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("EORA" , 0x0088, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("EORB" , 0x00c8, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("EORX" , 0x1888, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("EORY" , 0x18c8, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("GLDAA", 0x1886, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GLDAB", 0x18c6, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GLDD" , 0x18cc, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GLDS" , 0x18cf, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GLDX" , 0x18ce, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GLDY" , 0x18cd, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GSTAA", 0x184a, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GSTAB", 0x184b, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GSTD" , 0x184c, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GSTS" , 0x184f, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GSTX" , 0x184e, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("GSTY" , 0x184d, False
, True
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("INC" , 0x0042, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("INCW" , 0x1842, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("LDAA" , 0x0086, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("LDAB" , 0x00c6, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("LDD" , 0x00cc, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("LDS" , 0x00cf, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("LDX" , 0x00ce, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("LDY" , 0x00cd, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("LSL" , 0x0048, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("LSLW" , 0x1848, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("LSR" , 0x0044, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("LSRW" , 0x1844, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("MAXA" , 0x18f8, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("MAXM" , 0x18fc, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("MINA" , 0x18f9, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("MINM" , 0x18fd, False
, False
, False
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("NEG" , 0x0040, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("NEGW" , 0x1840, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("ORAA" , 0x008a, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ORAB" , 0x00ca, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("ORX" , 0x188a, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ORY" , 0x18ca, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("ROL" , 0x0045, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("ROLW" , 0x1845, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("ROR" , 0x0046, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("RORW" , 0x1846, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
AddGen
("SBCA" , 0x0082, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("SBCB" , 0x00c2, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("SBED" , 0x1883, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("SBEX" , 0x1882, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("SBEY" , 0x18c2, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("STAA" , 0x004a, False
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("STAB" , 0x004b, False
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("STD" , 0x004c, False
, True
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("STS" , 0x004f, False
, True
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("STX" , 0x004e, False
, True
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("STY" , 0x004d, False
, True
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("SUBA" , 0x0080, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("SUBB" , 0x00c0, True
, True
, True
, eSymbolSize8Bit
, CPU6812
);
AddGen
("SUBX" , 0x1880, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("SUBY" , 0x18c0, True
, True
, True
, eSymbolSize16Bit
, CPU6812X
);
AddGen
("SUBD" , 0x0083, True
, True
, True
, eSymbolSize16Bit
, CPU6812
);
AddGen
("TST" , 0x00c7, False
, False
, True
, eSymbolSizeUnknown
, CPU6812
);
AddGen
("TSTW" , 0x18c7, False
, False
, True
, eSymbolSizeUnknown
, CPU6812X
);
InstrZ
= 0;
AddLoop
("DBEQ", 0x00); AddLoop
("DBNE", 0x20);
AddLoop
("IBEQ", 0x80); AddLoop
("IBNE", 0xa0);
AddLoop
("TBEQ", 0x40); AddLoop
("TBNE", 0x60);
InstrZ
= 0;
AddLEA
("LEAS", 0x1b);
AddLEA
("LEAX", 0x1a);
AddLEA
("LEAY", 0x19);
InstrZ
= 0;
AddJmp
("JMP", 0x06, False
);
AddJmp
("JSR", 0x16, True
);
AddInstTable
(InstTable
, "TBL" , 0x3d, DecodeETBL
);
AddInstTable
(InstTable
, "ETBL" , 0x3f, DecodeETBL
);
AddInstTable
(InstTable
, "EMACS" , 0 , DecodeEMACS
);
AddInstTable
(InstTable
, "TFR" , 0x00, DecodeTransfer
);
AddInstTable
(InstTable
, "EXG" , 0x80, DecodeTransfer
);
AddInstTable
(InstTable
, "SEX" , 0 , DecodeSEX
);
AddInstTable
(InstTable
, "MOVB" , eSymbolSize8Bit
, DecodeMOV
);
AddInstTable
(InstTable
, "MOVW" , eSymbolSize16Bit
, DecodeMOV
);
AddInstTable
(InstTable
, "ANDCC" , 0x00, DecodeLogic
);
AddInstTable
(InstTable
, "ORCC" , 0x04, DecodeLogic
);
AddInstTable
(InstTable
, "BSET" , 0x0c, DecodeBit
);
AddInstTable
(InstTable
, "BCLR" , 0x0d, DecodeBit
);
AddInstTable
(InstTable
, "CALL" , 0 , DecodeCALL
);
AddInstTable
(InstTable
, "PCALL" , 0 , DecodePCALL
);
AddInstTable
(InstTable
, "BRSET" , 0x00, DecodeBrBit
);
AddInstTable
(InstTable
, "BRCLR" , 0x01, DecodeBrBit
);
AddInstTable
(InstTable
, "TRAP" , 0 , DecodeTRAP
);
AddInstTable
(InstTable
, "BTAS" , 0 , DecodeBTAS
);
RegTable
= CreateInstTable
(31);
InstrZ
= 0;
AddReg
("A" , eRegA
, 0, CPU6812
);
AddReg
("B" , eRegB
, 0, CPU6812
);
AddReg
("CCR" , eRegCCRL
, 0, CPU6812
);
AddReg
("CCRL", eRegCCRL
, 0, CPU6812
);
AddReg
("D" , eRegD
, 1, CPU6812
);
AddReg
("X" , eRegX
, 1, CPU6812
);
AddReg
("Y" , eRegY
, 1, CPU6812
);
AddReg
("SP" , eRegSP
, 1, CPU6812
);
AddReg
("PC" , eRegPC
, 1, CPU6812
);
AddReg
("XL" , eRegXL
, 0, CPU6812
);
AddReg
("XH" , eRegXH
, 0, CPU6812X
);
AddReg
("YL" , eRegYL
, 0, CPU6812
);
AddReg
("YH" , eRegYH
, 0, CPU6812X
);
AddReg
("SPL" , eRegSPL
, 0, CPU6812
);
AddReg
("SPH" , eRegSPH
, 0, CPU6812X
);
AddReg
("CCRH", eRegCCRH
, 0, CPU6812X
);
AddReg
("CCRW", eRegCCRW
, 1, CPU6812X
);
init_moto8_pseudo
(InstTable
, e_moto_8_be
| e_moto_8_db
| e_moto_8_dw
);
}
static void DeinitFields
(void)
{
DestroyInstTable
(InstTable
);
order_array_free
(FixedOrders
);
order_array_free
(BranchOrders
);
order_array_free
(GenOrders
);
order_array_free
(LoopOrders
);
order_array_free
(LEAOrders
);
order_array_free
(JmpOrders
);
DestroyInstTable
(RegTable
);
order_array_free
(Regs
);
}
/*--------------------------------------------------------------------------*/
/* Main Functions */
static Boolean DecodeAttrPart_6812
(void)
{
if (strlen(AttrPart.
str.
p_str) > 1)
{
WrStrErrorPos
(ErrNum_UndefAttr
, &AttrPart
);
return False
;
}
/* Operandengroesse festlegen */
return DecodeMoto16AttrSize
(*AttrPart.
str.
p_str, &AttrPartOpSize
[0], False
);
}
static void MakeCode_6812
(void)
{
CodeLen
= 0;
DontPrint
= False
;
OpSize
= AttrPartOpSize
[0];
/* zu ignorierendes */
if (Memo
(""))
return;
/* Pseudoanweisungen */
if (DecodeMoto16Pseudo
(OpSize
,True
)) return;
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
}
static void InitCode_6812
(void)
{
Reg_Direct
= 0;
Reg_GPage
= 0;
}
static Boolean IsDef_6812
(void)
{
return False
;
}
static Boolean ChkPC_6812X
(LargeWord Addr
)
{
Byte Page
= (Addr
>> 16) & 0xff;
if (ActPC
!= SegCode
)
return False
;
else if ((Addr
& 0xc000) == 0x8000)
return ((Page
== 0) || ((Page
>= 0x30) && (Page
<= 0x3f)));
else
return (Page
== 0);
}
static void SwitchTo_6812
(void)
{
TurnWords
= False
;
SetIntConstMode
(eIntConstModeMoto
);
PCSymbol
= "*";
HeaderID
= 0x66;
NOPCode
= 0xa7;
DivideChars
= ",";
HasAttrs
= True
;
AttrChars
= ".";
ValidSegs
= (1 << SegCode
);
Grans
[SegCode
] = 1; ListGrans
[SegCode
] = 1; SegInits
[SegCode
] = 0;
if (MomCPU
== CPU6812X
)
{
SegLimits
[SegCode
] = 0x3bfff;
ChkPC
= ChkPC_6812X
;
AddrInt
= UInt22
;
}
else
{
SegLimits
[SegCode
] = 0xffff;
AddrInt
= UInt16
;
}
DecodeAttrPart
= DecodeAttrPart_6812
;
MakeCode
= MakeCode_6812
;
IsDef
= IsDef_6812
;
SwitchFrom
= DeinitFields
;
InitFields
();
AddMoto16PseudoONOFF
(False
);
if (MomCPU
>= CPU6812X
)
{
#define ASSUME6812Count (sizeof(ASSUME6812s) / sizeof(*ASSUME6812s))
static const ASSUMERec ASSUME6812s
[] =
{
{ "DIRECT" , &Reg_Direct
, 0, 0xff, 0x100, NULL
},
{ "GPAGE" , &Reg_GPage
, 0, 0x7f, 0x80, NULL
}
};
pASSUMERecs
= ASSUME6812s
;
ASSUMERecCnt
= ASSUME6812Count
;
}
}
void code6812_init
(void)
{
CPU6812
= AddCPU
("68HC12", SwitchTo_6812
);
CPU6812X
= AddCPU
("68HC12X", SwitchTo_6812
);
AddInitPassProc
(InitCode_6812
);
}