home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / appleii.zip / apxa3.c < prev    next >
Text File  |  1988-08-16  |  21KB  |  1,039 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 ((prlnbuf[SFIELD] == ';') | (prlnbuf[SFIELD] == 0)) {
  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.     if (opflg == PSEUDO)
  53.         pseudo(&i);
  54.     else if (labldef(loccnt) == -1)
  55.         return;
  56.     else {
  57.         if (opflg == CLASS1)
  58.             class1();
  59.         else if (opflg == CLASS2)
  60.             class2(&i);
  61.         else class3(&i);
  62.     }
  63. }
  64.  
  65. /****************************************************************************/
  66.  
  67. /* printline prints the contents of prlnbuf */
  68.  
  69. println()
  70. {
  71.     if (lflag > 0)
  72.         fprintf(stdout, "%s\n", prlnbuf);
  73. }
  74.  
  75. /* colsym() collects a symbol from prlnbuf into symbol[],
  76.  *    leaves prlnbuf pointer at first invalid symbol character,
  77.  *    returns 0 if no symbol collected
  78.  */
  79.  
  80. colsym(ip)
  81.     int *ip;
  82. {
  83.     int    valid;
  84.     int    i;
  85.     char    ch;
  86.  
  87.     valid = 1;
  88.     i = 0;
  89.     while (valid == 1) {
  90.         ch = prlnbuf[*ip];
  91.         if (ch == '_' || ch == '.');
  92.         else if (ch >= 'a' && ch <= 'z');
  93.         else if (ch >= 'A' && ch <= 'Z');
  94.         else if (i >= 1 && ch >= '0' && ch <= '9');
  95.         else if (i == 1 && ch == '=');
  96.         else valid = 0;
  97.         if (valid == 1) {
  98.             if (i < SBOLSZ - 1)
  99.                 symbol[++i] = ch;
  100.             (*ip)++;
  101.         }
  102.     }
  103.     if (i == 1) {
  104.         switch (symbol[1]) {
  105.         case 'A': case 'a':
  106.         case 'X': case 'x':
  107.         case 'Y': case 'y':
  108.             error("Symbol is reserved (A, X or Y)");
  109.             i = 0;
  110.         }
  111.     }
  112.     symbol[0] = i;
  113.     return(i);
  114. }
  115.  
  116. /* symbol table lookup
  117.  *    if found, return pointer to symbol
  118.  *    else, install symbol as undefined, and return pointer
  119.  */
  120.  
  121. stlook()
  122. {
  123.     int    found;
  124.     int    hptr;
  125.     int    j;
  126.     int    nptr;
  127.     int    pptr;
  128.     int    ptr;
  129.  
  130.     hptr = 0;
  131.     for (j = 0; j < symbol[0]; j++)
  132.         hptr += symbol[j];
  133.     hptr %= 128;
  134.     ptr = hash_tbl[hptr];
  135.     if (ptr == -1) {        /* no entry for this link */
  136.         hash_tbl[hptr] = nxt_free;
  137.         return(stinstal());
  138.     }
  139.     while (symtab[ptr] != 0) {    /* 0 count = end of table */
  140.         found = 1;
  141.         for (j = 0; j <= symbol[0]; j++) {
  142.             if (symbol[j] != symtab[ptr + j]) {
  143.                 found = 0;
  144.                 pptr = ptr + symtab[ptr] + 4;
  145.                 nptr = (symtab[pptr + 1] << 8) + (symtab[pptr] & 0xff);
  146.                 nptr &= 0xffff;
  147.                 if (nptr == 0) {
  148.                     symtab[ptr + symtab[ptr] + 4] = nxt_free & 0xff;
  149.                     symtab[ptr + symtab[ptr] + 5] = (nxt_free >> 8) & 0xff;
  150.                     return(stinstal());
  151.                 }
  152.                 ptr = nptr;
  153.                 break;
  154.             }
  155.         }
  156.         if (found == 1)
  157.             return(ptr);
  158.     }
  159.     error("Symbol not found");
  160.     return(-1);
  161. }
  162.  
  163. /*  instal symbol into symtab
  164.  */
  165. stinstal()
  166. {
  167. register    int    j;
  168. register    int    ptr1;
  169. register    int    ptr2;
  170.  
  171.     ptr1 = ptr2 = nxt_free;
  172.     if ((ptr1 + symbol[0] + 6) >= STABSZ) {
  173.         error("Symbol table full");
  174.         return(-1);
  175.     }
  176.     for (j = 0; j <= symbol[0]; j++)
  177.         symtab[ptr1++] = symbol[j];
  178.     symtab[ptr1] = udtype;
  179.     nxt_free = ptr1 + 5;
  180.     return(ptr2);
  181. }
  182.  
  183. /* operation code table lookup
  184.  *    if found, return pointer to symbol,
  185.  *    else, return -1
  186.  */
  187.  
  188. oplook(ip)
  189.    int    *ip;
  190. {
  191. register    char    ch;
  192. register    int    i;
  193. register    int    j;
  194.     int    k;
  195.     int    temp[2];
  196.  
  197.     i = j = 0;
  198.     temp[0] = temp[1] = 0;
  199.     while((ch=prlnbuf[*ip])!= ' ' && ch!= 0 && ch!= '\t' && ch!= ';') {
  200.         if (ch >= 'A' && ch <= 'Z')
  201.             ch &= 0x1f;
  202.         else if (ch >= 'a' && ch <= 'z')
  203.             ch &= 0x1f;
  204.         else if (ch == '.')
  205.             ch = 31;
  206.         else if (ch == '*')
  207.             ch = 30;
  208.         else if (ch == '=')
  209.             ch = 29;
  210.         else return(-1);
  211.         temp[j] = (temp[j] * 0x20) + (ch & 0xff);
  212.         if (ch == 29)
  213.             break;
  214.         ++(*ip);
  215.         if (++i >= 3) {
  216.             i = 0;
  217.             if (++j >= 2) {
  218.                 return(-1);
  219.             }
  220.         }
  221.     }
  222.     if ((j = temp[0]^temp[1]) == 0)
  223.         return(-2);
  224.     k = 0;
  225.     i = step[k] - 3;
  226.     do {
  227.         if (j == optab[i]) {
  228.             opflg = optab[++i];
  229.             opval = optab[++i];
  230.             return(i);
  231.         }
  232.         else if (j < optab[i])
  233.             i -= step[++k];
  234.         else i += step[++k];
  235.     } while (step[k] != 0);
  236.     return(-1);
  237. }
  238.  
  239. /* error printing routine */
  240.  
  241. error(stptr)
  242.    char *stptr;
  243. {
  244.     loadlc(loccnt, 0, 1);
  245.     loccnt += 3;
  246.     loadv(0,0,0);
  247.     loadv(0,1,0);
  248.     loadv(0,2,0);
  249.     fprintf(stderr, "%s\n", prlnbuf);
  250.     fprintf(stderr, "***** %s\n", stptr);
  251.     errcnt++;
  252. }
  253.  
  254. /* load 16 bit value in printable form into prlnbuf */
  255.  
  256. loadlc(val, f, outflg)
  257.     int val;
  258.     int f;
  259.     int outflg;
  260. {
  261.     int    i;
  262.  
  263.     i = 6 + 7*f;
  264.     hexcon(4, val);
  265.     if (nflag == 0) {
  266.         prlnbuf[i++]  = hex[3];
  267.         prlnbuf[i++]  = hex[4];
  268.         prlnbuf[i++]  = ':';
  269.         prlnbuf[i++]  = hex[1];
  270.         prlnbuf[i] = hex[2];
  271.     }
  272.     else {
  273.         prlnbuf[i++] = hex[1];
  274.         prlnbuf[i++] = hex[2];
  275.         prlnbuf[i++] = hex[3];
  276.         prlnbuf[i] = hex[4];
  277.     }
  278.     if ((pass == LAST_PASS)&&(oflag != 0)&&(objcnt <= 0)&&(outflg != 0)) {
  279.          /* rearrange the next for franklin monitor tm */
  280.         fprintf(optr, "\n%c%c%c%c:", hex[1], hex[2], hex[3], hex[4]);
  281.         objcnt = 16;
  282.     }
  283. }
  284.  
  285.  
  286.  
  287. /* load value in hex into prlnbuf[contents[i]] */
  288. /* and output hex characters to obuf if LAST_PASS & oflag == 1 */
  289.  
  290. loadv(val,f,outflg)
  291.    int    val;
  292.    int    f;        /* contents field subscript */
  293.    int    outflg;        /* flag to output object bytes */
  294. {
  295.  
  296.     hexcon(2, val);
  297.     prlnbuf[13 + 3*f] = hex[1];
  298.     prlnbuf[14 + 3*f] = hex[2];
  299.     if ((pass == LAST_PASS) && (oflag != 0) && (outflg != 0)) {
  300.         fputc(hex[1], optr);
  301.         fputc(hex[2], optr);
  302.         fputc(' ', optr);   /* add space for franklin monitor tm */
  303.         --objcnt;
  304.     }
  305. }
  306.  
  307. /* convert number supplied as argument to hexadecimal in hex[digit] (lsd)
  308.         through hex[1] (msd)        */
  309.  
  310. hexcon(digit, num)
  311.     int digit;
  312.    int    num;
  313. {
  314.  
  315.     for (; digit > 0; digit--) {
  316.         hex[digit] = (num & 0x0f) + '0';
  317.         if (hex[digit] > '9')
  318.             hex[digit] += 'A' -'9' - 1;
  319.         num >>= 4;
  320.     }
  321. }
  322.  
  323. /* assign <value> to label pointed to by lablptr,
  324.  *    checking for valid definition, etc.
  325.  */
  326.  
  327. labldef(lval)
  328.     int lval;
  329. {
  330.     int    i;
  331.  
  332.     if (lablptr != -1) {
  333.         lablptr += symtab[lablptr] + 1;
  334.         if (pass == FIRST_PASS) {
  335.             if (symtab[lablptr] == UNDEF) {
  336.                 symtab[lablptr + 1] = lval & 0xff;
  337.                 i = symtab[lablptr + 2] = (lval >> 8) & 0xff;
  338.                 if (i == 0)
  339.                     symtab[lablptr] = DEFZRO;
  340.                 else    symtab[lablptr] = DEFABS;
  341.             }
  342.             else if (symtab[lablptr] == UNDEFAB) {
  343.                 symtab[lablptr] = DEFABS;
  344.                 symtab[lablptr + 1] = lval & 0xff;
  345.                 symtab[lablptr + 2] = (lval >> 8) & 0xff;
  346.             }
  347.             else {
  348.                 symtab[lablptr] = MDEF;
  349.                 symtab[lablptr + 1] = 0;
  350.                 symtab[lablptr + 2] = 0;
  351.                 error("Label multiply defined");
  352.                 return(-1);
  353.             }
  354.         }
  355.         else {
  356.             i = (symtab[lablptr + 2] << 8) +
  357.                 (symtab[lablptr+1] & 0xff);
  358.             i &= 0xffff;
  359.             if (i != lval && pass == LAST_PASS) {
  360.                 error("Sync error");
  361.                 return(-1);
  362.             }
  363.         }
  364.     }
  365.     return(0);
  366. }
  367.  
  368. /* determine the value of the symbol,
  369.  * given pointer to first character of symbol in symtab
  370.  */
  371.  
  372. symval(ip)
  373.     int *ip;
  374. {
  375.     int    ptr;
  376.     int    svalue;
  377.  
  378.     svalue = 0;
  379.     colsym(ip);
  380.     if ((ptr = stlook()) == -1)
  381.         undef = 1;        /* no room error */
  382.     else if (symtab[ptr + symtab[ptr] + 1] == UNDEF)
  383.         undef = 1;
  384.     else if (symtab[ptr + symtab[ptr] + 1] == UNDEFAB)
  385.         undef = 1;
  386.     else svalue = ((symtab[ptr + symtab[ptr] + 3] << 8) +
  387.         (symtab[ptr + symtab[ptr] + 2] & 0xff)) & 0xffff;
  388.     if (symtab[ptr + symtab[ptr] + 1] == DEFABS)
  389.         zpref = 1;
  390.     if (undef != 0)
  391.         zpref = 1;
  392.     return(svalue);
  393. }
  394. SHAR_EOF
  395. if test -f 'assm3.c'
  396. then
  397.     echo shar: over-writing existing file "'assm3.c'"
  398. fi
  399. cat << \SHAR_EOF > 'assm3.c'
  400. #include "stdio.h"
  401. #include "assm.d1"
  402. #include "assm.d2"
  403.  
  404. /* class 1 machine operations processor - 1 byte, no operand field */
  405.  
  406. class1()
  407. {
  408.     if (pass == LAST_PASS) {
  409.         loadlc(loccnt, 0, 1);
  410.         loadv(opval, 0, 1);
  411.         println();
  412.     }
  413.     loccnt++;
  414. }
  415.  
  416.  
  417. /* class 2 machine operations processor - 2 byte, relative addressing */
  418.  
  419. class2(ip)
  420.     int *ip;
  421. {
  422.  
  423.     if (pass == LAST_PASS) {
  424.         loadlc(loccnt, 0, 1);
  425.         loadv(opval, 0, 1);
  426.         while (prlnbuf[++(*ip)] == ' ');
  427.         if (evaluate(ip) != 0) {
  428.             loccnt += 2;
  429.             return;
  430.         }
  431.         loccnt += 2;
  432.         if ((value -= loccnt) >= -128 && value < 128) {
  433.             loadv(value, 1, 1);
  434.             println();
  435.         }
  436.         else error("Invalid branch address");
  437.     }
  438.     else loccnt += 2;
  439. }
  440.  
  441.  
  442. /* class 3 machine operations processor - various addressing modes */
  443.  
  444. class3(ip)
  445.     int *ip;
  446. {
  447.     char    ch;
  448.     int    code;
  449.     int    flag;
  450.     int    i;
  451.     int    ztmask;
  452.  
  453.     while ((ch = prlnbuf[++(*ip)]) == ' ');
  454.     switch(ch) {
  455.     case 0:
  456.     case ';':
  457.         error("Operand field missing");
  458.         return;
  459.     case 'A':
  460.     case 'a':
  461.         if ((ch = prlnbuf[*ip + 1]) == ' ' || ch == 0) {
  462.             flag = ACC;
  463.             break;
  464.         }
  465.     default:
  466.         switch(ch = prlnbuf[*ip]) {
  467.         case '#': case '=':
  468.             flag = IMM1 | IMM2;
  469.             ++(*ip);
  470.             break;
  471.         case '(':
  472.             flag = IND | INDX | INDY;
  473.             ++(*ip);
  474.             break;
  475.         default:
  476.             flag = ABS | ZER | ZERX | ABSX | ABSY | ABSY2 | ZERY;
  477.         }
  478.         if ((flag & (INDX | INDY | ZER | ZERX | ZERY) & opflg) != 0)
  479.             udtype = UNDEFAB;
  480.         if (evaluate(ip) != 0)
  481.             return;
  482.         if (zpref != 0) {
  483.             flag &= (ABS | ABSX | ABSY | ABSY2 | IND | IMM1 | IMM2);
  484.             ztmask = 0;
  485.         }
  486.         else ztmask = ZER | ZERX | ZERY;
  487.         code = 0;
  488.         i = 0;
  489.         while (( ch = prlnbuf[(*ip)++]) != ' ' && ch != 0 && i++ < 4) {
  490.             code *= 8;
  491.             switch(ch) {
  492.             case ')':        /* ) = 4 */
  493.                 ++code;
  494.             case ',':        /* , = 3 */
  495.                 ++code;
  496.             case 'X':        /* X = 2 */
  497.             case 'x':
  498.                 ++code;
  499.             case 'Y':        /* Y = 1 */
  500.             case 'y':
  501.                 ++code;
  502.                 break;
  503.             default:
  504.                 flag = 0;
  505.             }
  506.         }
  507.         switch(code) {
  508.         case 0:        /* no termination characters */
  509.             flag &= (ABS | ZER | IMM1 | IMM2);
  510.             break;
  511.         case 4:        /* termination = ) */
  512.             flag &= IND;
  513.             break;
  514.         case 25:        /* termination = ,Y */
  515.             flag &= (ABSY | ABSY2 | ZERY);
  516.             break;
  517.         case 26:        /* termination = ,X */
  518.             flag &= (ABSX | ZERX);
  519.             break;
  520.         case 212:        /* termination = ,X) */
  521.             flag &= INDX;
  522.             break;
  523.         case 281:        /* termination = ),Y */
  524.             flag &= INDY;
  525.             break;
  526.         default:
  527.             flag = 0;
  528.         }
  529.     }
  530.     if ((opflg &= flag) == 0) {
  531.         error("Invalid addressing mode");
  532.         return;
  533.     }
  534.     if ((opflg & ztmask) != 0)
  535.         opflg &= ztmask;
  536.     switch(opflg) {
  537.     case ACC:        /* single byte - class 3 */
  538.         if (pass == LAST_PASS) {
  539.             loadlc(loccnt, 0, 1);
  540.             loadv(opval + 8, 0, 1);
  541.             println();
  542.         }
  543.         loccnt++;
  544.         return;
  545.     case ZERX: case ZERY:    /* double byte - class 3 */
  546.         opval += 4;
  547.     case INDY:
  548.         opval += 8;
  549.     case IMM2:
  550.         opval += 4;
  551.     case ZER:
  552.         opval += 4;
  553.     case INDX: case IMM1:
  554.         if (pass == LAST_PASS) {
  555.             loadlc(loccnt, 0, 1);
  556.             loadv(opval, 0, 1);
  557.             loadv(value, 1, 1);
  558.             println();
  559.         }
  560.         loccnt += 2;
  561.         return;
  562.     case IND:        /* triple byte - class 3 */
  563.         opval += 16;
  564.     case ABSX:
  565.     case ABSY2:
  566.         opval += 4;
  567.     case ABSY:
  568.         opval += 12;
  569.     case ABS:
  570.         if (pass == LAST_PASS) {
  571.             opval += 12;
  572.             loadlc(loccnt, 0, 1);
  573.             loadv(opval, 0, 1);
  574.             loadv(value, 1, 1);
  575.             loadv(value >> 8, 2, 1);
  576.             println();
  577.         }
  578.         loccnt += 3;
  579.         return;
  580.     default:
  581.         error("Invalid addressing mode");
  582.         return;
  583.     }
  584. }
  585.  
  586. /* pseudo operations processor */
  587.  
  588. pseudo(ip)
  589.     int *ip;
  590. {
  591.     int    count;
  592.     int    i;
  593.     int    tvalue;
  594.     int     hibit; /* apple requires high bit to be on for chs */
  595.     int     pi;
  596.  
  597.     switch(opval) {
  598.     case 0:                /* .byte pseudo */
  599.         labldef(loccnt);
  600.         loadlc(loccnt, 0, 1);
  601.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  602.         count = 0;
  603.         do {
  604.             if (prlnbuf[*ip] == '"') {
  605.                 /* check for hibit on flag for ascii chs */
  606.                 hibit = 0 ;
  607.                 pi = *ip;
  608.                 while((i = prlnbuf[++pi]) != '"' && i != 0 );
  609.                 if (i != 0 )
  610.                   while(prlnbuf[++pi] == ' ' ) ;
  611.                 if (prlnbuf[pi] == '1' )
  612.                    hibit = 0x80 ;
  613.                 while ((tvalue = prlnbuf[++(*ip)]) != '"') {
  614.                     if (tvalue == 0) {
  615.                         error("Unterminated ASCII string");
  616.                         return;
  617.                     }
  618.                     if (tvalue == '\\')
  619.                         switch(tvalue = prlnbuf[++(*ip)]) {
  620.                         case 'n':
  621.                             tvalue = '\n';
  622.                             break;
  623.                         case 't':
  624.                             tvalue = '\t';
  625.                             break;
  626.                         }
  627.                     loccnt++;
  628.                     if (pass == LAST_PASS) {
  629.                         tvalue |= hibit ;
  630.                         loadv(tvalue, count, 1);
  631.                         if (++count >= 3) {
  632.                             println();
  633.                             for (i = 0; i < SFIELD; i++)
  634.                                 prlnbuf[i] = ' ';
  635.                             prlnbuf[i] = 0;
  636.                             count = 0;
  637.                             loadlc(loccnt, 0, 1);
  638.                         }
  639.                     }
  640.                 }
  641.                 ++(*ip);
  642.             }
  643.             else {
  644.                 if (evaluate(ip) != 0) {
  645.                     loccnt++;
  646.                     return;
  647.                 }
  648.                 loccnt++;
  649.                 if (value > 0xff) {
  650.                     error("Operand field size error");
  651.                     return;
  652.                 }
  653.                 else if (pass == LAST_PASS) {
  654.                     loadv(value, count, 1);
  655.                     if (++count >= 3) {
  656.                         println();
  657.                         for (i = 0; i < SFIELD; i++)
  658.                             prlnbuf[i] = ' ';
  659.                         prlnbuf[i] = 0;
  660.                         count = 0;
  661.                         loadlc(loccnt, 0, 1);
  662.                     }
  663.                 }
  664.             }
  665.         } while (prlnbuf[(*ip)++] == ',');
  666.         if ((pass == LAST_PASS) && (count != 0))
  667.             println();
  668.         return;
  669.     case 1:                /* = pseudo */
  670.         while (prlnbuf[++(*ip)] == ' ');
  671.         if (evaluate(ip) != 0)
  672.             return;
  673.         labldef(value);
  674.         if (pass == LAST_PASS) {
  675.             loadlc(value, 1, 0);
  676.             println();
  677.         }
  678.         return;
  679.     case 2:                /* .word pseudo */
  680.         labldef(loccnt);
  681.         loadlc(loccnt, 0, 1);
  682.         while (prlnbuf[++(*ip)] == ' ');
  683.         do {
  684.             if (evaluate(ip) != 0) {
  685.                 loccnt += 2;
  686.                 return;
  687.             }
  688.             loccnt += 2;
  689.             if (pass == LAST_PASS) {
  690.                 loadv(value, 0, 1);
  691.                 loadv(value>>8, 1, 1);
  692.                 println();
  693.                 for (i = 0; i < SFIELD; i++)
  694.                     prlnbuf[i] = ' ';
  695.                 prlnbuf[i] = 0;
  696.                 loadlc(loccnt, 0, 1);
  697.             }
  698.         } while (prlnbuf[(*ip)++] == ',');
  699.         return;
  700.     case 3:                /* *= pseudo */
  701.         while (prlnbuf[++(*ip)] == ' ');
  702.         if (prlnbuf[*ip] == '*') {
  703.             if (evaluate(ip) != 0)
  704.                 return;
  705.             if (undef != 0) {
  706.                 error("Undefined symbol in operand field.");
  707.                 return;
  708.             }
  709.             tvalue = loccnt;
  710.         }
  711.         else {
  712.             if (evaluate(ip) != 0)
  713.                 return;
  714.             if (undef != 0) {
  715.                 error("Undefined symbol in operand field.");
  716.                 return;
  717.             }
  718.             tvalue = value;
  719.         }
  720.         loccnt = value;
  721.         labldef(tvalue);
  722.         if (pass == LAST_PASS) {
  723.             objcnt = 0;
  724.             loadlc(tvalue, 1, 0);
  725.             println();
  726.         }
  727.         return;
  728.     case 4:                /* .list pseudo */
  729.         if (lflag >= 0)
  730.             lflag = 1;
  731.         return;
  732.     case 5:                /* .nlst pseudo */
  733.         if (lflag >= 0)
  734.             lflag = iflag;
  735.         return;
  736.     case 6:                /* .dbyt pseudo */
  737.         labldef(loccnt);
  738.         loadlc(loccnt, 0, 1);
  739.         while (prlnbuf[++(*ip)] == ' ');
  740.         do {
  741.             if (evaluate(ip) != 0) {
  742.                 loccnt += 2;
  743.                 return;
  744.             }
  745.             loccnt += 2;
  746.             if (pass == LAST_PASS) {
  747.                 loadv(value>>8, 0, 1);
  748.                 loadv(value, 1, 1);
  749.                 println();
  750.                 for (i = 0; i < SFIELD; i++)
  751.                     prlnbuf[i] = ' ';
  752.                 prlnbuf[i] = 0;
  753.                 loadlc(loccnt, 0, 1);
  754.             }
  755.         } while (prlnbuf[(*ip)++] == ',');
  756.         return;
  757.     case 7:                /* ds pseudo */
  758.         while (prlnbuf[++(*ip)] == ' ');
  759.         if (evaluate(ip) != 0)
  760.             return;
  761.         if (undef != 0) {
  762.             error("Undefined symbol in operand field.");
  763.             return;
  764.         }
  765.         tvalue = loccnt;
  766.         labldef(loccnt);
  767.         loccnt += value;
  768.         if (pass == LAST_PASS) {
  769.             objcnt = 0;
  770.             loadlc(tvalue, 1, 0);
  771.             println();
  772.         }
  773.         return;
  774.     case 8:                /* asc pseudo */
  775.         labldef(loccnt);
  776.         loadlc(loccnt, 0, 1);
  777.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  778.         count = 0;
  779.         do {
  780.             if (prlnbuf[*ip] == '\'') {
  781.                 while ((tvalue = prlnbuf[++(*ip)]) != '\'') {
  782.                     if (tvalue == 0) {
  783.                         error("Unterminated ASCII string");
  784.                         return;
  785.                     }
  786.                     if (tvalue == '\\')
  787.                         switch(tvalue = prlnbuf[++(*ip)]) {
  788.                         case 'n':
  789.                             tvalue = '\n';
  790.                             break;
  791.                         case 't':
  792.                             tvalue = '\t';
  793.                             break;
  794.                         }
  795.                     loccnt++;
  796.                     if (pass == LAST_PASS) {
  797.                         tvalue |= msb   ;
  798.                         loadv(tvalue, count, 1);
  799.                         if (++count >= 3) {
  800.                             println();
  801.                             for (i = 0; i < SFIELD; i++)
  802.                                 prlnbuf[i] = ' ';
  803.                             prlnbuf[i] = 0;
  804.                             count = 0;
  805.                             loadlc(loccnt, 0, 1);
  806.                         }
  807.                     }
  808.                 }
  809.                 ++(*ip);
  810.             }
  811.             else {
  812.                 if (evaluate(ip) != 0) {
  813.                     loccnt++;
  814.                     return;
  815.                 }
  816.                 loccnt++;
  817.                 if (value > 0xff) {
  818.                     error("Operand field size error");
  819.                     return;
  820.                 }
  821.                 else if (pass == LAST_PASS) {
  822.                     loadv(value, count, 1);
  823.                     if (++count >= 3) {
  824.                         println();
  825.                         for (i = 0; i < SFIELD; i++)
  826.                             prlnbuf[i] = ' ';
  827.                         prlnbuf[i] = 0;
  828.                         count = 0;
  829.                         loadlc(loccnt, 0, 1);
  830.                     }
  831.                 }
  832.             }
  833.         } while (prlnbuf[(*ip)++] == ',');
  834.         if ((pass == LAST_PASS) && (count != 0))
  835.             println();
  836.         return;
  837.     case 13:            /* msb pseudo */
  838.         while (prlnbuf[++(*ip)] == ' ');
  839.         if (pass == LAST_PASS) 
  840.             println();
  841.         pi = *ip;
  842.         if (( i = 0x20|prlnbuf[pi+1] ) == 'f' ){
  843.                 msb=0;
  844.                 return;
  845.                 }
  846.             else if (i=='n'){
  847.                 msb=0x80;
  848.                 return;
  849.                 }
  850.         error("Invalid symbol in operand field.");
  851.         return;
  852.     }
  853. }
  854.  
  855. /* evaluate expression */
  856.  
  857. evaluate(ip)
  858.    int    *ip;
  859. {
  860.     int    tvalue;
  861.     int    invalid;
  862.     int    parflg, value2;
  863.     char    ch;
  864.     char    op;
  865.     char    op2;
  866.  
  867.     op = '+';
  868.     parflg = zpref = undef = value = invalid = 0;
  869. /* hcj: zpref should reflect the value of the expression, not the value of
  870.    the intermediate symbols
  871. */
  872.     while ((ch=prlnbuf[*ip]) != ' ' && ch != ')' && ch != ',' && ch != ';') {
  873.         tvalue = 0;
  874.         if (ch == '$' || ch == '@' || ch == '%')
  875.             tvalue = colnum(ip);
  876.         else if (ch >= '0' && ch <= '9')
  877.             tvalue = colnum(ip);
  878.         else if (ch >= 'a' && ch <= 'z')
  879.             tvalue = symval(ip);
  880.         else if (ch >= 'A' && ch <= 'Z')
  881.             tvalue = symval(ip);
  882.         else if ((ch == '_') || (ch == '.'))
  883.             tvalue = symval(ip);
  884.         else if (ch == '*') {
  885.             tvalue = loccnt;
  886.             ++(*ip);
  887.         }
  888.         else if (ch == '\'') {
  889.             ++(*ip);
  890.             tvalue = prlnbuf[*ip] & 0xff;
  891.             ++(*ip);
  892.         }
  893.         else if (ch == '[') {
  894.             if (parflg == 1) {
  895.                 error("Too many ['s in expression");
  896.                 invalid++;
  897.             }
  898.             else {
  899.                 value2 = value;
  900.                 op2 = op;
  901.                 value = tvalue = 0;
  902.                 op = '+';
  903.                 parflg = 1;
  904.             }
  905.             goto next;
  906.         }
  907.         else if (ch == ']') {
  908.             if (parflg == 0) {
  909.                 error("No matching [ for ] in expression");
  910.                 invalid++;
  911.             }
  912.             else {
  913.                 parflg = 0;
  914.                 tvalue = value;
  915.                 value = value2;
  916.                 op = op2;
  917.             }
  918.             ++(*ip);
  919.         }
  920.         switch(op) {
  921.         case '+':
  922.             value += tvalue;
  923.             break;
  924.         case '-':
  925.             value -= tvalue;
  926.             break;
  927.         case '/':
  928.             value = (unsigned) value/tvalue;
  929.             break;
  930.         case '*':
  931.             value *= tvalue;
  932.             break;
  933.         case '%':
  934.             value = (unsigned) value%tvalue;
  935.             break;
  936.         case '^':
  937.             value ^= tvalue;
  938.             break;
  939.         case '~':
  940.             value = ~tvalue;
  941.             break;
  942.         case '&':
  943.             value &= tvalue;
  944.             break;
  945.         case '|':
  946.             value |= tvalue;
  947.             break;
  948.         case '<':
  949.             tvalue >>= 8;        /* fall through to '<' */
  950.         case '>':
  951.             if (value != 0) {
  952.                 error("High or low byte operator not first in operand field");
  953.             }
  954.             value = tvalue & 0xff;
  955.             zpref = 0;
  956.             break;
  957.         default:
  958.             invalid++;
  959.         }
  960.         if ((op=prlnbuf[*ip]) == ' '
  961.                 || op == ')'
  962.                 || op == ','
  963.                 || op == ';')
  964.             break;
  965.         else if (op != ']')
  966. next:            ++(*ip);
  967.     }
  968.     if (parflg == 1) {
  969.         error("Missing ] in expression");
  970.         return(1);
  971.     }
  972.     if (value < 0 || value >= 256) {
  973.         zpref = 1;
  974.     }
  975.     if (undef != 0) {
  976.         if (pass != FIRST_PASS) {
  977.             error("Undefined symbol in operand field");
  978.             invalid++;
  979.         }
  980.         value = 0;
  981.     }
  982.     else if (invalid != 0)
  983.     {
  984.         error("Invalid operand field");
  985.     }
  986.     else {
  987. /*
  988.  This is the only way out that may not signal error
  989. */
  990.         if (value < 0 || value >= 256) {
  991.             zpref = 1;
  992.         }
  993.         else {
  994.             zpref = 0;
  995.         }
  996.     }
  997.     return(invalid);
  998. }
  999.  
  1000. /* collect number operand        */
  1001.  
  1002. colnum(ip)
  1003.     int    *ip;
  1004. {
  1005.     int    mul;
  1006.     int    nval;
  1007.     char    ch;
  1008.  
  1009.     nval = 0;
  1010.     if ((ch = prlnbuf[*ip]) == '$')
  1011.         mul = 16;
  1012.     else if (ch >= '1' && ch <= '9') {
  1013.         mul = 10;
  1014.         nval = ch - '0';
  1015.     }
  1016.     else if (ch == '@' || ch == '0')
  1017.         mul = 8;
  1018.     else if (ch == '%')
  1019.         mul = 2;
  1020.     while ((ch = prlnbuf[++(*ip)] - '0') >= 0) {
  1021.         if (ch > 9) {
  1022.             ch -= ('A' - '9' - 1);
  1023.             if (ch > 15)
  1024.                 ch -= ('a' - 'A');
  1025.             if (ch > 15)
  1026.                 break;
  1027.             if (ch < 10)
  1028.                 break;
  1029.         }
  1030.         if (ch >= mul)
  1031.             break;
  1032.         nval = (nval * mul) + ch;
  1033.     }
  1034.     return(nval);
  1035. }
  1036. SHAR_EOF
  1037. #    End of shell archive
  1038. exit 0
  1039.