home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / appleii / appxas.3 / assm3.c < prev   
C/C++ Source or Header  |  2020-01-01  |  16KB  |  816 lines

  1. #include "stdio.h"
  2. #include "assm.d1"
  3. #include "assm.d2"
  4.  
  5. /* class 1 machine operations processor - 1 byte, no operand field */
  6.  
  7. class1()
  8. {
  9.     if (pass == LAST_PASS) {
  10.         loadlc(loccnt, 0, 1);
  11.         loadv(opval, 0, 1);
  12.         println();
  13.     }
  14.     loccnt++;
  15. }
  16.  
  17.  
  18. /* class 2 machine operations processor - 2 byte, relative addressing */
  19.  
  20. class2(ip)
  21.     int *ip;
  22. {
  23.  
  24.     if (pass == LAST_PASS) {
  25.         loadlc(loccnt, 0, 1);
  26.         loadv(opval, 0, 1);
  27.         while (prlnbuf[++(*ip)] == ' ');
  28.         if (evaluate(ip) != 0) {
  29.             loccnt += 2;
  30.             return;
  31.         }
  32.         loccnt += 2;
  33.         if ((value -= loccnt) >= -128 && value < 128) {
  34.             loadv(value, 1, 1);
  35.             println();
  36.         }
  37.         else error("Invalid branch address");
  38.     }
  39.     else loccnt += 2;
  40. }
  41.  
  42.  
  43. /* class 3 machine operations processor - various addressing modes */
  44.  
  45. class3(ip)
  46.     int *ip;
  47. {
  48.     char    ch;
  49.     int    code;
  50.     int    flag;
  51.     int    i;
  52.     int    ztmask;
  53.  
  54.     while ((ch = prlnbuf[++(*ip)]) == ' ');
  55.     switch(ch) {
  56.     case 0:
  57.     case ';':
  58.         error("Operand field missing");
  59.         return;
  60.     case 'A':
  61.     case 'a':
  62.         if ((ch = prlnbuf[*ip + 1]) == ' ' || ch == 0) {
  63.             flag = ACC;
  64.             break;
  65.         }
  66.     default:
  67.         switch(ch = prlnbuf[*ip]) {
  68.         case '#': case '=':
  69.             flag = IMM1 | IMM2;
  70.             ++(*ip);
  71.             break;
  72.         case '(':
  73.             flag = IND | INDX | INDY;
  74.             ++(*ip);
  75.             break;
  76.         default:
  77.             flag = ABS | ZER | ZERX | ABSX | ABSY | ABSY2 | ZERY;
  78.         }
  79.         if ((flag & (INDX | INDY | ZER | ZERX | ZERY) & opflg) != 0)
  80.             udtype = UNDEFAB;
  81.         if (evaluate(ip) != 0)
  82.             return;
  83.         if (zpref != 0) {
  84.             flag &= (ABS | ABSX | ABSY | ABSY2 | IND | IMM1 | IMM2);
  85.             ztmask = 0;
  86.         }
  87.         else ztmask = ZER | ZERX | ZERY;
  88.         code = 0;
  89.         i = 0;
  90.         while (( ch = prlnbuf[(*ip)++]) != ' ' && ch != 0 && i++ < 4) {
  91.             code *= 8;
  92.             switch(ch) {
  93.             case ')':        /* ) = 4 */
  94.                 ++code;
  95.             case ',':        /* , = 3 */
  96.                 ++code;
  97.             case 'X':        /* X = 2 */
  98.             case 'x':
  99.                 ++code;
  100.             case 'Y':        /* Y = 1 */
  101.             case 'y':
  102.                 ++code;
  103.                 break;
  104.             default:
  105.                 flag = 0;
  106.             }
  107.         }
  108.         switch(code) {
  109.         case 0:        /* no termination characters */
  110.             flag &= (ABS | ZER | IMM1 | IMM2);
  111.             break;
  112.         case 4:        /* termination = ) */
  113.             if (opval!=0x40 && ((flag&IND)==IND)) {
  114.                 if (zpref == 1) flag=0 ; /* fail it */
  115.                 else {      /* (zp)Mode */
  116.                 flag = ZER;
  117.                 opval += 13;
  118.                 }
  119.                 break;
  120.             }
  121.             flag &= IND;
  122.             break;
  123.         case 25:        /* termination = ,Y */
  124.             flag &= (ABSY | ABSY2 | ZERY);
  125.             break;
  126.         case 26:        /* termination = ,X */
  127.             flag &= (ABSX | ZERX);
  128.             break;
  129.         case 212:        /* termination = ,X) */
  130.             if (opval == 0x40 && zpref == 1) {
  131.                 flag &= IND;    /* jmp (abs,x) */
  132.                 opval = 0x50;
  133.                 break;
  134.             }
  135.             flag &= INDX;
  136.             break;
  137.         case 281:        /* termination = ),Y */
  138.             flag &= INDY;
  139.             break;
  140.         default:
  141.             flag = 0;
  142.         }
  143.     }
  144.     if ((opflg &= flag) == 0) {
  145.         error("Invalid addressing mode");
  146.         return;
  147.     }
  148.     if ((opflg & ztmask) != 0)
  149.         opflg &= ztmask;
  150.     switch(opflg) {
  151.     case ACC:        /* single byte - class 3 */
  152.         if (pass == LAST_PASS) {
  153.             loadlc(loccnt, 0, 1);
  154.             loadv(opval + 8, 0, 1);
  155.             println();
  156.         }
  157.         loccnt++;
  158.         return;
  159.     case ZERX: case ZERY:    /* double byte - class 3 */
  160.         opval += 4;
  161.     case INDY:
  162.         opval += 8;
  163.     case IMM2:
  164.         opval += 4;
  165.     case ZER:
  166.         opval += 4;
  167.     case INDX:
  168.     case IMM1:
  169.         if (pass == LAST_PASS) {
  170.             loadlc(loccnt, 0, 1);
  171.             loadv(opval, 0, 1);
  172.             loadv(value, 1, 1);
  173.             println();
  174.         }
  175.         loccnt += 2;
  176.         return;
  177.     case IND:        /* triple byte - class 3 */
  178.         opval += 16;
  179.     case ABSX:
  180.         if (opval==0x60 && opflg==ABSX)opval = 0x82; /* stz abs,x */
  181.     case ABSY2:
  182.         opval += 4;
  183.     case ABSY:
  184.         opval += 12;
  185.     case ABS:
  186.         if (opval == 0x60 && opflg == ABS) opval=0x90 ; /* stz abs */
  187.             
  188.         if (pass == LAST_PASS) {
  189.             opval += 12;
  190.             loadlc(loccnt, 0, 1);
  191.             loadv(opval, 0, 1);
  192.             loadv(value, 1, 1);
  193.             loadv(value >> 8, 2, 1);
  194.             println();
  195.         }
  196.         loccnt += 3;
  197.         return;
  198.     default:
  199.         error("Invalid addressing mode");
  200.         return;
  201.     }
  202. }
  203.  
  204. /* pseudo operations processor */
  205.  
  206. pseudo(ip)
  207.     int *ip;
  208. {
  209.     int    count;
  210.     int    i;
  211.     int    tvalue;
  212.     int     hibit; /* apple requires high bit to be on for chs */
  213.     int     pi;
  214.  
  215.     switch(opval) {
  216.     case 0:                /* .byte pseudo */
  217.         labldef(loccnt);
  218.         loadlc(loccnt, 0, 1);
  219.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  220.         count = 0;
  221.         do {
  222.             if (prlnbuf[*ip] == '"') {
  223.                 /* check for hibit on flag for ascii chs */
  224.                 hibit = 0 ;
  225.                 pi = *ip;
  226.                 while((i = prlnbuf[++pi]) != '"' && i != 0 );
  227.                 if (i != 0 )
  228.                   while(prlnbuf[++pi] == ' ' ) ;
  229.                 if (prlnbuf[pi] == '1' )
  230.                    hibit = 0x80 ;
  231.                 while ((tvalue = prlnbuf[++(*ip)]) != '"') {
  232.                     if (tvalue == 0) {
  233.                         error("Unterminated ASCII string");
  234.                         return;
  235.                     }
  236.                     if (tvalue == '\\')
  237.                         switch(tvalue = prlnbuf[++(*ip)]) {
  238.                         case 'n':
  239.                             tvalue = '\n';
  240.                             break;
  241.                         case 't':
  242.                             tvalue = '\t';
  243.                             break;
  244.                         }
  245.                     loccnt++;
  246.                     if (pass == LAST_PASS) {
  247.                         tvalue |= hibit ;
  248.                         loadv(tvalue, count, 1);
  249.                         if (++count >= 3) {
  250.                             println();
  251.                             for (i = 0; i < SFIELD; i++)
  252.                                 prlnbuf[i] = ' ';
  253.                             prlnbuf[i] = 0;
  254.                             count = 0;
  255.                             loadlc(loccnt, 0, 1);
  256.                         }
  257.                     }
  258.                 }
  259.                 ++(*ip);
  260.             }
  261.             else {
  262.                 if (evaluate(ip) != 0) {
  263.                     loccnt++;
  264.                     return;
  265.                 }
  266.                 loccnt++;
  267.                 if (value > 0xff) {
  268.                     error("Operand field size error");
  269.                     return;
  270.                 }
  271.                 else if (pass == LAST_PASS) {
  272.                     loadv(value, count, 1);
  273.                     if (++count >= 3) {
  274.                         println();
  275.                         for (i = 0; i < SFIELD; i++)
  276.                             prlnbuf[i] = ' ';
  277.                         prlnbuf[i] = 0;
  278.                         count = 0;
  279.                         loadlc(loccnt, 0, 1);
  280.                     }
  281.                 }
  282.             }
  283.         } while (prlnbuf[(*ip)++] == ',');
  284.         if ((pass == LAST_PASS) && (count != 0))
  285.             println();
  286.         return;
  287.     case 1:                /* = pseudo */
  288.         while (prlnbuf[++(*ip)] == ' ');
  289.         if (evaluate(ip) != 0)
  290.             return;
  291.         if (pass == LAST_PASS) {
  292.                 labldef2(value);
  293.             loadlc(value, 1, 0);
  294.             println();
  295.         }
  296.         else if (undef == 0 ) labldef(value);
  297.         return;
  298.     case 2:                /* .word pseudo */
  299.         labldef(loccnt);
  300.         loadlc(loccnt, 0, 1);
  301.         while (prlnbuf[++(*ip)] == ' ');
  302.         do {
  303.             if (evaluate(ip) != 0) {
  304.                 loccnt += 2;
  305.                 return;
  306.             }
  307.             loccnt += 2;
  308.             if (pass == LAST_PASS) {
  309.                 loadv(value, 0, 1);
  310.                 loadv(value>>8, 1, 1);
  311.                 println();
  312.                 for (i = 0; i < SFIELD; i++)
  313.                     prlnbuf[i] = ' ';
  314.                 prlnbuf[i] = 0;
  315.                 loadlc(loccnt, 0, 1);
  316.             }
  317.         } while (prlnbuf[(*ip)++] == ',');
  318.         return;
  319.     case 3:                /* *= pseudo */
  320.         while (prlnbuf[++(*ip)] == ' ');
  321.         /*
  322.         if (prlnbuf[*ip] == '*') {
  323.             if (evaluate(ip) != 0)
  324.                 return;
  325.             if (undef != 0) {
  326.                 error("Undefined symbol in operand field.");
  327.                 return;
  328.             }
  329.             tvalue = loccnt;
  330.         }
  331.         else {
  332.         */
  333.             if (evaluate(ip) != 0)
  334.                 return;
  335.             if (undef != 0) {
  336.                 error("Undefined symbol in operand field.");
  337.                 return;
  338.             }
  339.             tvalue = value;
  340.         /*
  341.         }
  342.         */
  343.         loccnt = value;
  344.         labldef(tvalue);
  345.         if (pass == LAST_PASS) {
  346.             objcnt = 0;
  347.             loadlc(tvalue, 1, 0);
  348.             println();
  349.         }
  350.         return;
  351.     case 4:                /* .list pseudo */
  352.         if (lflag >= 0)
  353.             lflag = 1;
  354.         return;
  355.     case 5:                /* .nlst pseudo */
  356.         if (lflag >= 0)
  357.             lflag = iflag;
  358.         return;
  359.     case 6:                /* .dbyt pseudo */
  360.         labldef(loccnt);
  361.         loadlc(loccnt, 0, 1);
  362.         while (prlnbuf[++(*ip)] == ' ');
  363.         do {
  364.             if (evaluate(ip) != 0) {
  365.                 loccnt += 2;
  366.                 return;
  367.             }
  368.             loccnt += 2;
  369.             if (pass == LAST_PASS) {
  370.                 loadv(value>>8, 0, 1);
  371.                 loadv(value, 1, 1);
  372.                 println();
  373.                 for (i = 0; i < SFIELD; i++)
  374.                     prlnbuf[i] = ' ';
  375.                 prlnbuf[i] = 0;
  376.                 loadlc(loccnt, 0, 1);
  377.             }
  378.         } while (prlnbuf[(*ip)++] == ',');
  379.         return;
  380.     case 7:                /* ds pseudo */
  381.         while (prlnbuf[++(*ip)] == ' ');
  382.         if (evaluate(ip) != 0)
  383.             return;
  384.         if (undef != 0) {
  385.             error("Undefined symbol in operand field.");
  386.             return;
  387.         }
  388.         tvalue = loccnt;
  389.         labldef(loccnt);
  390.         loccnt += value;
  391.         if (pass == LAST_PASS) {
  392.             objcnt = 0;
  393.             loadlc(tvalue, 1, 0);
  394.             println();
  395.         }
  396.         return;
  397.     case 8:                /* .asciz pseudo */
  398.         labldef(loccnt);
  399.         loadlc(loccnt, 0, 1);
  400.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  401.         count = 0;
  402.         do {
  403.             if (prlnbuf[*ip] == '/') {
  404.                 while ((tvalue = prlnbuf[++(*ip)]) != '/') {
  405.                     if (tvalue == 0) {
  406.                         error("Unterminated ASCII string");
  407.                         return;
  408.                     }
  409.                     if (tvalue == '\\')
  410.                         switch(tvalue = prlnbuf[++(*ip)]) {
  411.                         case 'n':
  412.                             tvalue = '\n';
  413.                             break;
  414.                         case 't':
  415.                             tvalue = '\t';
  416.                             break;
  417.                         }
  418.                     loccnt++;
  419.                     if (pass == LAST_PASS) {
  420.                         tvalue |= msb ;
  421.                         loadv(tvalue, count, 1);
  422.                         if (++count >= 3) {
  423.                             println();
  424.                             for (i = 0; i < SFIELD; i++)
  425.                                 prlnbuf[i] = ' ';
  426.                             prlnbuf[i] = 0;
  427.                             count = 0;
  428.                             loadlc(loccnt, 0, 1);
  429.                         }
  430.                     }
  431.                 }
  432.                 loccnt++;
  433.                 if (pass == LAST_PASS )
  434.                     loadv(0 ,count++,1);
  435.                 ++(*ip);
  436.             }
  437.             else {
  438.                 if (evaluate(ip) != 0) {
  439.                     loccnt++;
  440.                     return;
  441.                 }
  442.                 loccnt++;
  443.                 if (value > 0xff) {
  444.                     error("Operand field size error");
  445.                     return;
  446.                 }
  447.                 else if (pass == LAST_PASS) {
  448.                     loadv(value, count, 1);
  449.                     if (++count >= 3) {
  450.                         println();
  451.                         for (i = 0; i < SFIELD; i++)
  452.                             prlnbuf[i] = ' ';
  453.                         prlnbuf[i] = 0;
  454.                         count = 0;
  455.                         loadlc(loccnt, 0, 1);
  456.                     }
  457.                 }
  458.             }
  459.         } while (prlnbuf[(*ip)++] == ',');
  460.         if ((pass == LAST_PASS) && (count != 0))
  461.             println();
  462.         return;
  463.     case 9:                /* ifeq pseudo */
  464.         while (prlnbuf[++(*ip)] == ' ');
  465.             if (evaluate(ip) != 0)
  466.                 return;
  467.             if (undef != 0) {
  468.                 error("Undefined symbol in operand field.");
  469.                 return;
  470.             }
  471.         if (++nestct >= MAXNEST ) {
  472.             error("Too many nested ifeq ");
  473.             return;
  474.             }
  475.         if (value != 0 ) value=1;
  476.         nest[nestct] = value ;
  477.         noasm = 0;
  478.         for (i=0; i<=nestct ;i++)
  479.             noasm |= nest[i] ;
  480.         if (pass == LAST_PASS) 
  481.             println();
  482.         return;
  483.     case 10:                /* ifne pseudo */
  484.         while (prlnbuf[++(*ip)] == ' ');
  485.             if (evaluate(ip) != 0)
  486.                 return;
  487.             if (undef != 0) {
  488.                 error("Undefined symbol in operand field.");
  489.                 return;
  490.             }
  491.         if (++nestct >= MAXNEST ) {
  492.             error("Too many nested ifne");
  493.             return;
  494.             }
  495.         if (value != 0 ) value=0;
  496.         else value=1;
  497.         nest[nestct] = value ;
  498.         noasm = 0;
  499.         for (i=0; i<=nestct ;i++)
  500.             noasm |= nest[i] ;
  501.         if (pass == LAST_PASS) 
  502.             println();
  503.         return;
  504.     case 11:        /* endc pseudo */
  505.         if (--nestct < 0 ) {
  506.             error("Too many nested endc ");
  507.             return;
  508.             }
  509.         noasm = 0;
  510.         for (i=0; i<=nestct ;i++)
  511.             noasm |= nest[i] ;
  512.         if (pass == LAST_PASS) 
  513.             println();
  514.         return;
  515.     case 12:            /* nasc pseudo */
  516.         labldef(loccnt);
  517.         loadlc(loccnt, 0, 1);
  518.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  519.         count = 0;
  520.         do {
  521.             if (prlnbuf[*ip] == '<') {
  522.                 /* check for hibit on flag for ascii chs */
  523.                 hibit = 0 ;
  524.                 pi = *ip;
  525.                 while((i = prlnbuf[++pi]) != '>' && i != 0 );
  526.                 if (i != 0 )
  527.                   while(prlnbuf[++pi] == ' ' ) ;
  528.                 if (prlnbuf[pi] == '1' )
  529.                    hibit = 1 ;
  530.                 while ((tvalue = prlnbuf[++(*ip)]) != '>') {
  531.                     if (tvalue == 0) {
  532.                         error("Unterminated ASCII string");
  533.                         return;
  534.                     }
  535.                     if (tvalue == '\\')
  536.                         switch(tvalue = prlnbuf[++(*ip)]) {
  537.                         case 'n':
  538.                             tvalue = '\n';
  539.                             break;
  540.                         case 't':
  541.                             tvalue = '\t';
  542.                             break;
  543.                         }
  544.                     loccnt++;
  545.                     if (pass == LAST_PASS) {
  546.                         tvalue |= 0x80 ;
  547.                         loadv(tvalue, count, 1);
  548.                         if (++count >= 3) {
  549.                             println();
  550.                             for (i = 0; i < SFIELD; i++)
  551.                                 prlnbuf[i] = ' ';
  552.                             prlnbuf[i] = 0;
  553.                             count = 0;
  554.                             loadlc(loccnt, 0, 1);
  555.                         }
  556.                     }
  557.                 }
  558.                 if ( hibit ){
  559.                 loccnt++;
  560.                   if (pass == LAST_PASS )
  561.                     loadv(0 ,count++,1);
  562.                 }
  563.                 ++(*ip);
  564.             }
  565.             else {
  566.                 if (evaluate(ip) != 0) {
  567.                     loccnt++;
  568.                     return;
  569.                 }
  570.                 loccnt++;
  571.                 if (value > 0xff) {
  572.                     error("Operand field size error");
  573.                     return;
  574.                 }
  575.                 else if (pass == LAST_PASS) {
  576.                     loadv(value, count, 1);
  577.                     if (++count >= 3) {
  578.                         println();
  579.                         for (i = 0; i < SFIELD; i++)
  580.                             prlnbuf[i] = ' ';
  581.                         prlnbuf[i] = 0;
  582.                         count = 0;
  583.                         loadlc(loccnt, 0, 1);
  584.                     }
  585.                 }
  586.             }
  587.         } while (prlnbuf[(*ip)++] == ',');
  588.         if ((pass == LAST_PASS) && (count != 0))
  589.             println();
  590.         return;
  591.     case 13:            /* msb pseudo */
  592.         while (prlnbuf[++(*ip)] == ' ');
  593.         if (pass == LAST_PASS) 
  594.             println();
  595.         pi = *ip;
  596.         if (( i = 0x20|prlnbuf[pi+1] ) == 'f' ){
  597.                 msb=0;
  598.                 return;
  599.                 }
  600.             else if (i=='n'){
  601.                 msb=0x80;
  602.                 return;
  603.                 }
  604.         error("Invalid symbol in operand field.");
  605.         return;
  606.     }
  607. }
  608.  
  609. /* evaluate expression */
  610.  
  611. evaluate(ip)
  612.    int    *ip;
  613. {
  614.     int    i, tvalue;
  615.     int    invalid;
  616.     int    parflg, value2;
  617.     char    ch;
  618.     char    op;
  619.     char    op2;
  620.  
  621.     op = '+';
  622.     parflg = zpref = undef = value = invalid = 0;
  623. /* hcj: zpref should reflect the value of the expression, not the value of
  624.    the intermediate symbols
  625. */
  626. while((ch=prlnbuf[*ip])!=' '&& ch!= ')' && ch != ',' && ch != ';' && ch != 0){
  627.         tvalue = 0;
  628.         if (ch == '$' || ch == '@' || ch == '%')
  629.             tvalue = colnum(ip);
  630.         else if (ch == '^' ) {
  631.             if ((0x20|prlnbuf[++(*ip)]) == 'o') {
  632.             prlnbuf[*ip] = '0' ;
  633.             i = *ip ; /* save it */
  634.             tvalue = colnum(ip); 
  635.             prlnbuf[i] = 'o' ; /* restore it for printing */
  636.             }
  637.             else --(*ip);
  638.             }
  639.         else if (ch >= '0' && ch <= '9')
  640.             tvalue = colnum(ip);
  641.         else if (ch >= 'a' && ch <= 'z')
  642.             tvalue = symval(ip);
  643.         else if (ch >= 'A' && ch <= 'Z')
  644.             tvalue = symval(ip);
  645.         else if ((ch == '_')  ) /* || (ch == '.')) removed */
  646.             tvalue = symval(ip);
  647.         else if (ch == '*' || ch == '.') {
  648.             tvalue = loccnt;
  649.             ++(*ip);
  650.         }
  651.         else if (ch == '\'') {
  652.             ++(*ip);
  653.             tvalue = prlnbuf[*ip] & 0xff;
  654.             ++(*ip);
  655.         }
  656.         else if (ch == '<') {
  657.             if (parflg == 1) {
  658.                 error("Too many <'s in expression");
  659.                 invalid++;
  660.             }
  661.             else {
  662.                 value2 = value;
  663.                 op2 = op;
  664.                 value = tvalue = 0;
  665.                 op = '+';
  666.                 parflg = 1;
  667.             }
  668.             goto next;
  669.         }
  670.         else if (ch == '>') {
  671.             if (parflg == 0) {
  672.                 error("No matching < for > in expression");
  673.                 invalid++;
  674.             }
  675.             else {
  676.                 parflg = 0;
  677.                 tvalue = value;
  678.                 value = value2;
  679.                 op = op2;
  680.             }
  681.             ++(*ip);
  682.         }
  683.         switch(op) {
  684.         case '+':
  685.             value += tvalue;
  686.             break;
  687.         case '-':
  688.             value -= tvalue;
  689.             break;
  690.         case '/':
  691.             value = (unsigned) value/tvalue;
  692.             break;
  693.         case '*':
  694.             value *= tvalue;
  695.             break;
  696.         case '%':
  697.             value = (unsigned) value%tvalue;
  698.             break;
  699.         /* what to do with exclusive or ?? */
  700.         case '!':
  701.             value ^= tvalue;
  702.             break;
  703.         case '~':
  704.             value = ~tvalue;
  705.             break;
  706.         case '&':
  707.             value &= tvalue;
  708.             break;
  709.         case '|':
  710.             value |= tvalue;
  711.             break;
  712.         /*
  713.         case '<':
  714.             tvalue >>= 8;        /* fall through to '<' */
  715.         /*
  716.         case '>':
  717.             if (value != 0) {
  718.                 error("High or low byte operator not first in operand field");
  719.             }
  720.             value =  tvalue & 0xff;
  721.             zpref = 0;
  722.             break;
  723.         */
  724.         case '^':
  725.             break;
  726.         case '\\':
  727.             break;
  728.         default:
  729.             invalid++;
  730.         }
  731.         if ((op=prlnbuf[*ip]) == ' '
  732.                 || op == ')'
  733.                 || op == ','
  734.                 || op == ';')
  735.             break;
  736.         else switch(op) {
  737.             case '>': break ;
  738.             case '^':
  739.                   value >>= 8 ;
  740.             case '\\': value &= 0xff ;
  741.                 zpref = 0 ;
  742.             default:
  743. next:            ++(*ip);
  744.             }
  745.     }
  746.     if (parflg == 1) {
  747.         error("Missing > in expression");
  748.         return(1);
  749.     }
  750.     /* why is this needed?
  751.     if (value < 0 || value >= 256) {
  752.         zpref = 1;
  753.     }
  754.     I dont know */
  755.     if (undef != 0) {
  756.         if (pass != FIRST_PASS) {
  757.             error("Undefined symbol in operand field");
  758.             invalid++;
  759.         }
  760.         value = 0;
  761.     }
  762.     else if (invalid != 0)
  763.     {
  764.         error("Invalid operand field");
  765.     }
  766.     else {
  767. /*
  768.  This is the only way out that may not signal error
  769. */
  770.         if (value < 0 || value >= 256) {
  771.             zpref = 1;
  772.         }
  773.         else {
  774.             zpref = 0;
  775.         }
  776.     }
  777.     return(invalid);
  778. }
  779.  
  780. /* collect number operand        */
  781.  
  782. colnum(ip)
  783.     int    *ip;
  784. {
  785.     int    mul;
  786.     int    nval;
  787.     char    ch;
  788.  
  789.     nval = 0;
  790.     if ((ch = prlnbuf[*ip]) == '$')
  791.         mul = 16;
  792.     else if (ch >= '1' && ch <= '9') {
  793.         mul = 10;
  794.         nval = ch - '0';
  795.     }
  796.     else if (ch == '@' || ch == '0')
  797.         mul = 8;
  798.     else if (ch == '%')
  799.         mul = 2;
  800.     while ((ch = prlnbuf[++(*ip)] - '0') >= 0) {
  801.         if (ch > 9) {
  802.             ch -= ('A' - '9' - 1);
  803.             if (ch > 15)
  804.                 ch -= ('a' - 'A');
  805.             if (ch > 15)
  806.                 break;
  807.             if (ch < 10)
  808.                 break;
  809.         }
  810.         if (ch >= mul)
  811.             break;
  812.         nval = (nval * mul) + ch;
  813.     }
  814.     return(nval);
  815. }
  816.