/* * 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"); }