/********************************************************************/ /* NEGA.C */ /********************************************************************/ /* The NEGA compiler, v3.22 */ /* Copyright (C) Mar. 1997 by Tylisha C. Andersen */ /* Original idea developed by Jim Neil, c. 1989 */ /********************************************************************/ #include #include #include #include #include #define isxalpha(c) xalphatbl[(unsigned char) (c)] int FindCond(char *in, char *out); int GetLine(char *buf); int GetStatement(void); int GetToken(char *buf, int flg); void InitToken(void); int IsEmpty(char *buf); int ParseBumping(void); int ParseCond(char *in, char *out, int flip); int ParseStatement(void); int PeekToken(char *buf); int ReadLine(char *buf); void StripComments(char *buf); void soutput(char *s, char *fmt, ...); void xerror(int en); /********************************************************************/ /* Data section */ /********************************************************************/ char xalphatbl[256] = { // see isxalpha() macro 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; char InName[128], OutName[128]; char ErrorBuf[400], GenBuf[300]; char SendBuf[3000], FollowBuf[1000]; char LineBuf[300]; long LineCtr = 0; int LinePos; int BlkStack[30], BlkType[30]; int BlkPtr = -1, NextBlk = 1; int MainBlk = -1; char Strs[32][128]; char Stat[64]; FILE *InFile = NULL, *OutFile = NULL; /********************************************************************/ /* Main procedure */ /********************************************************************/ main(int argc, char *argv[]) { printf("ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ\n" "Û³ The NEGA compiler v3.22 (symbolic assembler) ³Û\n" "Û³ Copyright (C) Mar. 1997 by Tylisha C. Andersen ³Û\n" "ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß\n\n"); if(argc < 2) { printf("Syntax: NEGA file[.N]\n"); exit(1); } strcpy(InName, argv[1]); strupr(InName); if(!strchr(InName, '.')) strcat(InName, ".N"); strcpy(OutName, InName); strcpy(strchr(OutName, '.'), ".ASM"); if((InFile = fopen(InName, "rb")) == NULL) { sprintf(ErrorBuf, "can't open input file %s", InName); xerror(0); } if((OutFile = fopen(OutName, "wb")) == NULL) { sprintf(ErrorBuf, "can't open output file %s", OutName); xerror(1); } setvbuf(InFile, NULL, 16384, _IOFBF); setvbuf(OutFile, NULL, 16384, _IOFBF); printf("input: %s\n", InName); printf("output: %s\n\n", OutName); while(ParseStatement()); printf("\rprocessed %ld lines\n", LineCtr); fclose(InFile); fclose(OutFile); return 0; } /********************************************************************/ /* Parse one statement */ /********************************************************************/ int ParseStatement(void) { int i, j, true_blk, to_follow = 0; int k, sshift; char f_char, *p; static char cond1[5], cond2[5]; static char sbuf[5], ibuf[64]; if(!PeekToken(&f_char)) return 0; // peek token to get char if(!GetStatement()) return 0; // get the statement if(BlkType[true_blk = BlkPtr] == 0) // find the true block true_blk--; FollowBuf[0] = SendBuf[0] = 0; // clear output buffers to_follow = ParseBumping(); // parse pointer bumping if(strchr(Stat, '{') || strchr(Stat, '}')) { ////////////////////////////////////////////////////// BLOCK STRUCTURES FindCond(Stat, cond1); // decode condition(s) FindCond(Stat, cond2); if((p = strchr(Stat, ',')) != NULL) { ////////////////////////////////////////////////////// ELSE CLAUSE if(!strchr(Stat, '{')) goto ps_blkerr; // ELSE must have '{' strcpy(ibuf, p + 1); *(p + 1) = 0; // separate into halves if(ibuf[j = 0] == '.') j = 1; // check for long jump indicator // j = long jump flag k = 0; // assume end jump ok if(!strcmp(Stat, "},")) // nothing ; else if(Stat[0] != '}') { i = true_blk; // find the penultimate block if(--i < 0) goto ps_noblk; if(BlkType[i] == 0) i--; if(!strcmp(Stat, ".},") || !strcmp(Stat, "..},")) { soutput(SendBuf, "\tjmp\t%s?End%04X\n", Stat[1] == '.' ? "" : "short ", BlkStack[i]); k = 1; // end jump not needed } else if(!strcmp(Stat, "?C},") && !strcmp(cond1, "==")) soutput(SendBuf, "\tjcxz\t?End%04X\n", BlkStack[i]); else if(!strcmp(Stat, "-C},") && !strcmp(cond1, "==")) soutput(SendBuf, "\tloopz\t?End%04X\n", BlkStack[i]); else if(!strcmp(Stat, "-C},") && !strcmp(cond1, "<>")) soutput(SendBuf, "\tloopnz\t?End%04X\n", BlkStack[i]); else if(!strcmp(Stat, "-.},")) soutput(SendBuf, "\tloop\t?End%04X\n", BlkStack[i]); else { ParseCond(cond1, sbuf, 0); // parse conditions if(!strcmp(Stat, "C},") || !strcmp(Stat, ".C},")) soutput(SendBuf, "\tj%s\t%s?End%04X\n", sbuf, Stat[0] == '.' ? "" : "short ", BlkStack[i]); else goto ps_blkerr; } } else { ParseCond(cond1, sbuf, 0); // parse other conditions if(!strcmp(Stat, "}C,")) soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]); else if(!strcmp(Stat, "}.,")) soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]); else if(!strcmp(Stat, "}-.,")) soutput(SendBuf, "\tloop\t?Top%04X\n", BlkStack[BlkPtr]); else if(!strcmp(Stat, "}.C,")) { // distant loop ParseCond(cond1, sbuf, k = 1); // parse as reverse if(!j) { // short jump to end soutput(SendBuf, "\tj%s\t?End%04X\n", sbuf, BlkStack[true_blk]); soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]); } else { // long jump to end soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, NextBlk); soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]); soutput(SendBuf, "?Els%04X:\n", NextBlk++); soutput(SendBuf, "\tjmp\t?End%04X\n", BlkStack[true_blk]); } } else if(!strcmp(Stat, "}?C;") && !strcmp(cond1, "==")) { soutput(SendBuf, "\tjcxz\t?Top%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "==")) { soutput(SendBuf, "\tloopz\t?Top%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "<>")) { soutput(SendBuf, "\tloopnz\t?Top%04X\n", BlkStack[BlkPtr]); } else goto ps_blkerr; } if(strchr(Stat, 'C')) // cond1 = second conditional strcpy(cond1, cond2); if(!k) { // output jump to end if not done already soutput(SendBuf, "\tjmp\t%s?End%04X\n", j ? "" : "short ", BlkStack[true_blk]); } soutput(SendBuf, "?Els%04X:\n", BlkStack[BlkPtr]); if(BlkType[BlkPtr] == 1) // if true block, add an else block if(++BlkPtr >= 30) goto ps_nesterr; BlkStack[BlkPtr] = NextBlk++; // set up new block BlkType[BlkPtr] = 0; if(!strcmp(ibuf, "{") || !strcmp(ibuf, ".{")) ; // nothing else if(!strcmp(ibuf, "C{")) { // conditional else ParseCond(cond1, sbuf, 1); soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, BlkStack[BlkPtr]); } else if(!strcmp(ibuf, ".C{")) { // IF clause (near jump) ParseCond(cond1, sbuf, 0); soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]); soutput(SendBuf, "\tjmp\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(ibuf, "?C{") && !strcmp(cond1, "<>")) { soutput(SendBuf, "\tjcxz\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(ibuf, "-.{")) { soutput(SendBuf, "\tloop\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(ibuf, "-C{") && !strcmp(cond1, "<>")) { soutput(SendBuf, "\tloopne\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(ibuf, "-C{") && !strcmp(cond1, "==")) { soutput(SendBuf, "\tloope\t?Els%04X\n", BlkStack[BlkPtr]); } else goto ps_blkerr; soutput(SendBuf, "?Top%04X:\n", BlkStack[BlkPtr]); } else if(strchr(Stat, ';')) { ////////////////////////////////////////////////////// END OF BLOCK if(BlkPtr < 0) goto ps_blkerr; // no block here? if(!strcmp(Stat, "};")) // nothing ; else if(Stat[0] != '}') { i = true_blk; // find the penultimate block if(--i < 0) goto ps_noblk; if(BlkType[i] == 0) i--; if(!strcmp(Stat, ".};") || !strcmp(Stat, "..};")) soutput(SendBuf, "\tjmp\t%s?End%04X\n", Stat[1] == '.' ? "" : "short ", BlkStack[i]); else if(!strcmp(Stat, "?C};") && !strcmp(cond1, "==")) soutput(SendBuf, "\tjcxz\t?End%04X\n", BlkStack[i]); else if(!strcmp(Stat, "-C};") && !strcmp(cond1, "==")) soutput(SendBuf, "\tloopz\t?End%04X\n", BlkStack[i]); else if(!strcmp(Stat, "-C};") && !strcmp(cond1, "<>")) soutput(SendBuf, "\tloopnz\t?End%04X\n", BlkStack[i]); else if(!strcmp(Stat, "-.};")) soutput(SendBuf, "\tloop\t?End%04X\n", BlkStack[i]); else { ParseCond(cond1, sbuf, 0); // parse conditions if(!strcmp(Stat, "C};") || !strcmp(Stat, ".C};")) soutput(SendBuf, "\tj%s\t%s?End%04X\n", sbuf, Stat[0] == '.' ? "" : "short ", BlkStack[i]); else goto ps_blkerr; } } else { ParseCond(cond1, sbuf, 0); // parse other conditions if(!strcmp(Stat, "}C;")) soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]); else if(!strcmp(Stat, "}.;")) soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]); else if(!strcmp(Stat, "}-.;")) soutput(SendBuf, "\tloop\t?Top%04X\n", BlkStack[BlkPtr]); else if(!strcmp(Stat, "}.C;")) { // distant loop ParseCond(cond1, sbuf, 1); // parse as reverse soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, BlkStack[BlkPtr]); soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "}?C;") && !strcmp(cond1, "==")) { soutput(SendBuf, "\tjcxz\t?Top%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "==")) { soutput(SendBuf, "\tloopz\t?Top%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "<>")) { soutput(SendBuf, "\tloopnz\t?Top%04X\n", BlkStack[BlkPtr]); } else goto ps_blkerr; } soutput(SendBuf, "?Els%04X:\n", BlkStack[BlkPtr]); if(BlkType[BlkPtr] == 0) BlkPtr--; soutput(SendBuf, "?End%04X:\n", BlkStack[BlkPtr--]); } else { ////////////////////////////////////////////////////// START OF BLOCK if(++BlkPtr >= 30) goto ps_nesterr; // add a true block BlkStack[BlkPtr] = NextBlk++; BlkType[BlkPtr] = 1; if(!strcmp(Stat, "{")) // nothing ; else if(!strcmp(Stat, "C{")) { // IF clause (short jump) ParseCond(cond1, sbuf, 1); soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, BlkStack[BlkPtr]); } else if(!strcmp(Stat, ".C{")) { // IF clause (near jump) ParseCond(cond1, sbuf, 0); soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]); soutput(SendBuf, "\tjmp\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "?C{") && !strcmp(cond1, "<>")) { soutput(SendBuf, "\tjcxz\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, ".{")) { soutput(SendBuf, "\tjmp\tshort ?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "..{")) { soutput(SendBuf, "\tjmp\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "-.{")) { soutput(SendBuf, "\tloop\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "-C{") && !strcmp(cond1, "<>")) { soutput(SendBuf, "\tloopne\t?Els%04X\n", BlkStack[BlkPtr]); } else if(!strcmp(Stat, "-C{") && !strcmp(cond1, "==")) { soutput(SendBuf, "\tloope\t?Els%04X\n", BlkStack[BlkPtr]); } else goto ps_blkerr; soutput(SendBuf, "?Top%04X:\n", BlkStack[BlkPtr]); } } else if(f_char == 'A') { ////////////////////////////////////////////////////// ALPHA STATEMENT if(!memcmp(Stat, "A=A=", 4)) { // reverse-output command? p = Stat; while(!memcmp(p, "A=", 2)) // check for POP sequence p += 2; if(*p == ';') { // if POP sequence, then i = (p - 2 - Stat) / 2; for(; i >= 0; i--) // output the POPs soutput(SendBuf, "\tpop\t%s\n", Strs[i]); goto ps_output; } else { // chained assignments j = (p - 2 - Stat) / 2; // j = work register p = Stat; i = 0; for(i = 0; i < j; i++) { // output in order soutput(FollowBuf, "\tmov\t%s,%s\n", Strs[i], Strs[j]); } for(i = 0; i < 32 - j; i++) // shift out assignment commands strcpy(Strs[i], Strs[i + j]); memmove(Stat, Stat + j * 2, 64 - j * 2); to_follow = 1; // set follow flag } } j = 1; // current operand sshift = 0; // no shift for now ////////////////////////////////////////////////////// First-op-only commands if(!memcmp(Stat, "A,", 2)) { if(!memcmp(Stat, "A,A*A", 5)) { // three-operand IMUL soutput(SendBuf, "\timul\t%s,%s,%s\n", Strs[0], Strs[1], Strs[2]); sshift = 4; j++; } else if(!strcmp(Stat, "A,AA;")) { // shift right double soutput(SendBuf, "\tshrd\t%s,%s,%s\n", Strs[1], Strs[0], Strs[2]); goto ps_output; } else if(!strcmp(Stat, "A,A=A;")) { // LDS, LES, etc. soutput(SendBuf, "\tl%s\t%s,%s\n", Strs[0], Strs[1], Strs[2]); goto ps_output; } } else if(!strcmp(Stat, "A=;")) { // single POP soutput(SendBuf, "\tpop\t%s\n", Strs[0]); goto ps_output; } else if(!memcmp(Stat, "A=A", 3)) { soutput(SendBuf, "\tmov\t%s,%s\n", Strs[0], Strs[1]); sshift = 2; } else if(!memcmp(Stat, "A=+A", 4)) { soutput(SendBuf, "\tmovzx\t%s,%s\n",Strs[0], Strs[1]); sshift = 3; } else if(!memcmp(Stat, "A=-A", 4)) { soutput(SendBuf, "\tmovsx\t%s,%s\n",Strs[0], Strs[1]); sshift = 4; } else if(!memcmp(Stat, "A=+-A",5)) { soutput(SendBuf, "\tmovsx\t%s,%s\n",Strs[0], Strs[1]); sshift = 4; } else if(!memcmp(Stat, "A==A", 4)) { soutput(SendBuf, "\txchg\t%s,%s\n", Strs[0], Strs[1]); sshift = 3; } else if(!memcmp(Stat, "A===A",5)) { soutput(SendBuf, "\tlea\t%s,%s\n", Strs[0], Strs[1]); sshift = 4; } else if(!memcmp(Stat, "A=", 2)) { strcpy(ibuf, Stat + 2); // conditional set (SETNZ, SETBE, etc.) i = strlen(ibuf) - 1; if(ibuf[i] == ';') { ibuf[i] = 0; if(ParseCond(ibuf, sbuf, 0)) { soutput(SendBuf, "\tset%s\t%s\n", sbuf, Strs[0]); goto ps_output; } } } ////////////////////////////////////////////////////// General commands while(1) { if(sshift > 0) { // shift out first part memmove(Stat+1, Stat+1 + sshift, 63 - sshift); j++; // next operand } if(!strcmp(Stat, "A;") && j > 1) { goto ps_output; } else if(!strcmp(Stat, "A+;")) { soutput(SendBuf, "\tinc\t%s\n", Strs[0]); goto ps_output; } else if(!strcmp(Stat, "A-;")) { soutput(SendBuf, "\tdec\t%s\n", Strs[0]); goto ps_output; } else if(!strcmp(Stat, "A++;")) { soutput(SendBuf, "\tinc\t%s\n\tinc\t%s\n", Strs[0], Strs[0]); goto ps_output; } else if(!strcmp(Stat, "A--;")) { soutput(SendBuf, "\tdec\t%s\n\tdec\t%s\n", Strs[0], Strs[0]); goto ps_output; } else if(!strcmp(Stat, "A&A?")) { soutput(SendBuf, "\ttest\t%s,%s\n", Strs[0], Strs[j]); goto ps_output; } else if(!strcmp(Stat, "A-A?")) { soutput(SendBuf, "\tcmp\t%s,%s\n", Strs[0], Strs[j]); goto ps_output; } else if(!strcmp(Stat, "A?")) { soutput(SendBuf, "\ttest\t%s,%s\n", Strs[0], Strs[0]); goto ps_output; } else if(!memcmp(Stat, "A+++", 4)) { soutput(SendBuf, "\tinc\t%s\n", Strs[0]); j--; sshift = 1; } else if(!memcmp(Stat, "A---", 4)) { soutput(SendBuf, "\tdec\t%s\n", Strs[0]); j--; sshift = 1; } else if(!memcmp(Stat, "A+A", 3)) { soutput(SendBuf, "\tadd\t%s,%s\n", Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "A++A", 4)) { soutput(SendBuf, "\tadc\t%s,%s\n", Strs[0], Strs[j]); sshift = 3; } else if(!memcmp(Stat, "A-A", 3)) { soutput(SendBuf, "\tsub\t%s,%s\n", Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "A--A", 4)) { soutput(SendBuf, "\tsbb\t%s,%s\n", Strs[0], Strs[j]); sshift = 3; } else if(!memcmp(Stat, "A&A", 3)) { soutput(SendBuf, "\tand\t%s,%s\n", Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "A|A", 3)) { soutput(SendBuf, "\tor\t%s,%s\n", Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "A^A", 3)) { soutput(SendBuf, "\txor\t%s,%s\n", Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "A*A", 3)) { soutput(SendBuf, "\timul\t%s,%s\n",Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "AA", 3)) { soutput(SendBuf, "\tshr\t%s,%s\n", Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "A+->A",5)) { soutput(SendBuf, "\tsar\t%s,%s\n", Strs[0], Strs[j]); sshift = 4; } else if(!memcmp(Stat, "A<>A", 4)) { soutput(SendBuf, "\tror\t%s,%s\n", Strs[0], Strs[j]); sshift = 3; } else if(!memcmp(Stat, "A<<>>A",5)) { soutput(SendBuf, "\trcr\t%s,%s\n", Strs[0], Strs[j]); sshift = 4; } else if(!memcmp(Stat, "A**A", 4)) { soutput(SendBuf, "\tmul\t%s,%s\n", Strs[0], Strs[j]); sshift = 3; } else if(!memcmp(Stat, "A/A", 3)) { soutput(SendBuf, "\tidiv\t%s,%s\n",Strs[0], Strs[j]); sshift = 2; } else if(!memcmp(Stat, "A//A", 4)) { soutput(SendBuf, "\tdiv\t%s,%s\n", Strs[0], Strs[j]); sshift = 3; } else { if(j == 1) goto ps_passthru; // pass-through? else goto ps_error; } } } else switch(f_char) { // OTHER STATEMENTS (by char) case '!': if(!strcmp(Stat, "!A;")) soutput(SendBuf, "\tint\t%s\n", Strs[0]); else if(!strcmp(Stat, "!+;")) soutput(SendBuf, "\tsti\n"); else if(!strcmp(Stat, "!-;")) soutput(SendBuf, "\tcli\n"); else if(!strcmp(Stat, "!.=;")) soutput(SendBuf, "\tiret\n"); else if(!strcmp(Stat, "!+-;")) soutput(SendBuf, "\tinto\n"); else goto ps_error; break; case '\"': if(!strcmp(Stat, "\"*;")) soutput(SendBuf, "\taam\n"); else if(!strcmp(Stat, "\"+;")) soutput(SendBuf, "\taaa\n"); else if(!strcmp(Stat, "\"-;")) soutput(SendBuf, "\taas\n"); else if(!strcmp(Stat, "\"/;")) soutput(SendBuf, "\taad\n"); else if(!strcmp(Stat, "\"*A;")) soutput(SendBuf, "\tdb\t0D4h,%s\n", Strs[0]); else if(!strcmp(Stat, "\"/A;")) soutput(SendBuf, "\tdb\t0D5h,%s\n", Strs[0]); else goto ps_error; break; case '#': if(!strcmp(Stat, "#+-;")) soutput(SendBuf, "\tfabs\n"); else if(!strcmp(Stat, "#+;")) soutput(SendBuf, "\tfadd\n"); else if(!strcmp(Stat, "#+A;")) soutput(SendBuf, "\tfadd\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A+A;")) soutput(SendBuf, "\tfadd\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#+.;")) soutput(SendBuf, "\tfaddp\n"); else if(!strcmp(Stat, "#+A.;")) soutput(SendBuf, "\tfaddp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A+A.;")) soutput(SendBuf, "\tfaddp\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#-+;")) soutput(SendBuf, "\tfchs\n"); else if(!strcmp(Stat, "#-?;")) soutput(SendBuf, "\tfcom\n"); else if(!strcmp(Stat, "#-A?;")) soutput(SendBuf, "\tfcom\t%s\n", Strs[0]); else if(!strcmp(Stat, "#-?.;")) soutput(SendBuf, "\tfcomp\n"); else if(!strcmp(Stat, "#-A?.;")) soutput(SendBuf, "\tfcomp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#-?..;")) soutput(SendBuf, "\tfcompp\n"); else if(!strcmp(Stat, "#=-;")) soutput(SendBuf, "\tfdecstp\n"); else if(!strcmp(Stat, "#/;")) soutput(SendBuf, "\tfdiv\n"); else if(!strcmp(Stat, "#/A;")) soutput(SendBuf, "\tfdiv\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A/A;")) soutput(SendBuf, "\tfdiv\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#/.;")) soutput(SendBuf, "\tfdivp\n"); else if(!strcmp(Stat, "#/A.;")) soutput(SendBuf, "\tfdivp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A/A.;")) soutput(SendBuf, "\tfdivp\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#//;")) soutput(SendBuf, "\tfdivr\n"); else if(!strcmp(Stat, "#//A;")) soutput(SendBuf, "\tfdivr\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A//A;")) soutput(SendBuf, "\tfdivr\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#//.;")) soutput(SendBuf, "\tfdivrp\n"); else if(!strcmp(Stat, "#//A.;")) soutput(SendBuf, "\tfdivrp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A//A.;")) soutput(SendBuf, "\tfdivrp\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#&A;")) soutput(SendBuf, "\tffree\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>+A;")) soutput(SendBuf, "\tfiadd\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>-A?;")) soutput(SendBuf, "\tficom\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>-A?.;")) soutput(SendBuf, "\tficomp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>/A;")) soutput(SendBuf, "\tfidiv\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>//A;")) soutput(SendBuf, "\tfidivr\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>=A;")) soutput(SendBuf, "\tfild\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>*A;")) soutput(SendBuf, "\tfimul\t%s\n", Strs[0]); else if(!strcmp(Stat, "#=+;")) soutput(SendBuf, "\tfincstp\n"); else if(!strcmp(Stat, "#;")) soutput(SendBuf, "\tfinit\n"); else if(!strcmp(Stat, "#!;")) soutput(SendBuf, "\tfninit\n"); else if(!strcmp(Stat, "#>A=;")) soutput(SendBuf, "\tfist\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>A=.;")) soutput(SendBuf, "\tfistp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>-A;")) soutput(SendBuf, "\tfisub\t%s\n", Strs[0]); else if(!strcmp(Stat, "#>--A;")) soutput(SendBuf, "\tfisubr\t%s\n", Strs[0]); else if(!strcmp(Stat, "#=A;")) soutput(SendBuf, "\tfld\t%s\n", Strs[0]); else if(!strcmp(Stat, "#*;")) soutput(SendBuf, "\tfmul\n"); else if(!strcmp(Stat, "#*A;")) soutput(SendBuf, "\tfmul\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A*A;")) soutput(SendBuf, "\tfmul\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#*.;")) soutput(SendBuf, "\tfmulp\n"); else if(!strcmp(Stat, "#*A.;")) soutput(SendBuf, "\tfmulp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A*A.;")) soutput(SendBuf, "\tfmulp\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#%;")) soutput(SendBuf, "\tfprem\n"); else if(!strcmp(Stat, "#%%;")) soutput(SendBuf, "\tfprem1\n"); else if(!strcmp(Stat, "#<>;")) soutput(SendBuf, "\tfrndint\n"); else if(!strcmp(Stat, "#**;")) soutput(SendBuf, "\tfscale\n"); else if(!strcmp(Stat, "#A=;")) soutput(SendBuf, "\tfst\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A=.;")) soutput(SendBuf, "\tfstp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A=?;")) soutput(SendBuf, "\tfstsw\t%s\n", Strs[0]); else if(!strcmp(Stat, "#!A=?;")) soutput(SendBuf, "\tfnstsw\t%s\n", Strs[0]); else if(!strcmp(Stat, "#-;")) soutput(SendBuf, "\tfsub\n"); else if(!strcmp(Stat, "#-A;")) soutput(SendBuf, "\tfsub\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A-A;")) soutput(SendBuf, "\tfsub\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#-.;")) soutput(SendBuf, "\tfsubp\n"); else if(!strcmp(Stat, "#-A.;")) soutput(SendBuf, "\tfsubp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A-A.;")) soutput(SendBuf, "\tfsubp\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#--;")) soutput(SendBuf, "\tfsubr\n"); else if(!strcmp(Stat, "#--A;")) soutput(SendBuf, "\tfsubr\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A--A;")) soutput(SendBuf, "\tfsubr\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#--.;")) soutput(SendBuf, "\tfsubrp\n"); else if(!strcmp(Stat, "#--A.;")) soutput(SendBuf, "\tfsubrp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#A--A.;")) soutput(SendBuf, "\tfsubrp\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "#?;")) soutput(SendBuf, "\tftst\n"); else if(!strcmp(Stat, "#<>?;")) soutput(SendBuf, "\tfucom\n"); else if(!strcmp(Stat, "#<>A?;")) soutput(SendBuf, "\tfucom\t%s\n", Strs[0]); else if(!strcmp(Stat, "#<>?.;")) soutput(SendBuf, "\tfucomp\n"); else if(!strcmp(Stat, "#<>A?.;")) soutput(SendBuf, "\tfucomp\t%s\n", Strs[0]); else if(!strcmp(Stat, "#<>?..;")) soutput(SendBuf, "\tfucompp\n"); else if(!strcmp(Stat, "#.;")) soutput(SendBuf, "\tfwait\n"); else if(!strcmp(Stat, "#??;")) soutput(SendBuf, "\tfxam\n"); else if(!strcmp(Stat, "#==;")) soutput(SendBuf, "\tfxch\n"); else if(!strcmp(Stat, "#==A;")) soutput(SendBuf, "\tfxch\t%s\n", Strs[0]); else goto ps_error; break; case '%': if(!strcmp(Stat, "%.A;")) soutput(SendBuf, "\textrn\t%s:proc\n\tcall\t%s\n", Strs[0], Strs[0]); else if(!strcmp(Stat, "%=;")) soutput(SendBuf, "\tpopa\n"); else goto ps_error; break; case '&': if(!strcmp(Stat, "&&A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "&&;")) goto ps_parsebrk0; else if(!strcmp(Stat, "&;")) soutput(SendBuf, "\tclc\n"); else if(!strcmp(Stat, "&A;")) soutput(SendBuf, "\tsub\t%s,%s\n", Strs[0], Strs[0]); else goto ps_error; break; case '\'': if(!strcmp(Stat, "\'+;")) soutput(SendBuf, "\tdaa\n"); else if(!strcmp(Stat, "\'-;")) soutput(SendBuf, "\tdas\n"); else goto ps_error; break; case '*': if(!strcmp(Stat, "**A;")) soutput(SendBuf, "\tmul\t%s\n", Strs[0]); else if(!strcmp(Stat, "*A;")) soutput(SendBuf, "\timul\t%s\n", Strs[0]); else if(!strcmp(Stat, "*;")) soutput(SendBuf, "\tcbw\n"); else if(!strcmp(Stat, "**;")) soutput(SendBuf, "\tcwd\n"); else if(!strcmp(Stat, "****;")) soutput(SendBuf, "\tcdq\n"); else if(!strcmp(Stat, "*=;")) soutput(SendBuf, "\tstosb\n"); else if(!strcmp(Stat, "**=;")) soutput(SendBuf, "\tstosw\n"); else if(!strcmp(Stat, "****=;")) soutput(SendBuf, "\tstosd\n"); else if(!strcmp(Stat, "*=*;")) soutput(SendBuf, "\tmovsb\n"); else if(!strcmp(Stat, "**=**;")) soutput(SendBuf, "\tmovsw\n"); else if(!strcmp(Stat, "****=****;")) soutput(SendBuf, "\tmovsd\n"); else if(!strcmp(Stat, "*-?")) soutput(SendBuf, "\tscasb\n"); else if(!strcmp(Stat, "**-?")) soutput(SendBuf, "\tscasw\n"); else if(!strcmp(Stat, "****-?")) soutput(SendBuf, "\tscasd\n"); else if(!strcmp(Stat, "*-*?")) soutput(SendBuf, "\tcmpsb\n"); else if(!strcmp(Stat, "**-**?")) soutput(SendBuf, "\tcmpsw\n"); else if(!strcmp(Stat, "****-****?")) soutput(SendBuf, "\tcmpsd\n"); else if(!strcmp(Stat, "*=@;")) soutput(SendBuf, "\tinsb\n"); else if(!strcmp(Stat, "**=@;")) soutput(SendBuf, "\tinsw\n"); else if(!strcmp(Stat, "****=@;")) soutput(SendBuf, "\tinsd\n"); else if(!strcmp(Stat, "**=@@;")) soutput(SendBuf, "\tinsw\n"); else if(!strcmp(Stat, "****=@@@@;")) soutput(SendBuf, "\tinsd\n"); else if(!strcmp(Stat, "*A=;")) soutput(SendBuf, "\tstos\t%s\n", Strs[0]); else if(!strcmp(Stat, "*A=*A;")) soutput(SendBuf, "\tmovs\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "*A-?")) soutput(SendBuf, "\tscas\t%s\n", Strs[0]); else if(!strcmp(Stat, "*A-*A?")) soutput(SendBuf, "\tcmps\t%s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "*A=@;")) soutput(SendBuf, "\tins\t%s\n", Strs[0]); else goto ps_error; break; case '+': if(!strcmp(Stat, "++A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "+-A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "++;")) goto ps_parsebrk0; else if(!strcmp(Stat, "+-;")) goto ps_parsebrk0; else if(!strcmp(Stat, "+;")) soutput(SendBuf, "\tcld\n"); else goto ps_error; break; case '-': if(!strcmp(Stat, "-.;")) { // Break by LOOP if(true_blk < 0) goto ps_noblk; soutput(SendBuf, "\tloop\t?End%04X\n", BlkStack[true_blk]); } else if(!strcmp(Stat, "-==;")) { // Break by LOOPZ if(true_blk < 0) goto ps_noblk; soutput(SendBuf, "\tloopz\t?End%04X\n", BlkStack[true_blk]); } else if(!strcmp(Stat, "-<>;")) { // Break by LOOPNZ if(true_blk < 0) goto ps_noblk; soutput(SendBuf, "\tloopnz\t?End%04X\n", BlkStack[true_blk]); } else if(!strcmp(Stat, "--A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "-+A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "--;")) goto ps_parsebrk0; else if(!strcmp(Stat, "-+;")) goto ps_parsebrk0; else if(!strcmp(Stat, "-;")) soutput(SendBuf, "\tstd\n"); else if(!strcmp(Stat, "-A;")) soutput(SendBuf, "\tneg\t%s\n", Strs[0]); else if(!strcmp(Stat, "-.A;")) soutput(SendBuf, "\tloop\t%s\n", Strs[0]); else if(!strcmp(Stat, "-==A;")) soutput(SendBuf, "\tloopz\t%s\n", Strs[0]); else if(!strcmp(Stat, "-<>A;")) soutput(SendBuf, "\tloopnz\t%s\n", Strs[0]); else goto ps_error; break; case '.': if(!strcmp(Stat, ".A;") || !strcmp(Stat, "..A;")) { if(Strs[0][1] == 0 && isdigit(Strs[0][0])) { j = Strs[0][0] - '0'; // break multi-level for(i = 0; i < j; i++) { if(--true_blk < 0) goto ps_noblk; if(BlkType[true_blk] == 0) true_blk--; } soutput(SendBuf, "\tjmp\t%s?End%04X\n", Stat[1] == '.' ? "" : "short ", BlkStack[true_blk]); } else { soutput(SendBuf, "\tjmp\t%s%s\n", Stat[1] == '.' ? "" : "short ", Strs[0]); } } else if(!strcmp(Stat, ".;") || !strcmp(Stat, "..;")) { if(true_blk < 0) goto ps_noblk; // break out of block soutput(SendBuf, "\tjmp\t%s?End%04X\n", Stat[1] == '.' ? "" : "short ", BlkStack[true_blk]); } else if(!strcmp(Stat, ".=;")) soutput(SendBuf, "\tret\n"); else if(!strcmp(Stat, ".=A;")) soutput(SendBuf, "\tret\t%s\n", Strs[0]); else if(!strcmp(Stat, "...;")) soutput(SendBuf, "\twait\n"); else if(!strcmp(Stat, "....;")) soutput(SendBuf, "\thlt\n"); else if(strchr(Stat, 'A')) goto ps_parsejcc0; else goto ps_parsebrk0; break; case '/': if(!strcmp(Stat, "//A;")) soutput(SendBuf, "\tdiv\t%s\n", Strs[0]); else if(!strcmp(Stat, "/A;")) soutput(SendBuf, "\tidiv\t%s\n", Strs[0]); else goto ps_error; break; case '<': if(!strcmp(Stat, "<A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "<<;")) goto ps_parsebrk0; else if(!strcmp(Stat, "<<=;")) goto ps_parsebrk0; else if(!strcmp(Stat, "<;")) goto ps_parsebrk0; else if(!strcmp(Stat, "<=;")) goto ps_parsebrk0; else if(!strcmp(Stat, "<>;")) goto ps_parsebrk0; else if(!strcmp(Stat, "<>=*;")) soutput(SendBuf, "\trep\tlodsb\n"); else if(!strcmp(Stat, "<>=**;")) soutput(SendBuf, "\trep\tlodsw\n"); else if(!strcmp(Stat, "<>=****;")) soutput(SendBuf, "\trep\tlodsd\n"); else if(!strcmp(Stat, "<>*=;")) soutput(SendBuf, "\trep\tstosb\n"); else if(!strcmp(Stat, "<>**=;")) soutput(SendBuf, "\trep\tstosw\n"); else if(!strcmp(Stat, "<>****=;")) soutput(SendBuf, "\trep\tstosd\n"); else if(!strcmp(Stat, "<>*=*;")) soutput(SendBuf, "\trep\tmovsb\n"); else if(!strcmp(Stat, "<>**=**;")) soutput(SendBuf, "\trep\tmovsw\n"); else if(!strcmp(Stat, "<>****=****;")) soutput(SendBuf, "\trep\tmovsd\n"); else if(!strcmp(Stat, "<>*-?")) soutput(SendBuf, "\trepne\tscasb\n"); else if(!strcmp(Stat, "<>**-?")) soutput(SendBuf, "\trepne\tscasw\n"); else if(!strcmp(Stat, "<>****-?")) soutput(SendBuf, "\trepne\tscasd\n"); else if(!strcmp(Stat, "<>*-*?")) soutput(SendBuf, "\trepne\tcmpsb\n"); else if(!strcmp(Stat, "<>**-**?")) soutput(SendBuf, "\trepne\tcmpsw\n"); else if(!strcmp(Stat, "<>****-****?")) soutput(SendBuf, "\trepne\tcmpsd\n"); else if(!strcmp(Stat, "<>*=@;")) soutput(SendBuf, "\trep\tinsb\n"); else if(!strcmp(Stat, "<>**=@@;")) soutput(SendBuf, "\trep\tinsw\n"); else if(!strcmp(Stat, "<>****=@@@@;")) soutput(SendBuf, "\trep\tinsd\n"); else if(!strcmp(Stat, "<>**=@;")) soutput(SendBuf, "\trep\tinsw\n"); else if(!strcmp(Stat, "<>****=@;")) soutput(SendBuf, "\trep\tinsd\n"); else if(!strcmp(Stat, "<>@=*;")) soutput(SendBuf, "\trep\toutsb\n"); else if(!strcmp(Stat, "<>@=**;")) soutput(SendBuf, "\trep\toutsw\n"); else if(!strcmp(Stat, "<>@=****;")) soutput(SendBuf, "\trep\toutsd\n"); else if(!strcmp(Stat, "<>@@=**;")) soutput(SendBuf, "\trep\toutsw\n"); else if(!strcmp(Stat, "<>@@@@=****;")) soutput(SendBuf, "\trep\toutsd\n"); else if(!strcmp(Stat, "<>=*A;")) soutput(SendBuf, "\trep\tlods %s\n", Strs[0]); else if(!strcmp(Stat, "<>*A=;")) soutput(SendBuf, "\trep\tstos %s\n", Strs[0]); else if(!strcmp(Stat, "<>*A=*A;")) soutput(SendBuf, "\trep\tmovs %s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "<>*A-?")) soutput(SendBuf, "\trepne\tscas %s\n", Strs[0]); else if(!strcmp(Stat, "<>*A-*A?")) soutput(SendBuf, "\trepne\tcmps %s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "<>*A=@;")) soutput(SendBuf, "\trep\tins %s\n", Strs[0]); else if(!strcmp(Stat, "<>@=*A;")) soutput(SendBuf, "\trep\touts %s\n", Strs[0]); else goto ps_error; break; case '=': if(!memcmp(Stat, "=A", 2)) { // PUSH sequence i = 0; p = Stat; while(!memcmp(p, "=A", 2)) { soutput(SendBuf, "\tpush\t%s\n", Strs[i]); p += 2; i++; }; if(*p != ';') goto ps_error; } else if(!strcmp(Stat, "==A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "=<>A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "=A;")) goto ps_parsejcc0; else if(!strcmp(Stat, "==;")) goto ps_parsebrk0; else if(!strcmp(Stat, "=<<;")) goto ps_parsebrk0; else if(!strcmp(Stat, "=<;")) goto ps_parsebrk0; else if(!strcmp(Stat, "=>>;")) goto ps_parsebrk0; else if(!strcmp(Stat, "=>;")) goto ps_parsebrk0; else if(!strcmp(Stat, "=.A;")) soutput(SendBuf, "\tcall\t%s\n", Strs[0]); else if(!strcmp(Stat, "=??;")) soutput(SendBuf, "\tpushf\n"); else if(!strcmp(Stat, "=????;")) soutput(SendBuf, "\tpushfd\n"); else if(!strcmp(Stat, "=?;")) soutput(SendBuf, "\tlahf\n"); else if(!strcmp(Stat, "=;")) soutput(SendBuf, "\tdb\t0D6h\n"); else if(!strcmp(Stat, "=+A;")) soutput(SendBuf, "\tenter\t%s,0\n", Strs[0]); else if(!strcmp(Stat, "=-;")) soutput(SendBuf, "\tleave\n"); else if(!strcmp(Stat, "=%;")) soutput(SendBuf, "\tpusha\n"); else if(!strcmp(Stat, "=@;")) soutput(SendBuf, "\tin\tal,dx\n"); else if(!strcmp(Stat, "=@@;")) soutput(SendBuf, "\tin\tax,dx\n"); else if(!strcmp(Stat, "=@@@@;")) soutput(SendBuf, "\tin\teax,dx\n"); else if(!strcmp(Stat, "=@A;")) soutput(SendBuf, "\tin\tal,%s\n", Strs[0]); else if(!strcmp(Stat, "=@@A;")) soutput(SendBuf, "\tin\tax,%s\n", Strs[0]); else if(!strcmp(Stat, "=@@@@A;")) soutput(SendBuf, "\tin\teax,%s\n", Strs[0]); else if(!strcmp(Stat, "=*;")) soutput(SendBuf, "\tlodsb\n"); else if(!strcmp(Stat, "=**;")) soutput(SendBuf, "\tlodsw\n"); else if(!strcmp(Stat, "=****;")) soutput(SendBuf, "\tlodsd\n"); else if(!strcmp(Stat, "=*A;")) soutput(SendBuf, "\tlods\t%s\n", Strs[0]); else if(!strcmp(Stat, "===*;")) soutput(SendBuf, "\trep\tlodsb\n"); else if(!strcmp(Stat, "===**;")) soutput(SendBuf, "\trep\tlodsw\n"); else if(!strcmp(Stat, "===****;")) soutput(SendBuf, "\trep\tlodsd\n"); else if(!strcmp(Stat, "==*=;")) soutput(SendBuf, "\trep\tstosb\n"); else if(!strcmp(Stat, "==**=;")) soutput(SendBuf, "\trep\tstosw\n"); else if(!strcmp(Stat, "==****=;")) soutput(SendBuf, "\trep\tstosd\n"); else if(!strcmp(Stat, "==*=*;")) soutput(SendBuf, "\trep\tmovsb\n"); else if(!strcmp(Stat, "==**=**;")) soutput(SendBuf, "\trep\tmovsw\n"); else if(!strcmp(Stat, "==****=****;")) soutput(SendBuf, "\trep\tmovsd\n"); else if(!strcmp(Stat, "==*-?")) soutput(SendBuf, "\trepe\tscasb\n"); else if(!strcmp(Stat, "==**-?")) soutput(SendBuf, "\trepe\tscasw\n"); else if(!strcmp(Stat, "==****-?")) soutput(SendBuf, "\trepe\tscasd\n"); else if(!strcmp(Stat, "==*-*?")) soutput(SendBuf, "\trepe\tcmpsb\n"); else if(!strcmp(Stat, "==**-**?")) soutput(SendBuf, "\trepe\tcmpsw\n"); else if(!strcmp(Stat, "==****-****?")) soutput(SendBuf, "\trepe\tcmpsd\n"); else if(!strcmp(Stat, "==*=@;")) soutput(SendBuf, "\trep\tinsb\n"); else if(!strcmp(Stat, "==**=@;")) soutput(SendBuf, "\trep\tinsw\n"); else if(!strcmp(Stat, "==****=@;")) soutput(SendBuf, "\trep\tinsd\n"); else if(!strcmp(Stat, "==**=@@;")) soutput(SendBuf, "\trep\tinsw\n"); else if(!strcmp(Stat, "==****=@@@@;")) soutput(SendBuf, "\trep\tinsd\n"); else if(!strcmp(Stat, "==@=*;")) soutput(SendBuf, "\trep\toutsb\n"); else if(!strcmp(Stat, "==@=**;")) soutput(SendBuf, "\trep\toutsw\n"); else if(!strcmp(Stat, "==@=****;")) soutput(SendBuf, "\trep\toutsd\n"); else if(!strcmp(Stat, "==@@=**;")) soutput(SendBuf, "\trep\toutsw\n"); else if(!strcmp(Stat, "==@@@@=****;")) soutput(SendBuf, "\trep\toutsd\n"); else if(!strcmp(Stat, "===*A;")) soutput(SendBuf, "\trep\tlods %s\n", Strs[0]); else if(!strcmp(Stat, "==*A=;")) soutput(SendBuf, "\trep\tstos %s\n", Strs[0]); else if(!strcmp(Stat, "==*A=*A;")) soutput(SendBuf, "\trep\tmovs %s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "==*A-?")) soutput(SendBuf, "\trepe\tscas %s\n", Strs[0]); else if(!strcmp(Stat, "==*A-*A?")) soutput(SendBuf, "\trepe\tcmps %s,%s\n", Strs[0], Strs[1]); else if(!strcmp(Stat, "==*A=@;")) soutput(SendBuf, "\trep\tins %s\n", Strs[0]); else if(!strcmp(Stat, "==@=*A;")) soutput(SendBuf, "\trep\touts %s\n", Strs[0]); else goto ps_error; break; case '>': if(!strcmp(Stat, ">>A;")) goto ps_parsejcc0; else if(!strcmp(Stat, ">>=A;")) goto ps_parsejcc0; else if(!strcmp(Stat, ">A;")) goto ps_parsejcc0; else if(!strcmp(Stat, ">=A;")) goto ps_parsejcc0; else if(!strcmp(Stat, ">>;")) goto ps_parsebrk0; else if(!strcmp(Stat, ">>=;")) goto ps_parsebrk0; else if(!strcmp(Stat, ">;")) goto ps_parsebrk0; else if(!strcmp(Stat, ">=;")) goto ps_parsebrk0; else if(!strcmp(Stat, "><;")) soutput(SendBuf, "\txlatb\n"); else if(!strcmp(Stat, ">= 0; n--) { s = Strs[n]; do { d = 0; if((p = strchr(s, '[')) != NULL) { // look for '[+' or '[-' l = strlen(s); if(*(p+1) == '+' || *(p+1) == '-') { i = (p+2) - s; // extract alphanumeric string for(; i < l; i++) if(isxalpha(s[i])) break; for(j = 0; i+j < l; j++) { if(!isxalpha(s[i+j])) break; a[j] = s[i+j]; } a[j] = 0; // finish up soutput(SendBuf, "\t%s\t%s\n", *(p+1) == '+' ? "inc" : "dec", a); memmove(p+1, p+2, 126 - (p - s)); d = 1; } } if((p = strchr(s+1, ']')) != NULL) { // look for '+]' or '-]' l = strlen(s); if(*(p-1) == '+' || *(p-1) == '-') { i = (p-2) - s; // extract alpha string for(; i >= 0; i--) if(isxalpha(s[i])) break; a[0] = 0; for(; i >= 0; i--) { if(!isxalpha(s[i])) break; memmove(a+1, a, 127); a[0] = s[i]; } soutput(FollowBuf, "\t%s\t%s\n", // finish up *(p-1) == '+' ? "inc" : "dec", a); memmove(p-1, p, 128 - (p - s)); d = r = 1; } } } while(d); } return(r); } /********************************************************************/ /* Parse a conditional string */ /********************************************************************/ int ParseCond(char *in, char *out, int flip) { static char *outs[16] = { // output strings "o", "no", "b", "ae", "z", "nz", "be", "a", "s", "ns", "pe", "po", "l", "ge", "le", "g" }; static char *ins[20] = { // input strings "+-", "-+", "<<", ">>=", "=>>", "==", "<>", "<<=", "=<<", ">>", "--", "++", "&&", "||", "<", ">=", "=>", "<=", "=<", ">" }; static int inv[20] = { // string values 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 15 }; int i, n = -1; for(i = 0; i < 20; i++) // find the string if(!strcmp(in, ins[i])) n = inv[i]; if(n == -1) { // not a condition? *out = 0; // return a blank string return 0; } if(flip) n ^= 1; // opposite condition if needed strcpy(out, outs[n]); // return the condition string return 1; } /********************************************************************/ /* Find a conditional in a statement */ /********************************************************************/ int FindCond(char *in, char *out) { static char *conds[20] = { // List of conditions ">>=", "=>>", "<<=", "=<<", ">=", "=>", "<=", "=<", "+-", "-+", "--", "++", "<>", "<<", ">>", "<", ">", "==", "&&", "||" }; static unsigned char cond_len[20] = { // Length of each condition 3,3,3,3,2,2,2,2,2,2, 2,2,2,2,2,1,1,2,2,2 }; int i, j, l = strlen(in), m; for(i = 0; i < l; i++) { for(j = 0; j < 20; j++) { m = cond_len[j]; // get length of string if(!memcmp(in + i, conds[j], m)) { // found a condition? strcpy(out, conds[j]); // copy it into the output buffer memmove(in + i + 1, in + i + m, l - i - m + 1); in[i] = 'C'; // replace it by a 'C' in the main string return 1; } } } out[0] = 0; // not found, return a blank string return 0; } /********************************************************************/ /* Get one statement */ /********************************************************************/ int GetStatement(void) { static char buf[300]; char *p = Stat, oc = -1, c = -1; int stn = 0; do { if(Stat[0] != '#') oc = c; // oc = prev. char unless FPU instruction if(!GetToken(buf, p - Stat)) return 0; // get a token if(isxalpha(*buf) || buf[1] != 0) { // if alphanumeric or string, strcpy(Strs[stn++], buf); // then add it to string the list *p++ = c = 'A'; // and code it as an 'A' } else *p++ = c = *buf; // otherwise, code it as itself if(p - Stat > 60 || stn > 30) { // out of space? sprintf(ErrorBuf, "statement too big at or near line %d", LineCtr); xerror(3); } } while(c != ';' && c != '{' && // terminators are ';' and '{', sometines '?'. (c != '?' || !strchr("A-*", oc))); // '?' is terminator only if after 'A', '-', or '*'. *p++ = 0; return 1; } /********************************************************************/ /* Init token parsing */ /********************************************************************/ void InitToken(void) { GetLine(LineBuf); LinePos = 0; } /********************************************************************/ /* Return one token */ /********************************************************************/ int GetToken(char *buf, int flg) { int is_bracket, level, is_string = 0; int c, i, p = 0, is_alpha = 0; char deli[5] = "([\'\""; if(!flg) deli[2] = 0; // strings OK? while(1) { c = LineBuf[LinePos++]; // get char if(c == 0) { // end of line? if(!GetLine(LineBuf)) return 0; // get line LinePos = 0; // reset line pos } else if(isspace(c)) { // skip spaces } else if(isxalpha(c) || strchr(deli, c)) { is_string = 1; // set is_string flag if(flg && (c == '\'' || c == '\"')) { i = c; // handle quoted strings do { if(i == 0) goto gt_strerr; // end of line? buf[p++] = i; // add char to string } while((i = LineBuf[LinePos++]) != c); buf[p++] = i; continue; // add last char, continue } level = !isxalpha(c); // expression/alphanumeric string if(c == '(' && is_alpha) { // opening parenthesis needs space buf[p++] = ' '; // if last one was alpha } if(c == '[') { // handle opening bracket is_bracket = 1; buf[p++] = c; } else is_bracket = 0; if(isxalpha(c)) { // need first char if alpha string if(is_alpha) buf[p++] = ' '; // last one was alpha, separate with space is_alpha = 1; buf[p++] = c; } else is_alpha = 0; while(1) { // string handling loop c = LineBuf[LinePos++]; // get char if(isspace(c) || c == 0) { // process white space: if(level == 0) break; // end of alpha string buf[p++] = ' '; // encode as a single space do { // white space loop if(c == 0) { // process newlines if(!GetLine(LineBuf)) return 0; LinePos = 0; } c = LineBuf[LinePos++]; // get next char } while(isspace(c) || c == 0); // loop while whitespace } buf[p++] = c; // add character to buffer if(c == '(') { ++level; continue; } // opening parenthesis if(c == ')') if(--level == 0) { // closing parenthesis if(is_bracket) goto gt_error; // should be bracket, generate error if(!is_alpha) p--; // if it didn't begin as alpha, remove parenthesis is_alpha = 1; break; // need space in all cases, break } if(c == '[' && level == 0) { // process opening bracket is_bracket = level = 1; continue; } if(c == ']' && level == 1 && // process ending bracket is_bracket) break; if(c == '\'' || c == '\"') { // quoted strings while((i = LineBuf[LinePos++]) != c) { if(i == 0) goto gt_strerr; // end of line? buf[p++] = i; // add char to string } buf[p++] = i; continue; // add last char, continue } if(!isxalpha(c) && level == 0) { // end of alpha string, recycle last char p--; LinePos--; break; } } } else { // special char if(is_string) LinePos--; // terminates a string else buf[p++] = c; // not string, add char buf[p++] = 0; // add terminating null return 1; // break } } gt_error: // error in expression sprintf(ErrorBuf, "error in expression at or near line %ld", LineCtr); xerror(3); gt_strerr: // end of line in quoted string sprintf(ErrorBuf, "unterminated quoted string at or near line %ld", LineCtr); xerror(4); return 0; // to fix compiler warning } /********************************************************************/ /* Return the next token without removing it from the stream */ /********************************************************************/ int PeekToken(char *p) { int c, lp = LinePos; while(1) { c = LineBuf[lp++]; // get char if(c == 0) { // end of line? if(!GetLine(LineBuf)) return 0; // get line LinePos = lp = 0; // reset line pos continue; } else if(isspace(c)) { // skip spaces continue; } else { if(isxalpha(c) || strchr("([", c)) // identifier, expression, *p = 'A'; // or address = return an 'A' else *p = c; // otherwise, return the char return 1; } } } /********************************************************************/ /* Get line with full pass-through, stripping comments, etc. */ /********************************************************************/ int GetLine(char *buf) { int i; do { if(!ReadLine(buf)) return 0; // read a line if(!isspace(buf[0])) { i = 0; // statement starts line, label, etc. if(strchr(buf, ':')) { // if there's a ':', then while(isalnum(buf[i]) || // check for a label strchr("$_", buf[i])) i++; if(buf[i] == ':') { // If a label, then pass it through: i = 0; while(1) { fputc(buf[i], OutFile); // output one char if(buf[i] == ':') break; // char is ':', break i++; } } } if(buf[i] != ':') { // if no label, then i = 0; while(buf[i] != ';') { // while no semicolon, if(buf[i] == 0) { // if end of line, then if(!ReadLine(buf)) return 0; // read a line, reset the counter i = 0; continue; // and continue } fputc(buf[i++], OutFile); // output the char } } fputs("\n", OutFile); // output newline memmove(buf, buf + i + 1, 300 - i - 1); // shift over buffer } } while(IsEmpty(buf)); return 1; } /********************************************************************/ /* Read a line, passing delimited lines */ /********************************************************************/ int ReadLine(char *buf) { char *p; while(1) { if(!fgets(buf, 300, InFile)) return 0; // read one line if(!(++LineCtr & 0x3F)) // increment counter, put count every 64 lines fprintf(stderr, "\rlines in: %06ld", LineCtr); if(buf[0] == '!') { // is it a pass-through line? fputs(buf + 1, OutFile); // if so, then send it, and loop back for another continue; // make sure string is empty... } if((p = strchr(buf, 0x0D)) != NULL) *p = 0; // strip off CR and/or LF at the end if((p = strchr(buf, 0x0A)) != NULL) *p = 0; StripComments(buf); // strip off comments (if any) if(!IsEmpty(buf)) return 1; } } /********************************************************************/ /* Strip comments (and trailing spaces) from end of line */ /********************************************************************/ void StripComments(char *buf) { char c, e = 0; int i = -1; while((c = buf[++i]) != 0) { // while not null, if in a string ignore if(e) { // everything except the delimiter char; if(c == e) e = 0; // otherwise cut the string if '\' found. } else { if(c == '\'' || c == '\"') { e = c; } else if(c == '\\') { buf[i] = 0; break; } } } i = strlen(buf) - 1; // remove trailing spaces while(isspace(buf[i])) buf[i--] = 0; } /********************************************************************/ /* Check whether line is empty */ /********************************************************************/ int IsEmpty(char *buf) { int i = 0; while(buf[i] != 0) { if(!isspace(buf[i++])) return 0; } return 1; } /********************************************************************/ /* Error handling */ /********************************************************************/ void xerror(int en) { fprintf(stderr, "\nerror %02x: %s\n\n", en, ErrorBuf); if(InFile != NULL) fclose(InFile); if(OutFile != NULL) fclose(OutFile); exit(en); } /********************************************************************/ /* String printf + concatenation */ /********************************************************************/ void soutput(char *s, char *fmt, ...) { va_list ap; va_start(ap, fmt); vsprintf(s + strlen(s), fmt, ap); va_end(ap); }