dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/code3202x.c

1123 lines
25 KiB
C

/*
* AS-Portierung
*
* AS-Codegeneratormodul fuer die Texas Instruments TMS320C2x-Familie
*
* (C) 1996 Thomas Sailer <sailer@ife.ee.ethz.ch>
*
* 19.08.96: Erstellung
* 18.01.97: Anpassungen fuer Case-Sensitivitaet
* 7.07.1998 Fix Zugriffe auf CharTransTable wg. signed chars
* 18.08.1998 BookKeeping-Aufruf bei RES
* 9. 1.1999 ChkPC jetzt ueber SegLimits
*/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "strutil.h"
#include "chunks.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "codepseudo.h"
#include "endian.h"
#include "code3202x.h"
/* ---------------------------------------------------------------------- */
typedef struct {
char *name;
Word code;
} cmd_fixed;
typedef struct {
char *name;
Word code;
Boolean must1;
} cmd_adr;
typedef struct {
char *name;
Word code;
Word allow_shifts;
} cmd_adr_shift;
typedef struct {
char *name;
Word code;
Integer Min;
Integer Max;
Word mask;
} cmd_imm;
typedef struct {
char *name;
Word mode;
} adr_mode_t;
static cmd_fixed *cmd_fixed_order;
#define cmd_fixed_cnt 38
static cmd_fixed *cmd_jmp_order;
#define cmd_jmp_cnt 17
static cmd_adr *cmd_adr_order;
#define cmd_adr_cnt 44
static cmd_adr *cmd_adr_2ndadr_order;
#define cmd_adr_2ndadr_cnt 5
static cmd_adr_shift *cmd_adr_shift_order;
#define cmd_adr_shift_cnt 7
static cmd_imm *cmd_imm_order;
#define cmd_imm_cnt 17
static adr_mode_t *adr_modes;
#define adr_mode_cnt 10
static int instrz;
static void addfixed(char *nname, Word ncode)
{
if (instrz>=cmd_fixed_cnt) exit(255);
cmd_fixed_order[instrz].name=nname;
cmd_fixed_order[instrz++].code=ncode;
}
static void addjmp(char *nname, Word ncode)
{
if (instrz>=cmd_jmp_cnt) exit(255);
cmd_jmp_order[instrz].name=nname;
cmd_jmp_order[instrz++].code=ncode;
}
static void addadr(char *nname, Word ncode, Boolean nmust1)
{
if (instrz>=cmd_adr_cnt) exit(255);
cmd_adr_order[instrz].name=nname;
cmd_adr_order[instrz].code=ncode;
cmd_adr_order[instrz++].must1=nmust1;
}
static void add2ndadr(char *nname, Word ncode, Boolean nmust1)
{
if (instrz>=cmd_adr_2ndadr_cnt) exit(255);
cmd_adr_2ndadr_order[instrz].name=nname;
cmd_adr_2ndadr_order[instrz].code=ncode;
cmd_adr_2ndadr_order[instrz++].must1=nmust1;
}
static void addshiftadr(char *nname, Word ncode, Word nallow)
{
if (instrz>=cmd_adr_shift_cnt) exit(255);
cmd_adr_shift_order[instrz].name=nname;
cmd_adr_shift_order[instrz].code=ncode;
cmd_adr_shift_order[instrz++].allow_shifts=nallow;
}
static void addimm(char *nname, Word ncode, Integer nmin, Integer nmax,Word nmask)
{
if (instrz>=cmd_imm_cnt) exit(255);
cmd_imm_order[instrz].name=nname;
cmd_imm_order[instrz].code=ncode;
cmd_imm_order[instrz].Min=nmin;
cmd_imm_order[instrz].Max=nmax;
cmd_imm_order[instrz++].mask=nmask;
}
static void addadrmode(char *nname, Word nmode)
{
if (instrz>=adr_mode_cnt) exit(255);
adr_modes[instrz].name=nname;
adr_modes[instrz++].mode=nmode;
}
static void initfields(void)
{
cmd_fixed_order=(cmd_fixed *) malloc(sizeof(cmd_fixed)*cmd_fixed_cnt); instrz=0;
addfixed("ABS", 0xce1b); addfixed("CMPL", 0xce27);
addfixed("NEG", 0xce23); addfixed("ROL", 0xce34);
addfixed("ROR", 0xce35); addfixed("SFL", 0xce18);
addfixed("SFR", 0xce19); addfixed("ZAC", 0xca00);
addfixed("APAC", 0xce15); addfixed("PAC", 0xce14);
addfixed("SPAC", 0xce16); addfixed("BACC", 0xce25);
addfixed("CALA", 0xce24); addfixed("RET", 0xce26);
addfixed("RFSM", 0xce36); addfixed("RTXM", 0xce20);
addfixed("RXF", 0xce0c); addfixed("SFSM", 0xce37);
addfixed("STXM", 0xce21); addfixed("SXF", 0xce0d);
addfixed("DINT", 0xce01); addfixed("EINT", 0xce00);
addfixed("IDLE", 0xce1f); addfixed("NOP", 0x5500);
addfixed("POP", 0xce1d); addfixed("PUSH", 0xce1c);
addfixed("RC", 0xce30); addfixed("RHM", 0xce38);
addfixed("ROVM", 0xce02); addfixed("RSXM", 0xce06);
addfixed("RTC", 0xce32); addfixed("SC", 0xce31);
addfixed("SHM", 0xce39); addfixed("SOVM", 0xce03);
addfixed("SSXM", 0xce07); addfixed("STC", 0xce33);
addfixed("TRAP", 0xce1e); addfixed(NULL, 0);
cmd_jmp_order=(cmd_fixed *) malloc(sizeof(cmd_fixed)*cmd_jmp_cnt); instrz=0;
addjmp("B", 0xff80); addjmp("BANZ", 0xfb80);
addjmp("BBNZ", 0xf980); addjmp("BBZ", 0xf880);
addjmp("BC", 0x5e80); addjmp("BGEZ", 0xf480);
addjmp("BGZ", 0xf180); addjmp("BIOZ", 0xfa80);
addjmp("BLEZ", 0xf280); addjmp("BLZ", 0xf380);
addjmp("BNC", 0x5f80); addjmp("BNV", 0xf780);
addjmp("BNZ", 0xf580); addjmp("BV", 0xf080);
addjmp("BZ", 0xf680); addjmp("CALL", 0xfe80);
addjmp(NULL, 0);
cmd_adr_order=(cmd_adr *) malloc(sizeof(cmd_adr)*cmd_adr_cnt); instrz=0;
addadr("ADDC", 0x4300, False); addadr("ADDH", 0x4800, False);
addadr("ADDS", 0x4900, False); addadr("ADDT", 0x4a00, False);
addadr("AND", 0x4e00, False); addadr("LACT", 0x4200, False);
addadr("OR", 0x4d00, False); addadr("SUBB", 0x4f00, False);
addadr("SUBC", 0x4700, False); addadr("SUBH", 0x4400, False);
addadr("SUBS", 0x4500, False); addadr("SUBT", 0x4600, False);
addadr("XOR", 0x4c00, False); addadr("ZALH", 0x4000, False);
addadr("ZALR", 0x7b00, False); addadr("ZALS", 0x4100, False);
addadr("LDP", 0x5200, False); addadr("MAR", 0x5500, False);
addadr("LPH", 0x5300, False); addadr("LT", 0x3c00, False);
addadr("LTA", 0x3d00, False); addadr("LTD", 0x3f00, False);
addadr("LTP", 0x3e00, False); addadr("LTS", 0x5b00, False);
addadr("MPY", 0x3800, False); addadr("MPYA", 0x3a00, False);
addadr("MPYS", 0x3b00, False); addadr("MPYU", 0xcf00, False);
addadr("SPH", 0x7d00, False); addadr("SPL", 0x7c00, False);
addadr("SQRA", 0x3900, False); addadr("SQRS", 0x5a00, False);
addadr("DMOV", 0x5600, False); addadr("TBLR", 0x5800, False);
addadr("TBLW", 0x5900, False); addadr("BITT", 0x5700, False);
addadr("LST", 0x5000, False); addadr("LST1", 0x5100, False);
addadr("POPD", 0x7a00, False); addadr("PSHD", 0x5400, False);
addadr("RPT", 0x4b00, False); addadr("SST", 0x7800, True);
addadr("SST1", 0x7900, True); addadr(NULL, 0, False);
cmd_adr_2ndadr_order=(cmd_adr *) malloc(sizeof(cmd_adr)*cmd_adr_2ndadr_cnt); instrz=0;
add2ndadr("BLKD", 0xfd00, False); add2ndadr("BLKP", 0xfc00, False);
add2ndadr("MAC", 0x5d00, False); add2ndadr("MACD", 0x5c00, False);
add2ndadr(NULL, 0, False);
cmd_adr_shift_order=(cmd_adr_shift *) malloc(sizeof(cmd_adr_shift)*cmd_adr_shift_cnt); instrz=0;
addshiftadr("ADD", 0x0000, 0xf); addshiftadr("LAC", 0x2000, 0xf);
addshiftadr("SACH", 0x6800, 0x7); addshiftadr("SACL", 0x6000, 0x7);
addshiftadr("SUB", 0x1000, 0xf); addshiftadr("BIT", 0x9000, 0xf);
addshiftadr(NULL, 0, 0);
cmd_imm_order=(cmd_imm *) malloc(sizeof(cmd_imm)*cmd_imm_cnt); instrz=0;
addimm("ADDK", 0xcc00, 0, 255, 0xff);
addimm("LACK", 0xca00, 0, 255, 0xff);
addimm("SUBK", 0xcd00, 0, 255, 0xff);
addimm("ADRK", 0x7e00, 0, 255, 0xff);
addimm("SBRK", 0x7f00, 0, 255, 0xff);
addimm("RPTK", 0xcb00, 0, 255, 0xff);
addimm("MPYK", 0xa000, -4096, 4095, 0x1fff);
addimm("SPM", 0xce08, 0, 3, 0x3);
addimm("CMPR", 0xce50, 0, 3, 0x3);
addimm("FORT", 0xce0e, 0, 1, 0x1);
addimm("ADLK", 0xd002, 0, 0x7fff, 0xffff);
addimm("ANDK", 0xd004, 0, 0x7fff, 0xffff);
addimm("LALK", 0xd001, 0, 0x7fff, 0xffff);
addimm("ORK", 0xd005, 0, 0x7fff, 0xffff);
addimm("SBLK", 0xd003, 0, 0x7fff, 0xffff);
addimm("XORK", 0xd006, 0, 0x7fff, 0xffff);
addimm(NULL, 0, 0, 0, 0);
adr_modes=(adr_mode_t *) malloc(sizeof(adr_mode_t)*adr_mode_cnt); instrz=0;
addadrmode( "*-", 0x90 ); addadrmode( "*+", 0xa0 );
addadrmode( "*BR0-", 0xc0 ); addadrmode( "*0-", 0xd0 );
addadrmode( "*AR0-", 0xd0 ); addadrmode( "*0+", 0xe0 );
addadrmode( "*AR0+", 0xe0 ); addadrmode( "*BR0+", 0xf0 );
addadrmode( "*", 0x80 ); addadrmode( NULL, 0);
}
static void deinitfields(void)
{
free(cmd_fixed_order);
free(cmd_jmp_order);
free(cmd_adr_order);
free(cmd_adr_2ndadr_order);
free(cmd_adr_shift_order);
free(cmd_imm_order);
free(adr_modes);
}
/* ---------------------------------------------------------------------- */
static Word adr_mode;
static Boolean adr_ok;
static CPUVar cpu_32025, cpu_32026, cpu_32028;
/* ---------------------------------------------------------------------- */
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 void decode_adr(char *arg, int aux, Boolean must1)
{
const adr_mode_t *am = adr_modes;
Byte h;
adr_ok = False;
while (am->name && strcasecmp(am->name, arg))
am++;
if (!am->name) {
if (aux <= ArgCnt) {
WrError(1110);
return;
}
h = EvalIntExpression(arg, Int16, &adr_ok);
if (!adr_ok)
return;
if (must1 && (h >= 0x80) && (!FirstPassUnknown)) {
WrError(1315);
adr_ok = False;
return;
}
adr_mode = h & 0x7f;
ChkSpace(SegData);
return;
}
adr_mode = am->mode;
if (aux <= ArgCnt) {
h = eval_ar_expression(ArgStr[aux], &adr_ok);
if (adr_ok)
adr_mode |= 0x8 | h;
} else
adr_ok = True;
}
/* ---------------------------------------------------------------------- */
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(int 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, 15);
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_3202x(void)
{
Boolean ok;
Word adr_word;
LongInt adr_long;
const cmd_fixed *fo;
const cmd_adr *ao;
const cmd_adr_shift *aso;
const cmd_imm *io;
CodeLen = 0;
DontPrint = False;
/* zu ignorierendes */
if(Memo(""))
return;
/* Pseudoanweisungen */
if(decode_pseudo())
return;
/* prozessorspezifische Befehle */
if(Memo("CNFD")) {
if(ArgCnt) {
WrError(1110);
return;
}
if(MomCPU == cpu_32026) {
WrError(1500);
return;
}
CodeLen = 1;
WAsmCode[0] = 0xce04;
return;
}
if(Memo("CNFP")) {
if(ArgCnt) {
WrError(1110);
return;
}
if(MomCPU == cpu_32026) {
WrError(1500);
return;
}
CodeLen = 1;
WAsmCode[0] = 0xce05;
return;
}
if(Memo("CONF")) {
if(ArgCnt != 1) {
WrError(1110);
return;
}
if(MomCPU != cpu_32026) {
WrError(1500);
return;
}
WAsmCode[0] = 0xce3c|EvalIntExpression(ArgStr[1], UInt2, &ok);
if(ok)
CodeLen = 1;
return;
}
/* kein Argument */
for(fo = cmd_fixed_order; fo->name; fo++) {
if (Memo(fo->name)) {
if(ArgCnt) {
WrError(1110);
return;
}
CodeLen = 1;
WAsmCode[0] = fo->code;
return;
}
}
/* Spruenge */
for(fo = cmd_jmp_order; fo->name; fo++) {
if (Memo(fo->name)) {
if((ArgCnt < 1) || (ArgCnt > 3)) {
WrError(1110);
return;
}
adr_mode = 0;
if(ArgCnt > 1) {
decode_adr(ArgStr[2], 3, False);
if(adr_mode < 0x80)
WrError(1350);
}
WAsmCode[1] = EvalIntExpression(ArgStr[1],
Int16, &ok);
if(ok) {
CodeLen = 2;
WAsmCode[0] = fo->code | (adr_mode & 0x7f);
}
return;
}
}
/* nur Adresse */
for(ao = cmd_adr_order; ao->name; ao++) {
if (Memo(ao->name)) {
if((ArgCnt < 1) || (ArgCnt > 2)) {
WrError(1110);
return;
}
decode_adr(ArgStr[1], 2, ao->must1);
if(adr_ok) {
CodeLen = 1;
WAsmCode[0] = ao->code | adr_mode;
}
return;
}
}
/* 2 Addressen */
for(ao = cmd_adr_2ndadr_order; ao->name; ao++) {
if (Memo(ao->name)) {
if((ArgCnt < 2) || (ArgCnt > 3)) {
WrError(1110);
return;
}
WAsmCode[1] = EvalIntExpression(ArgStr[1], Int16, &ok);
decode_adr(ArgStr[2], 3, ao->must1);
if(ok && adr_ok) {
CodeLen = 2;
WAsmCode[0] = ao->code | adr_mode;
}
return;
}
}
/* Adresse & schieben */
for(aso = cmd_adr_shift_order; aso->name; aso++) {
if (Memo(aso->name)) {
if((ArgCnt < 1) || (ArgCnt > 3)) {
WrError(1110);
return;
}
decode_adr(ArgStr[1], 3, False);
if(!adr_ok)
return;
if(ArgCnt < 2) {
ok = True;
adr_word = 0;
} else {
adr_word = EvalIntExpression(ArgStr[2], Int4,
&ok);
if (ok && FirstPassUnknown)
adr_word = 0;
}
if(!ok)
return;
if(aso->allow_shifts < adr_word) {
WrError(1380);
return;
}
CodeLen = 1;
WAsmCode[0] = aso->code | adr_mode | (adr_word << 8);
return;
}
}
/* Ein/Ausgabe */
if((Memo("IN")) || (Memo("OUT"))) {
if((ArgCnt < 2) || (ArgCnt > 3)) {
WrError(1110);
return;
}
decode_adr(ArgStr[1], 3, False);
if(!adr_ok)
return;
adr_word = EvalIntExpression(ArgStr[2], Int4, &ok);
if(!ok)
return;
ChkSpace(SegIO);
CodeLen = 1;
WAsmCode[0] = ((Memo("OUT")) ? 0xe000 : 0x8000) | adr_mode |
(adr_word << 8);
return;
}
/* konstantes Argument */
for(io = cmd_imm_order; io->name; io++) {
if (Memo(io->name)) {
if((ArgCnt < 1) || (ArgCnt > 2) ||
((ArgCnt == 2) && (io->mask != 0xffff))) {
WrError(1110);
return;
}
adr_long = EvalIntExpression(ArgStr[1], Int32, &ok);
if(!ok)
return;
if(FirstPassUnknown)
adr_long &= io->mask;
if(io->mask == 0xffff) {
if(adr_long < -32768) {
WrError(1315);
return;
}
if(adr_long > 65535) {
WrError(1320);
return;
}
adr_word = 0;
ok = True;
if(ArgCnt == 2) {
adr_word = EvalIntExpression(ArgStr[2],
Int4,
&ok);
if(ok && FirstPassUnknown)
adr_word = 0;
}
if(!ok)
return;
CodeLen = 2;
WAsmCode[0] = io->code | (adr_word << 8);
WAsmCode[1] = adr_long;
return;
}
if(adr_long < io->Min) {
WrError(1315);
return;
}
if(adr_long > io->Max) {
WrError(1320);
return;
}
CodeLen = 1;
WAsmCode[0] = io->code | (adr_long & io->mask);
return;
}
}
/* mit Hilfsregistern */
if(Memo("LARP")) {
if(ArgCnt != 1) {
WrError(1110);
return;
}
adr_word = eval_ar_expression(ArgStr[1], &ok);
if(!ok)
return;
CodeLen = 1;
WAsmCode[0] = 0x5588 | adr_word;
return;
}
if((Memo("LAR")) OR (Memo("SAR"))) {
if((ArgCnt < 2) || (ArgCnt > 3)) {
WrError(1110);
return;
}
adr_word = eval_ar_expression(ArgStr[1], &ok);
if(!ok)
return;
decode_adr(ArgStr[2], 3, False);
if(!adr_ok)
return;
CodeLen = 1;
WAsmCode[0] = ((Memo("SAR")) ? 0x7000 : 0x3000) | adr_mode |
(adr_word << 8);
return;
}
if(Memo("LARK")) {
if(ArgCnt != 2) {
WrError(1110);
return;
}
adr_word = eval_ar_expression(ArgStr[1], &ok);
if(!ok)
return;
WAsmCode[0] = EvalIntExpression(ArgStr[2], Int8, &ok) & 0xff;
if(!ok)
return;
CodeLen = 1;
WAsmCode[0] |= 0xc000 | (adr_word << 8);
return;
}
if(Memo("LRLK")) {
if(ArgCnt != 2) {
WrError(1110);
return;
}
adr_word = eval_ar_expression(ArgStr[1], &ok);
if(!ok)
return;
WAsmCode[1] = EvalIntExpression(ArgStr[2], Int16, &ok);
if(!ok)
return;
CodeLen = 2;
WAsmCode[0] = 0xd000 | (adr_word << 8);
return;
}
if(Memo("LDPK")) {
if(ArgCnt != 1) {
WrError(1110);
return;
}
WAsmCode[0] = ConstIntVal(ArgStr[1], Int16, &ok);
if(ok && (!(WAsmCode[0] & (~0x1ff)))) { /* emulate Int9 */
CodeLen = 1;
WAsmCode[0] = (WAsmCode[0] & 0x1ff) | 0xc800;
return;
}
WAsmCode[0] = EvalIntExpression(ArgStr[1], Int16, &ok);
if(!ok)
return;
ChkSpace(SegData);
CodeLen = 1;
WAsmCode[0] = ((WAsmCode[0] >> 7) & 0x1ff) | 0xc800;
return;
}
if(Memo("NORM")) {
if((ArgCnt != 1)) {
WrError(1110);
return;
}
decode_adr(ArgStr[1], 2, False);
if(!adr_ok)
return;
if(adr_mode < 0x80) {
WrError(1350);
return;
}
CodeLen = 1;
WAsmCode[0] = 0xce82 | (adr_mode & 0x70);
return;
}
WrXError(1200, OpPart);
}
/* ---------------------------------------------------------------------- */
static Boolean is_def_3202x(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_3202x(void)
{
deinitfields();
}
/* ---------------------------------------------------------------------- */
static void switch_to_3202x(void)
{
TurnWords = False;
ConstMode = ConstModeIntel;
SetIsOccupied = False;
PCSymbol = "$";
HeaderID = 0x75;
NOPCode = 0x5500;
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 ] = 0xf;
MakeCode = make_code_3202x;
IsDef = is_def_3202x; SwitchFrom = switch_from_3202x;
initfields();
}
/* ---------------------------------------------------------------------- */
void code3202x_init(void)
{
cpu_32025 = AddCPU("320C25", switch_to_3202x);
cpu_32026 = AddCPU("320C26", switch_to_3202x);
cpu_32028 = AddCPU("320C28", switch_to_3202x);
AddCopyright("TMS320C2x-Generator (C) 1994/96 Thomas Sailer");
}