From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- code3202x.c | 1122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1122 insertions(+) create mode 100644 code3202x.c (limited to 'code3202x.c') diff --git a/code3202x.c b/code3202x.c new file mode 100644 index 0000000..8e7fe9d --- /dev/null +++ b/code3202x.c @@ -0,0 +1,1122 @@ +/* + * AS-Portierung + * + * AS-Codegeneratormodul fuer die Texas Instruments TMS320C2x-Familie + * + * (C) 1996 Thomas Sailer + * + * 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 +#include + +#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"); +} -- cgit v1.2.3