/* code62015.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator Sharp SC62015 */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "nls.h"
#include "strutil.h"
#include "chunks.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "onoff_common.h"
#include "asmitree.h"
#include "codevars.h"
#include "codepseudo.h"
#include "headids.h"
#include "errmsg.h"
#include "chartrans.h"
#include "codepseudo.h"
#include "intpseudo.h"
#include "code62015.h"
/*---------------------------------------------------------------------------*/
static CPUVar CPUSC62015
;
/*---------------------------------------------------------------------------*/
#define RegA 0
#define RegIL 1
#define RegBA 2
#define RegI 3
#define RegX 4
#define RegY 5
#define RegU 6
#define RegS 7
#define RegB 8
#define RegIH 9
#define RegPS 10
#define RegPC 11
#define RegF 12
#define RegIMR 13
#define IsR1(reg) ((reg) == RegA || (reg) == RegIL)
#define IsR2(reg) ((reg) == RegBA || (reg) == RegI)
#define IsR3(reg) ((reg) >= RegX && (reg) <= RegS)
#define IsR4(reg) ((reg) >= RegX && (reg) <= RegU)
#define IsWP(index) ((index) == 0 || (index) == 1)
#define IsWPL(index) ((index) == 0 || (index) == 1 || (index) == 2)
typedef struct
{
const char name
[4];
Byte addr
;
} tIntReg
;
static const tIntReg IntRegs
[] =
{
{ "BP" , 0xec },
{ "PX" , 0xed },
{ "PY" , 0xee },
{ "AMC", 0xef },
{ "KOL", 0xf0 },
{ "KOH", 0xf1 },
{ "KI" , 0xf2 },
{ "EOL", 0xf3 },
{ "EOH", 0xf4 },
{ "EIL", 0xf5 },
{ "EIH", 0xf6 },
{ "UCR", 0xf7 },
{ "USR", 0xf8 },
{ "RXD", 0xf9 },
{ "TXD", 0xfa },
{ "IMR", 0xfb },
{ "ISR", 0xfc },
{ "SCR", 0xfd },
{ "LCC", 0xfe },
{ "SSR", 0xff },
};
static Boolean DecodeReg
(const tStrComp
*arg
, Byte
*pReg
)
{
const char rtable
[][4] = { "A", "IL", "BA", "I", "X", "Y", "U", "S", "B", "IH", "PS", "PC", "F", "IMR" };
const char *str
= arg
->str.
p_str;
size_t i
;
for (i
= 0; i
< as_array_size
(rtable
); i
++)
{
if (as_strcasecmp
(str
, rtable
[i
]) == 0)
{
*pReg
= i
;
return True
;
}
}
return False
;
}
static int RegSize
(Byte Reg
)
{
int size
;
switch (Reg
)
{
case RegPS
:
size
= 0;
break;
case 0: /* A */
case 1: /* IL */
case 8: /* B */
case 9: /* IH */
size
= 1;
break;
case 2: /* BA */
case 3: /* I */
case 11: /* PC */
size
= 2;
break;
default:
size
= 3;
}
return size
;
}
static Boolean IsCoreReg
(Byte reg
)
{
return (reg
< 8) ? True
: False
;
}
static Boolean DecodeInternal
(const tStrComp
*pArg
, Byte
*pMode
, Byte
*pDisp
, const char *pPReg
)
{
size_t i
;
String Temp
;
tStrComp temp
;
Byte mode
= 0;
Boolean OK
;
int val
;
int sign
= 1;
tSymbolFlags flags
;
for (i
= 0; i
< as_array_size
(IntRegs
); i
++)
{
if (!as_strcasecmp
(pArg
->str.
p_str, IntRegs
[i
].
name))
{
*pMode
= 0;
*pDisp
= IntRegs
[i
].
addr;
return True
;
}
}
if (!IsIndirect
(pArg
->str.
p_str)) return False
;
#if 0
StrCompRefRight
(&temp
, pArg
, 1); /* strip off left '(' */
#endif
StrCompMkTemp
(&temp
, Temp
, sizeof(Temp
));
StrCompCopy
(&temp
, pArg
);
StrCompCutLeft
(&temp
, 1);
StrCompShorten
(&temp
, 1); /* strip off right ')' */
KillPrefBlanksStrComp
(&temp
);
KillPostBlanksStrComp
(&temp
);
if (!as_strncasecmp
(temp.
str.
p_str, "BP", 2))
{
mode
= 1;
}
else if (!as_strncasecmp
(temp.
str.
p_str, pPReg
, 2))
{
mode
= 2;
}
else
{
val
= EvalStrIntExpression
(&temp
, UInt8
, &OK
);
if (OK
)
{
*pMode
= 0;
*pDisp
= val
;
return OK
;
}
return False
;
}
StrCompCutLeft
(&temp
, 2);
KillPrefBlanksStrComp
(&temp
);
if (temp.
Pos.
Len == 0)
{
/* Displacement omitted */
*pMode
= mode
;
*pDisp
= 0;
return True
;
}
if (temp.
str.
p_str[0] == '+')
{
sign
= 1;
StrCompCutLeft
(&temp
, 1);
}
else if (temp.
str.
p_str[0] == '-')
{
sign
= -1;
StrCompCutLeft
(&temp
, 1);
}
KillPrefBlanksStrComp
(&temp
);
if (mode
== 1 && !as_strcasecmp
(temp.
str.
p_str, pPReg
))
{
*pMode
= 3;
*pDisp
= 0;
return True
;
}
val
= EvalStrIntExpressionWithFlags
(&temp
, UInt8
, &OK
, &flags
) * sign
;
if (OK
)
{
if (!mFirstPassUnknownOrQuestionable
(flags
) && (val
> 127 || val
< -128))
{
WrStrErrorPos
(ErrNum_DistTooBig
, pArg
);
return False
;
}
*pMode
= mode
;
*pDisp
= val
;
return True
;
}
return False
;
}
static void PreByte
(Byte mode1
, Byte mode2
)
{
static const Byte ptable
[] = {
0x32, 0x30, 0x33, 0x31,
0x22, 0x00, 0x23, 0x21,
0x36, 0x34, 0x37, 0x35,
0x26, 0x24, 0x27, 0x25 };
if (mode1
== 1 && mode2
== 1) return;
if (mode1
> 3 || mode2
> 3)
{
WrError
(ErrNum_InternalError
);
return;
}
BAsmCode
[CodeLen
++] = ptable
[mode1
* 4 + mode2
];
}
static Boolean DecodeDirect
(const tStrComp
*pArg
, LongInt
*pAddr
)
{
String Temp
;
tStrComp temp
;
LongInt val
;
Boolean OK
;
if (!IsIndirectGen
(pArg
->str.
p_str, "[]")) return False
;
StrCompMkTemp
(&temp
, Temp
, sizeof(Temp
));
StrCompCopy
(&temp
, pArg
);
StrCompCutLeft
(&temp
, 1);
StrCompShorten
(&temp
, 1);
KillPrefBlanksStrComp
(&temp
);
KillPostBlanksStrComp
(&temp
);
val
= EvalStrIntExpression
(&temp
, UInt20
, &OK
);
if (OK
)
{
*pAddr
= val
;
return OK
;
}
return False
;
}
static Boolean DecodeRegIndirect
(const tStrComp
*pArg
, Byte
*pReg
, Byte
*pMode
)
{
String Temp
;
tStrComp temp
;
Byte reg
;
int l
;
Byte mode
= 0x00;
if (!IsIndirectGen
(pArg
->str.
p_str, "[]")) return False
;
StrCompMkTemp
(&temp
, Temp
, sizeof(Temp
));
StrCompCopy
(&temp
, pArg
);
StrCompCutLeft
(&temp
, 1);
StrCompShorten
(&temp
, 1);
KillPrefBlanksStrComp
(&temp
);
KillPostBlanksStrComp
(&temp
);
l
= strlen(temp.
str.
p_str);
if ((l
>= 2) && !strncmp(temp.
str.
p_str + l
- 2, "++", 2))
{
mode
= 0x20;
StrCompShorten
(&temp
, 2);
}
else if (!strncmp(temp.
str.
p_str, "--", 2))
{
mode
= 0x30;
StrCompCutLeft
(&temp
, 2);
}
if (DecodeReg
(&temp
, ®
))
{
*pReg
= reg
;
*pMode
= mode
;
return True
;
}
return False
;
}
static Boolean DecodeRegBase
(const tStrComp
*pArg
, Byte
*pReg
, Byte
*pMode
, Byte
*pDisp
)
{
String Temp
;
tStrComp temp
;
String Temp2
;
tStrComp temp2
;
int i
;
char ch
;
Byte reg
;
Byte mode
;
Word val
;
Boolean OK
;
if (!IsIndirectGen
(pArg
->str.
p_str, "[]")) return False
;
StrCompMkTemp
(&temp
, Temp
, sizeof(Temp
));
StrCompCopy
(&temp
, pArg
);
StrCompCutLeft
(&temp
, 1);
StrCompShorten
(&temp
, 1);
KillPrefBlanksStrComp
(&temp
);
KillPostBlanksStrComp
(&temp
);
for (i
= 0; temp.
str.
p_str[i
]; i
++)
{
ch
= temp.
str.
p_str[i
];
if (isalpha(ch
)) continue;
if (isspace(ch
) || ch
== '+' || ch
== '-') break;
return False
;
}
if (i
<= 2)
{
StrCompMkTemp
(&temp2
, Temp2
, sizeof(Temp2
));
StrCompCopy
(&temp2
, &temp
);
StrCompShorten
(&temp
, strlen(temp.
str.
p_str) - i
);
StrCompCutLeft
(&temp2
, i
);
KillPrefBlanksStrComp
(&temp2
);
if (!DecodeReg
(&temp
, ®
) || !IsR3
(reg
)) return False
;
if (temp2.
str.
p_str[0] == '+')
{
mode
= 0x80;
}
else if (temp2.
str.
p_str[0] == '-')
{
mode
= 0xc0;
}
else return False
;
StrCompCutLeft
(&temp2
, i
);
KillPrefBlanksStrComp
(&temp2
);
val
= EvalStrIntExpression
(&temp2
, UInt8
, &OK
);
if (!OK
) return False
;
*pReg
= reg
;
*pMode
= mode
;
*pDisp
= val
;
return True
;
}
return False
;
}
static Boolean DecodeImm
(const tStrComp
*pArg
, LongInt
*pVal
, int size
)
{
LongInt val
;
Boolean OK
;
switch (size
)
{
case 1: /* 8 bit */
val
= EvalStrIntExpression
(pArg
, Int8
, &OK
);
break;
case 2: /* 16 bit */
val
= EvalStrIntExpression
(pArg
, Int16
, &OK
);
break;
case 3: /* 20 bit */
val
= EvalStrIntExpression
(pArg
, Int20
, &OK
);
break;
default:
WrError
(ErrNum_InternalError
);
return False
;
}
if (OK
)
{
*pVal
= val
;
return True
;
}
return False
;
}
static Boolean DecodeIntIndirect
(const tStrComp
*pArg
, Byte
*pDir
, Byte
*pDisp2
, Byte
*pMode
, Byte
*pDisp
, const char *pPReg
)
{
String Temp
;
String Temp2
;
tStrComp temp
;
tStrComp temp2
;
char *pEnd
;
int pos
;
Byte dir
;
Byte mode
;
Byte disp
;
Byte disp2
;
Boolean OK
;
if (!IsIndirectGen
(pArg
->str.
p_str, "[]")) return False
;
StrCompMkTemp
(&temp
, Temp
, sizeof(Temp
));
StrCompCopy
(&temp
, pArg
);
StrCompCutLeft
(&temp
, 1);
StrCompShorten
(&temp
, 1);
KillPrefBlanksStrComp
(&temp
);
KillPostBlanksStrComp
(&temp
);
if (temp.
str.
p_str[0] != '(') return False
;
pEnd
= FindClosingParenthese
(temp.
str.
p_str + 1);
pos
= pEnd
- temp.
str.
p_str + 1;
if (!pEnd
) return False
;
StrCompMkTemp
(&temp2
, Temp2
, sizeof(Temp2
));
StrCompCopySub
(&temp2
, &temp
, pos
, strlen(temp.
str.
p_str) - pos
);
StrCompShorten
(&temp
, strlen(temp.
str.
p_str) - pos
);
KillPrefBlanksStrComp
(&temp2
);
if (!DecodeInternal
(&temp
, &mode
, &disp
, pPReg
)) return False
;
dir
= 0x00;
if (strlen(temp2.
str.
p_str) > 0)
{
switch (temp2.
str.
p_str[0])
{
case '+':
dir
= 0x80;
break;
case '-':
dir
= 0xc0;
break;
default:
return False
;
}
StrCompCutLeft
(&temp2
, 1);
disp2
= EvalStrIntExpression
(&temp2
, UInt8
, &OK
);
if (!OK
) return False
;
}
else
disp2
= 0;
*pDir
= dir
;
*pMode
= mode
;
*pDisp2
= disp2
;
*pDisp
= disp
;
return True
;
}
static void AddrOut20
(LongInt addr
)
{
BAsmCode
[CodeLen
++] = addr
;
BAsmCode
[CodeLen
++] = addr
>> 8;
BAsmCode
[CodeLen
++] = addr
>> 16;
}
/*---------------------------------------------------------------------------*/
static void DecodeMV
(Word Index
)
{
int size
= Index
;
int i
;
Byte reg1
;
Byte reg2
;
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
Byte dir
;
Byte mdisp
;
LongInt addr
;
LongInt val
;
if (ChkArgCnt
(2, 2))
{
if (DecodeReg
(&ArgStr
[1], ®1
))
{
if (!size
) size
= RegSize
(reg1
);
if (DecodeReg
(&ArgStr
[2], ®2
))
{
if (size
== 1)
{
if (reg1
== RegA
&& reg2
== RegB
)
{
BAsmCode
[0] = 0x74;
CodeLen
= 1;
return;
}
if (reg1
== RegB
&& reg2
== RegA
)
{
BAsmCode
[0] = 0x75;
CodeLen
= 1;
return;
}
}
if (!Index
&& reg1
< 8 && reg2
< 8 && RegSize
(reg1
) > 1)
{
if (RegSize
(reg1
) != RegSize
(reg2
))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]); /* Register size conflict */
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = (reg1
<< 4) | reg2
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = 0x80 | reg1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (reg1
!= RegS
&& DecodeRegIndirect
(&ArgStr
[2], ®2
, &mode2
))
{
BAsmCode
[0] = 0x90 | reg1
;
BAsmCode
[1] = mode2
| reg2
;
CodeLen
= 2;
return;
}
if (DecodeRegBase
(&ArgStr
[2], ®2
, &mode2
, &disp2
))
{
BAsmCode
[0] = 0x90 | reg1
;
BAsmCode
[1] = mode2
| reg2
;
BAsmCode
[2] = disp2
;
CodeLen
= 3;
return;
}
if (DecodeIntIndirect
(&ArgStr
[2], &dir
, &mdisp
, &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = 0x98 | reg1
;
BAsmCode
[CodeLen
++] = dir
;
BAsmCode
[CodeLen
++] = disp2
;
if (dir
) BAsmCode
[CodeLen
++] = mdisp
;
return;
}
if (DecodeDirect
(&ArgStr
[2], &addr
))
{
BAsmCode
[CodeLen
++] = 0x88 | reg1
;
AddrOut20
(addr
);
return;
}
if (DecodeImm
(&ArgStr
[2], &val
, size
))
{
BAsmCode
[CodeLen
++] = 0x08 | reg1
;
for (i
= 0; i
< size
; i
++)
{
BAsmCode
[CodeLen
++] = val
>> (i
* 8);
}
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®2
) && IsCoreReg
(reg2
))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xa0 | reg2
;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xc8;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (DecodeRegIndirect
(&ArgStr
[2], ®2
, &mode2
))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xe0;
BAsmCode
[CodeLen
++] = mode2
| reg2
;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
if (DecodeRegBase
(&ArgStr
[2], ®2
, &mode2
, &disp2
))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xe0;
BAsmCode
[CodeLen
++] = mode2
| reg2
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (DecodeIntIndirect
(&ArgStr
[2], &dir
, &mdisp
, &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xf0;
BAsmCode
[CodeLen
++] = dir
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
if (dir
) BAsmCode
[CodeLen
++] = mdisp
;
return;
}
if (DecodeDirect
(&ArgStr
[2], &addr
))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xd0;
BAsmCode
[CodeLen
++] = disp1
;
AddrOut20
(addr
);
return;
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xcc;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeRegIndirect
(&ArgStr
[1], ®1
, &mode1
))
{
if (DecodeReg
(&ArgStr
[2], ®2
) && reg2
!= RegS
)
{
BAsmCode
[0] = 0xb0 | reg2
;
BAsmCode
[1] = mode1
| reg1
;
CodeLen
= 2;
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = 0xe8;
BAsmCode
[CodeLen
++] = mode1
| reg1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeRegBase
(&ArgStr
[1], ®1
, &mode1
, &disp1
))
{
if (DecodeReg
(&ArgStr
[2], ®2
))
{
BAsmCode
[0] = 0xb0 | reg2
;
BAsmCode
[1] = mode1
| reg1
;
BAsmCode
[2] = disp1
;
CodeLen
= 3;
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = 0xe8;
BAsmCode
[CodeLen
++] = mode1
| reg1
;
BAsmCode
[CodeLen
++] = disp2
;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeIntIndirect
(&ArgStr
[1], &dir
, &mdisp
, &mode1
, &disp1
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®2
))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xb8 | reg2
;
BAsmCode
[CodeLen
++] = dir
;
BAsmCode
[CodeLen
++] = disp1
;
if (dir
) BAsmCode
[CodeLen
++] = mdisp
;
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xf8;
BAsmCode
[CodeLen
++] = dir
;
BAsmCode
[CodeLen
++] = disp1
;
if (dir
) BAsmCode
[CodeLen
++] = mdisp
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeDirect
(&ArgStr
[1], &addr
))
{
if (DecodeReg
(&ArgStr
[2], ®2
) && IsCoreReg
(reg2
))
{
BAsmCode
[CodeLen
++] = 0xa8 | reg2
;
AddrOut20
(addr
);
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = 0xd8;
AddrOut20
(addr
);
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
return;
}
}
static void DecodeMVW
(Word Index
)
{
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
Byte reg
;
Byte dir
;
Byte mdisp
;
LongInt val
;
LongInt addr
;
int i
;
if (ChkArgCnt
(2, 2))
{
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = (Index
== 3) ? 0xcf : 0xc9 + Index
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (IsWPL
(Index
) && DecodeRegIndirect
(&ArgStr
[2], ®
, &mode2
))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xe1 + Index
;
BAsmCode
[CodeLen
++] = mode2
| reg
;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
if (IsWPL
(Index
) && DecodeRegBase
(&ArgStr
[2], ®
, &mode2
, &disp2
))
{
const Byte optab
[] = { 0xe1, 0xe2, 0x56, 0x00 };
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = optab
[Index
];
BAsmCode
[CodeLen
++] = mode2
| reg
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (IsWPL
(Index
) && DecodeIntIndirect
(&ArgStr
[2], &dir
, &mdisp
, &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xf1 + Index
;
BAsmCode
[CodeLen
++] = dir
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
if (dir
) BAsmCode
[CodeLen
++] = mdisp
;
return;
}
if (IsWPL
(Index
) && DecodeDirect
(&ArgStr
[2], &addr
))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xd1 + Index
;
BAsmCode
[CodeLen
++] = disp1
;
AddrOut20
(addr
);
return;
}
if (IsWP
(Index
) && DecodeImm
(&ArgStr
[2], &val
, Index
+ 2))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = (Index
== 0) ? 0xcd : 0xdc;
BAsmCode
[CodeLen
++] = disp1
;
for (i
= 0; i
< Index
+ 2; i
++)
{
BAsmCode
[CodeLen
++] = val
>> (i
* 8);
}
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeRegIndirect
(&ArgStr
[1], ®
, &mode1
))
{
if (IsWPL
(Index
) && DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = 0xe9 + Index
;
BAsmCode
[CodeLen
++] = mode1
| reg
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeRegBase
(&ArgStr
[1], ®
, &mode1
, &disp1
))
{
if (IsWPL
(Index
) && DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
const Byte optab
[] = { 0xe9, 0xea, 0x5e, 0x00 };
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = optab
[Index
];
BAsmCode
[CodeLen
++] = mode1
| reg
;
BAsmCode
[CodeLen
++] = disp2
;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeIntIndirect
(&ArgStr
[1], &dir
, &mdisp
, &mode1
, &disp1
, "PX"))
{
if (IsWPL
(Index
) && DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xf9 + Index
;
BAsmCode
[CodeLen
++] = dir
;
BAsmCode
[CodeLen
++] = disp1
;
if (dir
) BAsmCode
[CodeLen
++] = mdisp
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeDirect
(&ArgStr
[1], &addr
))
{
if (IsWPL
(Index
) && DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = 0xd9 + Index
;
AddrOut20
(addr
);
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
return;
}
}
static void DecodeEX
(Word Index
)
{
Byte reg1
;
Byte reg2
;
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
if (DecodeReg
(&ArgStr
[1], ®1
))
{
if (DecodeReg
(&ArgStr
[2], ®2
))
{
if (RegSize
(reg1
) != RegSize
(reg2
))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]); /* Register size conflict */
return;
}
if (RegSize
(reg1
) == 1)
{
if (reg1
!= RegA
|| reg2
!= RegB
)
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]); /* Register size conflict */
return;
}
BAsmCode
[0] = 0xdd;
CodeLen
=1;
return;
}
else
{
if ((IsR2
(reg1
) && IsR2
(reg2
)) || (IsR3
(reg1
) && IsR3
(reg2
)))
{
BAsmCode
[0] = 0xed;
BAsmCode
[1] = (reg1
<< 4) | reg2
;
CodeLen
= 2;
return;
}
}
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xc0;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
}
static void DecodeEXW
(Word Index
)
{
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
if (ChkArgCnt
(2, 2))
{
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = Index
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
return;
}
}
static void DecodeSWAP
(Word Index
)
{
Byte reg
;
if (ChkArgCnt
(1, 1))
{
if (DecodeReg
(&ArgStr
[1], ®
))
{
if (reg
== RegA
)
{
BAsmCode
[0] = Index
;
CodeLen
= 1;
return;
}
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
return;
}
}
static void DecodeADD
(Word Index
)
{
Byte reg1
;
Byte reg2
;
Byte mode
;
Byte disp
;
LongInt val
;
if (ChkArgCnt
(2, 2))
{
if (DecodeReg
(&ArgStr
[1], ®1
))
{
if (DecodeReg
(&ArgStr
[2], ®2
))
{
if (IsR1
(reg1
) && IsR1
(reg2
))
{
BAsmCode
[0] = Index
| 0x06;
}
else if (IsR2
(reg1
) && (IsR1
(reg2
) || IsR2
(reg2
)))
{
BAsmCode
[0] = Index
| 0x04;
}
else if (IsR3
(reg1
) && (IsR1
(reg2
) || IsR2
(reg2
) || IsR3
(reg2
)))
{
BAsmCode
[0] = Index
| 0x05;
}
else
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
BAsmCode
[1] = (reg1
<< 4) | reg2
;
CodeLen
= 2;
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode
, &disp
, "PX"))
{
if (reg1
== RegA
)
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x02;
BAsmCode
[CodeLen
++] = disp
;
return;
}
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
if (reg1
== RegA
)
{
BAsmCode
[0] = Index
;
BAsmCode
[1] = val
;
CodeLen
= 2;
return;
}
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®2
))
{
if (reg2
== RegA
)
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x03;
BAsmCode
[CodeLen
++] = disp
;
return;
}
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x01;
BAsmCode
[CodeLen
++] = disp
;
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeADC
(Word Index
)
{
Byte reg
;
LongInt val
;
Byte mode
;
Byte disp
;
if (ChkArgCnt
(2, 2))
{
if (DecodeReg
(&ArgStr
[1], ®
))
{
if (DecodeInternal
(&ArgStr
[2], &mode
, &disp
, "PX"))
{
if (reg
== RegA
)
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x02;
BAsmCode
[CodeLen
++] = disp
;
return;
}
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
if (reg
== RegA
)
{
BAsmCode
[0] = Index
;
BAsmCode
[1] = val
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®
))
{
if (reg
== RegA
)
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x03;
BAsmCode
[CodeLen
++] = disp
;
return;
}
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x01;
BAsmCode
[CodeLen
++] = disp
;
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeADCL
(Word Index
)
{
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
Byte reg
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®
))
{
if (reg
== RegA
)
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x01;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = Index
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodePMDF
(Word Index
)
{
Byte mode
;
Byte disp
;
Byte reg
;
LongInt val
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®
))
{
if (reg
== RegA
)
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = 0x57;
BAsmCode
[CodeLen
++] = disp
;
return;
}
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = 0x47;
BAsmCode
[CodeLen
++] = disp
;
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeAND
(Word Index
)
{
Byte reg
;
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
LongInt addr
;
LongInt val
;
if (ChkArgCnt
(2, 2))
{
if (DecodeReg
(&ArgStr
[1], ®
) && reg
== RegA
)
{
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PX"))
{
PreByte
(mode2
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x07;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
BAsmCode
[0] = Index
;
BAsmCode
[1] = val
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®
) && reg
== RegA
)
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x03;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = Index
| 0x06;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x01;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeDirect
(&ArgStr
[1], &addr
))
{
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
BAsmCode
[CodeLen
++] = Index
| 0x02;
AddrOut20
(addr
);
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeINC
(Word Index
)
{
Byte reg
;
Byte mode
;
Byte disp
;
if (ChkArgCnt
(1, 1))
{
if (DecodeReg
(&ArgStr
[1], ®
) && IsCoreReg
(reg
))
{
BAsmCode
[0] = Index
;
BAsmCode
[1] = reg
;
CodeLen
= 2;
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PX"))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x01;
BAsmCode
[CodeLen
++] = disp
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeROR
(Word Index
)
{
Byte reg
;
Byte mode
;
Byte disp
;
if (ChkArgCnt
(1, 1))
{
if (DecodeReg
(&ArgStr
[1], ®
) && reg
== RegA
)
{
BAsmCode
[0] = Index
;
CodeLen
= 1;
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PX"))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
| 0x01;
BAsmCode
[CodeLen
++] = disp
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeDSRL
(Word Index
)
{
Byte mode
;
Byte disp
;
UNUSED
(Index
);
if (ChkArgCnt
(1, 1))
{
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PX"))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = Index
;
BAsmCode
[CodeLen
++] = disp
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeCMP
(Word Index
)
{
Byte reg
;
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
LongInt val
;
LongInt addr
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
if (DecodeReg
(&ArgStr
[1], ®
) && reg
== RegA
)
{
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
BAsmCode
[0] = 0x60;
BAsmCode
[1] = val
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®
) && reg
== RegA
)
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0x63;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xb7;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0x61;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeDirect
(&ArgStr
[1], &addr
))
{
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
BAsmCode
[CodeLen
++] = 0x62;
AddrOut20
(addr
);
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeCMPW
(Word Index
)
{
Byte reg
;
Byte mode1
;
Byte mode2
;
Byte disp1
;
Byte disp2
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
if (DecodeInternal
(&ArgStr
[1], &mode1
, &disp1
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®
))
{
if (IsCoreReg
(reg
) && RegSize
(reg
) == Index
)
{
PreByte
(mode1
, 1);
BAsmCode
[CodeLen
++] = 0xd4 | Index
;
BAsmCode
[CodeLen
++] = reg
;
BAsmCode
[CodeLen
++] = disp1
;
return;
}
}
if (DecodeInternal
(&ArgStr
[2], &mode2
, &disp2
, "PY"))
{
PreByte
(mode1
, mode2
);
BAsmCode
[CodeLen
++] = 0xc4 | Index
;
BAsmCode
[CodeLen
++] = disp1
;
BAsmCode
[CodeLen
++] = disp2
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeTEST
(Word Index
)
{
Byte reg
;
Byte mode
;
Byte disp
;
LongInt val
;
LongInt addr
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2))
{
if (DecodeReg
(&ArgStr
[1], ®
) && reg
== RegA
)
{
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
BAsmCode
[0] = 0x64;
BAsmCode
[1] = val
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeDirect
(&ArgStr
[1], &addr
))
{
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
BAsmCode
[CodeLen
++] = 0x66;
AddrOut20
(addr
);
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PX"))
{
if (DecodeReg
(&ArgStr
[2], ®
) && reg
== RegA
)
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = 0x67;
BAsmCode
[CodeLen
++] = disp
;
return;
}
if (DecodeImm
(&ArgStr
[2], &val
, 1))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = 0x65;
BAsmCode
[CodeLen
++] = disp
;
BAsmCode
[CodeLen
++] = val
;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeJP
(Word Index
)
{
const Byte OP
= Index
& 0xff;
const int alen
= (Index
& 0x0100) ? 3 : 2;
int i
;
Boolean ValOK
;
tSymbolFlags flags
;
LongInt addr
;
Byte mode
;
Byte disp
;
Byte reg
;
if (ChkArgCnt
(1, 1))
{
if (Index
& 0x0200)
{
if (DecodeReg
(&ArgStr
[1], ®
) && IsR3
(reg
))
{
BAsmCode
[0] = 0x11;
BAsmCode
[1] = reg
;
CodeLen
= 2;
return;
}
if (DecodeInternal
(&ArgStr
[1], &mode
, &disp
, "PY"))
{
PreByte
(mode
, 1);
BAsmCode
[CodeLen
++] = 0x10;
BAsmCode
[CodeLen
++] = disp
;
return;
}
}
addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], Int20
, &ValOK
, &flags
);
if (ValOK
)
{
if (!(Index
& 0x100) &&
!mFirstPassUnknownOrQuestionable
(flags
) &&
(addr
& 0xf0000) != (EProgCounter
() & 0xf0000))
{
WrStrErrorPos
(ErrNum_TargOnDiffPage
, &ArgStr
[1]);
return;
}
BAsmCode
[CodeLen
++] = OP
;
for (i
= 0; i
< alen
; i
++)
{
BAsmCode
[CodeLen
++] = addr
>> (i
* 8);
}
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodeJR
(Word Index
)
{
Byte OpCode
= Index
;
LongInt addr
;
int disp
;
Boolean ValOK
;
tSymbolFlags flags
;
if (ChkArgCnt
(1, 1))
{
addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], Int20
, &ValOK
, &flags
);
if (!mFirstPassUnknownOrQuestionable
(flags
) &&
(addr
& 0xf0000) != (EProgCounter
() & 0xf0000))
{
WrStrErrorPos
(ErrNum_TargOnDiffPage
, &ArgStr
[1]);
return;
}
disp
= addr
- (EProgCounter
() + 2);
if (!mFirstPassUnknownOrQuestionable
(flags
))
{
if (disp
< -255 || disp
> 255)
{
WrStrErrorPos
(ErrNum_JmpDistTooBig
, &ArgStr
[1]);
return;
}
if (disp
< 0)
{
OpCode
|= 0x01;
disp
= -disp
;
}
}
BAsmCode
[0] = OpCode
;
BAsmCode
[1] = disp
;
CodeLen
= 2;
}
}
static void DecodeFixed
(Word Index
)
{
if (ChkArgCnt
(0, 0))
{
BAsmCode
[0] = Index
;
CodeLen
= 1;
}
}
static void DecodePUSHS
(Word Index
)
{
Byte reg
;
if (ChkArgCnt
(1, 1))
{
if (DecodeReg
(&ArgStr
[1], ®
))
{
if (IsR1
(reg
) || IsR2
(reg
) || reg
== RegX
|| reg
== RegY
)
{
BAsmCode
[0] = (Index
? 0x90 : 0xb0) | reg
;
BAsmCode
[1] = 0x37;
CodeLen
= 2;
return;
}
if (reg
== RegF
)
{
BAsmCode
[0] = Index
? 0x5f : 0x4f;
CodeLen
= 1;
return;
}
if (reg
== RegIMR
)
{
BAsmCode
[0] = 0x30;
BAsmCode
[1] = Index
? 0xe0 : 0xe8;
BAsmCode
[2] = Index
? 0x27 : 0x37;
BAsmCode
[3] = 0xfb;
CodeLen
= 4;
return;
}
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
static void DecodePUSHU
(Word Index
)
{
const Byte OpBase
= Index
? 0x38 : 0x28;
Byte reg
;
if (ChkArgCnt
(1, 1))
{
if (DecodeReg
(&ArgStr
[1], ®
))
{
if (IsR1
(reg
) || IsR2
(reg
) || reg
== RegX
|| reg
== RegY
)
{
BAsmCode
[0] = OpBase
| reg
;
CodeLen
= 1;
return;
}
if (reg
== RegF
)
{
BAsmCode
[0] = OpBase
| 0x06;
CodeLen
= 1;
return;
}
if (reg
== RegIMR
)
{
BAsmCode
[0] = OpBase
| 0x07;
CodeLen
= 1;
return;
}
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
}
/*---------------------------------------------------------------------------*/
static void AddMVW
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVW
);
}
static void AddEXW
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeEXW
);
}
static void AddADD
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeADD
);
}
static void AddADC
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeADC
);
}
static void AddADCL
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeADCL
);
}
static void AddAND
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeAND
);
}
static void AddINC
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeINC
);
}
static void AddROR
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeROR
);
}
static void AddDSRL
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeDSRL
);
}
static void AddCMPW
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeCMPW
);
}
static void AddJP
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeJP
);
}
static void AddJR
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeJR
);
}
static void AddFixed
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeFixed
);
}
static void AddPUSHS
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodePUSHS
);
}
static void AddPUSHU
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodePUSHU
);
}
static void InitFields
(void)
{
InstTable
= CreateInstTable
(64);
/* a. MV */
AddInstTable
(InstTable
, "MV", 0, DecodeMV
);
AddMVW
("MVW", 0);
AddMVW
("MVP", 1);
AddMVW
("MVL", 2);
AddMVW
("MVLD", 3);
/* b. EX/SWAP */
AddInstTable
(InstTable
, "EX", 0, DecodeEX
);
AddEXW
("EXW", 0xc1);
AddEXW
("EXP", 0xc2);
AddEXW
("EXL", 0xc3);
AddInstTable
(InstTable
, "SWAP", 0xee, DecodeSWAP
);
/* c. ADD/ADC/SUB/SBC/DADL/DSBL/PMDF */
AddADD
("ADD", 0x40);
AddADC
("ADC", 0x50);
AddADD
("SUB", 0x48);
AddADC
("SBC", 0x58);
AddADCL
("ADCL", 0x54);
AddADCL
("SBCL", 0x5c);
AddADCL
("DADL", 0xc4);
AddADCL
("DSBL", 0xd4);
AddInstTable
(InstTable
, "PMDF", 0, DecodePMDF
);
/* d. AND/OR/XOR */
AddAND
("AND", 0x70);
AddAND
("OR", 0x78);
AddAND
("XOR", 0x68);
/* e. INC/DEC */
AddINC
("INC", 0x6c);
AddINC
("DEC", 0x7c);
/* f. ROR */
AddROR
("ROR", 0xe4);
AddROR
("ROL", 0xe6);
AddROR
("SHR", 0xf4);
AddROR
("SHL", 0xf6);
AddDSRL
("DSRL", 0xfc);
AddDSRL
("DSLL", 0xec);
/* g. CMP/TEST */
AddInstTable
(InstTable
, "CMP", 0, DecodeCMP
);
AddCMPW
("CMPW", 2);
AddCMPW
("CMPP", 3);
AddInstTable
(InstTable
, "TEST", 0, DecodeTEST
);
/* h. JP/JPF/JR/CALL */
AddJP
("JP", 0x02 | 0x0200);
AddJP
("JPF", 0x03 | 0x0100);
AddJR
("JR", 0x12);
AddJP
("JPZ", 0x14);
AddJP
("JPNZ", 0x15);
AddJP
("JPC", 0x16);
AddJP
("JPNC", 0x17);
AddJR
("JRZ", 0x18);
AddJR
("JRNZ", 0x1a);
AddJR
("JRC", 0x1c);
AddJR
("JRNC", 0x1e);
/* i. CALL/CALLF/RET */
AddJP
("CALL", 0x04);
AddJP
("CALLF", 0x05 | 0x0100);
AddFixed
("RET", 0x06);
AddFixed
("RETF", 0x07);
/* j. PUSH/POP */
AddPUSHS
("PUSHS", 0);
AddPUSHU
("PUSHU", 0);
AddPUSHS
("POPS", 1);
AddPUSHU
("POPU", 1);
/* k. Other */
AddFixed
("NOP", 0x00);
AddFixed
("WAIT", 0xef);
AddFixed
("SC", 0x97);
AddFixed
("RC", 0x9f);
AddFixed
("RETI", 0x01);
AddFixed
("HALT", 0xde);
AddFixed
("OFF", 0xdf);
AddFixed
("TCL", 0xce);
AddFixed
("IR", 0xfe);
AddFixed
("RESET", 0xff);
}
static void DeinitFields
(void)
{
DestroyInstTable
(InstTable
);
}
/*---------------------------------------------------------------------------*/
static void MakeCode_SC62015
(void)
{
CodeLen
= 0;
DontPrint
= False
;
if (Memo
("")) return;
if (DecodeIntelPseudo
(False
)) return;
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
if ((EProgCounter
() & 0xf0000) != ((EProgCounter
() + CodeLen
) & 0xf0000))
WrError
(ErrNum_PageCrossing
);
}
static Boolean IsDef_SC62015
(void)
{
return False
;
}
static void SwitchFrom_SC62015
(void)
{
DeinitFields
();
}
static void SwitchTo_SC62015
(void)
{
const TFamilyDescr
*pDescr
;
TurnWords
= False
;
SetIntConstMode
(eIntConstModeIntel
);
pDescr
= FindFamilyByName
("SC62015");
PCSymbol
= "*";
HeaderID
= pDescr
->Id
;
NOPCode
= 0x00; /* NOP */
DivideChars
= ",";
HasAttrs
= False
;
ValidSegs
= (1 << SegCode
) | (1 << SegReg
);
Grans
[SegCode
] = 1;
ListGrans
[SegCode
] = 1;
SegInits
[SegCode
] = 0x00000;
SegLimits
[SegCode
] = 0xfffff;
Grans
[SegReg
] = 1;
ListGrans
[SegReg
] = 1;
SegInits
[SegReg
] = 0x00;
SegLimits
[SegReg
] = 0xff;
MakeCode
= MakeCode_SC62015
;
IsDef
= IsDef_SC62015
;
SwitchFrom
= SwitchFrom_SC62015
;
InitFields
();
}
void code62015_init
(void)
{
CPUSC62015
= AddCPU
("SC62015", SwitchTo_SC62015
);
}