Blame |
Last modification |
View Log
| Download
| RSS feed
| ?url?
/* code77230.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* Makroassembler AS */
/* */
/* Codegenerator NEC uPD77230 */
/* */
/*****************************************************************************/
/*---------------------------------------------------------------------------*/
/* Includes */
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "strutil.h"
#include "nls.h"
#include "be_le.h"
#include "ieeefloat.h"
#include "bpemu.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmitree.h"
#include "headids.h"
#include "codevars.h"
#include "codepseudo.h"
#include "onoff_common.h"
#include "errmsg.h"
#include "chartrans.h"
#include "code77230.h"
/*---------------------------------------------------------------------------*/
/* Definitionen */
#define CaseCnt 17
typedef struct
{
LongWord Code
;
} FixedOrder
;
typedef struct
{
const char *Name
;
LongWord Code
;
} Register
;
enum
{
InstrLDI
, InstrBranch
,
InstrALU
, InstrMove
,
InstrM0
, InstrM1
, InstrDP0
, InstrDP1
,
InstrEA
, InstrRP
, InstrFC
, InstrLC
,
InstrBASE0
, InstrBASE1
, InstrRPC
,
InstrP2
, InstrP3
, InstrEM
, InstrBM
,
InstrL
, InstrRW
, InstrWT
, InstrNF
, InstrWI
,
InstrFIS
, InstrFD
, InstrSHV
, InstrRPS
, InstrNAL
, InstrCnt
};
static LongWord CaseMasks
[CaseCnt
] =
{
(1l << InstrLDI
),
(1l << InstrBranch
) | (1l << InstrMove
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrM0
) | (1l << InstrM1
) | (1l << InstrDP0
) | (1l << InstrDP1
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrEA
) | (1l << InstrDP0
) | (1l << InstrDP1
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrRP
) | (1l << InstrM0
) | (1l << InstrDP0
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrRP
) | (1l << InstrM1
) | (1l << InstrDP1
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrRP
) | (1l << InstrM0
) | (1l << InstrM1
) | (1l << InstrL
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrBASE0
) | (1l << InstrBASE1
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrRPC
) | (1l << InstrL
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrP3
) | (1l << InstrP2
) | (1l << InstrEM
) | (1l << InstrBM
) | (1l << InstrL
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrRW
) | (1l << InstrL
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrWT
) | (1l << InstrL
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrNF
) | (1l << InstrWI
) | (1l << InstrL
) | (1l << InstrFC
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrFIS
) | (1l << InstrFD
) | (1l << InstrL
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrSHV
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrRPS
),
(1l << InstrALU
) | (1l << InstrMove
) | (1l << InstrNAL
)
};
static CPUVar CPU77230
;
static LongWord InstrMask
;
static Boolean Error
;
static LongWord
*InstrComps
, *InstrDefs
;
static Register
*SrcRegs
, *ALUSrcRegs
, *DestRegs
;
static FixedOrder
*JmpOrders
, *ALU1Orders
, *ALU2Orders
;
/*---------------------------------------------------------------------------*/
/* Hilfsroutinen */
static int DiscCnt
, SplittedArg
;
static char *DiscPtr
;
static Boolean SplitArgs
(int Count
)
{
char *p
, *p1
, *p2
;
SplittedArg
= DiscCnt
= Count
;
if (Count
== 0)
{
if (ArgCnt
> 0)
{
DiscPtr
= ArgStr
[1].
str.
p_str - 1;
SplittedArg
= 1;
}
else
DiscPtr
= NULL
;
return True
;
}
if (!ChkArgCnt
(Count
, ArgCntMax
))
{
Error
= True
;
return False
;
}
for (p
= ArgStr
[SplittedArg
].
str.
p_str; isspace(((usint
)*p
) & 0xff); p
++);
p1
= QuotPos
(p
, ' ');
p2
= QuotPos
(p
, '\t');
DiscPtr
= ((!p1
) || ((p2
) && (p2
< p1
))) ? p2
: p1
;
if (DiscPtr
)
*(DiscPtr
) = '\0';
return True
;
}
static void DiscardArgs
(void)
{
char *p
, *p2
;
int z
;
Boolean Eaten
;
if (DiscPtr
)
{
for (p
= DiscPtr
+ 1; as_isspace
(*p
); p
++)
if (*p
== '\0') break;
for (p2
= p
; !as_isspace
(*p2
); p2
++)
if (*p2
== '\0') break;
Eaten
= (*p2
== '\0');
*p2
= '\0';
strmov
(OpPart.
str.
p_str, p
);
NLS_UpString
(OpPart.
str.
p_str);
if (Eaten
)
{
for (z
= 1; z
< ArgCnt
; z
++)
strmov
(ArgStr
[z
].
str.
p_str, ArgStr
[z
+ 1].
str.
p_str);
ArgCnt
--;
}
else
{
if (p2
)
for (p2
++; as_isspace
(*p2
); p2
++);
strmov
(ArgStr
[SplittedArg
].
str.
p_str, p2
);
}
}
else
*OpPart.
str.
p_str = '\0';
if (DiscCnt
> 0)
{
for (z
= 0; z
<= ArgCnt
- DiscCnt
; z
++)
strmov
(ArgStr
[z
+ 1].
str.
p_str, ArgStr
[z
+ DiscCnt
].
str.
p_str);
ArgCnt
-= DiscCnt
- 1;
}
}
static void AddComp
(int Index
, LongWord Value
)
{
if ((InstrMask
& (1l << Index
)) != 0)
{
WrError
(ErrNum_InvParAddrMode
);
Error
= True
;
}
else
{
InstrMask
|= (1l << Index
);
InstrComps
[Index
] = Value
;
}
}
static Boolean DecodeReg
(char *Asc
, LongWord
*Erg
, Register
*Regs
)
{
int z
;
for (z
= 0; Regs
[z
].
Name; z
++)
if (!as_strcasecmp
(Asc
, Regs
[z
].
Name))
{
*Erg
= Regs
[z
].
Code;
return True
;
}
*Erg
= 0;
return False
;
}
/*---------------------------------------------------------------------------*/
/* Dekoder fuer Routinen */
static void DecodeJmp
(Word Index
)
{
FixedOrder
*Op
= JmpOrders
+ Index
;
int acnt
= Hi
(Op
->Code
);
LongWord Adr
;
if (!SplitArgs
(acnt
))
return;
if (acnt
== 0)
{
Adr
= 0;
Error
= True
;
}
else
Adr
= EvalStrIntExpression
(&ArgStr
[1], UInt13
, &Error
);
Error
= !Error
;
if (!Error
)
AddComp
(InstrBranch
, Lo
(Op
->Code
) + (Adr
<< 5));
DiscardArgs
();
}
static void DecodeMOV
(Word Index
)
{
LongWord DReg
, SReg
;
UNUSED
(Index
);
if (!SplitArgs
(2))
return;
if (!DecodeReg
(ArgStr
[1].
str.
p_str, &DReg
, DestRegs
))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
Error
= True
;
}
else if (!DecodeReg
(ArgStr
[2].
str.
p_str, &SReg
, SrcRegs
))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
Error
= True
;
}
else
AddComp
(InstrMove
, (SReg
<< 5) + DReg
);
DiscardArgs
();
}
static void DecodeLDI
(Word Index
)
{
LongWord DReg
, Src
= 0;
UNUSED
(Index
);
if (!SplitArgs
(2))
return;
if (!DecodeReg
(ArgStr
[1].
str.
p_str, &DReg
, DestRegs
))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
Error
= True
;
}
else
Src
= EvalStrIntExpression
(&ArgStr
[2], Int24
, &Error
);
Error
= !Error
;
if (!Error
)
AddComp
(InstrLDI
, (Src
<< 5) + DReg
);
DiscardArgs
();
}
static void DecodeNOP
(Word Index
)
{
UNUSED
(Index
);
if (!SplitArgs
(0))
return;
AddComp
(InstrALU
, 0);
DiscardArgs
();
}
static void DecodeALU1
(Word Index
)
{
FixedOrder
*Op
= ALU1Orders
+ Index
;
LongWord DReg
;
if (!SplitArgs
(1))
return;
if ((!DecodeReg
(ArgStr
[1].
str.
p_str, &DReg
, DestRegs
))
|| (DReg
< 16) || (DReg
> 23))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
Error
= True
;
}
else
AddComp
(InstrALU
, (Op
->Code
<< 17) + (DReg
& 7));
DiscardArgs
();
}
static void DecodeALU2
(Word Index
)
{
FixedOrder
*Op
= ALU2Orders
+ Index
;
LongWord DReg
, SReg
;
if (!SplitArgs
(2)) return;
if ((!DecodeReg
(ArgStr
[1].
str.
p_str, &DReg
, DestRegs
))
|| (DReg
< 16) || (DReg
> 23))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]);
Error
= True
;
}
else if (!DecodeReg
(ArgStr
[2].
str.
p_str, &SReg
, ALUSrcRegs
))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2]);
Error
= True
;
}
else
AddComp
(InstrALU
, (Op
->Code
<< 17) + (SReg
<< 3) + (DReg
& 7));
DiscardArgs
();
}
static void DecodeM0
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrM0
, Index
);
DiscardArgs
();
}
static void DecodeM1
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrM1
, Index
);
DiscardArgs
();
}
static void DecodeDP0
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrDP0
, Index
);
DiscardArgs
();
}
static void DecodeDP1
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrDP1
, Index
);
DiscardArgs
();
}
static void DecodeEA
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrEA
, Index
);
DiscardArgs
();
}
static void DecodeFC
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrFC
, Index
);
DiscardArgs
();
}
static void DecodeRP
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrRP
, Index
);
DiscardArgs
();
}
static void DecodeL
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrL
, Index
);
DiscardArgs
();
}
static void DecodeBASE
(Word Index
)
{
LongWord Value
;
if (!SplitArgs
(1))
return;
Value
= EvalStrIntExpression
(&ArgStr
[1], UInt3
, &Error
);
Error
= !Error
;
if (!Error
)
AddComp
(Index
, Value
);
DiscardArgs
();
}
static void DecodeRPC
(Word Index
)
{
LongWord Value
;
tSymbolFlags Flags
;
UNUSED
(Index
);
if (!SplitArgs
(1))
return;
Value
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt4
, &Error
, &Flags
);
if (mFirstPassUnknown
(Flags
))
Value
&= 7;
Error
= (Value
> 9) ? True
: !Error
;
if (!Error
)
AddComp
(InstrRPC
, Value
);
DiscardArgs
();
}
static void DecodeP2
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrP2
, Index
);
DiscardArgs
();
}
static void DecodeP3
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrP3
, Index
);
DiscardArgs
();
}
static void DecodeBM
(Word Index
)
{
/* Wenn EM-Feld schon da war, muss es EI gewesen sein */
if (!SplitArgs
(0))
return;
if ((InstrMask
& (1 << InstrEM
)) != 0)
{
Error
= (InstrComps
[InstrEM
] == 0);
if (Error
) WrError
(ErrNum_InvParAddrMode
);
else
AddComp
(InstrBM
, Index
);
}
else
AddComp
(InstrBM
, Index
);
DiscardArgs
();
}
static void DecodeEM
(Word Index
)
{
/* Wenn BM-Feld schon da war, muss es EI sein */
if (!SplitArgs
(0))
return;
if ((InstrMask
& (1 << InstrBM
)) != 0)
{
Error
= (Index
== 0);
if (Error
)
WrError
(ErrNum_InvParAddrMode
);
else
AddComp
(InstrEM
, Index
);
}
else
{
AddComp
(InstrEM
, Index
);
if (Index
== 0)
InstrComps
[InstrBM
] = 3;
}
DiscardArgs
();
}
static void DecodeRW
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrRW
, Index
);
DiscardArgs
();
}
static void DecodeWT
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrWT
, Index
);
DiscardArgs
();
}
static void DecodeNF
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrNF
, Index
);
DiscardArgs
();
}
static void DecodeWI
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrWI
, Index
);
DiscardArgs
();
}
static void DecodeFIS
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrFIS
, Index
);
DiscardArgs
();
}
static void DecodeFD
(Word Index
)
{
if (!SplitArgs
(0))
return;
AddComp
(InstrFD
, Index
);
DiscardArgs
();
}
static void DecodeSHV
(Word Index
)
{
LongWord Value
;
tSymbolFlags Flags
;
if (!SplitArgs
(1))
return;
Value
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt6
, &Error
, &Flags
);
if (mFirstPassUnknown
(Flags
))
Value
&= 31;
Error
= (Value
> 46) ? True
: !Error
;
if (!Error
)
AddComp
(InstrSHV
, (Index
<< 6) + Value
);
DiscardArgs
();
}
static void DecodeRPS
(Word Index
)
{
LongWord Value
;
UNUSED
(Index
);
if (!SplitArgs
(1))
return;
Value
= EvalStrIntExpression
(&ArgStr
[1], UInt9
, &Error
);
Error
= !Error
;
if (!Error
)
AddComp
(InstrRPS
, Value
);
DiscardArgs
();
}
static void DecodeNAL
(Word Index
)
{
LongWord Value
;
tSymbolFlags Flags
;
UNUSED
(Index
);
if (!SplitArgs
(1))
return;
Value
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt13
, &Error
, &Flags
);
Error
= !Error
;
if (!Error
)
{
if (ChkSamePage
(Value
, EProgCounter
(), 9, Flags
))
AddComp
(InstrNAL
, Value
& 0x1ff);
}
DiscardArgs
();
}
static Boolean DecodePseudo
(void)
{
LongWord temp
;
LongInt sign
, mant
, expo
, Size
;
if (Memo
("DW"))
{
if (ChkArgCnt
(1, ArgCntMax
))
{
TempResult t
;
Boolean OK
= True
;
tStrComp
*pArg
;
as_tempres_ini
(&t
);
forallargs
(pArg
, OK
)
{
EvalStrExpression
(pArg
, &t
);
switch(t.
Typ)
{
case TempString
:
if (MultiCharToInt
(&t
, 4))
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
? 4 : 1, True
);
break;
case TempInt
:
ToInt
:
if (!RangeCheck
(t.
Contents.
Int, Int32
))
{
WrStrErrorPos
(ErrNum_OverRange
, pArg
);
OK
= False
;
break;
}
DAsmCode
[CodeLen
++] = t.
Contents.
Int;
break;
case TempFloat
:
if (!FloatRangeCheck
(t.
Contents.
Float, Float32
))
{
WrStrErrorPos
(ErrNum_OverRange
, pArg
);
OK
= False
;
break;
}
Double_2_ieee4
(t.
Contents.
Float, (Byte
*) &temp
, HostBigEndian
);
sign
= (temp
>> 31) & 1;
expo
= (temp
>> 23) & 255;
mant
= temp
& 0x7fffff;
if ((mant
== 0) && (expo
== 0))
DAsmCode
[CodeLen
++] = 0x80000000;
else
{
if (expo
> 0)
{
mant
|= 0x800000;
expo
-= 127;
}
else
expo
-= 126;
if (mant
>= 0x800000)
{
mant
= mant
>> 1;
expo
+= 1;
}
if (sign
== 1)
mant
= ((mant
^ 0xffffff) + 1);
DAsmCode
[CodeLen
++] = ((expo
& 0xff) << 24) | (mant
& 0xffffff);
}
break;
default:
OK
= False
;
}
}
if (!OK
)
CodeLen
= 0;
as_tempres_free
(&t
);
}
return True
;
}
if (Memo
("DS"))
{
if (ChkArgCnt
(1, 1))
{
tSymbolFlags Flags
;
Boolean OK
;
Size
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], Int16
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
))
{
WrError
(ErrNum_FirstPassCalc
);
OK
= False
;
}
if (OK
)
{
DontPrint
= True
;
if (!Size
)
WrError
(ErrNum_NullResMem
);
CodeLen
= Size
;
BookKeeping
();
}
}
return True
;
}
return FALSE
;
}
/*---------------------------------------------------------------------------*/
/* Codetabellenverwaltung */
static void AddJmp
(const char *NName
, LongWord NCode
)
{
order_array_rsv_end
(JmpOrders
, FixedOrder
);
JmpOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeJmp
);
}
static void AddALU1
(const char *NName
, LongWord NCode
)
{
order_array_rsv_end
(ALU1Orders
, FixedOrder
);
ALU1Orders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeALU1
);
}
static void AddALU2
(const char *NName
, LongWord NCode
)
{
order_array_rsv_end
(ALU2Orders
, FixedOrder
);
ALU2Orders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeALU2
);
}
static void AddSrcReg
(const char *NName
, LongWord NCode
)
{
order_array_rsv_end
(SrcRegs
, Register
);
SrcRegs
[InstrZ
].
Name = NName
;
SrcRegs
[InstrZ
++].
Code = NCode
;
}
static void AddALUSrcReg
(const char *NName
, LongWord NCode
)
{
order_array_rsv_end
(ALUSrcRegs
, Register
);
ALUSrcRegs
[InstrZ
].
Name = NName
;
ALUSrcRegs
[InstrZ
++].
Code = NCode
;
}
static void AddDestReg
(const char *NName
, LongWord NCode
)
{
order_array_rsv_end
(DestRegs
, Register
);
DestRegs
[InstrZ
].
Name = NName
;
DestRegs
[InstrZ
++].
Code = NCode
;
}
static void InitFields
(void)
{
InstTable
= CreateInstTable
(201);
AddInstTable
(InstTable
, "MOV", 0, DecodeMOV
);
AddInstTable
(InstTable
, "LDI", 0, DecodeLDI
);
AddInstTable
(InstTable
, "NOP", 0, DecodeNOP
);
AddInstTable
(InstTable
, "SPCBP0", 1, DecodeM0
);
AddInstTable
(InstTable
, "SPCIX0", 2, DecodeM0
);
AddInstTable
(InstTable
, "SPCBI0", 3, DecodeM0
);
AddInstTable
(InstTable
, "SPCBP1", 1, DecodeM1
);
AddInstTable
(InstTable
, "SPCIX1", 2, DecodeM1
);
AddInstTable
(InstTable
, "SPCBI1", 3, DecodeM1
);
AddInstTable
(InstTable
, "INCBP0", 1, DecodeDP0
);
AddInstTable
(InstTable
, "DECBP0", 2, DecodeDP0
);
AddInstTable
(InstTable
, "CLRBP0", 3, DecodeDP0
);
AddInstTable
(InstTable
, "STIX0" , 4, DecodeDP0
);
AddInstTable
(InstTable
, "INCIX0", 5, DecodeDP0
);
AddInstTable
(InstTable
, "DECIX0", 6, DecodeDP0
);
AddInstTable
(InstTable
, "CLRIX0", 7, DecodeDP0
);
AddInstTable
(InstTable
, "INCBP1", 1, DecodeDP1
);
AddInstTable
(InstTable
, "DECBP1", 2, DecodeDP1
);
AddInstTable
(InstTable
, "CLRBP1", 3, DecodeDP1
);
AddInstTable
(InstTable
, "STIX1" , 4, DecodeDP1
);
AddInstTable
(InstTable
, "INCIX1", 5, DecodeDP1
);
AddInstTable
(InstTable
, "DECIX1", 6, DecodeDP1
);
AddInstTable
(InstTable
, "CLRIX1", 7, DecodeDP1
);
AddInstTable
(InstTable
, "INCAR" , 1, DecodeEA
);
AddInstTable
(InstTable
, "DECAR" , 2, DecodeEA
);
AddInstTable
(InstTable
, "XCHPSW", 1, DecodeFC
);
AddInstTable
(InstTable
, "INCRP" , 1, DecodeRP
);
AddInstTable
(InstTable
, "DECRP" , 2, DecodeRP
);
AddInstTable
(InstTable
, "INCBRP", 3, DecodeRP
);
AddInstTable
(InstTable
, "DECLC" , 1, DecodeL
);
AddInstTable
(InstTable
, "MCNBP0", InstrBASE0
, DecodeBASE
);
AddInstTable
(InstTable
, "MCNBP1", InstrBASE1
, DecodeBASE
);
AddInstTable
(InstTable
, "BITRP" , 0, DecodeRPC
);
AddInstTable
(InstTable
, "CLRP2" , 0, DecodeP2
);
AddInstTable
(InstTable
, "SETP2" , 1, DecodeP2
);
AddInstTable
(InstTable
, "CLRP3" , 0, DecodeP3
);
AddInstTable
(InstTable
, "SETP3" , 1, DecodeP3
);
AddInstTable
(InstTable
, "DI" , 0, DecodeEM
);
AddInstTable
(InstTable
, "EI" , 1, DecodeEM
);
AddInstTable
(InstTable
, "CLRBM" , 1, DecodeBM
);
AddInstTable
(InstTable
, "SETBM" , 2, DecodeBM
);
AddInstTable
(InstTable
, "RD" , 1, DecodeRW
);
AddInstTable
(InstTable
, "WR" , 2, DecodeRW
);
AddInstTable
(InstTable
, "WRBORD", 1, DecodeWT
);
AddInstTable
(InstTable
, "WRBL24", 2, DecodeWT
);
AddInstTable
(InstTable
, "WRBL23", 3, DecodeWT
);
AddInstTable
(InstTable
, "WRBEL8", 4, DecodeWT
);
AddInstTable
(InstTable
, "WRBL8E", 5, DecodeWT
);
AddInstTable
(InstTable
, "WRBXCH", 6, DecodeWT
);
AddInstTable
(InstTable
, "WRBBRV", 7, DecodeWT
);
AddInstTable
(InstTable
, "TRNORM", 2, DecodeNF
);
AddInstTable
(InstTable
, "RDNORM", 4, DecodeNF
);
AddInstTable
(InstTable
, "FLTFIX", 6, DecodeNF
);
AddInstTable
(InstTable
, "FIXMA" , 7, DecodeNF
);
AddInstTable
(InstTable
, "BWRL24", 1, DecodeWI
);
AddInstTable
(InstTable
, "BWRORD", 2, DecodeWI
);
AddInstTable
(InstTable
, "SPCPSW0", 1, DecodeFIS
);
AddInstTable
(InstTable
, "SPCPSW1", 2, DecodeFIS
);
AddInstTable
(InstTable
, "CLRPSW0", 4, DecodeFIS
);
AddInstTable
(InstTable
, "CLRPSW1", 5, DecodeFIS
);
AddInstTable
(InstTable
, "CLRPSW" , 6, DecodeFIS
);
AddInstTable
(InstTable
, "SPIE", 1, DecodeFD
);
AddInstTable
(InstTable
, "IESP", 2, DecodeFD
);
AddInstTable
(InstTable
, "SETSVL", 0, DecodeSHV
);
AddInstTable
(InstTable
, "SETSVR", 1, DecodeSHV
);
AddInstTable
(InstTable
, "SPCRA", 0, DecodeRPS
);
AddInstTable
(InstTable
, "JBLK" , 0, DecodeNAL
);
InstrZ
= 0;
AddJmp
("JMP" , 0x0100); AddJmp
("CALL" , 0x0101); AddJmp
("RET" , 0x0002);
AddJmp
("JNZRP" , 0x0103); AddJmp
("JZ0" , 0x0104); AddJmp
("JNZ0" , 0x0105);
AddJmp
("JZ1" , 0x0106); AddJmp
("JNZ1" , 0x0107); AddJmp
("JC0" , 0x0108);
AddJmp
("JNC0" , 0x0109); AddJmp
("JC1" , 0x010a); AddJmp
("JNC1" , 0x010b);
AddJmp
("JS0" , 0x010c); AddJmp
("JNS0" , 0x010d); AddJmp
("JS1" , 0x010e);
AddJmp
("JNS1" , 0x010f); AddJmp
("JV0" , 0x0110); AddJmp
("JNV0" , 0x0111);
AddJmp
("JV1" , 0x0112); AddJmp
("JNV1" , 0x0113); AddJmp
("JEV0" , 0x0114);
AddJmp
("JEV1" , 0x0115); AddJmp
("JNFSI" , 0x0116); AddJmp
("JNESO" , 0x0117);
AddJmp
("JIP0" , 0x0118); AddJmp
("JIP1" , 0x0119); AddJmp
("JNZIX0", 0x011a);
AddJmp
("JNZIX1", 0x011b); AddJmp
("JNZBP0", 0x011c); AddJmp
("JNZBP1", 0x011d);
AddJmp
("JRDY" , 0x011e); AddJmp
("JRQM" , 0x011f);
InstrZ
= 0;
AddALU1
("INC" , 0x01); AddALU1
("DEC" , 0x02); AddALU1
("ABS" , 0x03);
AddALU1
("NOT" , 0x04); AddALU1
("NEG" , 0x05); AddALU1
("SHLC" , 0x06);
AddALU1
("SHRC" , 0x07); AddALU1
("ROL" , 0x08); AddALU1
("ROR" , 0x09);
AddALU1
("SHLM" , 0x0a); AddALU1
("SHRM" , 0x0b); AddALU1
("SHRAM", 0x0c);
AddALU1
("CLR" , 0x0d); AddALU1
("NORM" , 0x0e); AddALU1
("CVT" , 0x0f);
InstrZ
= 0;
AddALU2
("ADD" , 0x10); AddALU2
("SUB" , 0x11); AddALU2
("ADDC" , 0x12);
AddALU2
("SUBC" , 0x13); AddALU2
("CMP" , 0x14); AddALU2
("AND" , 0x15);
AddALU2
("OR" , 0x16); AddALU2
("XOR" , 0x17); AddALU2
("ADDF" , 0x18);
AddALU2
("SUBF" , 0x19);
InstrZ
= 0;
AddSrcReg
("NON" , 0x00); AddSrcReg
("RP" , 0x01); AddSrcReg
("PSW0" , 0x02);
AddSrcReg
("PSW1", 0x03); AddSrcReg
("SVR" , 0x04); AddSrcReg
("SR" , 0x05);
AddSrcReg
("LC" , 0x06); AddSrcReg
("STX" , 0x07); AddSrcReg
("M" , 0x08);
AddSrcReg
("ML" , 0x09); AddSrcReg
("ROM" , 0x0a); AddSrcReg
("TR" , 0x0b);
AddSrcReg
("AR" , 0x0c); AddSrcReg
("SI" , 0x0d); AddSrcReg
("DR" , 0x0e);
AddSrcReg
("DRS" , 0x0f); AddSrcReg
("WR0" , 0x10); AddSrcReg
("WR1" , 0x11);
AddSrcReg
("WR2" , 0x12); AddSrcReg
("WR3" , 0x13); AddSrcReg
("WR4" , 0x14);
AddSrcReg
("WR5" , 0x15); AddSrcReg
("WR6" , 0x16); AddSrcReg
("WR7" , 0x17);
AddSrcReg
("RAM0", 0x18); AddSrcReg
("RAM1", 0x19); AddSrcReg
("BP0" , 0x1a);
AddSrcReg
("BP1" , 0x1b); AddSrcReg
("IX0" , 0x1c); AddSrcReg
("IX1" , 0x1d);
AddSrcReg
("K" , 0x1e); AddSrcReg
("L" , 0x1f); AddSrcReg
(NULL
, 0);
InstrZ
= 0;
AddALUSrcReg
("IB" , 0x00); AddALUSrcReg
("M" , 0x01);
AddALUSrcReg
("RAM0", 0x02); AddALUSrcReg
("RAM1", 0x03);
AddALUSrcReg
(NULL
, 0);
InstrZ
= 0;
AddDestReg
("NON" , 0x00); AddDestReg
("RP" , 0x01); AddDestReg
("PSW0" , 0x02);
AddDestReg
("PSW1", 0x03); AddDestReg
("SVR" , 0x04); AddDestReg
("SR" , 0x05);
AddDestReg
("LC" , 0x06); AddDestReg
("STK" , 0x07); AddDestReg
("LKR0" , 0x08);
AddDestReg
("KLR1", 0x09); AddDestReg
("TRE" , 0x0a); AddDestReg
("TR" , 0x0b);
AddDestReg
("AR" , 0x0c); AddDestReg
("SO" , 0x0d); AddDestReg
("DR" , 0x0e);
AddDestReg
("DRS" , 0x0f); AddDestReg
("WR0" , 0x10); AddDestReg
("WR1" , 0x11);
AddDestReg
("WR2" , 0x12); AddDestReg
("WR3" , 0x13); AddDestReg
("WR4" , 0x14);
AddDestReg
("WR5" , 0x15); AddDestReg
("WR6" , 0x16); AddDestReg
("WR7" , 0x17);
AddDestReg
("RAM0", 0x18); AddDestReg
("RAM1", 0x19); AddDestReg
("BP0" , 0x1a);
AddDestReg
("BP1" , 0x1b); AddDestReg
("IX0" , 0x1c); AddDestReg
("IX1" , 0x1d);
AddDestReg
("K" , 0x1e); AddDestReg
("L" , 0x1f); AddDestReg
(NULL
, 0);
InstrComps
= (LongWord
*) malloc(sizeof(LongWord
) * InstrCnt
);
InstrDefs
= (LongWord
*) malloc(sizeof(LongWord
) * InstrCnt
);
for (InstrZ
= 0; InstrZ
< InstrCnt
; InstrDefs
[InstrZ
++] = 0xffffffff);
InstrDefs
[InstrALU
] = 0;
InstrDefs
[InstrMove
] = 0;
InstrDefs
[InstrBM
] = 0;
InstrDefs
[InstrEM
] = 0;
InstrDefs
[InstrDP0
] = 0;
InstrDefs
[InstrDP1
] = 0;
InstrDefs
[InstrEA
] = 0;
InstrDefs
[InstrFC
] = 0;
InstrDefs
[InstrFD
] = 0;
InstrDefs
[InstrFIS
] = 0;
InstrDefs
[InstrL
] = 0;
InstrDefs
[InstrM0
] = 0;
InstrDefs
[InstrM1
] = 0;
InstrDefs
[InstrNF
] = 0;
InstrDefs
[InstrRP
] = 0;
InstrDefs
[InstrRW
] = 0;
InstrDefs
[InstrWI
] = 0;
InstrDefs
[InstrWT
] = 0;
}
static void DeinitFields
(void)
{
DestroyInstTable
(InstTable
);
order_array_free
(SrcRegs
);
order_array_free
(ALUSrcRegs
);
order_array_free
(DestRegs
);
order_array_free
(JmpOrders
);
order_array_free
(ALU1Orders
);
order_array_free
(ALU2Orders
);
free(InstrComps
);
free(InstrDefs
);
}
/*---------------------------------------------------------------------------*/
/* Callbacks */
static void MakeCode_77230
(void)
{
int z
, z2
;
LongWord Diff
;
/* Nullanweisung */
if (Memo
("") && !*AttrPart.
str.
p_str && (ArgCnt
== 0))
return;
/* Pseudoanweisungen */
if (DecodePseudo
())
return;
/* solange dekodieren, bis keine Operanden mehr da oder Fehler */
Error
= False
;
InstrMask
= 0;
memset(InstrComps
, 0, sizeof(LongWord
) * InstrCnt
);
do
{
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
{
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
Error
= True
;
}
}
while (!Error
&& (*OpPart.
str.
p_str != '\0'));
/* passende Verknuepfung suchen */
if (!Error
)
{
for (z
= 0; z
< CaseCnt
; z
++)
{
/* Bits ermitteln, die nur in einer Maske vorhanden sind */
Diff
= InstrMask
^CaseMasks
[z
];
/* Fall nur moeglich, wenn Bits im aktuellen Fall gesetzt sind, die
der Fall nicht hat */
if ((Diff
& InstrMask
) == 0)
{
/* ist irgendein Feld unbenutzt, fuer das wir keinen Default haben? */
for (z2
= 0; z2
< InstrCnt
; z2
++)
if (((Diff
& (1l << z2
)) != 0) && (InstrDefs
[z2
] == 0xffffffff))
break;
if (z2
== InstrCnt
)
break;
}
}
switch (z
)
{
case 0: /* nur LDI */
DAsmCode
[0] = 0xe0000000 + InstrComps
[InstrLDI
];
CodeLen
= 1;
break;
case 1: /* JMP + MOV */
DAsmCode
[0] = 0xd0000000 + (InstrComps
[InstrBranch
] << 10)
+ InstrComps
[InstrMove
];
CodeLen
= 1;
break;
case 2: /* ALU + MOV + M0 + M1 + DP0 + DP1 */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrDP1
] << 15) + (InstrComps
[InstrDP0
] << 18)
+ (InstrComps
[InstrM1
] << 21) + (InstrComps
[InstrM0
] << 23);
CodeLen
= 1;
break;
case 3: /* ALU + MOV + EA + DP0 + DP1 */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrDP1
] << 15) + (InstrComps
[InstrDP0
] << 18)
+ (InstrComps
[InstrEA
] << 21) + 0x02000000;
CodeLen
= 1;
break;
case 4: /* ALU + MOV + RP + M0 + DP0 + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrRP
] << 21) + (InstrComps
[InstrFC
] << 15)
+ (InstrComps
[InstrM0
] << 19) + (InstrComps
[InstrDP0
] << 16)
+ 0x02800000;
CodeLen
= 1;
break;
case 5: /* ALU + MOV + RP + M1 + DP1 + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrRP
] << 21) + (InstrComps
[InstrFC
] << 15)
+ (InstrComps
[InstrM1
] << 19) + (InstrComps
[InstrDP1
] << 16)
+ 0x03000000;
CodeLen
= 1;
break;
case 6: /* ALU + MOV + RP + M0 + M1 + L + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrRP
] << 21) + (InstrComps
[InstrL
] << 16)
+ (InstrComps
[InstrM0
] << 19) + (InstrComps
[InstrM1
] << 17)
+ (InstrComps
[InstrFC
] << 15) + 0x03800000;
CodeLen
= 1;
break;
case 7: /* ALU + MOV + BASE0 + BASE1 + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrBASE0
] << 19) + (InstrComps
[InstrBASE1
] << 16)
+ (InstrComps
[InstrFC
] << 15) + 0x04000000;
CodeLen
= 1;
break;
case 8: /* ALU + MOV + RPC + L+ FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrRPC
] << 18) + (InstrComps
[InstrL
] << 16)
+ (InstrComps
[InstrFC
] << 15) + 0x04400000;
CodeLen
= 1;
break;
case 9: /* ALU + MOV + P2 + P3 + EM + BM + L + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrP2
] << 20) + (InstrComps
[InstrP3
] << 21)
+ (InstrComps
[InstrEM
] << 19) + (InstrComps
[InstrBM
] << 17)
+ (InstrComps
[InstrL
] << 16) + (InstrComps
[InstrFC
] << 15)
+ 0x04800000;
CodeLen
= 1;
break;
case 10: /* ALU + MOV + RW + L + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrRW
] << 20) + (InstrComps
[InstrL
] << 16)
+ (InstrComps
[InstrFC
] << 15) + 0x04c00000;
CodeLen
= 1;
break;
case 11: /* ALU + MOV + WT + L + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrWT
] << 19) + (InstrComps
[InstrL
] << 16)
+ (InstrComps
[InstrFC
] << 15) + 0x05000000;
CodeLen
= 1;
break;
case 12: /* ALU + MOV + NF + WI + L + FC */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrNF
] << 19) + (InstrComps
[InstrWI
] << 17)
+ (InstrComps
[InstrL
] << 16) + (InstrComps
[InstrFC
] << 15)
+ 0x05400000;
CodeLen
= 1;
break;
case 13: /* ALU + MOV + FIS + FD + L */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrFIS
] << 19) + (InstrComps
[InstrFD
] << 17)
+ (InstrComps
[InstrL
] << 16) + 0x05800000;
CodeLen
= 1;
break;
case 14: /* ALU + MOV + SHV */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrSHV
] << 15) + 0x05c00000;
CodeLen
= 1;
break;
case 15: /* ALU + MOV + RPS */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrRPS
] << 15) + 0x06000000;
CodeLen
= 1;
break;
case 16: /* ALU + MOV + NAL */
DAsmCode
[0] = (InstrComps
[InstrALU
] << 10) + InstrComps
[InstrMove
]
+ (InstrComps
[InstrNAL
] << 15) + 0x07000000;
CodeLen
= 1;
break;
default:
WrError
(ErrNum_InvParAddrMode
);
}
}
}
static Boolean IsDef_77230
(void)
{
return False
;
}
static void SwitchFrom_77230
(void)
{
DeinitFields
();
}
static void SwitchTo_77230
(void)
{
const TFamilyDescr
*FoundDescr
;
FoundDescr
= FindFamilyByName
("77230");
TurnWords
= False
;
SetIntConstMode
(eIntConstModeIntel
);
PCSymbol
= "$";
HeaderID
= FoundDescr
->Id
;
NOPCode
= 0x00000000;
DivideChars
= ",";
HasAttrs
= False
;
ValidSegs
= (1 << SegCode
) | (1 << SegXData
) | (1 << SegYData
) | (1 << SegRData
);
Grans
[SegCode
] = 4; ListGrans
[SegCode
] = 4; SegInits
[SegCode
] = 0;
SegLimits
[SegCode
] = 0x1fff;
Grans
[SegXData
] = 4; ListGrans
[SegXData
] = 4; SegInits
[SegXData
] = 0;
SegLimits
[SegXData
] = 0x1ff;
Grans
[SegYData
] = 4; ListGrans
[SegYData
] = 4; SegInits
[SegYData
] = 0;
SegLimits
[SegYData
] = 0x1ff;
Grans
[SegRData
] = 4; ListGrans
[SegRData
] = 4; SegInits
[SegRData
] = 0;
SegLimits
[SegRData
] = 0x3ff;
onoff_packing_add
(True
);
MakeCode
= MakeCode_77230
;
IsDef
= IsDef_77230
;
SwitchFrom
= SwitchFrom_77230
;
InitFields
();
}
/*---------------------------------------------------------------------------*/
/* Initialisierung */
void code77230_init
(void)
{
CPU77230
= AddCPU
("77230", SwitchTo_77230
);
}