home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / appleii / apxa3.c / assm3.c < prev   
C/C++ Source or Header  |  2020-01-01  |  12KB  |  637 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.             flag &= IND;
  114.             break;
  115.         case 25:        /* termination = ,Y */
  116.             flag &= (ABSY | ABSY2 | ZERY);
  117.             break;
  118.         case 26:        /* termination = ,X */
  119.             flag &= (ABSX | ZERX);
  120.             break;
  121.         case 212:        /* termination = ,X) */
  122.             flag &= INDX;
  123.             break;
  124.         case 281:        /* termination = ),Y */
  125.             flag &= INDY;
  126.             break;
  127.         default:
  128.             flag = 0;
  129.         }
  130.     }
  131.     if ((opflg &= flag) == 0) {
  132.         error("Invalid addressing mode");
  133.         return;
  134.     }
  135.     if ((opflg & ztmask) != 0)
  136.         opflg &= ztmask;
  137.     switch(opflg) {
  138.     case ACC:        /* single byte - class 3 */
  139.         if (pass == LAST_PASS) {
  140.             loadlc(loccnt, 0, 1);
  141.             loadv(opval + 8, 0, 1);
  142.             println();
  143.         }
  144.         loccnt++;
  145.         return;
  146.     case ZERX: case ZERY:    /* double byte - class 3 */
  147.         opval += 4;
  148.     case INDY:
  149.         opval += 8;
  150.     case IMM2:
  151.         opval += 4;
  152.     case ZER:
  153.         opval += 4;
  154.     case INDX: case IMM1:
  155.         if (pass == LAST_PASS) {
  156.             loadlc(loccnt, 0, 1);
  157.             loadv(opval, 0, 1);
  158.             loadv(value, 1, 1);
  159.             println();
  160.         }
  161.         loccnt += 2;
  162.         return;
  163.     case IND:        /* triple byte - class 3 */
  164.         opval += 16;
  165.     case ABSX:
  166.     case ABSY2:
  167.         opval += 4;
  168.     case ABSY:
  169.         opval += 12;
  170.     case ABS:
  171.         if (pass == LAST_PASS) {
  172.             opval += 12;
  173.             loadlc(loccnt, 0, 1);
  174.             loadv(opval, 0, 1);
  175.             loadv(value, 1, 1);
  176.             loadv(value >> 8, 2, 1);
  177.             println();
  178.         }
  179.         loccnt += 3;
  180.         return;
  181.     default:
  182.         error("Invalid addressing mode");
  183.         return;
  184.     }
  185. }
  186.  
  187. /* pseudo operations processor */
  188.  
  189. pseudo(ip)
  190.     int *ip;
  191. {
  192.     int    count;
  193.     int    i;
  194.     int    tvalue;
  195.     int     hibit; /* apple requires high bit to be on for chs */
  196.     int     pi;
  197.  
  198.     switch(opval) {
  199.     case 0:                /* .byte pseudo */
  200.         labldef(loccnt);
  201.         loadlc(loccnt, 0, 1);
  202.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  203.         count = 0;
  204.         do {
  205.             if (prlnbuf[*ip] == '"') {
  206.                 /* check for hibit on flag for ascii chs */
  207.                 hibit = 0 ;
  208.                 pi = *ip;
  209.                 while((i = prlnbuf[++pi]) != '"' && i != 0 );
  210.                 if (i != 0 )
  211.                   while(prlnbuf[++pi] == ' ' ) ;
  212.                 if (prlnbuf[pi] == '1' )
  213.                    hibit = 0x80 ;
  214.                 while ((tvalue = prlnbuf[++(*ip)]) != '"') {
  215.                     if (tvalue == 0) {
  216.                         error("Unterminated ASCII string");
  217.                         return;
  218.                     }
  219.                     if (tvalue == '\\')
  220.                         switch(tvalue = prlnbuf[++(*ip)]) {
  221.                         case 'n':
  222.                             tvalue = '\n';
  223.                             break;
  224.                         case 't':
  225.                             tvalue = '\t';
  226.                             break;
  227.                         }
  228.                     loccnt++;
  229.                     if (pass == LAST_PASS) {
  230.                         tvalue |= hibit ;
  231.                         loadv(tvalue, count, 1);
  232.                         if (++count >= 3) {
  233.                             println();
  234.                             for (i = 0; i < SFIELD; i++)
  235.                                 prlnbuf[i] = ' ';
  236.                             prlnbuf[i] = 0;
  237.                             count = 0;
  238.                             loadlc(loccnt, 0, 1);
  239.                         }
  240.                     }
  241.                 }
  242.                 ++(*ip);
  243.             }
  244.             else {
  245.                 if (evaluate(ip) != 0) {
  246.                     loccnt++;
  247.                     return;
  248.                 }
  249.                 loccnt++;
  250.                 if (value > 0xff) {
  251.                     error("Operand field size error");
  252.                     return;
  253.                 }
  254.                 else if (pass == LAST_PASS) {
  255.                     loadv(value, count, 1);
  256.                     if (++count >= 3) {
  257.                         println();
  258.                         for (i = 0; i < SFIELD; i++)
  259.                             prlnbuf[i] = ' ';
  260.                         prlnbuf[i] = 0;
  261.                         count = 0;
  262.                         loadlc(loccnt, 0, 1);
  263.                     }
  264.                 }
  265.             }
  266.         } while (prlnbuf[(*ip)++] == ',');
  267.         if ((pass == LAST_PASS) && (count != 0))
  268.             println();
  269.         return;
  270.     case 1:                /* = pseudo */
  271.         while (prlnbuf[++(*ip)] == ' ');
  272.         if (evaluate(ip) != 0)
  273.             return;
  274.         labldef(value);
  275.         if (pass == LAST_PASS) {
  276.             loadlc(value, 1, 0);
  277.             println();
  278.         }
  279.         return;
  280.     case 2:                /* .word pseudo */
  281.         labldef(loccnt);
  282.         loadlc(loccnt, 0, 1);
  283.         while (prlnbuf[++(*ip)] == ' ');
  284.         do {
  285.             if (evaluate(ip) != 0) {
  286.                 loccnt += 2;
  287.                 return;
  288.             }
  289.             loccnt += 2;
  290.             if (pass == LAST_PASS) {
  291.                 loadv(value, 0, 1);
  292.                 loadv(value>>8, 1, 1);
  293.                 println();
  294.                 for (i = 0; i < SFIELD; i++)
  295.                     prlnbuf[i] = ' ';
  296.                 prlnbuf[i] = 0;
  297.                 loadlc(loccnt, 0, 1);
  298.             }
  299.         } while (prlnbuf[(*ip)++] == ',');
  300.         return;
  301.     case 3:                /* *= pseudo */
  302.         while (prlnbuf[++(*ip)] == ' ');
  303.         if (prlnbuf[*ip] == '*') {
  304.             if (evaluate(ip) != 0)
  305.                 return;
  306.             if (undef != 0) {
  307.                 error("Undefined symbol in operand field.");
  308.                 return;
  309.             }
  310.             tvalue = loccnt;
  311.         }
  312.         else {
  313.             if (evaluate(ip) != 0)
  314.                 return;
  315.             if (undef != 0) {
  316.                 error("Undefined symbol in operand field.");
  317.                 return;
  318.             }
  319.             tvalue = value;
  320.         }
  321.         loccnt = value;
  322.         labldef(tvalue);
  323.         if (pass == LAST_PASS) {
  324.             objcnt = 0;
  325.             loadlc(tvalue, 1, 0);
  326.             println();
  327.         }
  328.         return;
  329.     case 4:                /* .list pseudo */
  330.         if (lflag >= 0)
  331.             lflag = 1;
  332.         return;
  333.     case 5:                /* .nlst pseudo */
  334.         if (lflag >= 0)
  335.             lflag = iflag;
  336.         return;
  337.     case 6:                /* .dbyt pseudo */
  338.         labldef(loccnt);
  339.         loadlc(loccnt, 0, 1);
  340.         while (prlnbuf[++(*ip)] == ' ');
  341.         do {
  342.             if (evaluate(ip) != 0) {
  343.                 loccnt += 2;
  344.                 return;
  345.             }
  346.             loccnt += 2;
  347.             if (pass == LAST_PASS) {
  348.                 loadv(value>>8, 0, 1);
  349.                 loadv(value, 1, 1);
  350.                 println();
  351.                 for (i = 0; i < SFIELD; i++)
  352.                     prlnbuf[i] = ' ';
  353.                 prlnbuf[i] = 0;
  354.                 loadlc(loccnt, 0, 1);
  355.             }
  356.         } while (prlnbuf[(*ip)++] == ',');
  357.         return;
  358.     case 7:                /* ds pseudo */
  359.         while (prlnbuf[++(*ip)] == ' ');
  360.         if (evaluate(ip) != 0)
  361.             return;
  362.         if (undef != 0) {
  363.             error("Undefined symbol in operand field.");
  364.             return;
  365.         }
  366.         tvalue = loccnt;
  367.         labldef(loccnt);
  368.         loccnt += value;
  369.         if (pass == LAST_PASS) {
  370.             objcnt = 0;
  371.             loadlc(tvalue, 1, 0);
  372.             println();
  373.         }
  374.         return;
  375.     case 8:                /* asc pseudo */
  376.         labldef(loccnt);
  377.         loadlc(loccnt, 0, 1);
  378.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  379.         count = 0;
  380.         do {
  381.             if (prlnbuf[*ip] == '\'') {
  382.                 while ((tvalue = prlnbuf[++(*ip)]) != '\'') {
  383.                     if (tvalue == 0) {
  384.                         error("Unterminated ASCII string");
  385.                         return;
  386.                     }
  387.                     if (tvalue == '\\')
  388.                         switch(tvalue = prlnbuf[++(*ip)]) {
  389.                         case 'n':
  390.                             tvalue = '\n';
  391.                             break;
  392.                         case 't':
  393.                             tvalue = '\t';
  394.                             break;
  395.                         }
  396.                     loccnt++;
  397.                     if (pass == LAST_PASS) {
  398.                         tvalue |= msb   ;
  399.                         loadv(tvalue, count, 1);
  400.                         if (++count >= 3) {
  401.                             println();
  402.                             for (i = 0; i < SFIELD; i++)
  403.                                 prlnbuf[i] = ' ';
  404.                             prlnbuf[i] = 0;
  405.                             count = 0;
  406.                             loadlc(loccnt, 0, 1);
  407.                         }
  408.                     }
  409.                 }
  410.                 ++(*ip);
  411.             }
  412.             else {
  413.                 if (evaluate(ip) != 0) {
  414.                     loccnt++;
  415.                     return;
  416.                 }
  417.                 loccnt++;
  418.                 if (value > 0xff) {
  419.                     error("Operand field size error");
  420.                     return;
  421.                 }
  422.                 else if (pass == LAST_PASS) {
  423.                     loadv(value, count, 1);
  424.                     if (++count >= 3) {
  425.                         println();
  426.                         for (i = 0; i < SFIELD; i++)
  427.                             prlnbuf[i] = ' ';
  428.                         prlnbuf[i] = 0;
  429.                         count = 0;
  430.                         loadlc(loccnt, 0, 1);
  431.                     }
  432.                 }
  433.             }
  434.         } while (prlnbuf[(*ip)++] == ',');
  435.         if ((pass == LAST_PASS) && (count != 0))
  436.             println();
  437.         return;
  438.     case 13:            /* msb pseudo */
  439.         while (prlnbuf[++(*ip)] == ' ');
  440.         if (pass == LAST_PASS) 
  441.             println();
  442.         pi = *ip;
  443.         if (( i = 0x20|prlnbuf[pi+1] ) == 'f' ){
  444.                 msb=0;
  445.                 return;
  446.                 }
  447.             else if (i=='n'){
  448.                 msb=0x80;
  449.                 return;
  450.                 }
  451.         error("Invalid symbol in operand field.");
  452.         return;
  453.     }
  454. }
  455.  
  456. /* evaluate expression */
  457.  
  458. evaluate(ip)
  459.    int    *ip;
  460. {
  461.     int    tvalue;
  462.     int    invalid;
  463.     int    parflg, value2;
  464.     char    ch;
  465.     char    op;
  466.     char    op2;
  467.  
  468.     op = '+';
  469.     parflg = zpref = undef = value = invalid = 0;
  470. /* hcj: zpref should reflect the value of the expression, not the value of
  471.    the intermediate symbols
  472. */
  473.     while ((ch=prlnbuf[*ip]) != ' ' && ch != ')' && ch != ',' && ch != ';') {
  474.         tvalue = 0;
  475.         if (ch == '$' || ch == '@' || ch == '%')
  476.             tvalue = colnum(ip);
  477.         else if (ch >= '0' && ch <= '9')
  478.             tvalue = colnum(ip);
  479.         else if (ch >= 'a' && ch <= 'z')
  480.             tvalue = symval(ip);
  481.         else if (ch >= 'A' && ch <= 'Z')
  482.             tvalue = symval(ip);
  483.         else if ((ch == '_') || (ch == '.'))
  484.             tvalue = symval(ip);
  485.         else if (ch == '*') {
  486.             tvalue = loccnt;
  487.             ++(*ip);
  488.         }
  489.         else if (ch == '\'') {
  490.             ++(*ip);
  491.             tvalue = prlnbuf[*ip] & 0xff;
  492.             ++(*ip);
  493.         }
  494.         else if (ch == '[') {
  495.             if (parflg == 1) {
  496.                 error("Too many ['s in expression");
  497.                 invalid++;
  498.             }
  499.             else {
  500.                 value2 = value;
  501.                 op2 = op;
  502.                 value = tvalue = 0;
  503.                 op = '+';
  504.                 parflg = 1;
  505.             }
  506.             goto next;
  507.         }
  508.         else if (ch == ']') {
  509.             if (parflg == 0) {
  510.                 error("No matching [ for ] in expression");
  511.                 invalid++;
  512.             }
  513.             else {
  514.                 parflg = 0;
  515.                 tvalue = value;
  516.                 value = value2;
  517.                 op = op2;
  518.             }
  519.             ++(*ip);
  520.         }
  521.         switch(op) {
  522.         case '+':
  523.             value += tvalue;
  524.             break;
  525.         case '-':
  526.             value -= tvalue;
  527.             break;
  528.         case '/':
  529.             value = (unsigned) value/tvalue;
  530.             break;
  531.         case '*':
  532.             value *= tvalue;
  533.             break;
  534.         case '%':
  535.             value = (unsigned) value%tvalue;
  536.             break;
  537.         case '^':
  538.             value ^= tvalue;
  539.             break;
  540.         case '~':
  541.             value = ~tvalue;
  542.             break;
  543.         case '&':
  544.             value &= tvalue;
  545.             break;
  546.         case '|':
  547.             value |= tvalue;
  548.             break;
  549.         case '<':
  550.             tvalue >>= 8;        /* fall through to '<' */
  551.         case '>':
  552.             if (value != 0) {
  553.                 error("High or low byte operator not first in operand field");
  554.             }
  555.             value = tvalue & 0xff;
  556.             zpref = 0;
  557.             break;
  558.         default:
  559.             invalid++;
  560.         }
  561.         if ((op=prlnbuf[*ip]) == ' '
  562.                 || op == ')'
  563.                 || op == ','
  564.                 || op == ';')
  565.             break;
  566.         else if (op != ']')
  567. next:            ++(*ip);
  568.     }
  569.     if (parflg == 1) {
  570.         error("Missing ] in expression");
  571.         return(1);
  572.     }
  573.     if (value < 0 || value >= 256) {
  574.         zpref = 1;
  575.     }
  576.     if (undef != 0) {
  577.         if (pass != FIRST_PASS) {
  578.             error("Undefined symbol in operand field");
  579.             invalid++;
  580.         }
  581.         value = 0;
  582.     }
  583.     else if (invalid != 0)
  584.     {
  585.         error("Invalid operand field");
  586.     }
  587.     else {
  588. /*
  589.  This is the only way out that may not signal error
  590. */
  591.         if (value < 0 || value >= 256) {
  592.             zpref = 1;
  593.         }
  594.         else {
  595.             zpref = 0;
  596.         }
  597.     }
  598.     return(invalid);
  599. }
  600.  
  601. /* collect number operand        */
  602.  
  603. colnum(ip)
  604.     int    *ip;
  605. {
  606.     int    mul;
  607.     int    nval;
  608.     char    ch;
  609.  
  610.     nval = 0;
  611.     if ((ch = prlnbuf[*ip]) == '$')
  612.         mul = 16;
  613.     else if (ch >= '1' && ch <= '9') {
  614.         mul = 10;
  615.         nval = ch - '0';
  616.     }
  617.     else if (ch == '@' || ch == '0')
  618.         mul = 8;
  619.     else if (ch == '%')
  620.         mul = 2;
  621.     while ((ch = prlnbuf[++(*ip)] - '0') >= 0) {
  622.         if (ch > 9) {
  623.             ch -= ('A' - '9' - 1);
  624.             if (ch > 15)
  625.                 ch -= ('a' - 'A');
  626.             if (ch > 15)
  627.                 break;
  628.             if (ch < 10)
  629.                 break;
  630.         }
  631.         if (ch >= mul)
  632.             break;
  633.         nval = (nval * mul) + ch;
  634.     }
  635.     return(nval);
  636. }
  637.