/*
* AS-Portierung
*
* AS-Codegeneratormodul fuer die Texas Instruments TMS320C5x-Familie
*
*/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "nls.h"
#include "bpemu.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 "codevars.h"
#include "tipseudo.h"
#include "be_le.h"
#include "errmsg.h"
#include "code3205x.h"
/* ---------------------------------------------------------------------- */
typedef struct
{
CPUVar MinCPU
;
Word Code
;
} FixedOrder
;
typedef struct
{
CPUVar MinCPU
;
Word Code
;
Boolean Cond
;
} JmpOrder
;
typedef struct
{
const char *Name
;
CPUVar MinCPU
;
Word Mode
;
} tAdrMode
;
typedef struct
{
const char *Name
;
CPUVar MinCPU
;
Word CodeAND
;
Word CodeOR
;
Byte IsZL
;
Byte IsC
;
Byte IsV
;
Byte IsTP
;
} Condition
;
typedef struct
{
const char *name
;
CPUVar MinCPU
;
Word Code
;
} tBitTable
;
#define NOCONDITION 0xffff
static FixedOrder
*FixedOrders
;
static FixedOrder
*AdrOrders
;
static JmpOrder
*JmpOrders
;
static FixedOrder
*PluOrders
;
static tAdrMode
*AdrModes
;
static Condition
*Conditions
;
static tBitTable
*BitTable
;
static Word AdrMode
;
static CPUVar CPU320203
;
static CPUVar CPU32050
;
static CPUVar CPU32051
;
static CPUVar CPU32053
;
/* ---------------------------------------------------------------------- */
static Word EvalARExpression
(const tStrComp
*pArg
, Boolean
*OK
)
{
*OK
= True
;
if ((as_toupper
(pArg
->str.
p_str[0]) == 'A')
&& (as_toupper
(pArg
->str.
p_str[1]) == 'R')
&& (pArg
->str.
p_str[2] >= '0')
&& (pArg
->str.
p_str[2] <= '7')
&& (pArg
->str.
p_str[3] <= '\0'))
return pArg
->str.
p_str[2] - '0';
return EvalStrIntExpression
(pArg
, UInt3
, OK
);
}
/* ---------------------------------------------------------------------- */
static Boolean DecodeAdr
(const tStrComp
*pArg
, int MinArgCnt
, int aux
, Boolean Must1
)
{
Word h
;
tAdrMode
*pAdrMode
= AdrModes
;
tEvalResult EvalResult
;
/* Annahme: nicht gefunden */
Boolean AdrOK
= False
;
/* Adressierungsmodus suchen */
while (pAdrMode
->Name
&& as_strcasecmp
(pAdrMode
->Name
, pArg
->str.
p_str))
pAdrMode
++;
/* nicht gefunden: dann absolut */
if (!pAdrMode
->Name
)
{
/* ARn-Register darf dann nicht vorhanden sein */
if (aux
<= ArgCnt
)
{
(void)ChkArgCnt
(MinArgCnt
, aux
- 1);
return False
;
}
/* Adresse berechnen */
h
= EvalStrIntExpressionWithResult
(pArg
, Int16
, &EvalResult
);
if (!EvalResult.
OK)
return False
;
AdrOK
= True
;
/* Adresslage pruefen */
if (Must1
&& (h
>= 0x80) && !mFirstPassUnknown
(EvalResult.
Flags))
{
WrError
(ErrNum_UnderRange
);
return False
;
}
/* nur untere 7 Bit gespeichert */
AdrMode
= h
& 0x7f;
ChkSpace
(SegData
, EvalResult.
AddrSpaceMask);
}
/* ansonsten evtl. noch Adressregister dazu */
else
{
/* auf dieser CPU nicht erlaubter Modus ? */
if (!ChkMinCPUExt
(pAdrMode
->MinCPU
, ErrNum_AddrModeNotSupported
))
return False
;
AdrMode
= pAdrMode
->Mode
;
if (aux
<= ArgCnt
)
{
h
= EvalARExpression
(&ArgStr
[aux
], &AdrOK
);
if (AdrOK
) AdrMode
|= 0x8 | h
;
}
else
AdrOK
= True
;
}
return AdrOK
;
}
/* ---------------------------------------------------------------------- */
static Word DecodeCond
(int argp
)
{
Condition
*pCondition
;
Byte cntzl
= 0, cntc
= 0, cntv
= 0, cnttp
= 0;
Word ret
= 0x300;
while (argp
<= ArgCnt
)
{
for (pCondition
= Conditions
; pCondition
->Name
&& as_strcasecmp
(pCondition
->Name
, ArgStr
[argp
].
str.
p_str); pCondition
++);
if (!pCondition
->Name
)
{
WrError
(ErrNum_UndefCond
);
return ret
;
}
ret
&= pCondition
->CodeAND
;
ret
|= pCondition
->CodeOR
;
cntzl
+= pCondition
->IsZL
;
cntc
+= pCondition
->IsC
;
cntv
+= pCondition
->IsV
;
cnttp
+= pCondition
->IsTP
;
argp
++;
}
if ((cnttp
> 1) || (cntzl
> 1) || (cntv
> 1) || (cntc
> 1))
WrStrErrorPos
(ErrNum_UndefCond
, &ArgStr
[argp
]);
return ret
;
}
/* ---------------------------------------------------------------------- */
static Word DecodeShift
(const tStrComp
*pArg
, Boolean
*OK
)
{
Word Shift
;
tSymbolFlags Flags
;
Shift
= EvalStrIntExpressionWithFlags
(pArg
, UInt5
, OK
, &Flags
);
if (*OK
)
{
if (mFirstPassUnknown
(Flags
)) Shift
&= 15;
*OK
= ChkRange
(Shift
, 0, 16);
}
return Shift
;
}
/* ---------------------------------------------------------------------- */
static void DecodeFixed
(Word Index
)
{
const FixedOrder
*pOrder
= FixedOrders
+ Index
;
if (ChkArgCnt
(0, 0)
&& ChkMinCPU
(pOrder
->MinCPU
))
{
CodeLen
= 1;
WAsmCode
[0] = pOrder
->Code
;
}
}
static void DecodeCmdAdr
(Word Index
)
{
const FixedOrder
*pOrder
= AdrOrders
+ Index
;
if (ChkArgCnt
(1, 2)
&& ChkMinCPU
(pOrder
->MinCPU
)
&& DecodeAdr
(&ArgStr
[1], 1, 2, False
))
{
CodeLen
= 1;
WAsmCode
[0] = pOrder
->Code
| AdrMode
;
}
}
static void DecodeCmdJmp
(Word Index
)
{
const JmpOrder
*pOrder
= JmpOrders
+ Index
;
if (ChkMinCPU
(pOrder
->MinCPU
)
&& ChkArgCnt
(1, pOrder
->Cond
? ArgCntMax
: 3))
{
Boolean OK
;
AdrMode
= 0;
if (pOrder
->Cond
)
{
AdrMode
= DecodeCond
(2);
OK
= AdrMode
!= NOCONDITION
;
}
else if (ArgCnt
> 1)
{
OK
= DecodeAdr
(&ArgStr
[2], 1, 3, False
);
if ((AdrMode
< 0x80) && (OK
))
{
WrError
(ErrNum_InvAddrMode
);
OK
= FALSE
;
}
AdrMode
&= 0x7f;
}
else
OK
= TRUE
;
if (OK
)
{
WAsmCode
[1] = EvalStrIntExpression
(&ArgStr
[1], Int16
, &OK
);
if (OK
)
{
CodeLen
= 2;
WAsmCode
[0] = pOrder
->Code
| AdrMode
;
}
}
}
}
static void DecodeCmdPlu
(Word Index
)
{
Boolean OK
;
const FixedOrder
*pOrder
= PluOrders
+ Index
;
if (!ChkMinCPU
(pOrder
->MinCPU
));
else if (*ArgStr
[1].
str.
p_str == '#')
{
if (ChkArgCnt
(2, 3))
{
WAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[1], 1, Int16
, &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[2], 2, 3, False
)))
{
CodeLen
= 2;
WAsmCode
[0] = pOrder
->Code
| 0x0400 | AdrMode
;
}
}
}
else if (strlen(OpPart.
str.
p_str) == 4) WrError
(ErrNum_OnlyImmAddr
);
else
{
if (ChkArgCnt
(1, 2))
{
if (DecodeAdr
(&ArgStr
[1], 1, 2, False
))
{
CodeLen
= 1;
WAsmCode
[0] = pOrder
->Code
| AdrMode
;
}
}
}
}
static void DecodeADDSUB
(Word Index
)
{
Word Shift
;
LongInt AdrLong
;
Boolean OK
;
if (ChkArgCnt
(1, 3))
{
if (*ArgStr
[1].
str.
p_str == '#')
{
if (ChkArgCnt
(1, 2))
{
OK
= True
;
Shift
= (ArgCnt
== 1) ? 0 : EvalStrIntExpression
(&ArgStr
[2], UInt4
, &OK
);
if (OK
)
{
AdrLong
= EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt16
, &OK
);
if (OK
)
{
if ((Shift
== 0) && (Hi
(AdrLong
) == 0))
{
CodeLen
= 1;
WAsmCode
[0] = (Index
<< 9) | 0xb800 | (AdrLong
& 0xff);
}
else
{
CodeLen
= 2;
WAsmCode
[0] = ((Index
<< 4) + 0xbf90) | (Shift
& 0xf);
WAsmCode
[1] = AdrLong
;
}
}
}
}
}
else
{
if (DecodeAdr
(&ArgStr
[1], 1, 3, False
))
{
OK
= True
;
Shift
= (ArgCnt
>= 2) ? DecodeShift
(&ArgStr
[2], &OK
) : 0;
if (OK
)
{
CodeLen
= 1;
if (Shift
== 16)
WAsmCode
[0] = ((Index
<< 10) | 0x6100) | AdrMode
;
else
WAsmCode
[0] = ((Index
<< 12) | 0x2000) | ((Shift
& 0xf) << 8) | AdrMode
;
}
}
}
}
}
static void DecodeADRSBRK
(Word Index
)
{
Word adr_word
;
Boolean OK
;
if (!ChkArgCnt
(1, 1))
return;
if (*ArgStr
[1].
str.
p_str != '#')
{
WrError
(ErrNum_OnlyImmAddr
); /*invalid parameter*/
return;
}
adr_word
= EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt8
, &OK
);
if (OK
)
{
CodeLen
= 1;
WAsmCode
[0] = (Index
<< 10)| 0x7800 | (adr_word
& 0xff);
}
}
static void DecodeLogic
(Word Index
)
{
Boolean OK
;
Word Shift
;
if (!ChkArgCnt
(1, 2));
else if (*ArgStr
[1].
str.
p_str == '#')
{
WAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt16
, &OK
);
if (OK
)
{
OK
= True
;
Shift
= (ArgCnt
>= 2) ? DecodeShift
(&ArgStr
[2], &OK
) : 0;
if (OK
)
{
CodeLen
= 2;
if (Shift
>= 16)
WAsmCode
[0] = 0xbe80 | Lo
(Index
);
else
WAsmCode
[0] = 0xbfa0 + ((Index
& 3) << 4) + (Shift
& 0xf);
}
}
}
else
{
if (DecodeAdr
(&ArgStr
[1], 1, 2, False
))
{
CodeLen
= 1;
WAsmCode
[0] = (Index
& 0xff00) | AdrMode
;
}
}
}
static void DecodeBIT
(Word Index
)
{
Word bit
;
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 3))
{
bit
= EvalStrIntExpression
(&ArgStr
[2], UInt4
, &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[1], 2, 3, False
)))
{
CodeLen
= 1;
WAsmCode
[0] = 0x4000 | AdrMode
| ((bit
& 0xf) << 8);
}
}
}
static void DecodeBLDD
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (!ChkArgCnt
(2, 3));
else if (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "BMAR"))
{
if (ChkMinCPU
(CPU32050
))
{
if (DecodeAdr
(&ArgStr
[2], 2, 3, False
))
{
CodeLen
= 1;
WAsmCode
[0] = 0xac00 | AdrMode
;
}
}
}
else if (!as_strcasecmp
(ArgStr
[2].
str.
p_str, "BMAR"))
{
if (ChkMinCPU
(CPU32050
))
{
if (DecodeAdr
(&ArgStr
[1], 2, 3, False
))
{
CodeLen
= 1;
WAsmCode
[0] = 0xad00 | AdrMode
;
}
}
}
else if (*ArgStr
[1].
str.
p_str == '#')
{
WAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[1], 1, Int16
, &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[2], 2, 3, False
)))
{
CodeLen
= 2;
WAsmCode
[0] = 0xa800 | AdrMode
;
}
}
else if (*ArgStr
[2].
str.
p_str == '#')
{
WAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[2], 1, Int16
, &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[1], 2, 3, False
)))
{
CodeLen
= 2;
WAsmCode
[0] = 0xa900 | AdrMode
;
}
}
else
WrError
(ErrNum_InvAddrMode
); /* invalid addr mode */
}
static void DecodeBLPD
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (!ChkArgCnt
(2, 3));
else if (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "BMAR"))
{
if (ChkMinCPU
(CPU32050
)
&& DecodeAdr
(&ArgStr
[2], 2, 3, False
))
{
CodeLen
= 1;
WAsmCode
[0] = 0xa400 | AdrMode
;
}
}
else if (*ArgStr
[1].
str.
p_str == '#')
{
WAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[1], 1, Int16
, &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[2], 2, 3, False
)))
{
CodeLen
= 2;
WAsmCode
[0] = 0xa500 | AdrMode
;
}
}
else
WrError
(ErrNum_InvAddrMode
); /* invalid addressing mode */
}
static void DecodeCLRSETC
(Word Index
)
{
tBitTable
*pBitTable
;
if (ChkArgCnt
(1, 1))
{
WAsmCode
[0] = Index
;
NLS_UpString
(ArgStr
[1].
str.
p_str);
for (pBitTable
= BitTable
; pBitTable
->name
; pBitTable
++)
if (!strcmp(ArgStr
[1].
str.
p_str, pBitTable
->name
))
{
if (ChkMinCPU
(pBitTable
->MinCPU
))
{
WAsmCode
[0] |= pBitTable
->Code
;
CodeLen
= 1;
}
return;
}
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[1]); /* invalid instruction */
}
}
static void DecodeCMPRSPM
(Word Index
)
{
Boolean OK
;
if (ChkArgCnt
(1, 1))
{
WAsmCode
[0] = Index
| (EvalStrIntExpression
(&ArgStr
[1], UInt2
, &OK
) & 3);
if (OK
)
CodeLen
= 1;
}
}
static void DecodeIO
(Word Index
)
{
if (ChkArgCnt
(2, 3)
&& DecodeAdr
(&ArgStr
[1], 2, 3, False
))
{
tEvalResult EvalResult
;
WAsmCode
[1] = EvalStrIntExpressionWithResult
(&ArgStr
[2], UInt16
, &EvalResult
);
if (EvalResult.
OK)
{
ChkSpace
(SegIO
, EvalResult.
AddrSpaceMask);
CodeLen
= 2;
WAsmCode
[0] = Index
| AdrMode
;
}
}
}
static void DecodeINTR
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(1, 1))
{
WAsmCode
[0] = EvalStrIntExpression
(&ArgStr
[1], UInt5
, &OK
) | 0xbe60;
if (OK
)
CodeLen
= 1;
}
}
static void DecodeLACC
(Word Index
)
{
Boolean OK
;
LongWord AdrLong
;
Word Shift
;
UNUSED
(Index
);
if (!ChkArgCnt
(1, 3));
else if (*ArgStr
[1].
str.
p_str == '#')
{
if (ChkArgCnt
(1, 2))
{
AdrLong
= EvalStrIntExpressionOffs
(&ArgStr
[1], 1, Int16
, &OK
);
if (OK
)
{
OK
= True
;
Shift
= (ArgCnt
> 1) ? EvalStrIntExpression
(&ArgStr
[2], UInt4
, &OK
) : 0;
if (OK
)
{
CodeLen
= 2;
WAsmCode
[0] = 0xbf80 | (Shift
& 0xf);
WAsmCode
[1] = AdrLong
;
}
}
}
}
else
{
if (DecodeAdr
(&ArgStr
[1], 1, 3, False
))
{
OK
= True
;
Shift
= (ArgCnt
>= 2) ? DecodeShift
(&ArgStr
[2], &OK
) : 0;
if (OK
)
{
CodeLen
= 1;
if (Shift
>= 16)
WAsmCode
[0] = 0x6a00 | AdrMode
;
else
WAsmCode
[0] = 0x1000 | ((Shift
& 0xf) << 8) | AdrMode
;
}
}
}
}
static void DecodeLACL
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (*ArgStr
[1].
str.
p_str == '#')
{
if (ChkArgCnt
(1, 1))
{
WAsmCode
[0] = EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt8
, &OK
);
if (OK
)
{
CodeLen
= 1;
WAsmCode
[0] |= 0xb900;
}
}
}
else
{
if (ChkArgCnt
(1, 2))
{
if (DecodeAdr
(&ArgStr
[1], 1, 2, False
))
{
WAsmCode
[0] = 0x6900 | AdrMode
;
CodeLen
= 1;
}
}
}
}
static void DecodeLAR
(Word Index
)
{
Word Reg
;
LongWord AdrLong
;
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 3))
{
Reg
= EvalARExpression
(&ArgStr
[1], &OK
);
if (OK
)
{
if (*ArgStr
[2].
str.
p_str == '#')
{
if (!ChkArgCnt
(2, 2))
return;
AdrLong
= EvalStrIntExpressionOffs
(&ArgStr
[2], 1, Int16
, &OK
) & 0xffff;
if (OK
)
{
if (AdrLong
> 255)
{
CodeLen
= 2;
WAsmCode
[0] = 0xbf08 | (Reg
& 7);
WAsmCode
[1] = AdrLong
;
}
else
{
CodeLen
= 1;
WAsmCode
[0] = 0xb000 | ((Reg
& 7) << 8) | (AdrLong
& 0xff);
}
}
}
else
{
if (DecodeAdr
(&ArgStr
[2], 2, 3, False
))
{
CodeLen
= 1;
WAsmCode
[0] = 0x0000 | ((Reg
& 7) << 8) | AdrMode
;
}
}
}
}
}
static void DecodeLDP
(Word Index
)
{
Word konst
;
Boolean OK
;
UNUSED
(Index
);
if (*ArgStr
[1].
str.
p_str == '#')
{
if (ChkArgCnt
(1, 1))
{
konst
= EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt9
, &OK
);
if (OK
)
{
CodeLen
= 1;
WAsmCode
[0] = (konst
& 0x1ff) | 0xbc00;
}
}
}
else
{
if (ChkArgCnt
(1, 2))
{
if (DecodeAdr
(&ArgStr
[1], 1, 2, False
))
{
CodeLen
= 1;
WAsmCode
[0] = 0x0d00 | AdrMode
;
}
}
}
}
static void DecodeLSST
(Word Index
)
{
Word konst
;
Boolean OK
;
if (!ChkArgCnt
(2, 3));
else if (*ArgStr
[1].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
); /* invalid instruction */
else
{
konst
= EvalStrIntExpressionOffs
(&ArgStr
[1], 1, UInt1
, &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[2], 2, 3, Index
)))
{
CodeLen
= 1;
WAsmCode
[0] = 0x0e00 | (Index
<< 15) | ((konst
& 1) << 8) | AdrMode
;
}
}
}
static void DecodeMAC
(Word Index
)
{
if (ChkArgCnt
(2, 3))
{
tEvalResult EvalResult
;
WAsmCode
[1] = EvalStrIntExpressionWithResult
(&ArgStr
[1], Int16
, &EvalResult
);
if (EvalResult.
OK && DecodeAdr
(&ArgStr
[2], 2, 3, False
))
{
ChkSpace
(SegCode
, EvalResult.
AddrSpaceMask);
CodeLen
= 2;
WAsmCode
[0] = 0xa200 | (Index
<< 8) | AdrMode
;
}
}
}
static void DecodeMPY
(Word Index
)
{
LongInt Imm
;
Boolean OK
;
tSymbolFlags Flags
;
if (*ArgStr
[1].
str.
p_str == '#')
{
if (ChkArgCnt
(1, 1))
{
Imm
= EvalStrIntExpressionOffsWithFlags
(&ArgStr
[1], 1, SInt16
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
))
Imm
&= 0xfff;
if (OK
)
{
if ((Imm
< -4096) || (Imm
> 4095))
{
if (ChkMinCPU
(CPU32050
))
{
CodeLen
= 2; /* What does that mean? */
WAsmCode
[0] = 0xbe80;
WAsmCode
[1] = Imm
;
}
}
else
{
CodeLen
= 1;
WAsmCode
[0] = 0xc000 | (Imm
& 0x1fff);
}
}
}
}
else
{
if (ChkArgCnt
(1, 2)
&& DecodeAdr
(&ArgStr
[1], 1, 2, Index
))
{
CodeLen
= 1;
WAsmCode
[0] = 0x5400 | AdrMode
;
}
}
}
static void DecodeNORM
(Word Index
)
{
UNUSED
(Index
);
if (ChkArgCnt
(1, 2)
&& DecodeAdr
(&ArgStr
[1], 1, 2, False
))
{
if (AdrMode
< 0x80) WrError
(ErrNum_InvAddrMode
);
else
{
CodeLen
= 1;
WAsmCode
[0] = 0xa080 | (AdrMode
& 0x7f);
}
}
}
static void DecodeRETC
(Word Index
)
{
if (!ChkArgCnt
(1, 1));
else if (Index
&& !ChkMinCPU
(CPU32050
));
else
{
CodeLen
= 1;
WAsmCode
[0] = 0xec00 | (Index
<< 12) | DecodeCond
(1);
}
}
static void DecodeRPT
(Word Index
)
{
Word Imm
;
Boolean OK
;
UNUSED
(Index
);
if (*ArgStr
[1].
str.
p_str == '#')
{
if (ChkArgCnt
(1, 1))
{
Imm
= EvalStrIntExpressionOffs
(&ArgStr
[1], 1, (MomCPU
>= CPU32050
) ? UInt16
: UInt8
, &OK
);
if (OK
)
{
if (Imm
> 255)
{
CodeLen
= 2;
WAsmCode
[0] = 0xbec4;
WAsmCode
[1] = Imm
;
}
else
{
CodeLen
= 1;
WAsmCode
[0] = 0xbb00 | (Imm
& 0xff);
}
}
}
}
else
{
if (ChkArgCnt
(1, 2))
{
if (DecodeAdr
(&ArgStr
[1], 1, 2, False
))
{
CodeLen
= 1;
WAsmCode
[0] = 0x0b00 | AdrMode
;
}
}
}
}
static void DecodeSAC
(Word Index
)
{
Boolean OK
;
Word Shift
;
if (ChkArgCnt
(1, 3))
{
OK
= True
;
Shift
= (ArgCnt
>= 2) ? EvalStrIntExpression
(&ArgStr
[2], UInt3
, &OK
) : 0;
if ((DecodeAdr
(&ArgStr
[1], 1, 3, False
)) && (OK
))
{
CodeLen
= 1;
WAsmCode
[0] = (Index
<< 11) | 0x9000 | AdrMode
| ((Shift
& 7) << 8);
}
}
}
static void DecodeSAR
(Word Index
)
{
Word Reg
;
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 3))
{
Reg
= EvalARExpression
(&ArgStr
[1], &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[2], 2, 3, False
)))
{
CodeLen
= 1;
WAsmCode
[0] = 0x8000 | ((Reg
& 7) << 8) | AdrMode
;
}
}
}
static void DecodeBSAR
(Word Index
)
{
Word Shift
;
Boolean OK
;
tSymbolFlags Flags
;
UNUSED
(Index
);
if (ChkArgCnt
(1, 1)
&& ChkMinCPU
(CPU32050
))
{
Shift
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt5
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
))
Shift
= 1;
if (OK
)
{
if (ChkRange
(Shift
, 1, 16))
{
CodeLen
= 1;
WAsmCode
[0] = 0xbfe0 | ((Shift
- 1) & 0xf);
}
}
}
}
static void DecodeLSAMM
(Word Index
)
{
if (ChkArgCnt
(1, 2)
&& ChkMinCPU
(CPU32050
)
&& DecodeAdr
(&ArgStr
[1], 1, 2, True
))
{
CodeLen
= 1;
WAsmCode
[0] = 0x0800 | (Index
<< 15) | AdrMode
;
}
}
static void DecodeLSMMR
(Word Index
)
{
Boolean OK
;
if (!ChkArgCnt
(2, 3));
else if (!ChkMinCPU
(CPU32050
));
else if (ArgStr
[2].
str.
p_str[0] != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
WAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[2], 1, Int16
, &OK
);
if ((OK
) && (DecodeAdr
(&ArgStr
[1], 2, 3, True
)))
{
CodeLen
= 2;
WAsmCode
[0] = 0x0900 | (Index
<< 15) | AdrMode
;
}
}
}
static void DecodeRPTB
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(1, 1)
&& ChkMinCPU
(CPU32050
))
{
WAsmCode
[1] = EvalStrIntExpression
(&ArgStr
[1], Int16
, &OK
);
if (OK
)
{
CodeLen
= 2;
WAsmCode
[0] = 0xbec6;
}
}
}
static void DecodeRPTZ
(Word Index
)
{
Boolean OK
;
UNUSED
(Index
);
if (!ChkArgCnt
(1, 1));
else if (!ChkMinCPU
(CPU32050
));
else if (*ArgStr
[1].
str.
p_str != '#') WrError
(ErrNum_OnlyImmAddr
);
else
{
WAsmCode
[1] = EvalStrIntExpressionOffs
(&ArgStr
[1], 1, Int16
, &OK
);
if (OK
)
{
CodeLen
= 2;
WAsmCode
[0] = 0xbec5;
}
}
}
static void DecodeXC
(Word Index
)
{
Word Mode
;
Boolean OK
;
tSymbolFlags Flags
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2)
&& ChkMinCPU
(CPU32050
))
{
Mode
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt2
, &OK
, &Flags
);
if (OK
)
{
if ((Mode
!= 1) && (Mode
!= 2) && !mFirstPassUnknown
(Flags
)) WrError
(ErrNum_UnderRange
);
else
{
CodeLen
= 1;
WAsmCode
[0] = (0xd400 + (Mode
<< 12)) | DecodeCond
(2);
}
}
}
}
static void DecodePORT
(Word Code
)
{
UNUSED
(Code
);
CodeEquate
(SegIO
, 0, 65535);
}
/* ---------------------------------------------------------------------- */
static void AddFixed
(const char *NName
, CPUVar MinCPU
, Word NCode
)
{
order_array_rsv_end
(FixedOrders
, FixedOrder
);
FixedOrders
[InstrZ
].
MinCPU = MinCPU
;
FixedOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeFixed
);
}
static void AddAdr
(const char *NName
, CPUVar MinCPU
, Word NCode
)
{
order_array_rsv_end
(AdrOrders
, FixedOrder
);
AdrOrders
[InstrZ
].
MinCPU = MinCPU
;
AdrOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeCmdAdr
);
}
static void AddJmp
(const char *NName
, CPUVar MinCPU
, Word NCode
, Boolean NCond
)
{
order_array_rsv_end
(JmpOrders
, JmpOrder
);
JmpOrders
[InstrZ
].
MinCPU = MinCPU
;
JmpOrders
[InstrZ
].
Code = NCode
;
JmpOrders
[InstrZ
].
Cond = NCond
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeCmdJmp
);
}
static void AddPlu
(const char *NName
, CPUVar MinCPU
, Word NCode
)
{
order_array_rsv_end
(PluOrders
, FixedOrder
);
PluOrders
[InstrZ
].
MinCPU = MinCPU
;
PluOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeCmdPlu
);
}
static void AddAdrMode
(const char *NName
, CPUVar MinCPU
, Word NMode
)
{
order_array_rsv_end
(AdrModes
, tAdrMode
);
AdrModes
[InstrZ
].
Name = NName
;
AdrModes
[InstrZ
].
MinCPU = MinCPU
;
AdrModes
[InstrZ
++].
Mode = NMode
;
}
static void AddCond
(const char *NName
, CPUVar MinCPU
, Word NCodeAND
, Word NCodeOR
, Byte NIsZL
,
Byte NIsC
, Byte NIsV
, Byte NIsTP
)
{
order_array_rsv_end
(Conditions
, Condition
);
Conditions
[InstrZ
].
Name = NName
;
Conditions
[InstrZ
].
MinCPU = MinCPU
;
Conditions
[InstrZ
].
CodeAND = NCodeAND
;
Conditions
[InstrZ
].
CodeOR = NCodeOR
;
Conditions
[InstrZ
].
IsZL = NIsZL
;
Conditions
[InstrZ
].
IsC = NIsC
;
Conditions
[InstrZ
].
IsV = NIsV
;
Conditions
[InstrZ
++].
IsTP = NIsTP
;
}
static void AddBit
(const char *NName
, CPUVar MinCPU
, Word NCode
)
{
order_array_rsv_end
(BitTable
, tBitTable
);
BitTable
[InstrZ
].
name = NName
;
BitTable
[InstrZ
].
MinCPU = MinCPU
;
BitTable
[InstrZ
++].
Code = NCode
;
}
static void InitFields
(void)
{
InstTable
= CreateInstTable
(203);
InstrZ
= 0;
AddFixed
("ABS", CPU320203
, 0xbe00); AddFixed
("ADCB", CPU32050
, 0xbe11);
AddFixed
("ADDB", CPU32050
, 0xbe10); AddFixed
("ANDB", CPU32050
, 0xbe12);
AddFixed
("CMPL", CPU320203
, 0xbe01); AddFixed
("CRGT", CPU32050
, 0xbe1b);
AddFixed
("CRLT", CPU32050
, 0xbe1c); AddFixed
("EXAR", CPU32050
, 0xbe1d);
AddFixed
("LACB", CPU32050
, 0xbe1f); AddFixed
("NEG", CPU320203
, 0xbe02);
AddFixed
("ORB", CPU32050
, 0xbe13); AddFixed
("ROL", CPU320203
, 0xbe0c);
AddFixed
("ROLB", CPU32050
, 0xbe14); AddFixed
("ROR", CPU320203
, 0xbe0d);
AddFixed
("RORB", CPU32050
, 0xbe15); AddFixed
("SACB", CPU32050
, 0xbe1e);
AddFixed
("SATH", CPU32050
, 0xbe5a); AddFixed
("SATL", CPU32050
, 0xbe5b);
AddFixed
("SBB", CPU32050
, 0xbe18); AddFixed
("SBBB", CPU32050
, 0xbe19);
AddFixed
("SFL", CPU320203
, 0xbe09); AddFixed
("SFLB", CPU32050
, 0xbe16);
AddFixed
("SFR", CPU320203
, 0xbe0a); AddFixed
("SFRB", CPU32050
, 0xbe17);
AddFixed
("XORB", CPU32050
, 0xbe1a); AddFixed
("ZAP", CPU32050
, 0xbe59);
AddFixed
("APAC", CPU320203
, 0xbe04); AddFixed
("PAC", CPU320203
, 0xbe03);
AddFixed
("SPAC", CPU320203
, 0xbe05); AddFixed
("ZPR", CPU32050
, 0xbe58);
AddFixed
("BACC", CPU320203
, 0xbe20); AddFixed
("BACCD", CPU32050
, 0xbe21);
AddFixed
("CALA", CPU320203
, 0xbe30); AddFixed
("CALAD", CPU32050
, 0xbe3d);
AddFixed
("NMI", CPU320203
, 0xbe52); AddFixed
("RET", CPU320203
, 0xef00);
AddFixed
("RETD", CPU32050
, 0xff00); AddFixed
("RETE", CPU32050
, 0xbe3a);
AddFixed
("RETI", CPU32050
, 0xbe38); AddFixed
("TRAP", CPU320203
, 0xbe51);
AddFixed
("IDLE", CPU320203
, 0xbe22); AddFixed
("NOP", CPU320203
, 0x8b00);
AddFixed
("POP", CPU320203
, 0xbe32); AddFixed
("PUSH", CPU320203
, 0xbe3c);
AddFixed
("IDLE2", CPU32050
, 0xbe23);
InstrZ
= 0;
AddAdr
("ADDC", CPU320203
, 0x6000); AddAdr
("ADDS", CPU320203
, 0x6200);
AddAdr
("ADDT", CPU320203
, 0x6300); AddAdr
("LACT", CPU320203
, 0x6b00);
AddAdr
("SUBB", CPU320203
, 0x6400); AddAdr
("SUBC", CPU320203
, 0x0a00);
AddAdr
("SUBS", CPU320203
, 0x6600); AddAdr
("SUBT", CPU320203
, 0x6700);
AddAdr
("ZALR", CPU320203
, 0x6800); AddAdr
("MAR", CPU320203
, 0x8b00);
AddAdr
("LPH", CPU320203
, 0x7500); AddAdr
("LT", CPU320203
, 0x7300);
AddAdr
("LTA", CPU320203
, 0x7000); AddAdr
("LTD", CPU320203
, 0x7200);
AddAdr
("LTP", CPU320203
, 0x7100); AddAdr
("LTS", CPU320203
, 0x7400);
AddAdr
("MADD", CPU32050
, 0xab00); AddAdr
("MADS", CPU32050
, 0xaa00);
AddAdr
("MPYA", CPU320203
, 0x5000); AddAdr
("MPYS", CPU320203
, 0x5100);
AddAdr
("MPYU", CPU320203
, 0x5500); AddAdr
("SPH", CPU320203
, 0x8d00);
AddAdr
("SPL", CPU320203
, 0x8c00); AddAdr
("SQRA", CPU320203
, 0x5200);
AddAdr
("SQRS", CPU320203
, 0x5300); AddAdr
("BLDP", CPU32050
, 0x5700);
AddAdr
("DMOV", CPU320203
, 0x7700); AddAdr
("TBLR", CPU320203
, 0xa600);
AddAdr
("TBLW", CPU320203
, 0xa700); AddAdr
("BITT", CPU320203
, 0x6f00);
AddAdr
("POPD", CPU320203
, 0x8a00); AddAdr
("PSHD", CPU320203
, 0x7600);
InstrZ
= 0;
AddJmp
("B", CPU320203
, 0x7980, False
);
AddJmp
("BD", CPU32050
, 0x7d80, False
);
AddJmp
("BANZ", CPU320203
, 0x7b80, False
);
AddJmp
("BANZD", CPU32050
, 0x7f80, False
);
AddJmp
("BCND", CPU320203
, 0xe000, True
);
AddJmp
("BCNDD", CPU32050
, 0xf000, True
);
AddJmp
("CALL", CPU320203
, 0x7a80, False
);
AddJmp
("CALLD", CPU32050
, 0x7e80, False
);
AddJmp
("CC", CPU320203
, 0xe800, True
);
AddJmp
("CCD", CPU32050
, 0xf800, True
);
InstrZ
= 0;
AddPlu
("APL", CPU32050
, 0x5a00); AddPlu
("CPL", CPU32050
, 0x5b00);
AddPlu
("OPL", CPU32050
, 0x5900); AddPlu
("SPLK", CPU320203
, 0xaa00);
AddPlu
("XPL", CPU32050
, 0x5800);
InstrZ
= 0;
AddAdrMode
( "*-", CPU320203
, 0x90 ); AddAdrMode
( "*+", CPU320203
, 0xa0 );
AddAdrMode
( "*BR0-", CPU320203
, 0xc0 ); AddAdrMode
( "*0-", CPU320203
, 0xd0 );
AddAdrMode
( "*AR0-", CPU32050
, 0xd0 ); AddAdrMode
( "*0+", CPU320203
, 0xe0 );
AddAdrMode
( "*AR0+", CPU32050
, 0xe0 ); AddAdrMode
( "*BR0+", CPU320203
, 0xf0 );
AddAdrMode
( "*", CPU320203
, 0x80 ); AddAdrMode
( NULL
, CPU32050
, 0);
InstrZ
= 0;
AddCond
("EQ", CPU32050
, 0xf33, 0x088, 1, 0, 0, 0);
AddCond
("NEQ", CPU32050
, 0xf33, 0x008, 1, 0, 0, 0);
AddCond
("LT", CPU32050
, 0xf33, 0x044, 1, 0, 0, 0);
AddCond
("LEQ", CPU32050
, 0xf33, 0x0cc, 1, 0, 0, 0);
AddCond
("GT", CPU32050
, 0xf33, 0x004, 1, 0, 0, 0);
AddCond
("GEQ", CPU32050
, 0xf33, 0x08c, 1, 0, 0, 0);
AddCond
("NC", CPU32050
, 0xfee, 0x001, 0, 1, 0, 0);
AddCond
("C", CPU32050
, 0xfee, 0x011, 0, 1, 0, 0);
AddCond
("NOV", CPU32050
, 0xfdd, 0x002, 0, 0, 1, 0);
AddCond
("OV", CPU32050
, 0xfdd, 0x022, 0, 0, 1, 0);
AddCond
("BIO", CPU32050
, 0x0ff, 0x000, 0, 0, 0, 1);
AddCond
("NTC", CPU32050
, 0x0ff, 0x200, 0, 0, 0, 1);
AddCond
("TC", CPU32050
, 0x0ff, 0x100, 0, 0, 0, 1);
AddCond
("UNC", CPU32050
, 0x0ff, 0x300, 0, 0, 0, 1);
AddCond
(NULL
, CPU32050
, 0xfff, 0x000, 0, 0, 0, 0);
InstrZ
= 0;
AddBit
("OVM", CPU320203
, 0xbe42 ); AddBit
("SXM", CPU320203
, 0xbe46 );
AddBit
("HM", CPU32050
, 0xbe48 ); AddBit
("TC", CPU320203
, 0xbe4a );
AddBit
("C", CPU320203
, 0xbe4e ); AddBit
("XF", CPU320203
, 0xbe4c );
AddBit
("CNF", CPU320203
, 0xbe44 ); AddBit
("INTM", CPU320203
, 0xbe40 );
AddBit
(NULL
, CPU32050
, 0 );
AddInstTable
(InstTable
, "ADD" , 0, DecodeADDSUB
);
AddInstTable
(InstTable
, "SUB" , 1, DecodeADDSUB
);
AddInstTable
(InstTable
, "ADRK" , 0, DecodeADRSBRK
);
AddInstTable
(InstTable
, "SBRK" , 1, DecodeADRSBRK
);
AddInstTable
(InstTable
, "AND" , 0x6e01, DecodeLogic
);
AddInstTable
(InstTable
, "OR" , 0x6d02, DecodeLogic
);
AddInstTable
(InstTable
, "XOR" , 0x6c03, DecodeLogic
);
AddInstTable
(InstTable
, "BIT" , 0, DecodeBIT
);
AddInstTable
(InstTable
, "BLDD" , 0, DecodeBLDD
);
AddInstTable
(InstTable
, "BLPD" , 0, DecodeBLPD
);
AddInstTable
(InstTable
, "CLRC" , 0, DecodeCLRSETC
);
AddInstTable
(InstTable
, "SETC" , 1, DecodeCLRSETC
);
AddInstTable
(InstTable
, "CMPR" , 0xbf44, DecodeCMPRSPM
);
AddInstTable
(InstTable
, "SPM" , 0xbf00, DecodeCMPRSPM
);
AddInstTable
(InstTable
, "IN" , 0xaf00, DecodeIO
);
AddInstTable
(InstTable
, "OUT" , 0x0c00, DecodeIO
);
AddInstTable
(InstTable
, "INTR" , 0, DecodeINTR
);
AddInstTable
(InstTable
, "LACC" , 0, DecodeLACC
);
AddInstTable
(InstTable
, "LACL" , 0, DecodeLACL
);
AddInstTable
(InstTable
, "LAR" , 0, DecodeLAR
);
AddInstTable
(InstTable
, "LDP" , 0, DecodeLDP
);
AddInstTable
(InstTable
, "SST" , 1, DecodeLSST
);
AddInstTable
(InstTable
, "LST" , 0, DecodeLSST
);
AddInstTable
(InstTable
, "MAC" , 0, DecodeMAC
);
AddInstTable
(InstTable
, "MACD" , 1, DecodeMAC
);
AddInstTable
(InstTable
, "MPY" , 0, DecodeMPY
);
AddInstTable
(InstTable
, "NORM" , 0, DecodeNORM
);
AddInstTable
(InstTable
, "RETC" , 0, DecodeRETC
);
AddInstTable
(InstTable
, "RETCD", 1, DecodeRETC
);
AddInstTable
(InstTable
, "RPT" , 0, DecodeRPT
);
AddInstTable
(InstTable
, "SACL" , 0, DecodeSAC
);
AddInstTable
(InstTable
, "SACH" , 1, DecodeSAC
);
AddInstTable
(InstTable
, "SAR" , 0, DecodeSAR
);
AddInstTable
(InstTable
, "BSAR" , 0, DecodeBSAR
);
AddInstTable
(InstTable
, "LAMM" , 0, DecodeLSAMM
);
AddInstTable
(InstTable
, "SAMM" , 1, DecodeLSAMM
);
AddInstTable
(InstTable
, "LMMR" , 1, DecodeLSMMR
);
AddInstTable
(InstTable
, "SMMR" , 0, DecodeLSMMR
);
AddInstTable
(InstTable
, "RPTB" , 0, DecodeRPTB
);
AddInstTable
(InstTable
, "RPTZ" , 0, DecodeRPTZ
);
AddInstTable
(InstTable
, "XC" , 0, DecodeXC
);
AddInstTable
(InstTable
, "PORT" , 0, DecodePORT
);
}
static void DeinitFields
(void)
{
DestroyInstTable
(InstTable
);
order_array_free
(FixedOrders
);
order_array_free
(AdrOrders
);
order_array_free
(JmpOrders
);
order_array_free
(PluOrders
);
order_array_free
(AdrModes
);
order_array_free
(Conditions
);
order_array_free
(BitTable
);
}
/* ---------------------------------------------------------------------- */
static void MakeCode_3205x
(void)
{
CodeLen
= 0;
DontPrint
= False
;
/* zu ignorierendes */
if (Memo
(""))
return;
/* Pseudoanweisungen */
if (DecodeTIPseudo
())
return;
/* per Hash-Tabelle */
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
}
/* ---------------------------------------------------------------------- */
static Boolean IsDef_3205x
(void)
{
return Memo
("PORT") || IsTIDef
();
}
/* ---------------------------------------------------------------------- */
static void SwitchFrom_3205x
(void)
{
DeinitFields
();
}
/* ---------------------------------------------------------------------- */
static void SwitchTo_3205x
(void)
{
TurnWords
= False
;
SetIntConstMode
(eIntConstModeIntel
);
PCSymbol
= "$";
HeaderID
= 0x77;
NOPCode
= 0x8b00;
DivideChars
= ",";
HasAttrs
= False
;
ValidSegs
= (1 << SegCode
) | (1 << SegData
) | (1 << SegIO
);
Grans
[SegCode
] = 2; ListGrans
[SegCode
] = 2; SegInits
[SegCode
] = 0;
SegLimits
[SegCode
] = 0xffff;
Grans
[SegData
] = 2; ListGrans
[SegData
] = 2; SegInits
[SegData
] = 0;
SegLimits
[SegData
] = 0xffff;
Grans
[SegIO
] = 2; ListGrans
[SegIO
] = 2; SegInits
[SegIO
] = 0;
SegLimits
[SegIO
] = 0xffff;
MakeCode
= MakeCode_3205x
;
IsDef
= IsDef_3205x
;
SwitchFrom
= SwitchFrom_3205x
;
InitFields
();
}
/* ---------------------------------------------------------------------- */
void code3205x_init
(void)
{
CPU320203
= AddCPU
("320C203", SwitchTo_3205x
);
CPU32050
= AddCPU
("320C50", SwitchTo_3205x
);
CPU32051
= AddCPU
("320C51", SwitchTo_3205x
);
CPU32053
= AddCPU
("320C53", SwitchTo_3205x
);
AddCopyright
("TMS320C5x-Generator (C) 1995/96 Thomas Sailer");
}