home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / appleii.zip / appxas.3 < prev    next >
Text File  |  1990-12-05  |  26KB  |  1,271 lines

  1. #!/bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #!/bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create the files:
  6. #    assm2.c
  7. #    assm3.c
  8. # This archive created: Tue Apr  2 14:21:24 1985
  9. # By:    James Van Ornum (AT&T-Bell Laboratories)
  10. export PATH; PATH=/bin:$PATH
  11. if test -f 'assm2.c'
  12. then
  13.     echo shar: over-writing existing file "'assm2.c'"
  14. fi
  15. cat << \SHAR_EOF > 'assm2.c'
  16. #include "stdio.h"
  17. #include "assm.d1"
  18. #include "assm.d2"
  19.  
  20. extern    int    optab[];
  21. extern    int    step[];
  22.  
  23. /* translate source line to machine language */
  24.  
  25. assemble()
  26. {
  27.     int    flg;
  28.     int    i;        /* prlnbuf pointer */
  29.  
  30.     if ((i = prlnbuf[SFIELD]) == ';' || i == 0 || i == '.' )  {
  31.         if (pass == LAST_PASS)
  32.             println();
  33.         return;
  34.     }
  35.     lablptr = -1;
  36.     i = SFIELD;
  37.     udtype = UNDEF;
  38.     if (colsym(&i) != 0 && (lablptr = stlook()) == -1)
  39.         return;
  40.     while (prlnbuf[++i] == ' ');    /* find first non-space */
  41.     if ((flg = oplook(&i)) < 0) {    /* collect operation code */
  42.         labldef(loccnt);
  43.         if (flg == -1)
  44.             error("Invalid operation code");
  45.         if ((flg == -2) && (pass == LAST_PASS)) {
  46.             if (lablptr != -1)
  47.                 loadlc(loccnt, 1, 0);
  48.             println();
  49.         }
  50.         return;
  51.     }
  52.     else if (noasm) {
  53.         if (opflg == PSEUDO && opval <= ENDCOPVAL && opval >= IFEQOPVAL )
  54.         pseudo(&i);
  55.         else if (pass == LAST_PASS)
  56.             println();
  57.         return;
  58.         }
  59.     else if (opflg == PSEUDO)
  60.         pseudo(&i);
  61.     else if (labldef(loccnt) == -1)
  62.         return;
  63.     else {
  64.         if (opflg == CLASS1)
  65.             class1();
  66.         else if (opflg == CLASS2)
  67.             class2(&i);
  68.         else class3(&i);
  69.     }
  70. }
  71.  
  72. /****************************************************************************/
  73.  
  74. /* printline prints the contents of prlnbuf */
  75.  
  76. println()
  77. {
  78.     if (lflag > 0)
  79.         fprintf(stdout, "%s\n", prlnbuf);
  80. }
  81.  
  82. /* colsym() collects a symbol from prlnbuf into symbol[],
  83.  *    leaves prlnbuf pointer at first invalid symbol character,
  84.  *    returns 0 if no symbol collected
  85.  */
  86.  
  87. colsym(ip)
  88.     int *ip;
  89. {
  90.     int    valid;
  91.     int    i;
  92.     char    ch;
  93.  
  94.     valid = 1;
  95.     i = 0;
  96.     while (valid == 1) {
  97.         ch = prlnbuf[*ip];
  98.         /* drop : in labels */
  99.         if (i > 1 && ch == ':' ) ch = prlnbuf[++(*ip)] ;
  100.         if (ch == '_' || ch == '.');
  101.         else if (ch >= 'a' && ch <= 'z');
  102.         else if (ch >= 'A' && ch <= 'Z');
  103.         else if (i >= 1 && ch >= '0' && ch <= '9');
  104.         else if (i == 1 && ch == '=');
  105.         else valid = 0;
  106.         if (valid == 1) {
  107.             if (i < SBOLSZ - 1)
  108.                 symbol[++i] = ch;
  109.             (*ip)++;
  110.         }
  111.     }
  112.     if (i == 1) {
  113.         switch (symbol[1]) {
  114.         case 'A': case 'a':
  115.         case 'X': case 'x':
  116.         case 'Y': case 'y':
  117.             error("Symbol is reserved (A, X or Y)");
  118.             i = 0;
  119.         }
  120.     }
  121.     symbol[0] = i;
  122.     return(i);
  123. }
  124.  
  125. /* symbol table lookup
  126.  *    if found, return pointer to symbol
  127.  *    else, install symbol as undefined, and return pointer
  128.  */
  129.  
  130. stlook()
  131. {
  132.     int    found;
  133.     int    hptr;
  134.     int    j;
  135.     int    nptr;
  136.     int    pptr;
  137.     int    ptr;
  138.  
  139.     hptr = 0;
  140.     for (j = 0; j < symbol[0]; j++)
  141.         hptr += symbol[j];
  142.     hptr %= 128;
  143.     ptr = hash_tbl[hptr];
  144.     if (ptr == -1) {        /* no entry for this link */
  145.         hash_tbl[hptr] = nxt_free;
  146.         return(stinstal());
  147.     }
  148.     while (symtab[ptr] != 0) {    /* 0 count = end of table */
  149.         found = 1;
  150.         for (j = 0; j <= symbol[0]; j++) {
  151.             if (symbol[j] != symtab[ptr + j]) {
  152.                 found = 0;
  153.                 pptr = ptr + symtab[ptr] + 4;
  154.                 nptr = (symtab[pptr + 1] << 8) + (symtab[pptr] & 0xff);
  155.                 nptr &= 0xffff;
  156.                 if (nptr == 0) {
  157.                     symtab[ptr + symtab[ptr] + 4] = nxt_free & 0xff;
  158.                     symtab[ptr + symtab[ptr] + 5] = (nxt_free >> 8) & 0xff;
  159.                     return(stinstal());
  160.                 }
  161.                 ptr = nptr;
  162.                 break;
  163.             }
  164.         }
  165.         if (found == 1)
  166.             return(ptr);
  167.     }
  168.     error("Symbol not found");
  169.     return(-1);
  170. }
  171.  
  172. /*  instal symbol into symtab
  173.  */
  174. stinstal()
  175. {
  176. register    int    j;
  177. register    int    ptr1;
  178. register    int    ptr2;
  179.  
  180.     ptr1 = ptr2 = nxt_free;
  181.     if ((ptr1 + symbol[0] + 6) >= STABSZ) {
  182.         error("Symbol table full");
  183.         return(-1);
  184.     }
  185.     for (j = 0; j <= symbol[0]; j++)
  186.         symtab[ptr1++] = symbol[j];
  187.     symtab[ptr1] = udtype;
  188.     nxt_free = ptr1 + 5;
  189.     return(ptr2);
  190. }
  191.  
  192. /* operation code table lookup
  193.  *    if found, return pointer to symbol,
  194.  *    else, return -1
  195.  */
  196.  
  197. oplook(ip)
  198.    int    *ip;
  199. {
  200. register    char    ch;
  201. register    int    i;
  202. register    int    j;
  203.     int    k;
  204.     int    temp[2];
  205.  
  206.     i = j = 0;
  207.     temp[0] = temp[1] = 0;
  208.     while((ch=prlnbuf[*ip])!= ' ' && ch!= 0 && ch!= '\t' && ch!= ';') {
  209.         if (ch >= 'A' && ch <= 'Z')
  210.             ch &= 0x1f;
  211.         else if (ch >= 'a' && ch <= 'z')
  212.             ch &= 0x1f;
  213.         else if (ch == '.')
  214.             ch = 31;
  215.         else if (ch == '*')
  216.             ch = 30;
  217.         else if (ch == '=')
  218.             ch = 29;
  219.         else return(-1);
  220.         temp[j] = (temp[j] * 0x20) + (ch & 0xff);
  221.         if (ch == 29)
  222.             break;
  223.         ++(*ip);
  224.         if (++i >= 3) {
  225.             i = 0;
  226.             if (++j >= 3) {
  227.                 return(-1);
  228.             }
  229.         }
  230.     }
  231.     if ((j = temp[0]^temp[1]) == 0)
  232.         return(-2);
  233.     k = 0;
  234.     i = step[k] - 3;
  235.     do {
  236.         if (j == optab[i]) {
  237.             opflg = optab[++i];
  238.             opval = optab[++i];
  239.             return(i);
  240.         }
  241.         else if (j < optab[i])
  242.             i -= step[++k];
  243.         else i += step[++k];
  244.     } while (step[k] != 0);
  245.     return(-1);
  246. }
  247.  
  248. /* error printing routine */
  249.  
  250. error(stptr)
  251.    char *stptr;
  252. {
  253.     loadlc(loccnt, 0, 1);
  254.     loccnt += 3;
  255.     loadv(0,0,0);
  256.     loadv(0,1,0);
  257.     loadv(0,2,0);
  258.     fprintf(stderr, "%s\n", prlnbuf);
  259.     fprintf(stderr, "***** %s\n", stptr);
  260.     errcnt++;
  261. }
  262.  
  263. /* load 16 bit value in printable form into prlnbuf */
  264.  
  265. loadlc(val, f, outflg)
  266.     int val;
  267.     int f;
  268.     int outflg;
  269. {
  270.     int    i;
  271.  
  272.     i = 6 + 7*f;
  273.     hexcon(4, val);
  274.     if (nflag == 0) {
  275.         prlnbuf[i++]  = hex[3];
  276.         prlnbuf[i++]  = hex[4];
  277.         prlnbuf[i++]  = ':';
  278.         prlnbuf[i++]  = hex[1];
  279.         prlnbuf[i] = hex[2];
  280.     }
  281.     else {
  282.         prlnbuf[i++] = hex[1];
  283.         prlnbuf[i++] = hex[2];
  284.         prlnbuf[i++] = hex[3];
  285.         prlnbuf[i] = hex[4];
  286.     }
  287.     if ((pass == LAST_PASS)&&(oflag != 0)&&(objcnt <= 0)&&(outflg != 0)) {
  288.          /* rearrange the next for franklin monitor tm */
  289.         fprintf(optr, "\n%c%c%c%c:", hex[1], hex[2], hex[3], hex[4]);
  290.         objcnt = 16;
  291.     }
  292. }
  293.  
  294.  
  295.  
  296. /* load value in hex into prlnbuf[contents[i]] */
  297. /* and output hex characters to obuf if LAST_PASS & oflag == 1 */
  298.  
  299. loadv(val,f,outflg)
  300.    int    val;
  301.    int    f;        /* contents field subscript */
  302.    int    outflg;        /* flag to output object bytes */
  303. {
  304.  
  305.     hexcon(2, val);
  306.     prlnbuf[13 + 3*f] = hex[1];
  307.     prlnbuf[14 + 3*f] = hex[2];
  308.     if ((pass == LAST_PASS) && (oflag != 0) && (outflg != 0)) {
  309.         fputc(hex[1], optr);
  310.         fputc(hex[2], optr);
  311.         fputc(' ', optr);   /* add space for franklin monitor tm */
  312.         --objcnt;
  313.     }
  314. }
  315.  
  316. /* convert number supplied as argument to hexadecimal in hex[digit] (lsd)
  317.         through hex[1] (msd)        */
  318.  
  319. hexcon(digit, num)
  320.     int digit;
  321.    int    num;
  322. {
  323.  
  324.     for (; digit > 0; digit--) {
  325.         hex[digit] = (num & 0x0f) + '0';
  326.         if (hex[digit] > '9')
  327.             hex[digit] += 'A' -'9' - 1;
  328.         num >>= 4;
  329.     }
  330. }
  331.  
  332. /* assign <value> to label pointed to by lablptr,
  333.  *    checking for valid definition, etc.
  334.  */
  335.  
  336. labldef(lval)
  337.     int lval;
  338. {
  339.     int    i;
  340.  
  341.     if (lablptr != -1) {
  342.         lablptr += symtab[lablptr] + 1;
  343.         /* debug 
  344. fprintf(stderr,"L =%d Flag=%o val=%o%o next=%o%o\n",lablptr,symtab[lablptr],
  345. symtab[lablptr+1],symtab[lablptr+2],symtab[lablptr+3],symtab[lablptr+4]);
  346.         */
  347.         if (pass == FIRST_PASS  ) {
  348.             if (symtab[lablptr] == UNDEF) {
  349.                 symtab[lablptr + 1] = lval & 0xff;
  350.                 i = symtab[lablptr + 2] = (lval >> 8) & 0xff;
  351.                 if (i == 0)
  352.                     symtab[lablptr] = DEFZRO;
  353.                 else    symtab[lablptr] = DEFABS;
  354.             }
  355.             else if (symtab[lablptr] == UNDEFAB) {
  356.                 symtab[lablptr] = DEFABS;
  357.                 symtab[lablptr + 1] = lval & 0xff;
  358.                 symtab[lablptr + 2] = (lval >> 8) & 0xff;
  359.             }
  360.             else {
  361.                 symtab[lablptr] = MDEF;
  362.                 symtab[lablptr + 1] = 0;
  363.                 symtab[lablptr + 2] = 0;
  364.                 error("Label multiply defined");
  365.                 return(-1);
  366.             }
  367.         }
  368.         else {
  369.             i = (symtab[lablptr + 2] << 8) +
  370.                 (symtab[lablptr+1] & 0xff);
  371.             i &= 0xffff;
  372.             if (i != lval ) {
  373.                 error("Sync error");
  374.                 return(-1);
  375.             }
  376.         }
  377.     }
  378.     return(0);
  379. }
  380. /* assign <value> to label pointed to by lablptr
  381.  */
  382.  
  383. labldef2(lval)
  384.     int lval;
  385. {
  386.     int    i;
  387.  
  388.     if (lablptr != -1) {
  389.         lablptr += symtab[lablptr] + 1;
  390.         /* debug 
  391. fprintf(stderr,"L =%d Flag=%o val=%o%o next=%o%o\n",lablptr,symtab[lablptr],
  392. symtab[lablptr+1],symtab[lablptr+2],symtab[lablptr+3],symtab[lablptr+4]);
  393.         */
  394.             if (symtab[lablptr] == UNDEF) {
  395.                 symtab[lablptr + 1] = lval & 0xff;
  396.                 i = symtab[lablptr + 2] = (lval >> 8) & 0xff;
  397.                 if (i == 0)
  398.                     symtab[lablptr] = DEFZRO;
  399.                 else    symtab[lablptr] = DEFABS;
  400.             }
  401.             else if (symtab[lablptr] == UNDEFAB) {
  402.                 symtab[lablptr] = DEFABS;
  403.                 symtab[lablptr + 1] = lval & 0xff;
  404.                 symtab[lablptr + 2] = (lval >> 8) & 0xff;
  405.             }
  406.             else {
  407.                 i = (symtab[lablptr + 2] << 8) +
  408.                 (symtab[lablptr+1] & 0xff);
  409.                 i &= 0xffff;
  410.                 if (i != lval ) {
  411.                     error("Sync error");
  412.                     return(-1);
  413.                     }
  414.                 }
  415.     }
  416.     return(0);
  417. }
  418.  
  419. /* determine the value of the symbol,
  420.  * given pointer to first character of symbol in symtab
  421.  */
  422.  
  423. symval(ip)
  424.     int *ip;
  425. {
  426.     int    ptr;
  427.     int    svalue;
  428.  
  429.     svalue = 0;
  430.     colsym(ip);
  431.     if ((ptr = stlook()) == -1)
  432.         undef = 1;        /* no room error */
  433.     else if (symtab[ptr + symtab[ptr] + 1] == UNDEF)
  434.         undef = 1;
  435.     else if (symtab[ptr + symtab[ptr] + 1] == UNDEFAB)
  436.         undef = 1;
  437.     else svalue = ((symtab[ptr + symtab[ptr] + 3] << 8) +
  438.         (symtab[ptr + symtab[ptr] + 2] & 0xff)) & 0xffff;
  439.     if (symtab[ptr + symtab[ptr] + 1] == DEFABS)
  440.         zpref = 1;
  441.     if (undef != 0)
  442.         zpref = 1;
  443.     return(svalue);
  444. }
  445. SHAR_EOF
  446. if test -f 'assm3.c'
  447. then
  448.     echo shar: over-writing existing file "'assm3.c'"
  449. fi
  450. cat << \SHAR_EOF > 'assm3.c'
  451. #include "stdio.h"
  452. #include "assm.d1"
  453. #include "assm.d2"
  454.  
  455. /* class 1 machine operations processor - 1 byte, no operand field */
  456.  
  457. class1()
  458. {
  459.     if (pass == LAST_PASS) {
  460.         loadlc(loccnt, 0, 1);
  461.         loadv(opval, 0, 1);
  462.         println();
  463.     }
  464.     loccnt++;
  465. }
  466.  
  467.  
  468. /* class 2 machine operations processor - 2 byte, relative addressing */
  469.  
  470. class2(ip)
  471.     int *ip;
  472. {
  473.  
  474.     if (pass == LAST_PASS) {
  475.         loadlc(loccnt, 0, 1);
  476.         loadv(opval, 0, 1);
  477.         while (prlnbuf[++(*ip)] == ' ');
  478.         if (evaluate(ip) != 0) {
  479.             loccnt += 2;
  480.             return;
  481.         }
  482.         loccnt += 2;
  483.         if ((value -= loccnt) >= -128 && value < 128) {
  484.             loadv(value, 1, 1);
  485.             println();
  486.         }
  487.         else error("Invalid branch address");
  488.     }
  489.     else loccnt += 2;
  490. }
  491.  
  492.  
  493. /* class 3 machine operations processor - various addressing modes */
  494.  
  495. class3(ip)
  496.     int *ip;
  497. {
  498.     char    ch;
  499.     int    code;
  500.     int    flag;
  501.     int    i;
  502.     int    ztmask;
  503.  
  504.     while ((ch = prlnbuf[++(*ip)]) == ' ');
  505.     switch(ch) {
  506.     case 0:
  507.     case ';':
  508.         error("Operand field missing");
  509.         return;
  510.     case 'A':
  511.     case 'a':
  512.         if ((ch = prlnbuf[*ip + 1]) == ' ' || ch == 0) {
  513.             flag = ACC;
  514.             break;
  515.         }
  516.     default:
  517.         switch(ch = prlnbuf[*ip]) {
  518.         case '#': case '=':
  519.             flag = IMM1 | IMM2;
  520.             ++(*ip);
  521.             break;
  522.         case '(':
  523.             flag = IND | INDX | INDY;
  524.             ++(*ip);
  525.             break;
  526.         default:
  527.             flag = ABS | ZER | ZERX | ABSX | ABSY | ABSY2 | ZERY;
  528.         }
  529.         if ((flag & (INDX | INDY | ZER | ZERX | ZERY) & opflg) != 0)
  530.             udtype = UNDEFAB;
  531.         if (evaluate(ip) != 0)
  532.             return;
  533.         if (zpref != 0) {
  534.             flag &= (ABS | ABSX | ABSY | ABSY2 | IND | IMM1 | IMM2);
  535.             ztmask = 0;
  536.         }
  537.         else ztmask = ZER | ZERX | ZERY;
  538.         code = 0;
  539.         i = 0;
  540.         while (( ch = prlnbuf[(*ip)++]) != ' ' && ch != 0 && i++ < 4) {
  541.             code *= 8;
  542.             switch(ch) {
  543.             case ')':        /* ) = 4 */
  544.                 ++code;
  545.             case ',':        /* , = 3 */
  546.                 ++code;
  547.             case 'X':        /* X = 2 */
  548.             case 'x':
  549.                 ++code;
  550.             case 'Y':        /* Y = 1 */
  551.             case 'y':
  552.                 ++code;
  553.                 break;
  554.             default:
  555.                 flag = 0;
  556.             }
  557.         }
  558.         switch(code) {
  559.         case 0:        /* no termination characters */
  560.             flag &= (ABS | ZER | IMM1 | IMM2);
  561.             break;
  562.         case 4:        /* termination = ) */
  563.             if (opval!=0x40 && ((flag&IND)==IND)) {
  564.                 if (zpref == 1) flag=0 ; /* fail it */
  565.                 else {      /* (zp)Mode */
  566.                 flag = ZER;
  567.                 opval += 13;
  568.                 }
  569.                 break;
  570.             }
  571.             flag &= IND;
  572.             break;
  573.         case 25:        /* termination = ,Y */
  574.             flag &= (ABSY | ABSY2 | ZERY);
  575.             break;
  576.         case 26:        /* termination = ,X */
  577.             flag &= (ABSX | ZERX);
  578.             break;
  579.         case 212:        /* termination = ,X) */
  580.             if (opval == 0x40 && zpref == 1) {
  581.                 flag &= IND;    /* jmp (abs,x) */
  582.                 opval = 0x50;
  583.                 break;
  584.             }
  585.             flag &= INDX;
  586.             break;
  587.         case 281:        /* termination = ),Y */
  588.             flag &= INDY;
  589.             break;
  590.         default:
  591.             flag = 0;
  592.         }
  593.     }
  594.     if ((opflg &= flag) == 0) {
  595.         error("Invalid addressing mode");
  596.         return;
  597.     }
  598.     if ((opflg & ztmask) != 0)
  599.         opflg &= ztmask;
  600.     switch(opflg) {
  601.     case ACC:        /* single byte - class 3 */
  602.         if (pass == LAST_PASS) {
  603.             loadlc(loccnt, 0, 1);
  604.             loadv(opval + 8, 0, 1);
  605.             println();
  606.         }
  607.         loccnt++;
  608.         return;
  609.     case ZERX: case ZERY:    /* double byte - class 3 */
  610.         opval += 4;
  611.     case INDY:
  612.         opval += 8;
  613.     case IMM2:
  614.         opval += 4;
  615.     case ZER:
  616.         opval += 4;
  617.     case INDX:
  618.     case IMM1:
  619.         if (pass == LAST_PASS) {
  620.             loadlc(loccnt, 0, 1);
  621.             loadv(opval, 0, 1);
  622.             loadv(value, 1, 1);
  623.             println();
  624.         }
  625.         loccnt += 2;
  626.         return;
  627.     case IND:        /* triple byte - class 3 */
  628.         opval += 16;
  629.     case ABSX:
  630.         if (opval==0x60 && opflg==ABSX)opval = 0x82; /* stz abs,x */
  631.     case ABSY2:
  632.         opval += 4;
  633.     case ABSY:
  634.         opval += 12;
  635.     case ABS:
  636.         if (opval == 0x60 && opflg == ABS) opval=0x90 ; /* stz abs */
  637.             
  638.         if (pass == LAST_PASS) {
  639.             opval += 12;
  640.             loadlc(loccnt, 0, 1);
  641.             loadv(opval, 0, 1);
  642.             loadv(value, 1, 1);
  643.             loadv(value >> 8, 2, 1);
  644.             println();
  645.         }
  646.         loccnt += 3;
  647.         return;
  648.     default:
  649.         error("Invalid addressing mode");
  650.         return;
  651.     }
  652. }
  653.  
  654. /* pseudo operations processor */
  655.  
  656. pseudo(ip)
  657.     int *ip;
  658. {
  659.     int    count;
  660.     int    i;
  661.     int    tvalue;
  662.     int     hibit; /* apple requires high bit to be on for chs */
  663.     int     pi;
  664.  
  665.     switch(opval) {
  666.     case 0:                /* .byte pseudo */
  667.         labldef(loccnt);
  668.         loadlc(loccnt, 0, 1);
  669.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  670.         count = 0;
  671.         do {
  672.             if (prlnbuf[*ip] == '"') {
  673.                 /* check for hibit on flag for ascii chs */
  674.                 hibit = 0 ;
  675.                 pi = *ip;
  676.                 while((i = prlnbuf[++pi]) != '"' && i != 0 );
  677.                 if (i != 0 )
  678.                   while(prlnbuf[++pi] == ' ' ) ;
  679.                 if (prlnbuf[pi] == '1' )
  680.                    hibit = 0x80 ;
  681.                 while ((tvalue = prlnbuf[++(*ip)]) != '"') {
  682.                     if (tvalue == 0) {
  683.                         error("Unterminated ASCII string");
  684.                         return;
  685.                     }
  686.                     if (tvalue == '\\')
  687.                         switch(tvalue = prlnbuf[++(*ip)]) {
  688.                         case 'n':
  689.                             tvalue = '\n';
  690.                             break;
  691.                         case 't':
  692.                             tvalue = '\t';
  693.                             break;
  694.                         }
  695.                     loccnt++;
  696.                     if (pass == LAST_PASS) {
  697.                         tvalue |= hibit ;
  698.                         loadv(tvalue, count, 1);
  699.                         if (++count >= 3) {
  700.                             println();
  701.                             for (i = 0; i < SFIELD; i++)
  702.                                 prlnbuf[i] = ' ';
  703.                             prlnbuf[i] = 0;
  704.                             count = 0;
  705.                             loadlc(loccnt, 0, 1);
  706.                         }
  707.                     }
  708.                 }
  709.                 ++(*ip);
  710.             }
  711.             else {
  712.                 if (evaluate(ip) != 0) {
  713.                     loccnt++;
  714.                     return;
  715.                 }
  716.                 loccnt++;
  717.                 if (value > 0xff) {
  718.                     error("Operand field size error");
  719.                     return;
  720.                 }
  721.                 else if (pass == LAST_PASS) {
  722.                     loadv(value, count, 1);
  723.                     if (++count >= 3) {
  724.                         println();
  725.                         for (i = 0; i < SFIELD; i++)
  726.                             prlnbuf[i] = ' ';
  727.                         prlnbuf[i] = 0;
  728.                         count = 0;
  729.                         loadlc(loccnt, 0, 1);
  730.                     }
  731.                 }
  732.             }
  733.         } while (prlnbuf[(*ip)++] == ',');
  734.         if ((pass == LAST_PASS) && (count != 0))
  735.             println();
  736.         return;
  737.     case 1:                /* = pseudo */
  738.         while (prlnbuf[++(*ip)] == ' ');
  739.         if (evaluate(ip) != 0)
  740.             return;
  741.         if (pass == LAST_PASS) {
  742.                 labldef2(value);
  743.             loadlc(value, 1, 0);
  744.             println();
  745.         }
  746.         else if (undef == 0 ) labldef(value);
  747.         return;
  748.     case 2:                /* .word pseudo */
  749.         labldef(loccnt);
  750.         loadlc(loccnt, 0, 1);
  751.         while (prlnbuf[++(*ip)] == ' ');
  752.         do {
  753.             if (evaluate(ip) != 0) {
  754.                 loccnt += 2;
  755.                 return;
  756.             }
  757.             loccnt += 2;
  758.             if (pass == LAST_PASS) {
  759.                 loadv(value, 0, 1);
  760.                 loadv(value>>8, 1, 1);
  761.                 println();
  762.                 for (i = 0; i < SFIELD; i++)
  763.                     prlnbuf[i] = ' ';
  764.                 prlnbuf[i] = 0;
  765.                 loadlc(loccnt, 0, 1);
  766.             }
  767.         } while (prlnbuf[(*ip)++] == ',');
  768.         return;
  769.     case 3:                /* *= pseudo */
  770.         while (prlnbuf[++(*ip)] == ' ');
  771.         /*
  772.         if (prlnbuf[*ip] == '*') {
  773.             if (evaluate(ip) != 0)
  774.                 return;
  775.             if (undef != 0) {
  776.                 error("Undefined symbol in operand field.");
  777.                 return;
  778.             }
  779.             tvalue = loccnt;
  780.         }
  781.         else {
  782.         */
  783.             if (evaluate(ip) != 0)
  784.                 return;
  785.             if (undef != 0) {
  786.                 error("Undefined symbol in operand field.");
  787.                 return;
  788.             }
  789.             tvalue = value;
  790.         /*
  791.         }
  792.         */
  793.         loccnt = value;
  794.         labldef(tvalue);
  795.         if (pass == LAST_PASS) {
  796.             objcnt = 0;
  797.             loadlc(tvalue, 1, 0);
  798.             println();
  799.         }
  800.         return;
  801.     case 4:                /* .list pseudo */
  802.         if (lflag >= 0)
  803.             lflag = 1;
  804.         return;
  805.     case 5:                /* .nlst pseudo */
  806.         if (lflag >= 0)
  807.             lflag = iflag;
  808.         return;
  809.     case 6:                /* .dbyt pseudo */
  810.         labldef(loccnt);
  811.         loadlc(loccnt, 0, 1);
  812.         while (prlnbuf[++(*ip)] == ' ');
  813.         do {
  814.             if (evaluate(ip) != 0) {
  815.                 loccnt += 2;
  816.                 return;
  817.             }
  818.             loccnt += 2;
  819.             if (pass == LAST_PASS) {
  820.                 loadv(value>>8, 0, 1);
  821.                 loadv(value, 1, 1);
  822.                 println();
  823.                 for (i = 0; i < SFIELD; i++)
  824.                     prlnbuf[i] = ' ';
  825.                 prlnbuf[i] = 0;
  826.                 loadlc(loccnt, 0, 1);
  827.             }
  828.         } while (prlnbuf[(*ip)++] == ',');
  829.         return;
  830.     case 7:                /* ds pseudo */
  831.         while (prlnbuf[++(*ip)] == ' ');
  832.         if (evaluate(ip) != 0)
  833.             return;
  834.         if (undef != 0) {
  835.             error("Undefined symbol in operand field.");
  836.             return;
  837.         }
  838.         tvalue = loccnt;
  839.         labldef(loccnt);
  840.         loccnt += value;
  841.         if (pass == LAST_PASS) {
  842.             objcnt = 0;
  843.             loadlc(tvalue, 1, 0);
  844.             println();
  845.         }
  846.         return;
  847.     case 8:                /* .asciz pseudo */
  848.         labldef(loccnt);
  849.         loadlc(loccnt, 0, 1);
  850.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  851.         count = 0;
  852.         do {
  853.             if (prlnbuf[*ip] == '/') {
  854.                 while ((tvalue = prlnbuf[++(*ip)]) != '/') {
  855.                     if (tvalue == 0) {
  856.                         error("Unterminated ASCII string");
  857.                         return;
  858.                     }
  859.                     if (tvalue == '\\')
  860.                         switch(tvalue = prlnbuf[++(*ip)]) {
  861.                         case 'n':
  862.                             tvalue = '\n';
  863.                             break;
  864.                         case 't':
  865.                             tvalue = '\t';
  866.                             break;
  867.                         }
  868.                     loccnt++;
  869.                     if (pass == LAST_PASS) {
  870.                         tvalue |= msb ;
  871.                         loadv(tvalue, count, 1);
  872.                         if (++count >= 3) {
  873.                             println();
  874.                             for (i = 0; i < SFIELD; i++)
  875.                                 prlnbuf[i] = ' ';
  876.                             prlnbuf[i] = 0;
  877.                             count = 0;
  878.                             loadlc(loccnt, 0, 1);
  879.                         }
  880.                     }
  881.                 }
  882.                 loccnt++;
  883.                 if (pass == LAST_PASS )
  884.                     loadv(0 ,count++,1);
  885.                 ++(*ip);
  886.             }
  887.             else {
  888.                 if (evaluate(ip) != 0) {
  889.                     loccnt++;
  890.                     return;
  891.                 }
  892.                 loccnt++;
  893.                 if (value > 0xff) {
  894.                     error("Operand field size error");
  895.                     return;
  896.                 }
  897.                 else if (pass == LAST_PASS) {
  898.                     loadv(value, count, 1);
  899.                     if (++count >= 3) {
  900.                         println();
  901.                         for (i = 0; i < SFIELD; i++)
  902.                             prlnbuf[i] = ' ';
  903.                         prlnbuf[i] = 0;
  904.                         count = 0;
  905.                         loadlc(loccnt, 0, 1);
  906.                     }
  907.                 }
  908.             }
  909.         } while (prlnbuf[(*ip)++] == ',');
  910.         if ((pass == LAST_PASS) && (count != 0))
  911.             println();
  912.         return;
  913.     case 9:                /* ifeq pseudo */
  914.         while (prlnbuf[++(*ip)] == ' ');
  915.             if (evaluate(ip) != 0)
  916.                 return;
  917.             if (undef != 0) {
  918.                 error("Undefined symbol in operand field.");
  919.                 return;
  920.             }
  921.         if (++nestct >= MAXNEST ) {
  922.             error("Too many nested ifeq ");
  923.             return;
  924.             }
  925.         if (value != 0 ) value=1;
  926.         nest[nestct] = value ;
  927.         noasm = 0;
  928.         for (i=0; i<=nestct ;i++)
  929.             noasm |= nest[i] ;
  930.         if (pass == LAST_PASS) 
  931.             println();
  932.         return;
  933.     case 10:                /* ifne pseudo */
  934.         while (prlnbuf[++(*ip)] == ' ');
  935.             if (evaluate(ip) != 0)
  936.                 return;
  937.             if (undef != 0) {
  938.                 error("Undefined symbol in operand field.");
  939.                 return;
  940.             }
  941.         if (++nestct >= MAXNEST ) {
  942.             error("Too many nested ifne");
  943.             return;
  944.             }
  945.         if (value != 0 ) value=0;
  946.         else value=1;
  947.         nest[nestct] = value ;
  948.         noasm = 0;
  949.         for (i=0; i<=nestct ;i++)
  950.             noasm |= nest[i] ;
  951.         if (pass == LAST_PASS) 
  952.             println();
  953.         return;
  954.     case 11:        /* endc pseudo */
  955.         if (--nestct < 0 ) {
  956.             error("Too many nested endc ");
  957.             return;
  958.             }
  959.         noasm = 0;
  960.         for (i=0; i<=nestct ;i++)
  961.             noasm |= nest[i] ;
  962.         if (pass == LAST_PASS) 
  963.             println();
  964.         return;
  965.     case 12:            /* nasc pseudo */
  966.         labldef(loccnt);
  967.         loadlc(loccnt, 0, 1);
  968.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  969.         count = 0;
  970.         do {
  971.             if (prlnbuf[*ip] == '<') {
  972.                 /* check for hibit on flag for ascii chs */
  973.                 hibit = 0 ;
  974.                 pi = *ip;
  975.                 while((i = prlnbuf[++pi]) != '>' && i != 0 );
  976.                 if (i != 0 )
  977.                   while(prlnbuf[++pi] == ' ' ) ;
  978.                 if (prlnbuf[pi] == '1' )
  979.                    hibit = 1 ;
  980.                 while ((tvalue = prlnbuf[++(*ip)]) != '>') {
  981.                     if (tvalue == 0) {
  982.                         error("Unterminated ASCII string");
  983.                         return;
  984.                     }
  985.                     if (tvalue == '\\')
  986.                         switch(tvalue = prlnbuf[++(*ip)]) {
  987.                         case 'n':
  988.                             tvalue = '\n';
  989.                             break;
  990.                         case 't':
  991.                             tvalue = '\t';
  992.                             break;
  993.                         }
  994.                     loccnt++;
  995.                     if (pass == LAST_PASS) {
  996.                         tvalue |= 0x80 ;
  997.                         loadv(tvalue, count, 1);
  998.                         if (++count >= 3) {
  999.                             println();
  1000.                             for (i = 0; i < SFIELD; i++)
  1001.                                 prlnbuf[i] = ' ';
  1002.                             prlnbuf[i] = 0;
  1003.                             count = 0;
  1004.                             loadlc(loccnt, 0, 1);
  1005.                         }
  1006.                     }
  1007.                 }
  1008.                 if ( hibit ){
  1009.                 loccnt++;
  1010.                   if (pass == LAST_PASS )
  1011.                     loadv(0 ,count++,1);
  1012.                 }
  1013.                 ++(*ip);
  1014.             }
  1015.             else {
  1016.                 if (evaluate(ip) != 0) {
  1017.                     loccnt++;
  1018.                     return;
  1019.                 }
  1020.                 loccnt++;
  1021.                 if (value > 0xff) {
  1022.                     error("Operand field size error");
  1023.                     return;
  1024.                 }
  1025.                 else if (pass == LAST_PASS) {
  1026.                     loadv(value, count, 1);
  1027.                     if (++count >= 3) {
  1028.                         println();
  1029.                         for (i = 0; i < SFIELD; i++)
  1030.                             prlnbuf[i] = ' ';
  1031.                         prlnbuf[i] = 0;
  1032.                         count = 0;
  1033.                         loadlc(loccnt, 0, 1);
  1034.                     }
  1035.                 }
  1036.             }
  1037.         } while (prlnbuf[(*ip)++] == ',');
  1038.         if ((pass == LAST_PASS) && (count != 0))
  1039.             println();
  1040.         return;
  1041.     case 13:            /* msb pseudo */
  1042.         while (prlnbuf[++(*ip)] == ' ');
  1043.         if (pass == LAST_PASS) 
  1044.             println();
  1045.         pi = *ip;
  1046.         if (( i = 0x20|prlnbuf[pi+1] ) == 'f' ){
  1047.                 msb=0;
  1048.                 return;
  1049.                 }
  1050.             else if (i=='n'){
  1051.                 msb=0x80;
  1052.                 return;
  1053.                 }
  1054.         error("Invalid symbol in operand field.");
  1055.         return;
  1056.     }
  1057. }
  1058.  
  1059. /* evaluate expression */
  1060.  
  1061. evaluate(ip)
  1062.    int    *ip;
  1063. {
  1064.     int    i, tvalue;
  1065.     int    invalid;
  1066.     int    parflg, value2;
  1067.     char    ch;
  1068.     char    op;
  1069.     char    op2;
  1070.  
  1071.     op = '+';
  1072.     parflg = zpref = undef = value = invalid = 0;
  1073. /* hcj: zpref should reflect the value of the expression, not the value of
  1074.    the intermediate symbols
  1075. */
  1076. while((ch=prlnbuf[*ip])!=' '&& ch!= ')' && ch != ',' && ch != ';' && ch != 0){
  1077.         tvalue = 0;
  1078.         if (ch == '$' || ch == '@' || ch == '%')
  1079.             tvalue = colnum(ip);
  1080.         else if (ch == '^' ) {
  1081.             if ((0x20|prlnbuf[++(*ip)]) == 'o') {
  1082.             prlnbuf[*ip] = '0' ;
  1083.             i = *ip ; /* save it */
  1084.             tvalue = colnum(ip); 
  1085.             prlnbuf[i] = 'o' ; /* restore it for printing */
  1086.             }
  1087.             else --(*ip);
  1088.             }
  1089.         else if (ch >= '0' && ch <= '9')
  1090.             tvalue = colnum(ip);
  1091.         else if (ch >= 'a' && ch <= 'z')
  1092.             tvalue = symval(ip);
  1093.         else if (ch >= 'A' && ch <= 'Z')
  1094.             tvalue = symval(ip);
  1095.         else if ((ch == '_')  ) /* || (ch == '.')) removed */
  1096.             tvalue = symval(ip);
  1097.         else if (ch == '*' || ch == '.') {
  1098.             tvalue = loccnt;
  1099.             ++(*ip);
  1100.         }
  1101.         else if (ch == '\'') {
  1102.             ++(*ip);
  1103.             tvalue = prlnbuf[*ip] & 0xff;
  1104.             ++(*ip);
  1105.         }
  1106.         else if (ch == '<') {
  1107.             if (parflg == 1) {
  1108.                 error("Too many <'s in expression");
  1109.                 invalid++;
  1110.             }
  1111.             else {
  1112.                 value2 = value;
  1113.                 op2 = op;
  1114.                 value = tvalue = 0;
  1115.                 op = '+';
  1116.                 parflg = 1;
  1117.             }
  1118.             goto next;
  1119.         }
  1120.         else if (ch == '>') {
  1121.             if (parflg == 0) {
  1122.                 error("No matching < for > in expression");
  1123.                 invalid++;
  1124.             }
  1125.             else {
  1126.                 parflg = 0;
  1127.                 tvalue = value;
  1128.                 value = value2;
  1129.                 op = op2;
  1130.             }
  1131.             ++(*ip);
  1132.         }
  1133.         switch(op) {
  1134.         case '+':
  1135.             value += tvalue;
  1136.             break;
  1137.         case '-':
  1138.             value -= tvalue;
  1139.             break;
  1140.         case '/':
  1141.             value = (unsigned) value/tvalue;
  1142.             break;
  1143.         case '*':
  1144.             value *= tvalue;
  1145.             break;
  1146.         case '%':
  1147.             value = (unsigned) value%tvalue;
  1148.             break;
  1149.         /* what to do with exclusive or ?? */
  1150.         case '!':
  1151.             value ^= tvalue;
  1152.             break;
  1153.         case '~':
  1154.             value = ~tvalue;
  1155.             break;
  1156.         case '&':
  1157.             value &= tvalue;
  1158.             break;
  1159.         case '|':
  1160.             value |= tvalue;
  1161.             break;
  1162.         /*
  1163.         case '<':
  1164.             tvalue >>= 8;        /* fall through to '<' */
  1165.         /*
  1166.         case '>':
  1167.             if (value != 0) {
  1168.                 error("High or low byte operator not first in operand field");
  1169.             }
  1170.             value =  tvalue & 0xff;
  1171.             zpref = 0;
  1172.             break;
  1173.         */
  1174.         case '^':
  1175.             break;
  1176.         case '\\':
  1177.             break;
  1178.         default:
  1179.             invalid++;
  1180.         }
  1181.         if ((op=prlnbuf[*ip]) == ' '
  1182.                 || op == ')'
  1183.                 || op == ','
  1184.                 || op == ';')
  1185.             break;
  1186.         else switch(op) {
  1187.             case '>': break ;
  1188.             case '^':
  1189.                   value >>= 8 ;
  1190.             case '\\': value &= 0xff ;
  1191.                 zpref = 0 ;
  1192.             default:
  1193. next:            ++(*ip);
  1194.             }
  1195.     }
  1196.     if (parflg == 1) {
  1197.         error("Missing > in expression");
  1198.         return(1);
  1199.     }
  1200.     /* why is this needed?
  1201.     if (value < 0 || value >= 256) {
  1202.         zpref = 1;
  1203.     }
  1204.     I dont know */
  1205.     if (undef != 0) {
  1206.         if (pass != FIRST_PASS) {
  1207.             error("Undefined symbol in operand field");
  1208.             invalid++;
  1209.         }
  1210.         value = 0;
  1211.     }
  1212.     else if (invalid != 0)
  1213.     {
  1214.         error("Invalid operand field");
  1215.     }
  1216.     else {
  1217. /*
  1218.  This is the only way out that may not signal error
  1219. */
  1220.         if (value < 0 || value >= 256) {
  1221.             zpref = 1;
  1222.         }
  1223.         else {
  1224.             zpref = 0;
  1225.         }
  1226.     }
  1227.     return(invalid);
  1228. }
  1229.  
  1230. /* collect number operand        */
  1231.  
  1232. colnum(ip)
  1233.     int    *ip;
  1234. {
  1235.     int    mul;
  1236.     int    nval;
  1237.     char    ch;
  1238.  
  1239.     nval = 0;
  1240.     if ((ch = prlnbuf[*ip]) == '$')
  1241.         mul = 16;
  1242.     else if (ch >= '1' && ch <= '9') {
  1243.         mul = 10;
  1244.         nval = ch - '0';
  1245.     }
  1246.     else if (ch == '@' || ch == '0')
  1247.         mul = 8;
  1248.     else if (ch == '%')
  1249.         mul = 2;
  1250.     while ((ch = prlnbuf[++(*ip)] - '0') >= 0) {
  1251.         if (ch > 9) {
  1252.             ch -= ('A' - '9' - 1);
  1253.             if (ch > 15)
  1254.                 ch -= ('a' - 'A');
  1255.             if (ch > 15)
  1256.                 break;
  1257.             if (ch < 10)
  1258.                 break;
  1259.         }
  1260.         if (ch >= mul)
  1261.             break;
  1262.         nval = (nval * mul) + ch;
  1263.     }
  1264.     return(nval);
  1265. }
  1266. SHAR_EOF
  1267. #    End of shell archive
  1268. exit 0
  1269.  
  1270.  
  1271.