/* code56k.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* AS-Codegeneratormodul fuer die DSP56K-Familie */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "strutil.h"
#include "chunks.h"
#include "errmsg.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmitree.h"
#include "codepseudo.h"
#include "chartrans.h"
#include "codevars.h"
#include "onoff_common.h"
#include "code56k.h"
typedef struct
{
LongWord Code;
CPUVar MinCPU;
} FixedOrder;
typedef enum
{
ParAB, ParABShl1, ParABShl2, ParXYAB, ParABXYnAB, ParABBA, ParXYnAB, ParMul, ParFixAB
} ParTyp;
typedef struct
{
ParTyp Typ;
Byte Code;
} ParOrder;
#define CondCount (sizeof(CondNames) / sizeof(*CondNames))
static const char CondNames[][3] =
{
"CC", "GE", "NE", "PL", "NN", "EC", "LC", "GT", "CS", "LT", "EQ", "MI",
"NR", "ES", "LS", "LE", "HS", "LO"
};
static const Byte MacTable[4][4] =
{
{ 0, 2, 5, 4 },
{ 2, 0xff, 6, 7 },
{ 5, 6, 1, 3 },
{ 4, 7, 3, 0xff }
};
static const Byte Mac4Table[4][4] =
{
{ 0, 13, 10, 4 },
{ 5, 1, 14, 11 },
{ 2, 6, 8, 15 },
{ 12, 3, 7, 9 }
};
static const Byte Mac2Table[4] =
{
1, 3, 2, 0
};
enum
{
ModNone = -1,
ModImm = 0,
ModAbs = 1,
ModIReg = 2,
ModPreDec = 3,
ModPostDec = 4,
ModPostInc = 5,
ModIndex = 6,
ModModDec = 7,
ModModInc = 8,
ModDisp = 9
};
#define MModImm (1 << ModImm)
#define MModAbs (1 << ModAbs)
#define MModIReg (1 << ModIReg)
#define MModPreDec (1 << ModPreDec)
#define MModPostDec (1 << ModPostDec)
#define MModPostInc (1 << ModPostInc)
#define MModIndex (1 << ModIndex)
#define MModModDec (1 << ModModDec)
#define MModModInc (1 << ModModInc)
#define MModDisp (1 << ModDisp)
#define MModNoExt (MModIReg | MModPreDec | MModPostDec | MModPostInc | MModIndex | MModModDec | MModModInc)
#define MModNoImm (MModAbs | MModNoExt)
#define MModAll (MModNoImm | MModImm)
#define SegLData SegBData /* SegYData + 1 */
#define MSegCode (1 << SegCode)
#define MSegXData (1 << SegXData)
#define MSegYData (1 << SegYData)
#define MSegLData (1 << SegLData)
typedef struct
{
ShortInt Type;
LongInt Mode, Val;
Byte Seg, ShortMode;
Boolean ForceImmLong;
tSymbolFlags AbsSymFlags;
int Cnt;
} tAdrResult;
static CPUVar CPU56000, CPU56002, CPU56300;
static IntType AdrInt;
static LargeInt MemLimit;
static tStrComp LeftComp, MidComp, RightComp, Left1Comp, Left2Comp, Right1Comp, Right2Comp;
static FixedOrder *FixedOrders;
static ParOrder *ParOrders;
/*----------------------------------------------------------------------------------------------*/
static void SplitArg(const tStrComp *pOrig, tStrComp *pLDest, tStrComp *pRDest)
{
char *p;
p = QuotPos(pOrig->str.p_str, ',');
if (!p)
{
StrCompReset(pRDest);
StrCompCopy(pLDest, pOrig);
}
else
StrCompSplitCopy(pLDest, pRDest, pOrig, p);
}
static unsigned CutSize(const tStrComp *pArg, Byte *ShortMode)
{
switch (*pArg->str.p_str)
{
case '>':
*ShortMode = 2;
return 1;
case '<':
*ShortMode = 1;
return 1;
default:
*ShortMode = 0;
return 0;
}
}
static Boolean DecodeReg(char *Asc, LongInt *Erg)
{
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
static const char RegNames[][3] =
{
"X0", "X1", "Y0", "Y1", "A0", "B0", "A2", "B2", "A1", "B1", "A", "B"
};
Word z;
for (z = 0; z < RegCount; z++)
if (!as_strcasecmp(Asc, RegNames[z]))
{
*Erg = z + 4;
return True;
}
if ((strlen(Asc
) == 2) && (Asc
[1] >= '0') && (Asc
[1] <= '7'))
switch (as_toupper(*Asc))
{
case 'R':
*Erg = 16 + Asc[1] - '0';
return True;
case 'N':
*Erg = 24 + Asc[1] - '0';
return True;
}
return False;
#undef RegCount
}
static Boolean DecodeALUReg(char *Asc, LongInt *Erg,
Boolean MayX, Boolean MayY, Boolean MayAcc)
{
Boolean Result = False;
if (!DecodeReg(Asc, Erg))
return Result;
switch (*Erg)
{
case 4:
case 5:
if (MayX)
{
Result = True;
(*Erg) -= 4;
}
break;
case 6:
case 7:
if (MayY)
{
Result = True;
(*Erg) -= 6;
}
break;
case 14:
case 15:
if (MayAcc)
{
Result = True;
(*Erg) -= (MayX || MayY) ? 12 : 14;
}
break;
}
return Result;
}
static Boolean DecodeLReg(char *Asc, LongInt *Erg)
{
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
static const char RegNames[][4] =
{
"A10", "B10", "X", "Y", "A", "B", "AB", "BA"
};
Word z;
for (z = 0; z < RegCount; z++)
if (!as_strcasecmp(Asc, RegNames[z]))
{
*Erg = z;
return True;
}
return False;
#undef RegCount
}
static Boolean DecodeXYABReg(char *Asc, LongInt *Erg)
{
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
static const char RegNames[][3] =
{
"B", "A", "X", "Y", "X0", "Y0", "X1", "Y1"
};
Word z;
for (z = 0; z < RegCount; z++)
if (!as_strcasecmp(Asc, RegNames[z]))
{
*Erg = z;
return True;
}
return False;
#undef RegCount
}
static Boolean DecodeXYAB0Reg(char *Asc, LongInt *Erg)
{
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
static const char RegNames[][3] =
{
"A0", "B0", "X0", "Y0", "X1", "Y1"
};
Word z;
for (z = 0; z < RegCount; z++)
if (!as_strcasecmp(Asc, RegNames[z]))
{
*Erg = z + 2;
return True;
}
return False;
#undef RegCount
}
static Boolean DecodeXYAB1Reg(char *Asc, LongInt *Erg)
{
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
static const char RegNames[][3] =
{
"A1", "B1", "X0", "Y0", "X1", "Y1"
};
Word z;
for (z = 0; z < RegCount; z++)
if (!as_strcasecmp(Asc, RegNames[z]))
{
*Erg = z + 2;
return True;
}
return False;
#undef RegCount
}
static Boolean DecodePCReg(char *Asc, LongInt *Erg)
{
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
/** vvvv ab 56300 ? */
static const char RegNames[][4] =
{
"SZ", "SR", "OMR", "SP", "SSH", "SSL", "LA", "LC"
};
Word z;
for (z = 0; z < RegCount; z++)
if (!as_strcasecmp(Asc, RegNames[z]))
{
(*Erg) = z;
return True;
}
return False;
#undef RegCount
}
static Boolean DecodeAddReg(char *Asc, LongInt *Erg)
{
if ((strlen(Asc
) == 2) && (as_toupper
(*Asc
) == 'M') && (Asc
[1] >= '0') && (Asc
[1] <= '7'))
{
*Erg = Asc[1] - '0';
return True;
}
/* >=56300 ? */
if (!as_strcasecmp(Asc, "EP"))
{
*Erg = 0x0a;
return True;
}
if (!as_strcasecmp(Asc, "VBA"))
{
*Erg = 0x10;
return True;
}
if (!as_strcasecmp(Asc, "SC"))
{
*Erg = 0x11;
return True;
}
return False;
}
static Boolean DecodeGeneralReg(char *Asc, LongInt *Erg)
{
if (DecodeReg(Asc, Erg))
return True;
if (DecodePCReg(Asc, Erg))
{
(*Erg) += 0x38;
return True;
}
if (DecodeAddReg(Asc, Erg))
{
(*Erg) += 0x20;
return True;
}
return False;
}
static Boolean DecodeCtrlReg(char *Asc, LongInt *Erg)
{
if (DecodeAddReg(Asc, Erg))
return True;
if (DecodePCReg(Asc, Erg))
{
(*Erg) += 0x18;
return True;
}
return False;
}
static Boolean DecodeControlReg(char *Asc, LongInt *Erg)
{
Boolean Result = True;
if (!as_strcasecmp(Asc, "MR"))
*Erg = 0;
else if (!as_strcasecmp(Asc, "CCR"))
*Erg = 1;
else if ((!as_strcasecmp(Asc, "OMR")) || (!as_strcasecmp(Asc, "COM")))
*Erg = 2;
else if ((!as_strcasecmp(Asc, "EOM")) && (MomCPU >= CPU56000))
*Erg = 3;
else
Result = False;
return Result;
}
static void DecodeAdr(const tStrComp *pArg, Word Erl, Byte ErlSeg, tAdrResult *pResult)
{
static const char ModMasks[ModModInc + 1][8] =
{
"","", "(Rx)", "-(Rx)", "(Rx)-", "(Rx)+", "(Rx+Nx)", "(Rx)-Nx", "(Rx)+Nx"
};
static const Byte ModCodes[ModModInc + 1] =
{
0, 0, 4, 7, 2, 3, 5, 0, 1
};
#define Seg56KCount (sizeof(Seg56KNames) / sizeof(*Seg56KNames))
static const char Seg56KNames[] =
{
'P', 'X', 'Y', 'L'
};
static Byte Seg56KVals[] =
{
SegCode, SegXData, SegYData, SegLData
};
int z, l, ArgLen;
unsigned SegIndex, Offset;
Boolean OK;
tEvalResult EvalResult;
Byte OrdVal;
char *pp, *np, save;
tStrComp Arg;
pResult->Type = ModNone;
pResult->Cnt = 0;
pResult->ShortMode = 0;
/* Adressierungsmodi vom 56300 abschneiden */
if (MomCPU < CPU56300)
Erl |= (~MModDisp);
/* Defaultsegment herausfinden */
if (ErlSeg & MSegXData)
pResult->Seg = SegXData;
else if (ErlSeg & MSegYData)
pResult->Seg = SegYData;
else if (ErlSeg & MSegCode)
pResult->Seg = SegCode;
else
pResult->Seg = SegNone;
/* Zielsegment vorgegeben ? */
Offset = 0;
for (SegIndex = 0; SegIndex < Seg56KCount; SegIndex++)
if ((as_toupper(*pArg->str.p_str) == Seg56KNames[SegIndex]) && (pArg->str.p_str[1] == ':'))
{
pResult->Seg = Seg56KVals[SegIndex];
Offset = 2;
}
StrCompRefRight(&Arg, pArg, Offset);
/* Adressausdruecke abklopfen: dazu mit Referenzstring vergleichen */
ArgLen
= strlen(Arg.
str.
p_str);
for (z = ModIReg; z <= ModModInc; z++)
if (ArgLen
== (int)strlen(ModMasks
[z
]))
{
pResult->Mode = 0xffff;
for (l = 0; l <= ArgLen; l++)
if (ModMasks[z][l] == 'x')
{
OrdVal = Arg.str.p_str[l] - '0';
if (OrdVal > 7)
break;
else if (pResult->Mode == 0xffff)
pResult->Mode = OrdVal;
else if (pResult->Mode != OrdVal)
{
WrError(ErrNum_InvRegPair);
goto chk;
}
}
else if (ModMasks[z][l] != as_toupper(Arg.str.p_str[l]))
break;
if (l > ArgLen)
{
pResult->Type = z;
pResult->Mode += ModCodes[z] << 3;
goto chk;
}
}
/* immediate ? */
if (*Arg.str.p_str == '#')
{
if (Arg.str.p_str[1] == '>')
{
pResult->ForceImmLong = TRUE;
pResult->Val = EvalStrIntExpressionOffs(&Arg, 2, Int24, &OK);
}
else
{
pResult->ForceImmLong = FALSE;
pResult->Val = EvalStrIntExpressionOffs(&Arg, 1, Int24, &OK);
}
if (OK)
{
pResult->Type = ModImm; pResult->Cnt = 1; pResult->Mode = 0x34;
goto chk;
}
}
/* Register mit Displacement bei 56300 */
if (IsIndirect(Arg.str.p_str))
{
tStrComp IArg;
Arg.str.p_str[--ArgLen] = '\0'; Arg.Pos.Len--;
StrCompRefRight(&IArg, &Arg, 1);
pp
= strchr(IArg.
str.
p_str, '+');
np
= strchr(IArg.
str.
p_str, '-');
if ((!pp) || ((np) && (np < pp)))
pp = np;
if (pp)
{
save = *pp;
*pp = '\0';
if ((DecodeGeneralReg(IArg.str.p_str, &pResult->Mode)) && (pResult->Mode >= 16) && (pResult->Mode <= 23))
{
*pp = save;
pResult->Mode -= 16;
pResult->Val = EvalStrIntExpressionOffsWithResult(&IArg, pp - IArg.str.p_str, Int24, &EvalResult);
if (EvalResult.OK)
{
if (mFirstPassUnknown(EvalResult.Flags))
pResult->Val &= 63;
pResult->Type = ModDisp;
}
goto chk;
}
*pp = save;
}
}
/* dann absolut */
Offset = CutSize(&Arg, &pResult->ShortMode);
pResult->Val = EvalStrIntExpressionOffsWithResult(&Arg, Offset, AdrInt, &EvalResult);
if (EvalResult.OK)
{
pResult->Type = ModAbs;
pResult->AbsSymFlags = EvalResult.Flags;
pResult->Mode = 0x30; pResult->Cnt = 1;
if ((pResult->Seg & ((1 << SegCode) | (1 << SegXData) | (1 << SegYData))) != 0)
ChkSpace(pResult->Seg, EvalResult.AddrSpaceMask);
goto chk;
}
chk:
if ((pResult->Type != ModNone) && (!(Erl & (1 << pResult->Type))))
{
WrError(ErrNum_InvAddrMode);
pResult->Cnt = 0;
pResult->Type = ModNone;
}
if ((pResult->Seg != SegNone) && (!(ErlSeg & (1 << pResult->Seg))))
{
WrError(ErrNum_InvSegment);
pResult->Cnt = 0;
pResult->Type = ModNone;
}
}
static Boolean DecodeOpPair(const tStrComp *pLeft, const tStrComp *pRight, Byte WorkSeg,
LongInt *Dir, LongInt *Reg1, LongInt *Reg2, tAdrResult *pResult)
{
Boolean Result = False;
if (DecodeALUReg(pLeft->str.p_str, Reg1, WorkSeg == SegXData, WorkSeg == SegYData, True))
{
if (DecodeALUReg(pRight->str.p_str, Reg2, WorkSeg == SegXData, WorkSeg == SegYData, True))
{
*Dir = 2;
pResult->Type = ModNone;
pResult->Mode = 0;
pResult->Cnt = 0;
pResult->Val = 0;
Result = True;
}
else
{
*Dir = 0;
*Reg2 = -1;
DecodeAdr(pRight, MModNoImm, 1 << WorkSeg, pResult);
if (pResult->Type != ModNone)
Result = True;
}
}
else if (DecodeALUReg(pRight->str.p_str, Reg1, WorkSeg == SegXData, WorkSeg == SegYData, True))
{
*Dir = 1;
*Reg2 = -1;
DecodeAdr(pLeft, MModAll, 1 << WorkSeg, pResult);
if (pResult->Type != ModNone)
Result = True;
}
return Result;
}
static LongInt TurnXY(LongInt Inp)
{
switch (Inp)
{
case 4:
case 7:
return Inp - 4;
case 5:
case 6:
return 7 - Inp;
default: /* wird nie erreicht */
return 0;
}
}
static Boolean DecodeTFR(const tStrComp *pArg, LongInt *Erg)
{
LongInt Part1, Part2;
SplitArg(pArg, &LeftComp, &RightComp);
if (!DecodeALUReg(RightComp.str.p_str, &Part2, False, False, True)) return False;
if (!DecodeReg(LeftComp.str.p_str, &Part1)) return False;
if ((Part1 < 4) || ((Part1 > 7) && (Part1 < 14)) || (Part1 > 15)) return False;
if (Part1 > 13)
{
if (((Part1 ^ Part2) & 1) == 0) return False;
else
Part1 = 0;
}
else
Part1 = TurnXY(Part1) + 4;
*Erg = (Part1 << 1) + Part2;
return True;
}
static Boolean DecodeRR(const tStrComp *pArg, LongInt *Erg)
{
LongInt Part1, Part2;
SplitArg(pArg, &LeftComp, &RightComp);
if (!DecodeGeneralReg(RightComp.str.p_str, &Part2)) return False;
if ((Part2 < 16) || (Part2 > 23)) return False;
if (!DecodeGeneralReg(LeftComp.str.p_str, &Part1)) return False;
if ((Part1 < 16) || (Part1 > 23)) return False;
*Erg = (Part2 & 7) + ((Part1 & 7) << 8);
return True;
}
static Boolean DecodeCondition(char *Asc, Word *Erg)
{
Boolean Result;
(*Erg) = 0;
while ((*Erg < CondCount) && (as_strcasecmp(CondNames[*Erg], Asc)))
(*Erg)++;
if (*Erg == CondCount - 1)
*Erg = 8;
Result = (*Erg < CondCount);
*Erg &= 15;
return Result;
}
static Boolean DecodeMOVE_0(void)
{
DAsmCode[0] = 0x200000;
CodeLen = 1;
return True;
}
static Boolean DecodeMOVE_1(int Start)
{
LongInt RegErg, RegErg2, IsY, MixErg, l;
char c;
Word Condition;
Boolean Result = False;
Byte SegMask;
if (!as_strncasecmp(ArgStr[Start].str.p_str, "IF", 2))
{
l
= strlen(ArgStr
[Start
].
str.
p_str);
if (!as_strcasecmp(ArgStr[Start].str.p_str + l - 2, ".U"))
{
RegErg = 0x1000;
l -= 2;
}
else
RegErg = 0;
c = ArgStr[Start].str.p_str[l];
ArgStr[Start].str.p_str[l] = '\0';
if (DecodeCondition(ArgStr[Start].str.p_str + 2, &Condition))
{
if (ChkMinCPUExt(CPU56300, ErrNum_AddrModeNotSupported))
{
DAsmCode[0] = 0x202000 + (Condition << 8) + RegErg;
CodeLen = 1;
return True;
}
}
ArgStr[Start].str.p_str[l] = c;
}
SplitArg(&ArgStr[Start], &LeftComp, &RightComp);
/* 1. Register-Update */
if (*RightComp.str.p_str == '\0')
{
tAdrResult AdrResult;
DecodeAdr(&LeftComp, MModPostDec | MModPostInc | MModModDec | MModModInc, 0, &AdrResult);
if (AdrResult.Type != ModNone)
{
Result = True;
DAsmCode[0] = 0x204000 + (AdrResult.Mode << 8);
CodeLen = 1;
}
return Result;
}
/* 2. Ziel ist Register */
if (DecodeReg(RightComp.str.p_str, &RegErg))
{
tAdrResult AdrResult;
AdrResult.Seg = SegNone;
if (DecodeReg(LeftComp.str.p_str, &RegErg2))
{
Result = True;
DAsmCode[0] = 0x200000 + (RegErg << 8) + (RegErg2 << 13);
CodeLen = 1;
}
else
{
/* A und B gehen auch als L:..., in L-Zweig zwingen! */
SegMask = MSegXData + MSegYData;
if ((RegErg == 14) || (RegErg == 15))
SegMask |= MSegLData;
DecodeAdr(&LeftComp, MModAll | MModDisp, SegMask, &AdrResult);
if (AdrResult.Seg != SegLData)
{
IsY = Ord(AdrResult.Seg == SegYData);
MixErg = ((RegErg & 0x18) << 17) + (IsY << 19) + ((RegErg & 7) << 16);
if (AdrResult.Type == ModDisp)
{
if ((AdrResult.Val < 63) && (AdrResult.Val > -64) && (RegErg <= 15))
{
DAsmCode[0] = 0x020090 + ((AdrResult.Val & 1) << 6) + ((AdrResult.Val & 0x7e) << 10)
+ (AdrResult.Mode << 8) + (IsY << 5) + RegErg;
CodeLen = 1;
}
else
{
DAsmCode[0] = 0x0a70c0 + (AdrResult.Mode << 8) + (IsY << 16) + RegErg;
DAsmCode[1] = AdrResult.Val;
CodeLen = 2;
}
}
else if (!AdrResult.ForceImmLong && (AdrResult.Type == ModImm) && RangeCheck(AdrResult.Val, UInt8))
{
Result = True;
DAsmCode[0] = 0x200000 + (RegErg << 16) + ((AdrResult.Val & 0xff) << 8);
CodeLen = 1;
}
else if ((AdrResult.Type == ModAbs) && (AdrResult.Val <= 63) && (AdrResult.Val >= 0) && (AdrResult.ShortMode != 2))
{
Result = True;
DAsmCode[0] = 0x408000 + MixErg + (AdrResult.Val << 8);
CodeLen = 1;
}
else if (AdrResult.Type != ModNone)
{
Result = True;
DAsmCode[0] = 0x40c000 + MixErg + (AdrResult.Mode << 8);
DAsmCode[1] = AdrResult.Val;
CodeLen = 1 + AdrResult.Cnt;
}
}
}
if (AdrResult.Seg != SegLData)
return Result;
}
/* 3. Quelle ist Register */
if (DecodeReg(LeftComp.str.p_str, &RegErg))
{
tAdrResult RightAdrResult;
/* A und B gehen auch als L:..., in L-Zweig zwingen! */
SegMask = MSegXData + MSegYData;
if ((RegErg == 14) || (RegErg == 15))
SegMask |= MSegLData;
DecodeAdr(&RightComp, MModNoImm | MModDisp, SegMask, &RightAdrResult);
if (RightAdrResult.Seg != SegLData)
{
IsY = Ord(RightAdrResult.Seg == SegYData);
MixErg = ((RegErg & 0x18) << 17) + (IsY << 19) + ((RegErg & 7) << 16);
if (RightAdrResult.Type == ModDisp)
{
if ((RightAdrResult.Val < 63) && (RightAdrResult.Val > -64) && (RegErg <= 15))
{
DAsmCode[0] = 0x020080 + ((RightAdrResult.Val & 1) << 6) + ((RightAdrResult.Val & 0x7e) << 10)
+ (RightAdrResult.Mode << 8) + (IsY << 5) + RegErg;
CodeLen = 1;
}
else
{
DAsmCode[0] = 0x0a7080 + (RightAdrResult.Mode << 8) + (IsY << 16) + RegErg;
DAsmCode[1] = RightAdrResult.Val;
CodeLen = 2;
}
}
else if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
{
Result = True;
DAsmCode[0] = 0x400000 + MixErg + (RightAdrResult.Val << 8);
CodeLen = 1;
}
else if (RightAdrResult.Type != ModNone)
{
Result = True;
DAsmCode[0] = 0x404000 + MixErg + (RightAdrResult.Mode << 8);
DAsmCode[1] = RightAdrResult.Val;
CodeLen = 1 + RightAdrResult.Cnt;
}
return Result;
}
}
/* 4. Ziel ist langes Register */
if (DecodeLReg(RightComp.str.p_str, &RegErg))
{
tAdrResult LeftAdrResult;
DecodeAdr(&LeftComp, MModNoImm, MSegLData, &LeftAdrResult);
MixErg = ((RegErg & 4) << 17) + ((RegErg & 3) << 16);
if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.Val >= 0) && (LeftAdrResult.ShortMode != 2))
{
Result = True;
DAsmCode[0] = 0x408000 + MixErg + (LeftAdrResult.Val << 8);
CodeLen = 1;
}
else
{
Result = True;
DAsmCode[0] = 0x40c000 + MixErg + (LeftAdrResult.Mode << 8);
DAsmCode[1] = LeftAdrResult.Val;
CodeLen = 1 + LeftAdrResult.Cnt;
}
return Result;
}
/* 5. Quelle ist langes Register */
if (DecodeLReg(LeftComp.str.p_str, &RegErg))
{
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModNoImm, MSegLData, &RightAdrResult);
MixErg = ((RegErg & 4) << 17) + ((RegErg & 3) << 16);
if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
{
Result = True;
DAsmCode[0] = 0x400000 + MixErg + (RightAdrResult.Val << 8);
CodeLen = 1;
}
else
{
Result = True;
DAsmCode[0] = 0x404000 + MixErg + (RightAdrResult.Mode << 8);
DAsmCode[1] = RightAdrResult.Val;
CodeLen = 1 + RightAdrResult.Cnt;
}
return Result;
}
WrError(ErrNum_InvAddrMode);
return Result;
}
static Boolean DecodeMOVE_2(int Start)
{
LongInt RegErg, Reg1L, Reg1R, Reg2L, Reg2R, Dir1, Dir2;
tAdrResult AdrResult1, AdrResult2;
Boolean Result = False;
SplitArg(&ArgStr[Start], &Left1Comp, &Right1Comp);
SplitArg(&ArgStr[Start + 1], &Left2Comp, &Right2Comp);
/* 1. Spezialfall X auf rechter Seite ? */
if (!as_strcasecmp(Left2Comp.str.p_str, "X0"))
{
if (!DecodeALUReg(Right2Comp.str.p_str, &RegErg, False, False, True)) WrError(ErrNum_InvAddrMode);
else if (strcmp(Left1Comp.
str.
p_str, Right2Comp.
str.
p_str)) WrError
(ErrNum_InvAddrMode
);
else
{
DecodeAdr(&Right1Comp, MModNoImm, MSegXData, &AdrResult1);
if (AdrResult1.Type != ModNone)
{
CodeLen = 1 + AdrResult1.Cnt;
DAsmCode[0] = 0x080000 + (RegErg << 16) + (AdrResult1.Mode << 8);
DAsmCode[1] = AdrResult1.Val;
Result = True;
}
}
return Result;
}
/* 2. Spezialfall Y auf linker Seite ? */
if (!as_strcasecmp(Left1Comp.str.p_str, "Y0"))
{
if (!DecodeALUReg(Right1Comp.str.p_str, &RegErg, False, False, True)) WrError(ErrNum_InvAddrMode);
else if (strcmp(Left2Comp.
str.
p_str, Right1Comp.
str.
p_str)) WrError
(ErrNum_InvAddrMode
);
else
{
DecodeAdr(&Right2Comp, MModNoImm, MSegYData, &AdrResult2);
if (AdrResult2.Type != ModNone)
{
CodeLen = 1 + AdrResult2.Cnt;
DAsmCode[0] = 0x088000 + (RegErg << 16) + (AdrResult2.Mode << 8);
DAsmCode[1] = AdrResult2.Val;
Result = True;
}
}
return Result;
}
/* der Rest..... */
if ((DecodeOpPair(&Left1Comp, &Right1Comp, SegXData, &Dir1, &Reg1L, &Reg1R, &AdrResult1))
&& (DecodeOpPair(&Left2Comp, &Right2Comp, SegYData, &Dir2, &Reg2L, &Reg2R, &AdrResult2)))
{
if ((Reg1R == -1) && (Reg2R == -1))
{
if ((AdrResult1.Mode >> 3 < 1) || (AdrResult1.Mode >> 3 > 4) || (AdrResult2.Mode >> 3 < 1) || (AdrResult2.Mode >> 3 > 4)) WrError(ErrNum_InvAddrMode);
else if (((AdrResult1.Mode ^ AdrResult2.Mode) & 4) == 0) WrError(ErrNum_InvRegPair);
else
{
DAsmCode[0] = 0x800000 + (Dir2 << 22) + (Dir1 << 15)
+ (Reg1L << 18) + (Reg2L << 16) + ((AdrResult1.Mode & 0x1f) << 8)
+ ((AdrResult2.Mode & 3) << 13) + ((AdrResult2.Mode & 24) << 17);
CodeLen = 1;
Result = True;
}
}
else if (Reg1R == -1)
{
if ((Reg2L < 2) || (Reg2R > 1)) WrError(ErrNum_InvAddrMode);
else
{
DAsmCode[0] = 0x100000 + (Reg1L << 18) + ((Reg2L - 2) << 17) + (Reg2R << 16)
+ (Dir1 << 15) + (AdrResult1.Mode << 8);
DAsmCode[1] = AdrResult1.Val;
CodeLen = 1 + AdrResult1.Cnt;
Result = True;
}
}
else if (Reg2R == -1)
{
if ((Reg1L < 2) || (Reg1R > 1)) WrError(ErrNum_InvAddrMode);
else
{
DAsmCode[0] = 0x104000 + (Reg2L << 16) + ((Reg1L - 2) << 19) + (Reg1R << 18)
+ (Dir2 << 15) + (AdrResult2.Mode << 8);
DAsmCode[1] = AdrResult2.Val;
CodeLen = 1 + AdrResult2.Cnt;
Result = True;
}
}
else
WrError(ErrNum_InvAddrMode);
return Result;
}
WrError(ErrNum_InvAddrMode);
return Result;
}
static Boolean DecodeMOVE(int Start)
{
switch (ArgCnt - Start + 1)
{
case 0:
return DecodeMOVE_0();
case 1:
return DecodeMOVE_1(Start);
case 2:
return DecodeMOVE_2(Start);
default:
(void)ChkArgCnt(0, 2);
return False;
}
}
static tErrorNum ErrCode;
static const tStrComp *pErrComp;
static void SetError(tErrorNum Code)
{
ErrCode = Code; pErrComp = NULL;
}
static void SetXError(tErrorNum Code, const tStrComp *pNewErrComp)
{
ErrCode = Code; pErrComp = pNewErrComp;
}
static void PrError(void)
{
if (pErrComp) WrStrErrorPos(ErrCode, pErrComp);
else if (ErrCode != 0) WrError(ErrCode);
}
/*----------------------------------------------------------------------------------------------*/
static void DecodeSFR(Word space)
{
CodeEquate((as_addrspace_t)space, 0, MemLimit);
}
static void DecodeDS(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
Boolean OK;
tSymbolFlags Flags;
Word AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrInt, &OK, &Flags);
if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
if (OK && !mFirstPassUnknown(Flags))
{
if (!AdrWord) WrError(ErrNum_NullResMem);
CodeLen = AdrWord; DontPrint = True;
BookKeeping();
}
}
}
static void DecodeDC(Word Code)
{
TempResult t;
UNUSED(Code);
as_tempres_ini(&t);
if (ChkArgCnt(1, ArgCntMax))
{
Boolean OK = True;
tStrComp *pArg;
forallargs(pArg, OK)
{
EvalStrExpression(pArg, &t);
switch (t.Typ)
{
case TempString:
if (MultiCharToInt(&t, 3))
goto ToInt;
if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
OK = False;
else
OK = !string_2_dasm_code(&t.Contents.str, Packing ? 3 : 1, True);
break;
ToInt:
case TempInt:
if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xffffff;
if (!(OK = RangeCheck(t.Contents.Int, Int24))) WrStrErrorPos(ErrNum_OverRange, pArg);
else
DAsmCode[CodeLen++] = t.Contents.Int & 0xffffff;
break;
case TempFloat:
WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
/* fall-through */
default:
OK = False;
}
}
if (!OK) CodeLen = 0;
}
as_tempres_free(&t);
}
/* ohne Argument */
static void DecodeFixed(Word Index)
{
const FixedOrder *pOrder = FixedOrders + Index;
if (!ChkArgCnt(0, 0));
else if (ChkMinCPU(pOrder->MinCPU))
{
CodeLen = 1;
DAsmCode[0] = pOrder->Code;
}
}
/* ALU */
static void DecodePar(Word Index)
{
const ParOrder *pOrder = ParOrders + Index;
Boolean OK, DontAdd;
tSymbolFlags Flags;
tStrComp LeftRegComp;
LargeInt LAddVal;
LongInt AddVal, h = 0, Reg1, Reg2, Reg3;
if (DecodeMOVE(2))
{
SetError((tErrorNum)0);
DontAdd = False;
switch (pOrder->Typ)
{
case ParAB:
if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
else
h = Reg1 << 3;
break;
case ParFixAB:
if (as_strcasecmp(ArgStr[1].str.p_str, "A,B")) SetError(ErrNum_InvRegPair);
else
h = 0;
break;
case ParABShl1:
if (!strchr(ArgStr
[1].
str.
p_str, ','))
{
if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
else
h = Reg1 << 3;
}
else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
else
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (!strchr(RightComp.
str.
p_str, ','))
StrCompCopy(&MidComp, &RightComp);
else
SplitArg(&RightComp, &MidComp, &RightComp);
if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
else if (!DecodeALUReg(MidComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &MidComp);
else if (*LeftComp.str.p_str == '#')
{
AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, UInt6, &OK);
if (OK)
{
DAsmCode[0] = 0x0c1c00 + ((pOrder->Code & 0x10) << 4) + (Reg2 << 7)
+ (AddVal << 1) + Reg1;
CodeLen = 1;
DontAdd = True;
}
}
else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) SetXError(ErrNum_InvReg, &LeftComp);
else
{
DAsmCode[0] = 0x0c1e60 - ((pOrder->Code & 0x10) << 2) + (Reg2 << 4)
+ (Reg3 << 1) + Reg1;
CodeLen = 1;
DontAdd = True;
}
}
break;
case ParABShl2:
if (!strchr(ArgStr
[1].
str.
p_str, ','))
{
if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
else
h = Reg1 << 3;
}
else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
else
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
else if (*LeftComp.str.p_str == '#')
{
AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, UInt5, &OK);
if (OK)
{
DAsmCode[0] = 0x0c1e80 + ((0x33 - pOrder->Code) << 2)
+ (AddVal << 1) + Reg1;
CodeLen = 1;
DontAdd = True;
}
}
else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) SetXError(ErrNum_InvReg, &LeftComp);
else
{
DAsmCode[0] = 0x0c1e10 + ((0x33 - pOrder->Code) << 1)
+ (Reg3 << 1) + Reg1;
CodeLen = 1;
DontAdd = True;
}
}
break;
case ParXYAB:
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
else if (!DecodeLReg(LeftComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
else if ((Reg1 < 2) || (Reg1 > 3)) SetXError(ErrNum_InvReg, &LeftComp);
else
h = (Reg2 << 3) + ((Reg1 - 2) << 4);
break;
case ParABXYnAB:
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
else if (*LeftComp.str.p_str == '#')
{
if (Memo("CMPM")) SetError(ErrNum_InvAddrMode);
else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
else
{
AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
if (!OK) SetError((tErrorNum)-1);
else if ((AddVal >= 0) && (AddVal <= 63))
{
DAsmCode[0] = 0x014000 + (AddVal << 8);
h = 0x80 + (Reg2 << 3);
}
else
{
DAsmCode[0] = 0x014000; h = 0xc0 + (Reg2 << 3);
DAsmCode[1] = AddVal & 0xffffff; CodeLen = 2;
}
}
}
else
{
if (!DecodeXYABReg(LeftComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
else if ((Reg1 ^ Reg2) == 1) SetError(ErrNum_InvRegPair);
else if ((Memo("CMPM")) && ((Reg1 &6) == 2)) SetXError(ErrNum_InvReg, &LeftComp);
else
{
if (Reg1 < 2)
Reg1 = Ord(!Memo("CMPM"));
h = (Reg2 << 3) + (Reg1 << 4);
}
}
break;
case ParABBA:
if (!as_strcasecmp(ArgStr[1].str.p_str, "B,A"))
h = 0;
else if (!as_strcasecmp(ArgStr[1].str.p_str, "A,B"))
h = 8;
else
SetXError(ErrNum_InvRegPair, &ArgStr[1]);
break;
case ParXYnAB:
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
else if (*LeftComp.str.p_str == '#')
{
if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
else
{
AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
if (!OK) SetError((tErrorNum)-1);
else if ((AddVal >= 0) && (AddVal <= 63))
{
DAsmCode[0] = 0x014080 + (AddVal << 8) + (Reg2 << 3) + (pOrder->Code & 7);
CodeLen = 1;
DontAdd = True;
}
else
{
DAsmCode[0] = 0x0140c0 + (Reg2 << 3) + (pOrder->Code & 7);
DAsmCode[1] = AddVal & 0xffffff;
CodeLen = 2;
DontAdd = True;
}
}
}
else
{
if (!DecodeReg(LeftComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
else if ((Reg1 < 4) || (Reg1 > 7)) SetXError(ErrNum_InvReg, &LeftComp);
else
h = (Reg2 << 3) + (TurnXY(Reg1) << 4);
}
break;
case ParMul:
SplitArg(&ArgStr[1], &LeftComp, &MidComp);
SplitArg(&MidComp, &MidComp, &RightComp);
h = 0;
if (*LeftComp.str.p_str == '-')
{
StrCompRefRight(&LeftRegComp, &LeftComp, 1);
h += 4;
}
else if (*LeftComp.str.p_str == '+')
StrCompRefRight(&LeftRegComp, &LeftComp, 1);
else
StrCompRefRight(&LeftRegComp, &LeftComp, 0);
if (!DecodeALUReg(RightComp.str.p_str, &Reg3, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
else if (!DecodeReg(LeftRegComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftRegComp);
else if ((Reg1 < 4) || (Reg1 > 7)) SetXError(ErrNum_InvReg, &LeftRegComp);
else if (*MidComp.str.p_str == '#')
{
if (!ChkArgCnt(1, 1));
else if (ChkMinCPU(CPU56300))
{
AddVal = EvalStrIntExpressionOffsWithFlags(&MidComp, 1, UInt24, &OK, &Flags);
if (mFirstPassUnknown(Flags))
AddVal = 1;
if ((!(SingleBit(AddVal, &LAddVal))) || (LAddVal > 22)) WrError(ErrNum_NotOneBit);
else
{
LAddVal = 23 - LAddVal;
DAsmCode[0] = 0x010040 + (LAddVal << 8) + (Mac2Table[Reg1 & 3] << 4)
+ (Reg3 << 3);
CodeLen = 1;
}
}
}
else if (!DecodeReg(MidComp.str.p_str, &Reg2)) SetXError(ErrNum_InvReg, &MidComp);
else if ((Reg2 < 4) || (Reg2 > 7)) SetXError(ErrNum_InvReg, &MidComp);
else if (MacTable[Reg1 - 4][Reg2 - 4] == 0xff) SetError(ErrNum_InvRegPair);
else
h += (Reg3 << 3) + (MacTable[Reg1 - 4][Reg2 - 4] << 4);
break;
}
if (ErrCode == 0)
{
if (!DontAdd)
DAsmCode[0] += pOrder->Code + h;
}
else
{
if (ErrCode > 0)
PrError();
CodeLen = 0;
}
}
}
static void DecodeDIV(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
LongInt Reg2, Reg1;
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrError(ErrNum_InvAddrMode);
else if (!DecodeReg(LeftComp.str.p_str, &Reg1)) WrError(ErrNum_InvAddrMode);
else if ((Reg1 < 4) || (Reg1 > 7)) WrError(ErrNum_InvAddrMode);
else
{
CodeLen = 1;
DAsmCode[0] = 0x018040 + (Reg2 << 3) + (TurnXY(Reg1) << 4);
}
}
}
static void DecodeImmMac(Word Code)
{
tStrComp LeftArg;
Boolean OK;
LongInt h = 0, Reg1, Reg2;
if (!ChkArgCnt(1, 1));
else if (ChkMinCPU(CPU56300))
{
SplitArg(&ArgStr[1], &LeftComp, &MidComp);
SplitArg(&MidComp, &MidComp, &RightComp);
h = 0;
StrCompRefRight(&LeftArg, &LeftComp, 0);
switch (*LeftComp.str.p_str)
{
case '-':
h = 4;
/* fall-through */
case '+':
StrCompRefRight(&LeftArg, &LeftComp, 1);
}
if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeXYABReg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if ((Reg2 < 4) || (Reg2 > 7)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if (*LeftArg.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
else
{
DAsmCode[1] = EvalStrIntExpressionOffs(&LeftArg, 1, Int24, &OK);
if (OK)
{
DAsmCode[0] = 0x0141c0 + Code + h + (Reg1 << 3) + ((Reg2 & 3) << 4);
CodeLen = 2;
}
}
}
}
static void DecodeDMAC(Word Code)
{
if (!ChkArgCnt(1, 1));
else if (ChkMinCPU(CPU56300))
{
LongInt Reg1, Reg2, Reg3;
tStrComp LeftReg;
SplitArg(&ArgStr[1], &LeftComp, &MidComp);
SplitArg(&MidComp, &MidComp, &RightComp);
if (*LeftComp.str.p_str == '-')
{
StrCompRefRight(&LeftReg, &LeftComp, 1);
Code += 16;
}
else if (*LeftComp.str.p_str == '+')
StrCompRefRight(&LeftReg, &LeftComp, 1);
else
StrCompRefRight(&LeftReg, &LeftComp, 0);
if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeXYAB1Reg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if (Reg2 < 4) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if (!DecodeXYAB1Reg(LeftReg.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
else if (Reg3 < 4) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
else
{
DAsmCode[0] = 0x012480 + Code + (Reg1 << 5) + Mac4Table[Reg3 - 4][Reg2 - 4];
CodeLen = 1;
}
}
}
static void DecodeMAC_MPY(Word Code)
{
if (!ChkArgCnt(1, 1));
else if (ChkMinCPU(CPU56300))
{
tStrComp LeftReg;
LongInt Reg1, Reg2, Reg3;
SplitArg(&ArgStr[1], &LeftComp, &MidComp);
SplitArg(&MidComp, &MidComp, &RightComp);
if (*LeftComp.str.p_str == '-')
{
StrCompRefRight(&LeftReg, &LeftComp, 1);
Code += 16;
}
else if (*LeftComp.str.p_str == '+')
StrCompRefRight(&LeftReg, &LeftComp, 1);
else
StrCompRefRight(&LeftReg, &LeftComp, 0);
if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeXYAB1Reg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if (Reg2 < 4) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if (!DecodeXYAB1Reg(LeftReg.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
else if (Reg3 < 4) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
else
{
DAsmCode[0] = 0x012680 + Code + (Reg1 << 5) + Mac4Table[Reg3 - 4][Reg2 - 4];
CodeLen = 1;
}
}
}
static void DecodeINC_DEC(Word Code)
{
LongInt Reg1;
if (!ChkArgCnt(1, 1));
else if (!ChkMinCPU(CPU56002));
else if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
else
{
DAsmCode[0] = (LongWord)Code + Reg1;
CodeLen = 1;
}
}
static void DecodeANDI_ORI(Word Code)
{
LongInt Reg1, h = 0;
Boolean OK;
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeControlReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvAddrMode, &RightComp);
else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
else
{
h = EvalStrIntExpressionOffs(&LeftComp, 1, Int8, &OK);
if (OK)
{
CodeLen = 1;
DAsmCode[0] = (LongWord)Code + ((h & 0xff) << 8) + Reg1;
}
}
}
}
static void DecodeNORM(Word Code)
{
LongInt Reg1, Reg2;
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrError(ErrNum_InvAddrMode);
else if (!DecodeReg(LeftComp.str.p_str, &Reg1)) WrError(ErrNum_InvAddrMode);
else if ((Reg1 < 16) || (Reg1 > 23)) WrError(ErrNum_InvAddrMode);
else
{
CodeLen = 1;
DAsmCode[0] = 0x01d815 + ((Reg1 & 7) << 8) + (Reg2 << 3);
}
}
}
static void DecodeNORMF(Word Code)
{
LongInt Reg1, Reg2;
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else
{
CodeLen = 1;
DAsmCode[0] = 0x0c1e20 + Reg2 + (Reg1 << 1);
}
}
}
static void DecodeBit(Word Code)
{
LongInt Reg1, Reg2, Reg3, h = 0;
Boolean OK;
tSymbolFlags Flags;
if (ChkArgCnt(1, 1))
{
Reg2 = ((Code & 1) << 5) + (((LongInt) Code >> 1) << 16);
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
else
{
h = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
if (mFirstPassUnknown(Flags)) h &= 15;
if (OK)
{
if ((h < 0) || (h > 23)) WrError(ErrNum_OverRange);
else if (DecodeGeneralReg(RightComp.str.p_str, &Reg1))
{
CodeLen = 1;
DAsmCode[0] = 0x0ac040 + h + (Reg1 << 8) + Reg2;
}
else
{
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData, &RightAdrResult);
Reg3 = Ord(RightAdrResult.Seg == SegYData) << 6;
if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x0a0000 + h + (RightAdrResult.Val << 8) + Reg3 + Reg2;
}
else if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val >= MemLimit - 0x3f) && (RightAdrResult.Val <= MemLimit) && (RightAdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x0a8000 + h + ((RightAdrResult.Val & 0x3f) << 8) + Reg3 + Reg2;
}
else if ((RightAdrResult.Type == ModAbs) && (MomCPU >= CPU56300) && (RightAdrResult.Val >= MemLimit - 0x7f) && (RightAdrResult.Val <= MemLimit - 0x40) && (RightAdrResult.ShortMode != 2))
{
Reg2 = ((Code & 1) << 5) + (((LongInt) Code >> 1) << 14);
CodeLen = 1;
DAsmCode[0] = 0x010000 + h + ((RightAdrResult.Val & 0x3f) << 8) + Reg3 + Reg2;
}
else if (RightAdrResult.Type != ModNone)
{
CodeLen = 1 + RightAdrResult.Cnt;
DAsmCode[0] = 0x0a4000 + h + (RightAdrResult.Mode << 8) + Reg3 + Reg2;
DAsmCode[1] = RightAdrResult.Val;
}
}
}
}
}
}
static void DecodeEXTRACT_EXTRACTU(Word Code)
{
LongInt Reg1, Reg2, Reg3;
Boolean OK;
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
SplitArg(&ArgStr[1], &LeftComp, &MidComp);
SplitArg(&MidComp, &MidComp, &RightComp);
if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeALUReg(MidComp.str.p_str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if (*LeftComp.str.p_str == '#')
{
DAsmCode[1] = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
if (OK)
{
DAsmCode[0] = 0x0c1800 + Code + Reg1 + (Reg2 << 4);
CodeLen = 2;
}
}
else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else
{
DAsmCode[0] = 0x0c1a00 + Code + Reg1 + (Reg2 << 4) + (Reg3 << 1);
CodeLen = 1;
}
}
}
static void DecodeINSERT(Word Code)
{
LongInt Reg1, Reg2, Reg3;
Boolean OK;
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
SplitArg(&ArgStr[1], &LeftComp, &MidComp);
SplitArg(&MidComp, &MidComp, &RightComp);
if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeXYAB0Reg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
else if (*LeftComp.str.p_str == '#')
{
DAsmCode[1] = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
if (OK)
{
DAsmCode[0] = 0x0c1900 + Reg1 + (Reg2 << 4);
CodeLen = 2;
}
}
else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else
{
DAsmCode[0] = 0x0c1b00 + Reg1 + (Reg2 << 4) + (Reg3 << 1);
CodeLen = 1;
}
}
}
static void DecodeMERGE(Word Code)
{
LongInt Reg1, Reg2;
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else
{
DAsmCode[0] = 0x0c1b80 + Reg1 + (Reg2 << 1);
CodeLen = 1;
}
}
}
static void DecodeCLB(Word Code)
{
LongInt Reg1, Reg2;
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(LeftComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else
{
DAsmCode[0] = 0x0c1e00 + Reg2 + (Reg1 << 1);
CodeLen = 1;
}
}
}
static void DecodeCMPU(Word Code)
{
LongInt Reg1, Reg2;
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (!DecodeXYABReg(LeftComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else if ((Reg1 ^ Reg2) == 1) WrError(ErrNum_InvRegPair);
else if ((Reg2 & 6) == 2) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else
{
if (Reg2 < 2)
Reg2 = 0;
DAsmCode[0] = 0x0c1ff0 + (Reg2 << 1) + Reg1;
CodeLen = 1;
}
}
}
/* Datentransfer */
static void DecodePlainMOVE(Word Code)
{
UNUSED(Code);
DecodeMOVE(1);
}
static void DecodeMOVEC(Word Code)
{
LongInt Reg1, Reg2, Reg3;
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
else if (DecodeCtrlReg(LeftComp.str.p_str, &Reg1))
{
if (DecodeGeneralReg(RightComp.str.p_str, &Reg2))
{
DAsmCode[0] = 0x0440a0 + (Reg2 << 8) + Reg1;
CodeLen = 1;
}
else
{
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData, &RightAdrResult);
Reg3 = (Ord(RightAdrResult.Seg == SegYData)) << 6;
if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.ShortMode != 2))
{
DAsmCode[0] = 0x050020 + (RightAdrResult.Val << 8) + Reg3 + Reg1;
CodeLen = 1;
}
else
{
DAsmCode[0] = 0x054020 + (RightAdrResult.Mode << 8) + Reg3 + Reg1;
DAsmCode[1] = RightAdrResult.Val; CodeLen = 1 + RightAdrResult.Cnt;
}
}
}
else if (!DecodeCtrlReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvCtrlReg, &RightComp);
else
{
if (DecodeGeneralReg(LeftComp.str.p_str, &Reg2))
{
DAsmCode[0] = 0x04c0a0 + (Reg2 << 8) + Reg1;
CodeLen = 1;
}
else
{
tAdrResult LeftAdrResult;
DecodeAdr(&LeftComp, MModAll, MSegXData + MSegYData, &LeftAdrResult);
Reg3 = (Ord(LeftAdrResult.Seg == SegYData)) << 6;
if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.ShortMode != 2))
{
DAsmCode[0] = 0x058020 + (LeftAdrResult.Val << 8) + Reg3 + Reg1;
CodeLen = 1;
}
else if (!LeftAdrResult.ForceImmLong && (LeftAdrResult.Type == ModImm) && (LeftAdrResult.Val <= 255))
{
DAsmCode[0] = 0x0500a0 + (LeftAdrResult.Val << 8) + Reg1;
CodeLen = 1;
}
else
{
DAsmCode[0] = 0x05c020 + (LeftAdrResult.Mode << 8) + Reg3 + Reg1;
DAsmCode[1] = LeftAdrResult.Val; CodeLen = 1 + LeftAdrResult.Cnt;
}
}
}
}
}
static void DecodeMOVEM(Word Code)
{
LongInt Reg1, Reg2;
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg1))
{
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModNoImm, MSegCode, &RightAdrResult);
if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val >= 0) && (RightAdrResult.Val <= 63) && (RightAdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x070000 + Reg1 + (RightAdrResult.Val << 8);
}
else if (RightAdrResult.Type != ModNone)
{
CodeLen = 1 + RightAdrResult.Cnt;
DAsmCode[1] = RightAdrResult.Val;
DAsmCode[0] = 0x074080 + Reg1 + (RightAdrResult.Mode << 8);
}
}
else if (!DecodeGeneralReg(RightComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else
{
tAdrResult LeftAdrResult;
DecodeAdr(&LeftComp, MModNoImm, MSegCode, &LeftAdrResult);
if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val >= 0) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x078000 + Reg2 + (LeftAdrResult.Val << 8);
}
else if (LeftAdrResult.Type != ModNone)
{
CodeLen = 1 + LeftAdrResult.Cnt;
DAsmCode[1] = LeftAdrResult.Val;
DAsmCode[0] = 0x07c080 + Reg2 + (LeftAdrResult.Mode << 8);
}
}
}
}
static void DecodeMOVEP(Word Code)
{
LongInt Reg1, Reg2;
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg1))
{
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModAbs, MSegXData + MSegYData, &RightAdrResult);
if (RightAdrResult.Type != ModNone)
{
if ((RightAdrResult.Val <= MemLimit) && (RightAdrResult.Val >= MemLimit - 0x3f))
{
CodeLen = 1;
DAsmCode[0] = 0x08c000 + (Ord(RightAdrResult.Seg == SegYData) << 16)
+ (RightAdrResult.Val & 0x3f) + (Reg1 << 8);
}
else if ((MomCPU >= CPU56300) && (RightAdrResult.Val <= MemLimit - 0x40) && (RightAdrResult.Val >= MemLimit - 0x7f))
{
CodeLen = 1;
DAsmCode[0] = 0x04c000 + (Ord(RightAdrResult.Seg == SegYData) << 5)
+ (Ord(RightAdrResult.Seg == SegXData) << 7)
+ (RightAdrResult.Val & 0x1f) + ((RightAdrResult.Val & 0x20) << 1) + (Reg1 << 8);
}
else
WrError(ErrNum_UnderRange);
}
}
else if (DecodeGeneralReg(RightComp.str.p_str, &Reg2))
{
tAdrResult LeftAdrResult;
DecodeAdr(&LeftComp, MModAbs, MSegXData + MSegYData, &LeftAdrResult);
if (LeftAdrResult.Type != ModNone)
{
if ((LeftAdrResult.Val <= MemLimit) && (LeftAdrResult.Val >= MemLimit - 0x3f))
{
CodeLen = 1;
DAsmCode[0] = 0x084000 + (Ord(LeftAdrResult.Seg == SegYData) << 16)
+ (LeftAdrResult.Val & 0x3f) + (Reg2 << 8);
}
else if ((MomCPU >= CPU56300) && (LeftAdrResult.Val <= MemLimit - 0x40) && (LeftAdrResult.Val >= MemLimit - 0x7f))
{
CodeLen = 1;
DAsmCode[0] = 0x044000 + (Ord(LeftAdrResult.Seg == SegYData) << 5)
+ (Ord(LeftAdrResult.Seg == SegXData) << 7)
+ (LeftAdrResult.Val & 0x1f) + ((LeftAdrResult.Val & 0x20) << 1) + (Reg2 << 8);
}
else
WrError(ErrNum_UnderRange);
}
}
else
{
tAdrResult LeftAdrResult;
DecodeAdr(&LeftComp, MModAll, MSegXData + MSegYData + MSegCode, &LeftAdrResult);
if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Seg != SegCode) && (LeftAdrResult.Val >= MemLimit - 0x3f) && (LeftAdrResult.Val <= MemLimit))
{
LongInt HVal = LeftAdrResult.Val & 0x3f, HSeg = LeftAdrResult.Seg;
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData + MSegCode, &RightAdrResult);
if (RightAdrResult.Type != ModNone)
{
if (RightAdrResult.Seg == SegCode)
{
CodeLen = 1 + RightAdrResult.Cnt;
DAsmCode[1] = RightAdrResult.Val;
DAsmCode[0] = 0x084040 + HVal + (RightAdrResult.Mode << 8)
+ (Ord(HSeg == SegYData) << 16);
}
else
{
CodeLen = 1 + RightAdrResult.Cnt;
DAsmCode[1] = RightAdrResult.Val;
DAsmCode[0] = 0x084080 + HVal + (RightAdrResult.Mode << 8)
+ (Ord(HSeg == SegYData) << 16)
+ (Ord(RightAdrResult.Seg == SegYData) << 6);
}
}
}
else if ((LeftAdrResult.Type == ModAbs) && (MomCPU >= CPU56300) && (LeftAdrResult.Seg != SegCode) && (LeftAdrResult.Val >= MemLimit - 0x7f) && (LeftAdrResult.Val <= MemLimit - 0x40) && (LeftAdrResult.ShortMode != 2))
{
LongInt HVal = LeftAdrResult.Val & 0x3f, HSeg = LeftAdrResult.Seg;
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData + MSegCode, &RightAdrResult);
if (RightAdrResult.Type != ModNone)
{
if (RightAdrResult.Seg == SegCode)
{
CodeLen = 1 + RightAdrResult.Cnt;
DAsmCode[1] = RightAdrResult.Val;
DAsmCode[0] = 0x008000 + HVal + (RightAdrResult.Mode << 8)
+ (Ord(HSeg == SegYData) << 6);
}
else
{
CodeLen = 1 + RightAdrResult.Cnt;
DAsmCode[1] = RightAdrResult.Val;
DAsmCode[0] = 0x070000 + HVal + (RightAdrResult.Mode << 8)
+ (Ord(HSeg == SegYData) << 7)
+ (Ord(HSeg == SegXData) << 14)
+ (Ord(RightAdrResult.Seg == SegYData) << 6);
}
}
}
else if (LeftAdrResult.Type != ModNone)
{
LongInt HVal = LeftAdrResult.Val,
HCnt = LeftAdrResult.Cnt,
HMode = LeftAdrResult.Mode,
HSeg = LeftAdrResult.Seg;
tAdrResult RightAdrResult;
DecodeAdr(&RightComp, MModAbs, MSegXData + MSegYData, &RightAdrResult);
if (RightAdrResult.Type != ModNone)
{
if ((RightAdrResult.Val >= MemLimit - 0x3f) && (RightAdrResult.Val <= MemLimit))
{
if (HSeg == SegCode)
{
CodeLen = 1 + HCnt;
DAsmCode[1] = HVal;
DAsmCode[0] = 0x08c040 + (RightAdrResult.Val & 0x3f) + (HMode << 8)
+ (Ord(RightAdrResult.Seg == SegYData) << 16);
}
else
{
CodeLen = 1 + HCnt;
DAsmCode[1] = HVal;
DAsmCode[0] = 0x08c080 + (((Word)RightAdrResult.Val) & 0x3f) + (HMode << 8)
+ (Ord(RightAdrResult.Seg == SegYData) << 16)
+ (Ord(HSeg == SegYData) << 6);
}
}
else if ((MomCPU >= CPU56300) && (RightAdrResult.Val >= MemLimit - 0x7f) && (RightAdrResult.Val <= MemLimit - 0x40))
{
if (HSeg == SegCode)
{
CodeLen = 1 + HCnt;
DAsmCode[1] = HVal;
DAsmCode[0] = 0x00c000 + (RightAdrResult.Val & 0x3f) + (HMode << 8)
+ (Ord(RightAdrResult.Seg == SegYData) << 6);
}
else
{
CodeLen = 1 + HCnt;
DAsmCode[1] = HVal;
DAsmCode[0] = 0x078000 + (((Word)RightAdrResult.Val) & 0x3f) + (HMode << 8)
+ (Ord(RightAdrResult.Seg == SegYData) << 7)
+ (Ord(RightAdrResult.Seg == SegXData) << 14)
+ (Ord(HSeg == SegYData) << 6);
}
}
else
WrError(ErrNum_UnderRange);
}
}
}
}
}
static void DecodePlainTFR(Word Code)
{
LongInt Reg1;
UNUSED(Code);
if (ChkArgCnt(1, ArgCntMax))
if (DecodeMOVE(2))
{
if (DecodeTFR(&ArgStr[1], &Reg1))
{
DAsmCode[0] += 0x01 + (Reg1 << 3);
}
else
{
WrError(ErrNum_InvAddrMode);
CodeLen = 0;
}
}
}
static void DecodeTcc(Word Condition)
{
LongInt Reg1, Reg2;
if (!ChkArgCnt(1, 2));
else if (DecodeTFR(&ArgStr[1], &Reg1))
{
if (ArgCnt == 1)
{
CodeLen = 1;
DAsmCode[0] = 0x020000 + (Condition << 12) + (Reg1 << 3);
}
else if (!DecodeRR(&ArgStr[2], &Reg2)) WrError(ErrNum_InvAddrMode);
else
{
CodeLen = 1;
DAsmCode[0] = 0x030000 + (Condition << 12) + (Reg1 << 3) + Reg2;
}
}
else if (!ChkArgCnt(1, 1));
else if (!DecodeRR(&ArgStr[1], &Reg1)) WrError(ErrNum_InvAddrMode);
else
{
DAsmCode[0] = 0x020800 + (Condition << 12) + Reg1;
CodeLen = 1;
}
}
static void DecodeBitBr(Word Code)
{
LongInt Reg1, Reg3, h = 0, h2, AddVal;
Boolean OK;
tSymbolFlags Flags;
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
h = (Code & 1) << 5;
h2 = (((LongInt) Code) & 2) << 15;
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
SplitArg(&RightComp, &MidComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0') || (*MidComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
else
{
AddVal = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
if (mFirstPassUnknown(Flags)) AddVal &= 15;
if (OK)
{
if ((AddVal < 0) || (AddVal > 23)) WrError(ErrNum_OverRange);
else if (DecodeGeneralReg(MidComp.str.p_str, &Reg1))
{
CodeLen = 1;
DAsmCode[0] = 0x0cc080 + AddVal + (Reg1 << 8) + h + h2;
}
else
{
tAdrResult AdrResult;
DecodeAdr(&MidComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
Reg3 = Ord(AdrResult.Seg == SegYData) << 6;
if ((AdrResult.Type == ModAbs) && (mFirstPassUnknown(AdrResult.AbsSymFlags))) AdrResult.Val &= 0x3f;
if ((AdrResult.Type == ModAbs) && (AdrResult.Val <= 63) && (AdrResult.Val >= 0) && (AdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x0c8080 + AddVal + (AdrResult.Val << 8) + Reg3 + h + h2;
}
else if ((AdrResult.Type == ModAbs) && (AdrResult.Val >= MemLimit - 0x3f) && (AdrResult.Val <= MemLimit))
{
CodeLen = 1;
DAsmCode[0] = 0x0cc000 + AddVal + ((AdrResult.Val & 0x3f) << 8) + Reg3 + h + h2;
}
else if ((AdrResult.Type == ModAbs) && (AdrResult.Val >= MemLimit - 0x7f) && (AdrResult.Val <= MemLimit - 0x40))
{
CodeLen = 1;
DAsmCode[0] = 0x048000 + AddVal + ((AdrResult.Val & 0x3f) << 8) + Reg3 + h + (h2 >> 9);
}
else if (AdrResult.Type == ModAbs) WrError(ErrNum_InvAddrMode);
else if (AdrResult.Type != ModNone)
{
CodeLen = 1;
DAsmCode[0] = 0x0c8000 + AddVal + (AdrResult.Mode << 8) + Reg3 + h + h2;
}
}
}
}
if (CodeLen == 1)
{
LongInt Dist = EvalStrIntExpression(&RightComp, AdrInt, &OK) - EProgCounter();
if (OK)
{
DAsmCode[1] = Dist & 0xffffff;
CodeLen = 2;
}
else
CodeLen = 0;
}
}
}
static void DecodeBRA_BSR(Word Code)
{
LongInt Reg1, Dist;
Byte Size;
Boolean OK;
tSymbolFlags Flags;
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300)
&& DecodeReg(ArgStr[1].str.p_str, &Reg1))
{
if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
else
{
Reg1 -= 16;
DAsmCode[0] = 0x0d1880 + (Reg1 << 8) + Code;
CodeLen = 1;
}
}
else
{
unsigned Offset = CutSize(&ArgStr[1], &Size);
Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
if (Size == 0)
Size = ((Dist> - 256) && (Dist < 255)) ? 1 : 2;
switch (Size)
{
case 1:
if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
else
{
Dist &= 0x1ff;
DAsmCode[0] = 0x050800 + (Code << 4) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
CodeLen = 1;
}
break;
case 2:
DAsmCode[0] = 0x0d1080 + Code;
DAsmCode[1] = Dist & 0xffffff;
CodeLen = 2;
break;
}
}
}
static void DecodeBcc(Word Condition)
{
LongInt Dist, Reg1;
Boolean OK;
tSymbolFlags Flags;
Byte Size;
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300)
&& DecodeReg(ArgStr[1].str.p_str, &Reg1))
{
if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
else
{
Reg1 -= 16;
DAsmCode[0] = 0x0d1840 + (Reg1 << 8) + Condition;
CodeLen = 1;
}
}
else
{
unsigned Offset = CutSize(&ArgStr[1], &Size);
Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
if (Size == 0)
Size = ((Dist > -256) && (Dist < 255)) ? 1 : 2;
switch (Size)
{
case 1:
if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
else
{
Dist &= 0x1ff;
DAsmCode[0] = 0x050400 + (Condition << 12) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
CodeLen = 1;
}
break;
case 2:
DAsmCode[0] = 0x0d1040 + Condition;
DAsmCode[1] = Dist & 0xffffff;
CodeLen = 2;
break;
}
}
}
static void DecodeBScc(Word Condition)
{
LongInt Reg1, Dist;
Byte Size;
Boolean OK;
tSymbolFlags Flags;
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300)
&& DecodeReg(ArgStr[1].str.p_str, &Reg1))
{
if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
else
{
Reg1 -= 16;
DAsmCode[0] = 0x0d1800 + (Reg1 << 8) + Condition;
CodeLen = 1;
}
}
else
{
unsigned Offset;
Offset = CutSize(&ArgStr[1], &Size);
Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
if (Size == 0)
Size = ((Dist > -256) && (Dist < 255)) ? 1 : 2;
switch (Size)
{
case 1:
if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
else
{
Dist &= 0x1ff;
DAsmCode[0] = 0x050000 + (Condition << 12) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
CodeLen = 1;
}
break;
case 2:
DAsmCode[0] = 0x0d1000 + Condition;
DAsmCode[1] = Dist & 0xffffff;
CodeLen = 2;
break;
}
}
}
static void DecodeLUA_LEA(Word Code)
{
LongInt Reg1;
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (!DecodeReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (Reg1 > 31) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else
{
tAdrResult AdrResult;
DecodeAdr(&LeftComp, MModModInc | MModModDec | MModPostInc | MModPostDec | MModDisp, MSegXData, &AdrResult);
if (AdrResult.Type == ModDisp)
{
if (ChkRange(AdrResult.Val, -64, 63))
{
AdrResult.Val &= 0x7f;
DAsmCode[0] = 0x040000 + (Reg1 - 16) + (AdrResult.Mode << 8)
+ ((AdrResult.Val & 0x0f) << 4)
+ ((AdrResult.Val & 0x70) << 7);
CodeLen = 1;
}
}
else if (AdrResult.Type != ModNone)
{
CodeLen = 1;
DAsmCode[0] = 0x044000 + (AdrResult.Mode << 8) + Reg1;
}
}
}
}
static void DecodeLRA(Word Code)
{
LongInt Reg1, Reg2;
Boolean OK;
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
else if (!DecodeGeneralReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (Reg1 > 0x1f) WrStrErrorPos(ErrNum_InvReg, &RightComp);
else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg2))
{
if ((Reg2 < 16) || (Reg2 > 23)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
else
{
DAsmCode[0] = 0x04c000 + ((Reg2 & 7) << 8) + Reg1;
CodeLen = 1;
}
}
else
{
DAsmCode[1] = EvalStrIntExpression(&LeftComp, AdrInt, &OK) - EProgCounter();
if (OK)
{
DAsmCode[0] = 0x044040 + Reg1;
CodeLen = 2;
}
}
}
}
static void DecodePLOCK(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
tAdrResult AdrResult;
DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
if (AdrResult.Type != ModNone)
{
DAsmCode[0] = 0x0ac081 + (AdrResult.Mode << 8); DAsmCode[1] = AdrResult.Val;
CodeLen = 2;
}
}
}
static void DecodePLOCKR_PUNLOCKR(Word Code)
{
if (ChkArgCnt(1, 1)
&& ChkMinCPU(CPU56300))
{
Boolean OK;
DAsmCode[1] = (EvalStrIntExpression(&ArgStr[1], AdrInt, &OK) - EProgCounter()) & 0xffffff;
if (OK)
{
DAsmCode[0] = Code;
CodeLen = 2;
}
}
}
/* Spruenge */
static void DecodeJMP_JSR(Word Code)
{
if (ChkArgCnt(1, 1))
{
LongWord AddVal = (LongWord)Code << 16;
tAdrResult AdrResult;
DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
if (AdrResult.Type == ModAbs)
if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x0c0000 + AddVal + (AdrResult.Val & 0xfff);
}
else
{
CodeLen = 2;
DAsmCode[0] = 0x0af080 + AddVal;
DAsmCode[1] = AdrResult.Val;
}
else if (AdrResult.Type != ModNone)
{
CodeLen = 1;
DAsmCode[0] = 0x0ac080 + AddVal + (AdrResult.Mode << 8);
}
}
}
static void DecodeJcc(Word Condition)
{
if (ChkArgCnt(1, 1))
{
tAdrResult AdrResult;
DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
if (AdrResult.Type == ModAbs)
{
if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x0e0000 + (Condition << 12) + (AdrResult.Val & 0xfff);
}
else
{
CodeLen = 2;
DAsmCode[0] = 0x0af0a0 + Condition;
DAsmCode[1] = AdrResult.Val;
}
}
else if (AdrResult.Type != ModNone)
{
CodeLen = 1;
DAsmCode[0] = 0x0ac0a0 + Condition + (AdrResult.Mode << 8);
}
}
}
static void DecodeJScc(Word Condition)
{
if (ChkArgCnt(1, 1))
{
tAdrResult AdrResult;
DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
if (AdrResult.Type == ModAbs)
{
if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
{
CodeLen = 1;
DAsmCode[0] = 0x0f0000 + (Condition << 12) + (AdrResult.Val & 0xfff);
}
else
{
CodeLen = 2;
DAsmCode[0] = 0x0bf0a0 + Condition;
DAsmCode[1] = AdrResult.Val;
}
}
else if (AdrResult.Type != ModNone)
{
CodeLen = 1;
DAsmCode[0] = 0x0bc0a0 + Condition + (AdrResult.Mode << 8);
}
}
}
static void DecodeBitJmp(Word Code)
{
Boolean OK;
tSymbolFlags Flags;
LongInt h, Reg1, Reg2, Reg3;
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &MidComp);
SplitArg(&MidComp, &MidComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
else
{
DAsmCode[1] = EvalStrIntExpression(&RightComp, AdrInt, &OK);
if (OK)
{
h = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
if (mFirstPassUnknown(Flags))
h &= 15;
if (OK)
{
if ((h < 0) || (h > 23)) WrError(ErrNum_OverRange);
else
{
Reg2 = ((Code & 1) << 5) + (((LongInt)(Code >> 1)) << 16);
if (DecodeGeneralReg(MidComp.str.p_str, &Reg1))
{
CodeLen = 2;
DAsmCode[0] = 0x0ac000 + h + Reg2 + (Reg1 << 8);
}
else
{
tAdrResult AdrResult;
DecodeAdr(&MidComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
Reg3 = Ord(AdrResult.Seg == SegYData) << 6;
if (AdrResult.Type == ModAbs)
{
if ((AdrResult.Val >= 0) && (AdrResult.Val <= 63))
{
CodeLen = 2;
DAsmCode[0] = 0x0a0080 + h + Reg2 + Reg3 + (AdrResult.Val << 8);
}
else if ((AdrResult.Val >= MemLimit - 0x3f) && (AdrResult.Val <= MemLimit))
{
CodeLen = 2;
DAsmCode[0] = 0x0a8080 + h + Reg2 + Reg3 + ((AdrResult.Val & 0x3f) << 8);
}
else if ((MomCPU >= CPU56300) && (AdrResult.Val >= MemLimit - 0x7f) && (AdrResult.Val <= MemLimit - 0x40))
{
CodeLen = 2;
Reg2 = ((Code & 1) << 5) + (((LongInt)(Code >> 1)) << 14);
DAsmCode[0] = 0x018080 + h + Reg2 + Reg3 + ((AdrResult.Val & 0x3f) << 8);
}
else WrError(ErrNum_OverRange);
}
else if (AdrResult.Type != ModNone)
{
CodeLen = 2;
DAsmCode[0] = 0x0a4080 + h + Reg2 + Reg3 + (AdrResult.Mode << 8);
}
}
}
}
}
}
}
}
static void DecodeDO_DOR(Word Code)
{
if (ChkArgCnt(1, 1))
{
SplitArg(&ArgStr[1], &LeftComp, &RightComp);
if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
else
{
LongInt Reg1;
tEvalResult EvalResult;
DAsmCode[1] = EvalStrIntExpressionWithResult(&RightComp, AdrInt, &EvalResult) - 1;
if (EvalResult.OK)
{
ChkSpace(SegCode, EvalResult.AddrSpaceMask);
if (!as_strcasecmp(LeftComp.str.p_str, "FOREVER"))
{
if (ChkMinCPU(CPU56300))
{
DAsmCode[0] = 0x000203 - Code;
CodeLen = 2;
}
}
else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg1))
{
if (Reg1 == 0x3c) WrXError(ErrNum_InvReg, LeftComp.str.p_str); /* kein SSH!! */
else
{
CodeLen = 2;
DAsmCode[0] = 0x06c000 + (Reg1 << 8) + (Code << 4);
}
}
else if (*LeftComp.str.p_str == '#')
{
Reg1 = EvalStrIntExpressionOffsWithResult(&LeftComp, 1, UInt12, &EvalResult);
if (EvalResult.OK)
{
CodeLen = 2;
DAsmCode[0] = 0x060080 + (Reg1 >> 8) + ((Reg1 & 0xff) << 8) + (Code << 4);
}
}
else
{
tAdrResult AdrResult;
DecodeAdr(&LeftComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
if (AdrResult.Type == ModAbs)
if ((AdrResult.Val < 0) || (AdrResult.Val > 63)) WrError(ErrNum_OverRange);
else
{
CodeLen = 2;
DAsmCode[0] = 0x060000 + (AdrResult.Val << 8) + (Ord(AdrResult.Seg == SegYData) << 6) + (Code << 4);
}
else
{
CodeLen = 2;
DAsmCode[0] = 0x064000 + (AdrResult.Mode << 8) + (Ord(AdrResult.Seg == SegYData) << 6) + (Code << 4);
}
}
}
}
}
}
static void DecodeBRKcc(Word Condition)
{
if (ChkArgCnt(0, 0)
&& ChkMinCPU(CPU56300))
{
DAsmCode[0] = 0x00000210 + Condition;
CodeLen = 1;
}
}
static void DecodeTRAPcc(Word Condition)
{
if (ChkArgCnt(0, 0)
&& ChkMinCPU(CPU56300))
{
DAsmCode[0] = 0x000010 + Condition;
CodeLen = 1;
}
}
static void DecodeDEBUGcc(Word Condition)
{
if (ChkArgCnt(0, 0)
&& ChkMinCPU(CPU56300))
{
DAsmCode[0] = 0x00000300 + Condition;
CodeLen = 1;
}
}
static void DecodeREP(Word Code)
{
LongInt Reg1;
UNUSED(Code);
if (!ChkArgCnt(1, 1));
else if (DecodeGeneralReg(ArgStr[1].str.p_str, &Reg1))
{
CodeLen = 1;
DAsmCode[0] = 0x06c020 + (Reg1 << 8);
}
else
{
tAdrResult AdrResult;
DecodeAdr(&ArgStr[1], MModAll, MSegXData + MSegYData, &AdrResult);
if (AdrResult.Type == ModImm)
{
if ((AdrResult.Val < 0) || (AdrResult.Val > 0xfff)) WrError(ErrNum_OverRange);
else
{
CodeLen = 1;
DAsmCode[0] = 0x0600a0 + (AdrResult.Val >> 8) + ((AdrResult.Val & 0xff) << 8);
}
}
else if (AdrResult.Type == ModAbs)
{
if ((AdrResult.Val < 0) || (AdrResult.Val > 63)) WrError(ErrNum_OverRange);
else
{
CodeLen = 1;
DAsmCode[0] = 0x060020 + (AdrResult.Val << 8) + (Ord(AdrResult.Seg == SegYData) << 6);
}
}
else
{
CodeLen = 1 + AdrResult.Cnt;
DAsmCode[1] = AdrResult.Val;
DAsmCode[0] = 0x064020 + (AdrResult.Mode << 8) + (Ord(AdrResult.Seg == SegYData) << 6);
}
}
}
/*----------------------------------------------------------------------------------------------*/
static void AddFixed(const char *Name, LongWord Code, CPUVar NMin)
{
order_array_rsv_end(FixedOrders, FixedOrder);
FixedOrders[InstrZ].Code = Code;
FixedOrders[InstrZ].MinCPU = NMin;
AddInstTable(InstTable, Name, InstrZ++, DecodeFixed);
}
static void AddPar(const char *Name, ParTyp Typ, LongWord Code)
{
order_array_rsv_end(ParOrders, ParOrder);
ParOrders[InstrZ].Typ = Typ;
ParOrders[InstrZ].Code = Code;
AddInstTable(InstTable, Name, InstrZ++, DecodePar);
}
static void AddMix(const char *pName, Word Code, InstProc Proc, unsigned Mask)
{
char TmpName[30];
if (Mask & 1)
{
as_snprintf(TmpName, sizeof(TmpName), "%sSS", pName);
AddInstTable(InstTable, TmpName, Code + 0x0000, Proc);
}
if (Mask & 2)
{
as_snprintf(TmpName, sizeof(TmpName), "%sSU", pName);
AddInstTable(InstTable, TmpName, Code + 0x0100, Proc);
}
if (Mask & 4)
{
as_snprintf(TmpName, sizeof(TmpName), "%sUU", pName);
AddInstTable(InstTable, TmpName, Code + 0x0140, Proc);
}
}
static void AddCondition(const char *pName, InstProc Proc)
{
unsigned z;
char TmpName[30];
Word Code;
for (z = 0; z < CondCount; z++)
{
as_snprintf(TmpName, sizeof(TmpName), "%s%s", pName, CondNames[z]);
Code = (z == CondCount - 1) ? 8 : z & 15;
AddInstTable(InstTable, TmpName, Code, Proc);
}
}
static void InitFields(void)
{
InstTable = CreateInstTable(307);
SetDynamicInstTable(InstTable);
AddInstTable(InstTable, "DIV", 0, DecodeDIV);
AddInstTable(InstTable, "INC", 0x0008, DecodeINC_DEC);
AddInstTable(InstTable, "DEC", 0x000a, DecodeINC_DEC);
AddInstTable(InstTable, "ANDI", 0x00b8, DecodeANDI_ORI);
AddInstTable(InstTable, "ORI", 0x00f8, DecodeANDI_ORI);
AddInstTable(InstTable, "NORM", 0, DecodeNORM);
AddInstTable(InstTable, "NORMF", 0, DecodeNORMF);
AddInstTable(InstTable, "EXTRACT", 0, DecodeEXTRACT_EXTRACTU);
AddInstTable(InstTable, "EXTRACTU", 128, DecodeEXTRACT_EXTRACTU);
AddInstTable(InstTable, "INSERT", 0, DecodeINSERT);
AddInstTable(InstTable, "MERGE", 0, DecodeMERGE);
AddInstTable(InstTable, "CLB", 0, DecodeCLB);
AddInstTable(InstTable, "CMPU", 0, DecodeCMPU);
AddInstTable(InstTable, "MOVE", 0, DecodePlainMOVE);
AddInstTable(InstTable, "MOVEC", 0, DecodeMOVEC);
AddInstTable(InstTable, "MOVEM", 0, DecodeMOVEM);
AddInstTable(InstTable, "MOVEP", 0, DecodeMOVEP);
AddInstTable(InstTable, "TFR", 0, DecodePlainTFR);
AddInstTable(InstTable, "BRA", 0x40, DecodeBRA_BSR);
AddInstTable(InstTable, "BSR", 0x00, DecodeBRA_BSR);
AddInstTable(InstTable, "LUA", 0, DecodeLUA_LEA);
AddInstTable(InstTable, "LEA", 0, DecodeLUA_LEA);
AddInstTable(InstTable, "LRA", 0, DecodeLRA);
AddInstTable(InstTable, "PLOCK", 0, DecodePLOCK);
AddInstTable(InstTable, "PLOCKR", 0x00000e, DecodePLOCKR_PUNLOCKR);
AddInstTable(InstTable, "PUNLOCKR", 0x00000f, DecodePLOCKR_PUNLOCKR);
AddInstTable(InstTable, "JMP", 0, DecodeJMP_JSR);
AddInstTable(InstTable, "JSR", 1, DecodeJMP_JSR);
AddInstTable(InstTable, "DO", 0, DecodeDO_DOR);
AddInstTable(InstTable, "DOR", 1, DecodeDO_DOR);
AddInstTable(InstTable, "REP", 0, DecodeREP);
InstrZ = 0;
AddFixed("NOP" , 0x000000, CPU56000);
AddFixed("ENDDO" , 0x00008c, CPU56000);
AddFixed("ILLEGAL", 0x000005, CPU56000);
AddFixed("RESET" , 0x000084, CPU56000);
AddFixed("RTI" , 0x000004, CPU56000);
AddFixed("RTS" , 0x00000c, CPU56000);
AddFixed("STOP" , 0x000087, CPU56000);
AddFixed("SWI" , 0x000006, CPU56000);
AddFixed("WAIT" , 0x000086, CPU56000);
AddFixed("DEBUG" , 0x000200, CPU56300);
AddFixed("PFLUSH" , 0x000003, CPU56300);
AddFixed("PFLUSHUN",0x000001, CPU56300);
AddFixed("PFREE" , 0x000002, CPU56300);
AddFixed("TRAP" , 0x000006, CPU56300);
InstrZ = 0;
AddPar("ABS" , ParAB, 0x26);
AddPar("ASL" , ParABShl1, 0x32);
AddPar("ASR" , ParABShl1, 0x22);
AddPar("CLR" , ParAB, 0x13);
AddPar("LSL" , ParABShl2, 0x33);
AddPar("LSR" , ParABShl2, 0x23);
AddPar("NEG" , ParAB, 0x36);
AddPar("NOT" , ParAB, 0x17);
AddPar("RND" , ParAB, 0x11);
AddPar("ROL" , ParAB, 0x37);
AddPar("ROR" , ParAB, 0x27);
AddPar("TST" , ParAB, 0x03);
AddPar("ADC" , ParXYAB, 0x21);
AddPar("SBC" , ParXYAB, 0x25);
AddPar("ADD" , ParABXYnAB,0x00);
AddPar("CMP" , ParABXYnAB,0x05);
AddPar("CMPM", ParABXYnAB,0x07);
AddPar("SUB" , ParABXYnAB,0x04);
AddPar("ADDL", ParABBA, 0x12);
AddPar("ADDR", ParABBA, 0x02);
AddPar("SUBL", ParABBA, 0x16);
AddPar("SUBR", ParABBA, 0x06);
AddPar("AND" , ParXYnAB, 0x46);
AddPar("EOR" , ParXYnAB, 0x43);
AddPar("OR" , ParXYnAB, 0x42);
AddPar("MAC" , ParMul, 0x82);
AddPar("MACR", ParMul, 0x83);
AddPar("MPY" , ParMul, 0x80);
AddPar("MPYR", ParMul, 0x81);
AddPar("MAX" , ParFixAB, 0x1d);
AddPar("MAXM", ParFixAB, 0x15);
InstrZ = 0;
AddInstTable(InstTable, "MPYI", InstrZ++, DecodeImmMac);
AddInstTable(InstTable, "MPYRI", InstrZ++, DecodeImmMac);
AddInstTable(InstTable, "MACI", InstrZ++, DecodeImmMac);
AddInstTable(InstTable, "MACRI", InstrZ++, DecodeImmMac);
InstrZ = 0;
AddInstTable(InstTable, "BCLR", InstrZ++, DecodeBit);
AddInstTable(InstTable, "BSET", InstrZ++, DecodeBit);
AddInstTable(InstTable, "BCHG", InstrZ++, DecodeBit);
AddInstTable(InstTable, "BTST", InstrZ++, DecodeBit);
InstrZ = 0;
AddInstTable(InstTable, "BRCLR", InstrZ++, DecodeBitBr);
AddInstTable(InstTable, "BRSET", InstrZ++, DecodeBitBr);
AddInstTable(InstTable, "BSCLR", InstrZ++, DecodeBitBr);
AddInstTable(InstTable, "BSSET", InstrZ++, DecodeBitBr);
InstrZ = 0;
AddInstTable(InstTable, "JCLR", InstrZ++, DecodeBitJmp);
AddInstTable(InstTable, "JSET", InstrZ++, DecodeBitJmp);
AddInstTable(InstTable, "JSCLR", InstrZ++, DecodeBitJmp);
AddInstTable(InstTable, "JSSET", InstrZ++, DecodeBitJmp);
AddMix("DMAC", 0, DecodeDMAC, 7);
AddMix("MAC", 0xff00, DecodeMAC_MPY, 6);
AddMix("MPY", 0, DecodeMAC_MPY, 6);
AddCondition("T", DecodeTcc);
AddCondition("B", DecodeBcc);
AddCondition("BS", DecodeBScc);
AddCondition("J", DecodeJcc);
AddCondition("JS", DecodeJScc);
AddCondition("BRK", DecodeBRKcc);
AddCondition("TRAP", DecodeTRAPcc);
AddCondition("DEBUG", DecodeDEBUGcc);
AddInstTable(InstTable, "XSFR", SegXData, DecodeSFR);
AddInstTable(InstTable, "YSFR", SegYData, DecodeSFR);
AddInstTable(InstTable, "DS", 0, DecodeDS);
AddInstTable(InstTable, "DC", 0, DecodeDC);
StrCompAlloc(&LeftComp, STRINGSIZE);
StrCompAlloc(&MidComp, STRINGSIZE);
StrCompAlloc(&RightComp, STRINGSIZE);
StrCompAlloc(&Left1Comp, STRINGSIZE);
StrCompAlloc(&Left2Comp, STRINGSIZE);
StrCompAlloc(&Right1Comp, STRINGSIZE);
StrCompAlloc(&Right2Comp, STRINGSIZE);
}
static void DeinitFields(void)
{
DestroyInstTable(InstTable);
order_array_free(FixedOrders);
order_array_free(ParOrders);
StrCompFree(&LeftComp);
StrCompFree(&MidComp);
StrCompFree(&RightComp);
StrCompFree(&Left1Comp);
StrCompFree(&Left2Comp);
StrCompFree(&Right1Comp);
StrCompFree(&Right2Comp);
}
static void MakeCode_56K(void)
{
CodeLen = 0;
DontPrint = False;
/* zu ignorierendes */
if (Memo(""))
return;
if (!LookupInstTable(InstTable, OpPart.str.p_str))
WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}
static Boolean IsDef_56K(void)
{
return ((Memo("XSFR")) || (Memo("YSFR")));
}
static void SwitchFrom_56K(void)
{
DeinitFields();
}
static void SwitchTo_56K(void)
{
TurnWords = True;
SetIntConstMode(eIntConstModeMoto);
PCSymbol = "*";
HeaderID = 0x09;
NOPCode = 0x000000;
DivideChars = " \t";
HasAttrs = False;
if (MomCPU == CPU56300)
{
AdrInt = UInt24;
MemLimit = 0xffffffl;
}
else
{
AdrInt = UInt16;
MemLimit = 0xffff;
}
ValidSegs = (1 << SegCode) | (1 << SegXData) | (1 << SegYData);
Grans[SegCode ] = 4; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
SegLimits[SegCode ] = MemLimit;
Grans[SegXData] = 4; ListGrans[SegXData] = 4; SegInits[SegXData] = 0;
SegLimits[SegXData] = MemLimit;
Grans[SegYData] = 4; ListGrans[SegYData] = 4; SegInits[SegYData] = 0;
SegLimits[SegYData] = MemLimit;
onoff_packing_add(True);
MakeCode = MakeCode_56K;
IsDef = IsDef_56K;
SwitchFrom = SwitchFrom_56K;
InitFields();
}
void code56k_init(void)
{
CPU56000 = AddCPU("56000", SwitchTo_56K);
CPU56002 = AddCPU("56002", SwitchTo_56K);
CPU56300 = AddCPU("56300", SwitchTo_56K);
}