1853 lines
43 KiB
C
1853 lines
43 KiB
C
/*
|
|
* AS-Portierung
|
|
*
|
|
* AS-Codegeneratormodul fuer die Texas Instruments TMS320C5x-Familie
|
|
*
|
|
* (C) 1996 Thomas Sailer <sailer@ife.ee.ethz.ch>
|
|
*
|
|
* 20.08.96: Erstellung
|
|
* 7.07.1998 Fix Zugriffe auf CharTransTable wg. signed chars
|
|
* 18.08.1998 BookKeeping-Aufruf in RES
|
|
* 9. 1.1999 ChkPC jetzt ueber SegLimits
|
|
* 30. 5.1999 Erweiterung auf C203 abgeschlossen, Hashtabelle fuer
|
|
* Prozessorbefehle erledigt
|
|
*/
|
|
|
|
#include "stdinc.h"
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "nls.h"
|
|
#include "bpemu.h"
|
|
#include "strutil.h"
|
|
#include "chunks.h"
|
|
#include "asmdef.h"
|
|
#include "asmsub.h"
|
|
#include "asmpars.h"
|
|
#include "asmitree.h"
|
|
#include "codepseudo.h"
|
|
#include "endian.h"
|
|
|
|
#include "code3202x.h"
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
typedef struct {
|
|
char *name;
|
|
CPUVar mincpu;
|
|
Word code;
|
|
} cmd_fixed;
|
|
typedef struct {
|
|
char *name;
|
|
CPUVar mincpu;
|
|
Word code;
|
|
Boolean cond;
|
|
} cmd_jmp;
|
|
typedef struct {
|
|
char *name;
|
|
CPUVar mincpu;
|
|
Word mode;
|
|
} adr_mode_t;
|
|
typedef struct {
|
|
char *name;
|
|
CPUVar mincpu;
|
|
Word codeand;
|
|
Word codeor;
|
|
Byte iszl;
|
|
Byte isc;
|
|
Byte isv;
|
|
Byte istp;
|
|
} condition;
|
|
typedef struct {
|
|
char *name;
|
|
CPUVar mincpu;
|
|
Word code;
|
|
} bit_table_t;
|
|
|
|
static cmd_fixed *cmd_fixed_order;
|
|
#define cmd_fixed_cnt 45
|
|
static cmd_fixed *cmd_adr_order;
|
|
#define cmd_adr_cnt 32
|
|
static cmd_jmp *cmd_jmp_order;
|
|
#define cmd_jmp_cnt 11
|
|
static cmd_fixed *cmd_plu_order;
|
|
#define cmd_plu_cnt 7
|
|
static adr_mode_t *adr_modes;
|
|
#define adr_mode_cnt 10
|
|
static condition *cond_tab;
|
|
#define cond_cnt 15
|
|
static bit_table_t *bit_table;
|
|
#define bit_cnt 9
|
|
|
|
static Word adr_mode;
|
|
static Boolean adr_ok;
|
|
|
|
static CPUVar cpu_320203;
|
|
static CPUVar cpu_32050;
|
|
static CPUVar cpu_32051;
|
|
static CPUVar cpu_32053;
|
|
|
|
static PInstTable InstTable;
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static Word eval_ar_expression(char *asc, Boolean *ok)
|
|
{
|
|
*ok = True;
|
|
|
|
if ((toupper(asc[0]) == 'A') && (toupper(asc[1]) == 'R') && (asc[2] >= '0') &&
|
|
(asc[2] <= '7') && (asc[3] <= '\0'))
|
|
return asc[2] - '0';
|
|
return EvalIntExpression(asc, UInt3, ok);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static Boolean decode_adr(char *arg, int aux, Boolean must1)
|
|
{
|
|
Word h;
|
|
adr_mode_t *am = adr_modes;
|
|
|
|
/* Annahme: nicht gefunden */
|
|
|
|
adr_ok = False;
|
|
|
|
/* Adressierungsmodus suchen */
|
|
|
|
while (am->name && strcasecmp(am->name, arg))
|
|
am++;
|
|
|
|
/* nicht gefunden: dann absolut */
|
|
|
|
if (!am->name)
|
|
BEGIN
|
|
/* ARn-Register darf dann nicht vorhanden sein */
|
|
if (aux <= ArgCnt)
|
|
BEGIN
|
|
WrError(1110); return FALSE;
|
|
END
|
|
|
|
/* Adresse berechnen */
|
|
h = EvalIntExpression(arg, Int16, &adr_ok);
|
|
if (!adr_ok) return FALSE;
|
|
|
|
/* Adresslage pruefen */
|
|
if (must1 && (h >= 0x80) && (!FirstPassUnknown))
|
|
BEGIN
|
|
WrError(1315);
|
|
adr_ok = False;
|
|
return FALSE;
|
|
END
|
|
|
|
/* nur untere 7 Bit gespeichert */
|
|
adr_mode = h & 0x7f;
|
|
ChkSpace(SegData);
|
|
END
|
|
|
|
/* ansonsten evtl. noch Adressregister dazu */
|
|
|
|
else
|
|
BEGIN
|
|
/* auf dieser CPU nicht erlaubter Modus ? */
|
|
|
|
if (am->mincpu > MomCPU)
|
|
BEGIN
|
|
WrError(1505); return FALSE;
|
|
END
|
|
|
|
adr_mode = am->mode;
|
|
if (aux <= ArgCnt)
|
|
BEGIN
|
|
h = eval_ar_expression(ArgStr[aux], &adr_ok);
|
|
if (adr_ok) adr_mode |= 0x8 | h;
|
|
END
|
|
else
|
|
adr_ok = True;
|
|
END
|
|
|
|
return adr_ok;
|
|
END
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static Word decode_cond(int argp)
|
|
{
|
|
condition *cndp;
|
|
Byte cntzl = 0, cntc = 0, cntv = 0, cnttp = 0;
|
|
Word ret = 0x300;
|
|
|
|
while(argp <= ArgCnt) {
|
|
for(cndp = cond_tab;
|
|
cndp->name && strcasecmp(cndp->name, ArgStr[argp]); cndp++);
|
|
if (!cndp->name) {
|
|
WrError(1360);
|
|
return ret;
|
|
}
|
|
ret &= cndp->codeand;
|
|
ret |= cndp->codeor;
|
|
cntzl += cndp->iszl;
|
|
cntc += cndp->isc;
|
|
cntv += cndp->isv;
|
|
cnttp += cndp->istp;
|
|
argp++;
|
|
}
|
|
if ((cnttp > 1) || (cntzl > 1) || (cntv > 1) || (cntc > 1))
|
|
WrXError(1200, ArgStr[argp]); /* invalid condition */
|
|
return ret;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static Word DecodeShift(char *arg, Boolean *ok)
|
|
BEGIN
|
|
Word Shift;
|
|
|
|
FirstPassUnknown = False;
|
|
Shift = EvalIntExpression(arg, UInt5, ok);
|
|
if (*ok)
|
|
BEGIN
|
|
if (FirstPassUnknown) Shift &= 15;
|
|
*ok = ChkRange(Shift, 0, 16);
|
|
END
|
|
return Shift;
|
|
END
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void DecodeFixed(Word Index)
|
|
BEGIN
|
|
cmd_fixed *fo = cmd_fixed_order + Index;
|
|
|
|
if (ArgCnt != 0)
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (fo->mincpu > MomCPU)
|
|
BEGIN
|
|
WrError(1500);
|
|
return;
|
|
END
|
|
|
|
CodeLen = 1;
|
|
WAsmCode[0] = fo->code;
|
|
END
|
|
|
|
static void DecodeCmdAdr(Word Index)
|
|
BEGIN
|
|
cmd_fixed *fo = cmd_adr_order + Index;
|
|
|
|
if ((ArgCnt < 1) OR (ArgCnt > 2))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (MomCPU < fo->mincpu)
|
|
BEGIN
|
|
WrError(1500);
|
|
return;
|
|
END
|
|
|
|
decode_adr(ArgStr[1], 2, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = fo->code | adr_mode;
|
|
END
|
|
END
|
|
|
|
static void DecodeCmdJmp(Word Index)
|
|
BEGIN
|
|
cmd_jmp *jo = cmd_jmp_order + Index;
|
|
Boolean ok;
|
|
|
|
if (MomCPU < jo->mincpu)
|
|
BEGIN
|
|
WrError(1500);
|
|
return;
|
|
END
|
|
|
|
if ((ArgCnt < 1) || ((ArgCnt > 3) && (!jo->cond)))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
adr_mode = 0;
|
|
if (jo->cond)
|
|
adr_mode = decode_cond(2);
|
|
else if (ArgCnt > 1)
|
|
BEGIN
|
|
decode_adr(ArgStr[2], 3, False);
|
|
if (adr_mode < 0x80)
|
|
BEGIN
|
|
WrError(1350);
|
|
return;
|
|
END
|
|
adr_mode &= 0x7f;
|
|
END
|
|
|
|
WAsmCode[1] = EvalIntExpression(ArgStr[1], Int16, &ok);
|
|
if (!ok) return;
|
|
|
|
CodeLen = 2;
|
|
WAsmCode[0] = jo->code | adr_mode;
|
|
END
|
|
|
|
static void DecodeCmdPlu(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
cmd_fixed *fo = cmd_plu_order + Index;
|
|
|
|
if (MomCPU < fo->mincpu) WrError(1500);
|
|
else if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
if ((ArgCnt < 2) OR (ArgCnt > 3)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[2], 3, False);
|
|
WAsmCode[1] = EvalIntExpression(ArgStr[1] + 1, Int16, &ok);
|
|
if ((ok) AND (adr_ok))
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = fo->code | 0x0400 | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
else if (strlen(OpPart) == 4) WrError(1120);
|
|
else
|
|
BEGIN
|
|
if ((ArgCnt < 1) OR (ArgCnt > 2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 2, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = fo->code | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeADDSUB(Word Index)
|
|
BEGIN
|
|
Word Shift;
|
|
LongInt adr_long;
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 1) || (ArgCnt > 3)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
if (ArgCnt > 2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
ok = True;
|
|
if (ArgCnt == 1) Shift = 0;
|
|
else Shift = EvalIntExpression(ArgStr[2], UInt4, &adr_ok);
|
|
if (ok)
|
|
BEGIN
|
|
adr_long = EvalIntExpression(ArgStr[1] + 1, UInt16, &ok);
|
|
if (ok)
|
|
if ((Shift == 0) && (Hi(adr_long) == 0))
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = (Index << 9) | 0xb800 | (adr_long & 0xff);
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = ((Index << 4) + 0xbf90) | (Shift & 0xf);
|
|
WAsmCode[1] = adr_long;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 3, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
ok = True;
|
|
if (ArgCnt >= 2)
|
|
Shift = DecodeShift(ArgStr[2], &ok);
|
|
else
|
|
Shift = 0;
|
|
if (ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
if (Shift == 16)
|
|
WAsmCode[0] = ((Index << 10) | 0x6100) | adr_mode;
|
|
else
|
|
WAsmCode[0] = ((Index << 12) | 0x2000) | ((Shift & 0xf) << 8) | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeADRSBRK(Word Index)
|
|
BEGIN
|
|
Word adr_word;
|
|
Boolean ok;
|
|
|
|
if (ArgCnt != 1)
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (*ArgStr[1] != '#')
|
|
BEGIN
|
|
WrError(1120); /*invalid parameter*/
|
|
return;
|
|
END
|
|
|
|
adr_word = EvalIntExpression(ArgStr[1] + 1, UInt8, &ok);
|
|
if (ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = (Index << 10)| 0x7800 | (adr_word & 0xff);
|
|
END
|
|
END
|
|
|
|
static void DecodeLogic(Word Index)
|
|
BEGIN
|
|
Boolean adr_ok, ok;
|
|
Word Shift;
|
|
|
|
if ((ArgCnt != 1) AND (ArgCnt != 2))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
WAsmCode[1] = EvalIntExpression((ArgStr[1])+1, UInt16, &ok);
|
|
Shift = 0;
|
|
adr_ok = True;
|
|
if (ArgCnt >= 2)
|
|
Shift = DecodeShift(ArgStr[2], &adr_ok);
|
|
if ((ok) AND (adr_ok))
|
|
BEGIN
|
|
CodeLen = 2;
|
|
if (Shift >= 16)
|
|
WAsmCode[0] = 0xbe80 | Lo(Index);
|
|
else
|
|
WAsmCode[0] = 0xbfa0 + ((Index & 3) << 4) + (Shift & 0xf);
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
if (decode_adr(ArgStr[1], 2, False))
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = (Index & 0xff00) | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeBIT(Word Index)
|
|
BEGIN
|
|
Word bit;
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
bit = EvalIntExpression(ArgStr[2], UInt4, &ok);
|
|
|
|
decode_adr(ArgStr[1], 3, False);
|
|
|
|
if ((adr_ok) AND (ok))
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x4000 | adr_mode | ((bit & 0xf) << 8);
|
|
END
|
|
END
|
|
|
|
static void DecodeBLDD(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (!strcasecmp(ArgStr[1], "BMAR"))
|
|
BEGIN
|
|
if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[2], 3, False);
|
|
if (!adr_ok) return;
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xac00 | adr_mode;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (!strcasecmp(ArgStr[2], "BMAR"))
|
|
BEGIN
|
|
if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 3, False);
|
|
if (!adr_ok) return;
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xad00 | adr_mode;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
WAsmCode[1] = EvalIntExpression((ArgStr[1])+1, Int16, &ok);
|
|
decode_adr(ArgStr[2], 3, False);
|
|
if ((!adr_ok) || (!ok)) return;
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xa800 | adr_mode;
|
|
return;
|
|
END
|
|
|
|
if (*ArgStr[2] == '#')
|
|
BEGIN
|
|
WAsmCode[1] = EvalIntExpression((ArgStr[2])+1, Int16, &ok);
|
|
decode_adr(ArgStr[1], 3, False);
|
|
if ((!adr_ok) || (!ok)) return;
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xa900 | adr_mode;
|
|
return;
|
|
END
|
|
|
|
WrError(1350); /* invalid addr mode */
|
|
END
|
|
|
|
static void DecodeBLPD(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (!strcasecmp(ArgStr[1], "BMAR"))
|
|
BEGIN
|
|
if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[2], 3, False);
|
|
if (!adr_ok) return;
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xa400 | adr_mode;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
WAsmCode[1] = EvalIntExpression((ArgStr[1])+1, Int16, &ok);
|
|
decode_adr(ArgStr[2], 3, False);
|
|
if ((!adr_ok) || (!ok)) return;
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xa500 | adr_mode;
|
|
return;
|
|
END
|
|
|
|
WrError(1350); /* invalid addressing mode */
|
|
END
|
|
|
|
static void DecodeCLRSETC(Word Index)
|
|
BEGIN
|
|
bit_table_t *bitp;
|
|
|
|
if (ArgCnt != 1)
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
WAsmCode[0] = Index; NLS_UpString(ArgStr[1]);
|
|
|
|
for(bitp = bit_table; bitp->name; bitp++)
|
|
if (!strcmp(ArgStr[1], bitp->name))
|
|
BEGIN
|
|
if (bitp->mincpu > MomCPU) WrError(1500);
|
|
else
|
|
BEGIN
|
|
WAsmCode[0] |= bitp->code;
|
|
CodeLen = 1;
|
|
END
|
|
return;
|
|
END
|
|
|
|
WrXError(1445, ArgStr[1]); /* invalid instruction */
|
|
END
|
|
|
|
static void DecodeCMPRSPM(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if (ArgCnt != 1)
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
WAsmCode[0] = Index | (EvalIntExpression(ArgStr[1], UInt2, &ok) & 3);
|
|
if (!ok) return;
|
|
CodeLen = 1;
|
|
END
|
|
|
|
static void DecodeIO(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
decode_adr(ArgStr[1],3,False);
|
|
if (!adr_ok) return;
|
|
|
|
WAsmCode[1] = EvalIntExpression(ArgStr[2], UInt16, &ok);
|
|
if (!ok) return;
|
|
ChkSpace(SegIO);
|
|
|
|
CodeLen = 2;
|
|
WAsmCode[0] = Index | adr_mode;
|
|
END
|
|
|
|
static void DecodeINTR(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if (ArgCnt != 1)
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
WAsmCode[0] = EvalIntExpression(ArgStr[1], UInt5, &ok) | 0xbe60;
|
|
if (!ok) return;
|
|
CodeLen = 1;
|
|
END
|
|
|
|
static void DecodeLACC(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
LongWord adr_long;
|
|
Word Shift;
|
|
|
|
if ((ArgCnt < 1) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
if (ArgCnt > 2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
adr_long = EvalIntExpression(ArgStr[1] + 1, Int16, &ok);
|
|
if (ok)
|
|
BEGIN
|
|
Shift = 0;
|
|
adr_ok = True;
|
|
if (ArgCnt > 1)
|
|
Shift = EvalIntExpression(ArgStr[2], UInt4, &adr_ok);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xbf80 | (Shift & 0xf);
|
|
WAsmCode[1] = adr_long;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 3, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
Shift = 0; ok = True;
|
|
if (ArgCnt >= 2)
|
|
Shift = DecodeShift(ArgStr[2], &ok);
|
|
if (ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
if (Shift >= 16)
|
|
WAsmCode[0] = 0x6a00 | adr_mode;
|
|
else
|
|
WAsmCode[0] = 0x1000 | ((Shift & 0xf) << 8) | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeLACL(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
if (ArgCnt != 1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
WAsmCode[0] = EvalIntExpression(ArgStr[1] + 1, UInt8, &ok);
|
|
if (!ok) return;
|
|
CodeLen = 1;
|
|
WAsmCode[0] |= 0xb900;
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
if ((ArgCnt < 1) OR (ArgCnt > 2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 2, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
WAsmCode[0] = 0x6900 | adr_mode;
|
|
CodeLen = 1;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeLAR(Word Index)
|
|
BEGIN
|
|
Word Reg;
|
|
LongWord adr_long;
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
Reg = eval_ar_expression(ArgStr[1], &ok);
|
|
if (!ok) return;
|
|
|
|
if (*ArgStr[2] == '#')
|
|
BEGIN
|
|
if (ArgCnt > 2) WrError(1110);
|
|
adr_long = EvalIntExpression(ArgStr[2] + 1, Int16,
|
|
&adr_ok) & 0xffff;
|
|
if (adr_ok)
|
|
if (adr_long > 255)
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xbf08 | (Reg & 7);
|
|
WAsmCode[1] = adr_long;
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xb000 | ((Reg & 7) << 8) | (adr_long & 0xff);
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[2], 3, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x0000 | ((Reg & 7) << 8) | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeLDP(Word Index)
|
|
BEGIN
|
|
Word konst;
|
|
Boolean ok;
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
if (ArgCnt != 1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
konst = EvalIntExpression(ArgStr[1] + 1, UInt9, &ok);
|
|
if (ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = (konst & 0x1ff) | 0xbc00;
|
|
END
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
if ((ArgCnt != 1) AND (ArgCnt != 2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 2, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x0d00 | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeLSST(Word Index)
|
|
BEGIN
|
|
Word konst;
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
if (*ArgStr[1] != '#')
|
|
BEGIN
|
|
WrError(1120); /* invalid instruction */
|
|
END
|
|
|
|
konst = EvalIntExpression(ArgStr[1] + 1, UInt1, &ok);
|
|
decode_adr(ArgStr[2], 3, Index);
|
|
if ((ok) AND (adr_ok))
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x0e00 | (Index << 15) | ((konst & 1) << 8) | adr_mode;
|
|
END
|
|
END
|
|
|
|
static void DecodeMAC(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) OR (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
WAsmCode[1] = EvalIntExpression(ArgStr[1], Int16, &ok);
|
|
ChkSpace(SegCode);
|
|
|
|
decode_adr(ArgStr[2], 3, False);
|
|
|
|
if ((adr_ok) AND (ok))
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xa200 | (Index << 8) | adr_mode;
|
|
END
|
|
END
|
|
|
|
static void DecodeMPY(Word Index)
|
|
BEGIN
|
|
LongInt Imm;
|
|
Boolean ok;
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
if (ArgCnt != 1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown = FALSE;
|
|
Imm = EvalIntExpression(ArgStr[1] + 1, SInt16, &ok);
|
|
if (FirstPassUnknown) Imm &= 0xfff;
|
|
if (ok)
|
|
if ((Imm < -4096) || (Imm > 4095))
|
|
BEGIN
|
|
if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
CodeLen = 2; /* What does that mean? */
|
|
WAsmCode[0] = 0xbe80;
|
|
WAsmCode[1] = Imm;
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xc000 | (Imm & 0x1fff);
|
|
END
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
if ((ArgCnt < 1) OR (ArgCnt > 2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 2, Index);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x5400 | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeNORM(Word Index)
|
|
BEGIN
|
|
if ((ArgCnt < 1) || (ArgCnt > 2))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
decode_adr(ArgStr[1], 2, False);
|
|
if (adr_ok)
|
|
if (adr_mode < 0x80) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xa080 | (adr_mode & 0x7f);
|
|
END
|
|
END
|
|
|
|
static void DecodeRETC(Word Index)
|
|
BEGIN
|
|
if (ArgCnt < 1) WrError(1110);
|
|
else if ((Memo("RETCD")) AND (MomCPU < cpu_32050)) WrError(1500);
|
|
else
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xec00 | (Index << 12) | decode_cond(1);
|
|
END
|
|
END
|
|
|
|
static void DecodeRPT(Word Index)
|
|
BEGIN
|
|
Word Imm;
|
|
Boolean ok;
|
|
|
|
if (*ArgStr[1] == '#')
|
|
BEGIN
|
|
if (ArgCnt != 1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
Imm = EvalIntExpression(ArgStr[1] + 1, (MomCPU >= cpu_32050) ? UInt16 : UInt8, &ok);
|
|
if (ok)
|
|
if (Imm > 255)
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xbec4;
|
|
WAsmCode[1] = Imm;
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xbb00 | (Imm & 0xff);
|
|
END
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
if ((ArgCnt != 1) AND (ArgCnt != 2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 2, False);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x0b00 | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeSAC(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
Word Shift;
|
|
|
|
if ((ArgCnt < 1) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
ok = True;
|
|
Shift = 0;
|
|
if (ArgCnt >= 2)
|
|
Shift = EvalIntExpression(ArgStr[2], UInt3, &ok);
|
|
|
|
decode_adr(ArgStr[1], 3, False);
|
|
|
|
if ((adr_ok) AND (ok))
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = (Index << 11) | 0x9000 | adr_mode | ((Shift & 7) << 8);
|
|
END
|
|
END
|
|
|
|
static void DecodeSAR(Word Index)
|
|
BEGIN
|
|
Word Reg;
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) || (ArgCnt > 3))
|
|
BEGIN
|
|
WrError(1110);
|
|
return;
|
|
END
|
|
|
|
Reg = eval_ar_expression(ArgStr[1], &ok);
|
|
decode_adr(ArgStr[2], 3, False);
|
|
|
|
if ((adr_ok) AND (ok))
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x8000 | ((Reg & 7) << 8) | adr_mode;
|
|
END
|
|
END
|
|
|
|
static void DecodeBSAR(Word Index)
|
|
BEGIN
|
|
Word Shift;
|
|
Boolean ok;
|
|
|
|
if (ArgCnt != 1) WrError(1110);
|
|
else if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown = False;
|
|
Shift = EvalIntExpression(ArgStr[1], UInt5, &ok);
|
|
if (FirstPassUnknown) Shift = 1;
|
|
if (ok)
|
|
if (ChkRange(Shift, 1, 16))
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0xbfe0 | ((Shift - 1) & 0xf);
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeLSAMM(Word Index)
|
|
BEGIN
|
|
if ((ArgCnt < 1) OR (ArgCnt > 2)) WrError(1110);
|
|
else if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
decode_adr(ArgStr[1], 2, True);
|
|
if (adr_ok)
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = 0x0800 | (Index << 15) | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeLSMMR(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if ((ArgCnt < 2) OR (ArgCnt > 3)) WrError(1110);
|
|
else if (MomCPU < cpu_32050) WrError(1500);
|
|
else if (ArgStr[2][0] != '#') WrError(1120);
|
|
else
|
|
BEGIN
|
|
WAsmCode[1] = EvalIntExpression(ArgStr[2] + 1, Int16, &ok);
|
|
decode_adr(ArgStr[1], 3, True);
|
|
if ((adr_ok) AND (ok))
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0x0900 | (Index << 15) | adr_mode;
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeRPTB(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if (ArgCnt != 1) WrError(1110);
|
|
else if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
WAsmCode[1] = EvalIntExpression(ArgStr[1], Int16, &ok);
|
|
if (ok)
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xbec6;
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeRPTZ(Word Index)
|
|
BEGIN
|
|
Boolean ok;
|
|
|
|
if (ArgCnt != 1) WrError(1110);
|
|
else if (MomCPU < cpu_32050) WrError(1500);
|
|
else if (*ArgStr[1] != '#') WrError(1120);
|
|
else
|
|
BEGIN
|
|
WAsmCode[1] = EvalIntExpression(ArgStr[1] + 1, Int16, &ok);
|
|
if (ok)
|
|
BEGIN
|
|
CodeLen = 2;
|
|
WAsmCode[0] = 0xbec5;
|
|
END
|
|
END
|
|
END
|
|
|
|
static void DecodeXC(Word Index)
|
|
BEGIN
|
|
Word Mode;
|
|
Boolean ok;
|
|
|
|
if (ArgCnt < 2) WrError(1110);
|
|
else if (MomCPU < cpu_32050) WrError(1500);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown = False;
|
|
Mode = EvalIntExpression(ArgStr[1], UInt2, &ok);
|
|
if (ok)
|
|
if ((Mode != 1) && (Mode != 2) && (!FirstPassUnknown)) WrError(1315);
|
|
else
|
|
BEGIN
|
|
CodeLen = 1;
|
|
WAsmCode[0] = (0xd400 + (Mode << 12)) | decode_cond(2);
|
|
END
|
|
END
|
|
END
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static int instrz;
|
|
|
|
static void addfixed(char *nname, CPUVar mincpu, Word ncode)
|
|
{
|
|
if (instrz>=cmd_fixed_cnt) exit(255);
|
|
cmd_fixed_order[instrz].name = nname;
|
|
cmd_fixed_order[instrz].mincpu = mincpu;
|
|
cmd_fixed_order[instrz].code = ncode;
|
|
AddInstTable(InstTable, nname, instrz++, DecodeFixed);
|
|
}
|
|
|
|
static void addadr(char *nname, CPUVar mincpu, Word ncode)
|
|
{
|
|
if (instrz>=cmd_adr_cnt) exit(255);
|
|
cmd_adr_order[instrz].name = nname;
|
|
cmd_adr_order[instrz].mincpu = mincpu;
|
|
cmd_adr_order[instrz].code = ncode;
|
|
AddInstTable(InstTable, nname, instrz++, DecodeCmdAdr);
|
|
}
|
|
|
|
static void addjmp(char *nname, CPUVar mincpu, Word ncode, Boolean ncond)
|
|
{
|
|
if (instrz>=cmd_jmp_cnt) exit(255);
|
|
cmd_jmp_order[instrz].name = nname;
|
|
cmd_jmp_order[instrz].mincpu = mincpu;
|
|
cmd_jmp_order[instrz].code = ncode;
|
|
cmd_jmp_order[instrz].cond = ncond;
|
|
AddInstTable(InstTable, nname, instrz++, DecodeCmdJmp);
|
|
}
|
|
|
|
static void addplu(char *nname, CPUVar mincpu, Word ncode)
|
|
{
|
|
if (instrz>=cmd_plu_cnt) exit(255);
|
|
cmd_plu_order[instrz].name = nname;
|
|
cmd_plu_order[instrz].mincpu = mincpu;
|
|
cmd_plu_order[instrz].code = ncode;
|
|
AddInstTable(InstTable, nname, instrz++, DecodeCmdPlu);
|
|
}
|
|
|
|
static void addadrmode(char *nname, CPUVar mincpu, Word nmode)
|
|
{
|
|
if (instrz>=adr_mode_cnt) exit(255);
|
|
adr_modes[instrz].name = nname;
|
|
adr_modes[instrz].mincpu = mincpu;
|
|
adr_modes[instrz++].mode= nmode;
|
|
}
|
|
|
|
static void addcond(char *nname, CPUVar mincpu, Word ncodeand, Word ncodeor, Byte niszl,
|
|
Byte nisc, Byte nisv, Byte nistp)
|
|
{
|
|
if (instrz>=cond_cnt) exit(255);
|
|
cond_tab[instrz].name = nname;
|
|
cond_tab[instrz].mincpu = mincpu;
|
|
cond_tab[instrz].codeand = ncodeand;
|
|
cond_tab[instrz].codeor = ncodeor;
|
|
cond_tab[instrz].iszl = niszl;
|
|
cond_tab[instrz].isc = nisc;
|
|
cond_tab[instrz].isv = nisv;
|
|
cond_tab[instrz++].istp = nistp;
|
|
}
|
|
|
|
static void addbit(char *nname, CPUVar mincpu, Word ncode)
|
|
{
|
|
if (instrz>=bit_cnt) exit(255);
|
|
bit_table[instrz].name = nname;
|
|
bit_table[instrz].mincpu = mincpu;
|
|
bit_table[instrz++].code = ncode;
|
|
}
|
|
|
|
static void initfields(void)
|
|
{
|
|
InstTable = CreateInstTable(203);
|
|
|
|
cmd_fixed_order=(cmd_fixed *) malloc(sizeof(cmd_fixed)*cmd_fixed_cnt); instrz = 0;
|
|
addfixed("ABS", cpu_320203, 0xbe00); addfixed("ADCB", cpu_32050 , 0xbe11);
|
|
addfixed("ADDB", cpu_32050 , 0xbe10); addfixed("ANDB", cpu_32050 , 0xbe12);
|
|
addfixed("CMPL", cpu_320203, 0xbe01); addfixed("CRGT", cpu_32050 , 0xbe1b);
|
|
addfixed("CRLT", cpu_32050 , 0xbe1c); addfixed("EXAR", cpu_32050 , 0xbe1d);
|
|
addfixed("LACB", cpu_32050 , 0xbe1f); addfixed("NEG", cpu_320203, 0xbe02);
|
|
addfixed("ORB", cpu_32050 , 0xbe13); addfixed("ROL", cpu_320203, 0xbe0c);
|
|
addfixed("ROLB", cpu_32050 , 0xbe14); addfixed("ROR", cpu_320203, 0xbe0d);
|
|
addfixed("RORB", cpu_32050 , 0xbe15); addfixed("SACB", cpu_32050 , 0xbe1e);
|
|
addfixed("SATH", cpu_32050 , 0xbe5a); addfixed("SATL", cpu_32050 , 0xbe5b);
|
|
addfixed("SBB", cpu_32050 , 0xbe18); addfixed("SBBB", cpu_32050 , 0xbe19);
|
|
addfixed("SFL", cpu_320203, 0xbe09); addfixed("SFLB", cpu_32050 , 0xbe16);
|
|
addfixed("SFR", cpu_320203, 0xbe0a); addfixed("SFRB", cpu_32050 , 0xbe17);
|
|
addfixed("XORB", cpu_32050 , 0xbe1a); addfixed("ZAP", cpu_32050 , 0xbe59);
|
|
addfixed("APAC", cpu_320203, 0xbe04); addfixed("PAC", cpu_320203, 0xbe03);
|
|
addfixed("SPAC", cpu_320203, 0xbe05); addfixed("ZPR", cpu_32050 , 0xbe58);
|
|
addfixed("BACC", cpu_320203, 0xbe20); addfixed("BACCD", cpu_32050 , 0xbe21);
|
|
addfixed("CALA", cpu_320203, 0xbe30); addfixed("CALAD", cpu_32050 , 0xbe3d);
|
|
addfixed("NMI", cpu_320203, 0xbe52); addfixed("RET", cpu_320203, 0xef00);
|
|
addfixed("RETD", cpu_32050 , 0xff00); addfixed("RETE", cpu_32050 , 0xbe3a);
|
|
addfixed("RETI", cpu_32050 , 0xbe38); addfixed("TRAP", cpu_320203, 0xbe51);
|
|
addfixed("IDLE", cpu_320203, 0xbe22); addfixed("NOP", cpu_320203, 0x8b00);
|
|
addfixed("POP", cpu_320203, 0xbe32); addfixed("PUSH", cpu_320203, 0xbe3c);
|
|
addfixed("IDLE2", cpu_32050 , 0xbe23);
|
|
|
|
cmd_adr_order = (cmd_fixed *) malloc(sizeof(cmd_fixed)*cmd_adr_cnt); instrz = 0;
|
|
addadr("ADDC", cpu_320203, 0x6000); addadr("ADDS", cpu_320203, 0x6200);
|
|
addadr("ADDT", cpu_320203, 0x6300); addadr("LACT", cpu_320203, 0x6b00);
|
|
addadr("SUBB", cpu_320203, 0x6400); addadr("SUBC", cpu_320203, 0x0a00);
|
|
addadr("SUBS", cpu_320203, 0x6600); addadr("SUBT", cpu_320203, 0x6700);
|
|
addadr("ZALR", cpu_320203, 0x6800); addadr("MAR", cpu_320203, 0x8b00);
|
|
addadr("LPH", cpu_320203, 0x7500); addadr("LT", cpu_320203, 0x7300);
|
|
addadr("LTA", cpu_320203, 0x7000); addadr("LTD", cpu_320203, 0x7200);
|
|
addadr("LTP", cpu_320203, 0x7100); addadr("LTS", cpu_320203, 0x7400);
|
|
addadr("MADD", cpu_32050 , 0xab00); addadr("MADS", cpu_32050 , 0xaa00);
|
|
addadr("MPYA", cpu_320203, 0x5000); addadr("MPYS", cpu_320203, 0x5100);
|
|
addadr("MPYU", cpu_320203, 0x5500); addadr("SPH", cpu_320203, 0x8d00);
|
|
addadr("SPL", cpu_320203, 0x8c00); addadr("SQRA", cpu_320203, 0x5200);
|
|
addadr("SQRS", cpu_320203, 0x5300); addadr("BLDP", cpu_32050 , 0x5700);
|
|
addadr("DMOV", cpu_320203, 0x7700); addadr("TBLR", cpu_320203, 0xa600);
|
|
addadr("TBLW", cpu_320203, 0xa700); addadr("BITT", cpu_320203, 0x6f00);
|
|
addadr("POPD", cpu_320203, 0x8a00); addadr("PSHD", cpu_320203, 0x7600);
|
|
|
|
cmd_jmp_order=(cmd_jmp *) malloc(sizeof(cmd_jmp)*cmd_jmp_cnt); instrz=0;
|
|
addjmp("B", cpu_320203, 0x7980, False);
|
|
addjmp("BD", cpu_32050 , 0x7d80, False);
|
|
addjmp("BANZ", cpu_320203, 0x7b80, False);
|
|
addjmp("BANZD", cpu_32050 , 0x7f80, False);
|
|
addjmp("BCND", cpu_320203, 0xe000, True);
|
|
addjmp("BCNDD", cpu_32050 , 0xf000, True);
|
|
addjmp("CALL", cpu_320203, 0x7a80, False);
|
|
addjmp("CALLD", cpu_32050 , 0x7e80, False);
|
|
addjmp("CC", cpu_320203, 0xe800, True);
|
|
addjmp("CCD", cpu_32050 , 0xf800, True);
|
|
|
|
cmd_plu_order=(cmd_fixed *) malloc(sizeof(cmd_fixed)*cmd_plu_cnt); instrz=0;
|
|
addplu("APL", cpu_32050 , 0x5a00); addplu("CPL", cpu_32050 , 0x5b00);
|
|
addplu("OPL", cpu_32050 , 0x5900); addplu("SPLK", cpu_320203, 0xaa00);
|
|
addplu("XPL", cpu_32050 , 0x5800);
|
|
|
|
adr_modes=(adr_mode_t *) malloc(sizeof(adr_mode_t)*adr_mode_cnt); instrz=0;
|
|
addadrmode( "*-", cpu_320203, 0x90 ); addadrmode( "*+", cpu_320203, 0xa0 );
|
|
addadrmode( "*BR0-", cpu_320203, 0xc0 ); addadrmode( "*0-", cpu_320203, 0xd0 );
|
|
addadrmode( "*AR0-", cpu_32050 , 0xd0 ); addadrmode( "*0+", cpu_320203, 0xe0 );
|
|
addadrmode( "*AR0+", cpu_32050 , 0xe0 ); addadrmode( "*BR0+", cpu_320203, 0xf0 );
|
|
addadrmode( "*", cpu_320203, 0x80 ); addadrmode( NULL, cpu_32050 , 0);
|
|
|
|
cond_tab=(condition *) malloc(sizeof(condition)*cond_cnt); instrz=0;
|
|
addcond("EQ", cpu_32050 , 0xf33, 0x088, 1, 0, 0, 0);
|
|
addcond("NEQ", cpu_32050 , 0xf33, 0x008, 1, 0, 0, 0);
|
|
addcond("LT", cpu_32050 , 0xf33, 0x044, 1, 0, 0, 0);
|
|
addcond("LEQ", cpu_32050 , 0xf33, 0x0cc, 1, 0, 0, 0);
|
|
addcond("GT", cpu_32050 , 0xf33, 0x004, 1, 0, 0, 0);
|
|
addcond("GEQ", cpu_32050 , 0xf33, 0x08c, 1, 0, 0, 0);
|
|
addcond("NC", cpu_32050 , 0xfee, 0x001, 0, 1, 0, 0);
|
|
addcond("C", cpu_32050 , 0xfee, 0x011, 0, 1, 0, 0);
|
|
addcond("NOV", cpu_32050 , 0xfdd, 0x002, 0, 0, 1, 0);
|
|
addcond("OV", cpu_32050 , 0xfdd, 0x022, 0, 0, 1, 0);
|
|
addcond("BIO", cpu_32050 , 0x0ff, 0x000, 0, 0, 0, 1);
|
|
addcond("NTC", cpu_32050 , 0x0ff, 0x200, 0, 0, 0, 1);
|
|
addcond("TC", cpu_32050 , 0x0ff, 0x100, 0, 0, 0, 1);
|
|
addcond("UNC", cpu_32050 , 0x0ff, 0x300, 0, 0, 0, 1);
|
|
addcond(NULL, cpu_32050 , 0xfff, 0x000, 0, 0, 0, 0);
|
|
|
|
bit_table=(bit_table_t *) malloc(sizeof(bit_table_t)*bit_cnt); instrz=0;
|
|
addbit("OVM", cpu_320203, 0xbe42 ); addbit("SXM", cpu_320203, 0xbe46 );
|
|
addbit("HM", cpu_32050 , 0xbe48 ); addbit("TC", cpu_320203, 0xbe4a );
|
|
addbit("C", cpu_320203, 0xbe4e ); addbit("XF", cpu_320203, 0xbe4c );
|
|
addbit("CNF", cpu_320203, 0xbe44 ); addbit("INTM", cpu_320203, 0xbe40 );
|
|
addbit(NULL, cpu_32050 , 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);
|
|
}
|
|
|
|
static void deinitfields(void)
|
|
{
|
|
DestroyInstTable(InstTable);
|
|
free(cmd_fixed_order);
|
|
free(cmd_adr_order);
|
|
free(cmd_jmp_order);
|
|
free(cmd_plu_order);
|
|
free(adr_modes);
|
|
free(cond_tab);
|
|
free(bit_table);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void pseudo_qxx(Integer num)
|
|
{
|
|
int z;
|
|
Boolean ok;
|
|
double res;
|
|
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return;
|
|
}
|
|
for(z = 1; z <= ArgCnt; z++) {
|
|
res = ldexp(EvalFloatExpression(ArgStr[z], Float64, &ok), num);
|
|
if (!ok) {
|
|
CodeLen = 0;
|
|
return;
|
|
}
|
|
if ((res > 32767.49) || (res < -32768.49)) {
|
|
CodeLen = 0;
|
|
WrError(1320);
|
|
return;
|
|
}
|
|
WAsmCode[CodeLen++] = res;
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void pseudo_lqxx(Integer num)
|
|
{
|
|
int z;
|
|
Boolean ok;
|
|
double res;
|
|
LongInt resli;
|
|
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return;
|
|
}
|
|
for(z = 1; z <= ArgCnt; z++) {
|
|
res = ldexp(EvalFloatExpression(ArgStr[z], Float64, &ok), num);
|
|
if (!ok) {
|
|
CodeLen = 0;
|
|
return;
|
|
}
|
|
if ((res > 2147483647.49) || (res < -2147483647.49)) {
|
|
CodeLen = 0;
|
|
WrError(1320);
|
|
return;
|
|
}
|
|
resli = res;
|
|
WAsmCode[CodeLen++] = resli & 0xffff;
|
|
WAsmCode[CodeLen++] = resli >> 16;
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void define_untyped_label(void)
|
|
{
|
|
if (LabPart[0]) {
|
|
PushLocHandle(-1);
|
|
EnterIntSymbol(LabPart, EProgCounter(), SegNone, False);
|
|
PopLocHandle();
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void wr_code_byte(Boolean *ok, int *adr, LongInt val)
|
|
{
|
|
if ((val < -128) || (val > 0xff)) {
|
|
WrError(1320);
|
|
*ok = False;
|
|
return;
|
|
}
|
|
WAsmCode[(*adr)++] = val & 0xff;
|
|
CodeLen = *adr;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void wr_code_word(Boolean *ok, int *adr, LongInt val)
|
|
{
|
|
if ((val < -32768) || (val > 0xffff)) {
|
|
WrError(1320);
|
|
*ok = False;
|
|
return;
|
|
}
|
|
WAsmCode[(*adr)++] = val;
|
|
CodeLen = *adr;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void wr_code_long(Boolean *ok, int *adr, LongInt val)
|
|
{
|
|
WAsmCode[(*adr)++] = val & 0xffff;
|
|
WAsmCode[(*adr)++] = val >> 16;
|
|
CodeLen = *adr;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void wr_code_byte_hilo(Boolean *ok, int *adr, LongInt val)
|
|
{
|
|
if ((val < -128) || (val > 0xff)) {
|
|
WrError(1320);
|
|
*ok = False;
|
|
return;
|
|
}
|
|
if ((*adr) & 1)
|
|
WAsmCode[((*adr)++)/2] |= val & 0xff;
|
|
else
|
|
WAsmCode[((*adr)++)/2] = val << 8;
|
|
CodeLen = ((*adr)+1)/2;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void wr_code_byte_lohi(Boolean *ok, int *adr, LongInt val)
|
|
{
|
|
if ((val < -128) || (val > 0xff)) {
|
|
WrError(1320);
|
|
*ok = False;
|
|
return;
|
|
}
|
|
if ((*adr) & 1)
|
|
WAsmCode[((*adr)++)/2] |= val << 8;
|
|
else
|
|
WAsmCode[((*adr)++)/2] = val & 0xff;
|
|
CodeLen = ((*adr)+1)/2;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
typedef void (*tcallback)(
|
|
#ifdef __PROTOS__
|
|
Boolean *, int *, LongInt
|
|
#endif
|
|
);
|
|
|
|
static void pseudo_store(tcallback callback)
|
|
{
|
|
Boolean ok = True;
|
|
int adr = 0;
|
|
int z;
|
|
TempResult t;
|
|
unsigned char *cp;
|
|
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return;
|
|
}
|
|
define_untyped_label();
|
|
for(z = 1; z <= ArgCnt; z++) {
|
|
if (!ok)
|
|
return;
|
|
EvalExpression(ArgStr[z], &t);
|
|
switch(t.Typ) {
|
|
case TempInt:
|
|
callback(&ok, &adr, t.Contents.Int);
|
|
break;
|
|
case TempFloat:
|
|
WrError(1135);
|
|
return;
|
|
case TempString:
|
|
cp = (unsigned char *)t.Contents.Ascii;
|
|
while (*cp)
|
|
callback(&ok, &adr, CharTransTable[((usint)*cp++)&0xff]);
|
|
break;
|
|
default:
|
|
WrError(1135);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static Boolean decode_pseudo(void)
|
|
{
|
|
Word size;
|
|
Boolean ok;
|
|
TempResult t;
|
|
int z,z2;
|
|
unsigned char *cp;
|
|
float flt;
|
|
double dbl, mant;
|
|
int exp;
|
|
long lmant;
|
|
Word w;
|
|
|
|
if (Memo("PORT")) {
|
|
CodeEquate(SegIO,0,65535);
|
|
return True;
|
|
}
|
|
|
|
if (Memo("RES") || Memo("BSS")) {
|
|
if (ArgCnt != 1) {
|
|
WrError(1110);
|
|
return True;
|
|
}
|
|
if (Memo("BSS"))
|
|
define_untyped_label();
|
|
FirstPassUnknown = False;
|
|
size = EvalIntExpression(ArgStr[1], Int16, &ok);
|
|
if (FirstPassUnknown) {
|
|
WrError(1820);
|
|
return True;
|
|
}
|
|
if (!ok)
|
|
return True;
|
|
DontPrint = True;
|
|
CodeLen = size;
|
|
BookKeeping();
|
|
return True;
|
|
}
|
|
|
|
if (Memo("DATA")) {
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return True;
|
|
}
|
|
ok = True;
|
|
for(z = 1; (z <= ArgCnt) && ok; z++) {
|
|
EvalExpression(ArgStr[z], &t);
|
|
switch(t.Typ) {
|
|
case TempInt:
|
|
if ((t.Contents.Int < -32768) ||
|
|
(t.Contents.Int > 0xffff)) {
|
|
WrError(1320);
|
|
ok = False;
|
|
} else
|
|
WAsmCode[CodeLen++] = t.Contents.Int;
|
|
break;
|
|
default:
|
|
case TempFloat:
|
|
WrError(1135);
|
|
ok = False;
|
|
break;
|
|
case TempString:
|
|
z2 = 0;
|
|
cp = (unsigned char *)t.Contents.Ascii;
|
|
while (*cp) {
|
|
if (z2 & 1)
|
|
WAsmCode[CodeLen++] |=
|
|
(CharTransTable[((usint)*cp++)&0xff]
|
|
<< 8);
|
|
else
|
|
WAsmCode[CodeLen] =
|
|
CharTransTable[((usint)*cp++)&0xff];
|
|
z2++;
|
|
}
|
|
if (z2 & 1)
|
|
CodeLen++;
|
|
break;
|
|
}
|
|
}
|
|
if (!ok)
|
|
CodeLen = 0;
|
|
return True;
|
|
}
|
|
|
|
if (Memo("STRING")) {
|
|
pseudo_store(wr_code_byte_hilo);
|
|
return True;
|
|
}
|
|
if (Memo("RSTRING")) {
|
|
pseudo_store(wr_code_byte_lohi);
|
|
return True;
|
|
}
|
|
if (Memo("BYTE")) {
|
|
pseudo_store(wr_code_byte);
|
|
return True;
|
|
}
|
|
if (Memo("WORD")) {
|
|
pseudo_store(wr_code_word);
|
|
return True;
|
|
}
|
|
if (Memo("LONG")) {
|
|
pseudo_store(wr_code_long);
|
|
return True;
|
|
}
|
|
|
|
/* Qxx */
|
|
|
|
if ((OpPart[0] == 'Q') && (OpPart[1] >= '0') && (OpPart[1] <= '9') &&
|
|
(OpPart[2] >= '0') && (OpPart[2] <= '9') && (OpPart[3] == '\0')) {
|
|
pseudo_qxx(10*(OpPart[1]-'0')+OpPart[2]-'0');
|
|
return True;
|
|
}
|
|
|
|
/* LQxx */
|
|
|
|
if ((OpPart[0] == 'L') && (OpPart[1] == 'Q') && (OpPart[2] >= '0') &&
|
|
(OpPart[2] <= '9') && (OpPart[3] >= '0') && (OpPart[3] <= '9') &&
|
|
(OpPart[4] == '\0')) {
|
|
pseudo_lqxx(10*(OpPart[2]-'0')+OpPart[3]-'0');
|
|
return True;
|
|
}
|
|
|
|
/* Floating point definitions */
|
|
|
|
if (Memo("FLOAT")) {
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return True;
|
|
}
|
|
define_untyped_label();
|
|
ok = True;
|
|
for(z = 1; (z <= ArgCnt) && ok; z++) {
|
|
flt = EvalFloatExpression(ArgStr[z], Float32, &ok);
|
|
memcpy(WAsmCode+CodeLen, &flt, sizeof(float));
|
|
if (BigEndian) {
|
|
w = WAsmCode[CodeLen];
|
|
WAsmCode[CodeLen] = WAsmCode[CodeLen+1];
|
|
WAsmCode[CodeLen+1] = w;
|
|
}
|
|
CodeLen += sizeof(float)/2;
|
|
}
|
|
if (!ok)
|
|
CodeLen = 0;
|
|
return True;
|
|
}
|
|
|
|
if (Memo("DOUBLE")) {
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return True;
|
|
}
|
|
define_untyped_label();
|
|
ok = True;
|
|
for(z = 1; (z <= ArgCnt) && ok; z++) {
|
|
dbl = EvalFloatExpression(ArgStr[z], Float64, &ok);
|
|
memcpy(WAsmCode+CodeLen, &dbl, sizeof(dbl));
|
|
if (BigEndian) {
|
|
w = WAsmCode[CodeLen];
|
|
WAsmCode[CodeLen] = WAsmCode[CodeLen+3];
|
|
WAsmCode[CodeLen+3] = w;
|
|
w = WAsmCode[CodeLen+1];
|
|
WAsmCode[CodeLen+1] = WAsmCode[CodeLen+2];
|
|
WAsmCode[CodeLen+2] = w;
|
|
}
|
|
CodeLen += sizeof(dbl)/2;
|
|
}
|
|
if (!ok)
|
|
CodeLen = 0;
|
|
return True;
|
|
}
|
|
|
|
if (Memo("EFLOAT")) {
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return True;
|
|
}
|
|
define_untyped_label();
|
|
ok = True;
|
|
for(z = 1; (z <= ArgCnt) && ok; z++) {
|
|
dbl = EvalFloatExpression(ArgStr[z], Float64, &ok);
|
|
mant = frexp(dbl, &exp);
|
|
WAsmCode[CodeLen++] = ldexp(mant, 15);
|
|
WAsmCode[CodeLen++] = exp-1;
|
|
}
|
|
if (!ok)
|
|
CodeLen = 0;
|
|
return True;
|
|
}
|
|
|
|
if (Memo("BFLOAT")) {
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return True;
|
|
}
|
|
define_untyped_label();
|
|
ok = True;
|
|
for(z = 1; (z <= ArgCnt) && ok; z++) {
|
|
dbl = EvalFloatExpression(ArgStr[z], Float64, &ok);
|
|
mant = frexp(dbl, &exp);
|
|
lmant = ldexp(mant, 31);
|
|
WAsmCode[CodeLen++] = (lmant & 0xffff);
|
|
WAsmCode[CodeLen++] = (lmant >> 16);
|
|
WAsmCode[CodeLen++] = exp-1;
|
|
}
|
|
if (!ok)
|
|
CodeLen = 0;
|
|
return True;
|
|
}
|
|
|
|
if (Memo("TFLOAT")) {
|
|
if (!ArgCnt) {
|
|
WrError(1110);
|
|
return True;
|
|
}
|
|
define_untyped_label();
|
|
ok = True;
|
|
for(z = 1; (z <= ArgCnt) && ok; z++) {
|
|
dbl = EvalFloatExpression(ArgStr[z], Float64, &ok);
|
|
mant = frexp(dbl, &exp);
|
|
mant = modf(ldexp(mant, 15), &dbl);
|
|
WAsmCode[CodeLen+3] = dbl;
|
|
mant = modf(ldexp(mant, 16), &dbl);
|
|
WAsmCode[CodeLen+2] = dbl;
|
|
mant = modf(ldexp(mant, 16), &dbl);
|
|
WAsmCode[CodeLen+1] = dbl;
|
|
mant = modf(ldexp(mant, 16), &dbl);
|
|
WAsmCode[CodeLen] = dbl;
|
|
CodeLen += 4;
|
|
WAsmCode[CodeLen++] = ((exp - 1) & 0xffff);
|
|
WAsmCode[CodeLen++] = ((exp - 1) >> 16);
|
|
}
|
|
if (!ok)
|
|
CodeLen = 0;
|
|
return True;
|
|
}
|
|
return False;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void make_code_3205x(void)
|
|
BEGIN
|
|
CodeLen = 0;
|
|
DontPrint = False;
|
|
|
|
/* zu ignorierendes */
|
|
|
|
if (Memo("")) return;
|
|
|
|
/* Pseudoanweisungen */
|
|
|
|
if (decode_pseudo()) return;
|
|
|
|
/* per Hash-Tabelle */
|
|
|
|
if (NOT LookupInstTable(InstTable, OpPart)) WrXError(1200, OpPart);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static Boolean is_def_3205x(void)
|
|
{
|
|
static const char *defs[] = { "BSS", "PORT", "STRING", "RSTRING",
|
|
"BYTE", "WORD", "LONG", "FLOAT",
|
|
"DOUBLE", "EFLOAT", "BFLOAT",
|
|
"TFLOAT", NULL };
|
|
const char **cp = defs;
|
|
|
|
while(*cp) {
|
|
if (Memo(*cp))
|
|
return True;
|
|
cp++;
|
|
}
|
|
return False;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void switch_from_3205x(void)
|
|
{
|
|
deinitfields();
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static void switch_to_3205x(void)
|
|
{
|
|
TurnWords = False;
|
|
ConstMode = ConstModeIntel;
|
|
SetIsOccupied = False;
|
|
|
|
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 = make_code_3205x;
|
|
IsDef = is_def_3205x; SwitchFrom = switch_from_3205x;
|
|
initfields();
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
void code3205x_init(void)
|
|
{
|
|
cpu_320203 = AddCPU("320C203", switch_to_3205x);
|
|
cpu_32050 = AddCPU("320C50", switch_to_3205x);
|
|
cpu_32051 = AddCPU("320C51", switch_to_3205x);
|
|
cpu_32053 = AddCPU("320C53", switch_to_3205x);
|
|
|
|
AddCopyright("TMS320C5x-Generator (C) 1995/96 Thomas Sailer");
|
|
}
|