home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / CROSSASM / AS68K.ZIP / AS5.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-01-10  |  25.8 KB  |  887 lines

  1. #include "a:printf.h"
  2. #include "a:stdio.h"
  3. #include "as.h"
  4.  
  5.  
  6. ldmstm(opskel)
  7. unsigned    opskel;
  8. {
  9.  
  10. /*
  11.           process MOVEM, STM, and LDM instructions
  12.           STM <RLIST>,<ADR>  LDM <ADR>,<RLIST>
  13. */
  14.     int    i;
  15.  
  16.         if (imode == 1)
  17.                 return 3;
  18.  
  19.         if (imode == 3)
  20.                 opskel |= 0x40;
  21.  
  22.         /* try picking up a register operand */
  23.  
  24.         op = opnptr;
  25.         rlstdc(&op,&dlist,&alist);
  26.  
  27.         if (dlist == 0 && alist == 0)
  28.                 return ldm(opskel);
  29.  
  30.         /* check if destination EA is legal for a STM instruction */
  31.         /* -(An) and CTL alterable addressing modes are legal     */
  32.  
  33.         if (op2ea != 3 && op2ea != 5 && op2ea != 0)
  34.                 return 3;
  35.  
  36.         /* reformat data and address bitmaps for STM instruction */
  37.  
  38.         if (op2ea == 5) {
  39.  
  40.                 /* -(An) requires registers to be backwards in the bitmap */
  41.  
  42.         dlsti = alsti = 0;
  43.                 for (i = 0; i < 8; ++i) {
  44.                         if (dlist & (1 << i))
  45.                                 dlsti |= (0x80 >> i);
  46.  
  47.                         if (alist & (1 << i))
  48.                                 alsti |= (0x80 >> i);
  49.                 }
  50.  
  51.                 alist = dlsti;
  52.                 dlist = alsti;
  53.         }
  54.  
  55.         /* build bitmap */
  56.  
  57.         objbuf[2] = ((alist & 0xff) << 8) | (dlist & 0xff);
  58.  
  59.         /* process destination operand */
  60.  
  61.         objwc = 2;
  62.  
  63.         if (op2ea != 0) {
  64.  
  65.                 /* simple destination operand */
  66.  
  67.                 objbuf[1] = opskel | op2da | ((op2ea - 1) * 8);
  68.                 return 1;
  69.         }
  70.  
  71.         /* process complex destination operand */
  72.  
  73.         procop(&opnpt2);
  74.         objbuf[1] = opskel | opnwrd[1];
  75.         objbuf[3] = opnwrd[2];
  76.  
  77.         if (opnwc == 2) {
  78.                 objbuf[3] = opnwrd[3];
  79.                 objbuf[4] = opnwrd[2];
  80.         }
  81.  
  82.         objwc += opnwc;
  83.         return 1;
  84. }
  85.  
  86.  
  87. ldm(opskel)
  88. unsigned    opskel;
  89. {
  90.         opskel |= 0x400;
  91.  
  92.         /* check if source is legal for LDM instruction */
  93.         /* (An)+ and CTL adrressing modes are legal     */
  94.  
  95.         if ((op1ea != 3) && (op1ea != 4) && op1ea != 0)
  96.                 return 3;
  97.  
  98.         /* process source operand */
  99.  
  100.         if (op1ea != 0)
  101.                 objbuf[1] = opskel | op1da | ((op1ea - 1) * 8);
  102.         else {
  103.                 procop(&opnptr);
  104.                 objbuf[1] = opskel | opnwrd[1];
  105.                 objbuf[2] = opnwrd[2];
  106.  
  107.                 if (opnwc == 2) {
  108.                         objbuf[2] = opnwrd[3];
  109.                         objbuf[3] = opnwrd[2];
  110.                 }
  111.  
  112.                 objwc += opnwc;
  113.         }
  114.  
  115.         /* process register list */
  116.  
  117.         op = opnpt2;
  118.         rlstdc(&op,&dlist,&alist);
  119.  
  120.         if (dlist == 0 && alist == 0)
  121.                 return 3;
  122.  
  123.         /* reformat data and address bitmaps for LDM instruction */
  124.  
  125.         objbuf[++objwc] = ((alist & 0xff) << 8) | (dlist & 0xff);
  126.         return 1;
  127. }
  128.  
  129.  
  130. rlstdc(op,dlist,alist)
  131. unsigned    *op,*dlist,*alist;
  132. {
  133.  
  134. /*
  135.      this subroutine will attempt to process a register
  136.      list in the source line pointed to by 'op' into
  137.      a pair of words which can be converted into a register
  138.      bitmap for the 'MOVEM' instruction
  139. */
  140.         unsigned    i,streg,grpflg,stregt,regtyp,regnum;
  141.  
  142.         /* initialize default output values */
  143.  
  144.         *alist = *dlist = 0;
  145.         grpflg = FALSE;
  146.  
  147.         /* try to find a register to decode */
  148.  
  149.         while (regtyp = rdecod(op,®num)) {
  150.  
  151.                 if (grpflg) {
  152.                         if ((streg >= regnum) || (stregt != regtyp))
  153.                                 break;
  154.  
  155.                         /* set bits in register list bitmap */
  156.  
  157.                         if (regtyp == 1)
  158.                                 for (i = streg; i <= regnum; ++i)
  159.                                         *dlist |= (1 << i);
  160.                         else
  161.                                 for (i = streg; i <= regnum; ++i)
  162.                                         *alist |= (1 << i);
  163.  
  164.                         streg = regnum = 0;
  165.                         grpflg = FALSE;
  166.                 }
  167.                 else {
  168.                         /* add an individual register to list */
  169.  
  170.                         if (regtyp == 1)
  171.                                 *dlist |= (1 << regnum);
  172.                         else
  173.             if (regtyp == 2)
  174.                                 *alist |= (1 << regnum);
  175.                 }
  176.  
  177.                 /* check for '/' */
  178.  
  179.                 if (srclne[*op] == '/') {
  180.                         if (grpflg)
  181.                                 break;
  182.  
  183.                         ++(*op);
  184.                 }
  185.  
  186.                 /* check for '-' or end of register list */
  187.  
  188.                 else
  189.         if (srclne[*op] == '-') {
  190.                         streg = regnum;
  191.                         stregt = regtyp;
  192.                         grpflg = TRUE;
  193.                         ++(*op);
  194.                 }
  195.                 else
  196.                         break;
  197.         }
  198.  
  199.         /* error processing */
  200.  
  201.         if (grpflg) {
  202.                 *alist = *dlist = 0;
  203.                 return 0;
  204.         }
  205.         else
  206.                 return 1;
  207. }
  208.  
  209.  
  210. rdecod(op,regnum)
  211. unsigned    *op,*regnum;
  212. {
  213.  
  214. /*
  215.      This subroutine returns the register type and number
  216.      if the next two characters in a source line specify registers
  217.  
  218.      regtyp = 0 next two characters don't specify a register
  219.               1 Data register
  220.               2 Address register
  221.  
  222.      regnum = register number (0-7)
  223.  
  224.      op     = op + 2 unless a register wasn't found
  225. */
  226.  
  227.         unsigned    regtyp;
  228.  
  229.         regtyp = 0;
  230.  
  231.         if (srclne[*op] == 'A' || srclne[*op] == 'S')
  232.                 regtyp = 2;
  233.         else
  234.     if (srclne[*op] == 'D')
  235.                 regtyp = 1;
  236.         else
  237.                 return 0;
  238.  
  239.         ++(*op);
  240.  
  241.     if (srclne[*op] == 'P')  {
  242.         *regnum = 7;
  243.         return 2;
  244.     }
  245.  
  246.         if ((srclne[*op] < '0') || (srclne[*op] > '7'))
  247.                 return 0;
  248.  
  249.         *regnum = srclne[*op] & 7;
  250.         ++(*op);
  251.  
  252.         return regtyp;
  253. }
  254.  
  255.  
  256. procop(op)
  257. unsigned    *op;
  258. {
  259.  
  260. /*
  261.      EVALUATE COMPLEX EFFECTIVE ADDRESSES
  262.  
  263.      OUTPUT WORDS:
  264.  
  265.      opnflg 0 IF OPERAND CAN BE USED IN 'QUicK' INSTRUCTioNS
  266.             1 IF OPERAND CONTAINED A FWD REF SYMBOL
  267.  
  268.      opnwc  NUMBER OF BYTES GENERATED (6 MAX)
  269.  
  270.      OPNWRD OPERAND WORDS GENERATED
  271.             FIRST WORD - ADR typE
  272.             NEXT WORD  - OPN DATA <LOW WORD>
  273.             NEXT WORD  - OPN DATA <HIGH WORD>
  274. */
  275.  
  276.         long            symval,tmpval;
  277.         int             imd,amd,nochrs,nval,i,n,isindex,issym;
  278.         unsigned    ah,al;
  279.  
  280.         /* ZERO OPERAND RESULT BUFFER */
  281.  
  282.         opnwrd[1] = opnwrd[2] = opnwrd[3] = 0;
  283.  
  284.         /* SET PARSE POINTER TO START OF OPN FOR error PROCESSOR */
  285.  
  286.         scanpt = *op;
  287.  
  288.         /* DEFAULT IS NON-IMMEDIATE MODE  */
  289.         /* WITH SUBOPNS ADDED TO ORIG OPN */
  290.  
  291.         imd = opnwc = 0;
  292.         amd = 1;
  293.         opnflg = isindex = issym = FALSE;
  294.         symval = 0l;
  295.  
  296.         /* CHECK FOR '#' <IMMEDIATE MODE> */
  297.  
  298.         if (srclne[*op] == '#') {
  299.                 imd = 1;
  300.                 ++(*op);
  301.         }
  302.  
  303.         while (srclne[*op] != ',' && srclne[*op] != ' ' &&
  304.               srclne[*op] != '\t' && srclne[*op] != EOS) {
  305.  
  306.                 tmpval = 0l;
  307.  
  308.                 /* CHECK FOR ASCII LITERAL ' */
  309.  
  310.                 if (srclne[*op] == '\'') {
  311.                         imd = 1;
  312.                         nochrs = 0;
  313.                         while (srclne[++(*op)] != '\'') {
  314.                                 if (++nochrs > 4)
  315.                                         break;
  316.  
  317.                                 tmpval = (tmpval << 8) | (long)(srclne[*op]);
  318.                         }
  319.  
  320.                         if (srclne[*op] == '\'')
  321.                                 ++(*op);
  322.                 }
  323.  
  324.                 /* CHECK FOR '*' <PC> */
  325.  
  326.                 else if (srclne[*op] == '*') {
  327.                         if (amd == 1) {
  328.                                 symval += pc;
  329.                                 ++(*op);
  330.                         }
  331.                         else if (amd == 2) {
  332.                                 symval -= pc;
  333.                                 ++(*op);
  334.                         }
  335.                         else {
  336.                                 opnwc = 7;
  337.                                 scanpt = *op;
  338.                                 return opnwc;
  339.                         }
  340.                 }
  341.  
  342.                 /* CHECK FOR '$' <HEXADECIMAL> */
  343.  
  344.                 else if (srclne[*op] == '$') {
  345.  
  346.                         /* HEXADECIMAL LITERAL */
  347.  
  348.                         while ((srclne[++(*op)] >= '0' &&
  349.                             srclne[*op] <= '9') ||
  350.                            (srclne[*op] >= 'A' &&
  351.                             srclne[*op] <= 'F')) {
  352.                                 if (srclne[*op] >= '0' &&
  353.                                     srclne[*op] <= '9')
  354.                                         nval = srclne[*op] - '0';
  355.                                 else
  356.                                         nval = srclne[*op] - '7';
  357.  
  358.                                 tmpval <<= 4;
  359.                                 tmpval |= (long)nval;
  360.                         }
  361.                 }
  362.  
  363.                 /* CHECK FOR 0-9 <DECIMAL> */
  364.  
  365.                 else if (srclne[*op] >= '0' && srclne[*op] <= '9') {
  366.  
  367.                         /* DECIMAL LITERAL */
  368.  
  369.                         while (srclne[*op] >= '0' && srclne[*op] <= '9') {
  370.                                 nval = srclne[*op] - '0';
  371.                                 tmpval *= 10l;
  372.                                 tmpval += (long)nval;
  373.                                 ++(*op);
  374.                         }
  375.                 }
  376.  
  377.                 /* CHECK FOR A-Z <SYMBOLic> */
  378.  
  379.                 else if ((srclne[*op] >= 'A' && srclne[*op] <= 'Z') ||
  380.                         (srclne[*op] == '@' || srclne[*op] == '_')) {
  381.                         opnflg = chksym(imd,op,&tmpval);
  382.                         issym = TRUE;
  383.                 }
  384.                 else if (srclne[*op] != '-' && srclne[*op] != '+') {
  385.                         /* not unary + or - */
  386.                         scanpt = *op;
  387.                         error(406);
  388.                         ++(*op);
  389.                 }
  390.  
  391.                 /* PROCESS +,-,*,/,!,<<,>> */
  392.  
  393.                 switch (amd) {
  394.                 case 1:         symval += tmpval;
  395.                                 break;
  396.                 case 2:         symval -= tmpval;
  397.                                 break;
  398.                 case 3:         symval *= tmpval;
  399.                                 break;
  400.                 case 4:         /* dividing by zero is bad news */
  401.                                 if (tmpval == 0l) {
  402.                                         opnwc = 7;
  403.                                         scanpt = *op;
  404.                                         return opnwc;
  405.                                 }
  406.                                 symval /= tmpval;
  407.                                 break;
  408.                 case 5:         symval &= tmpval;
  409.                                 break;
  410.                 case 6:         symval |= tmpval;
  411.                                 break;
  412.                 case 7:         symval <<= tmpval;
  413.                                 break;
  414.                 case 8:         symval >>= tmpval;
  415.                                 break;
  416.                 }
  417.                 amd = 1;
  418.  
  419.                 /* CHECK FOR +,-,*,/   */
  420.  
  421.                 switch (srclne[*op]) {
  422.                 case ' ':
  423.                 case ',':
  424.                 case '\t':
  425.                 case EOS:       break;
  426.                 case '+':       amd = 1;
  427.                                 ++(*op);
  428.                                 break;
  429.                 case '-':       amd = 2;
  430.                                 ++(*op);
  431.                                 break;
  432.                 case '*':       amd = 3;
  433.                                 ++(*op);
  434.                                 break;
  435.                 case '/':       amd = 4;
  436.                                 ++(*op);
  437.                                 break;
  438.                 case '&':       amd = 5;
  439.                                 ++(*op);
  440.                                 break;
  441.                 case '!':       amd = 6;
  442.                                 ++(*op);
  443.                                 break;
  444.                 case '<':       ++(*op);
  445.                                 if (srclne[*op] != '<') {
  446.                                         opnwc = 7;
  447.                                         scanpt = *op;
  448.                                         return opnwc;
  449.                                 }
  450.  
  451.                                 amd = 7;
  452.                                 ++(*op);
  453.                                 break;
  454.                 case '>':       ++(*op);
  455.                                 if (srclne[*op] != '>') {
  456.                                         opnwc = 7;
  457.                                         scanpt = *op;
  458.                                         return opnwc;
  459.                                 }
  460.                                 amd = 8;
  461.                                 ++(*op);
  462.                                 break;
  463.                 case '(':       if (chkreg(imd,op,symval) == 7)
  464.                                         return opnwc;
  465.  
  466.                                 isindex = TRUE;
  467.                                 break;
  468.                 default:        opnwc = 7;
  469.                                 scanpt = *op;
  470.                                 return opnwc;
  471.                 }
  472.  
  473.                 /* go back and CHECK FOR END OF OPERAND */
  474.         }
  475.  
  476.         /* IF BRANCH INSTRUCTION PROC VAL AS PC REL OFFSET */
  477.  
  478.         if (dbflg == 1 ) {
  479.  
  480.                 /* GENERATE PC RELATIVE OFFSET */
  481.  
  482.                 opnwrd[1] = 0x3a;
  483.                 symval = symval - 2l - pc;
  484.                 opnwrd[2] = (unsigned)(symval & (long)0xffff);
  485.                 opnwrd[3] = (unsigned)((symval >> 16) & (long)0xffff);
  486.                 opnwc = 1;
  487.                 return opnwc;
  488.         }
  489.  
  490.         /* PROCESS VAL AS PC REL UNLESS ABS OR IMMEDIATE OR 2ND OP */
  491.  
  492.         if (rflg == 0 && imd != 1 && issym && op != &opnpt2 &&
  493.  
  494.         /* IF OPERAND HAD AN EQUATED SYMBOL PROC VAL AS IMMEDIATE */
  495.  
  496.            !(symflg[stind] & 0x10)) {
  497.                 tmpval = symval - 2l - pc;
  498.                 opnwrd[2] = (unsigned)(tmpval & (long)0xffff);
  499.                 opnwrd[3] = (unsigned)((tmpval >> 16) & (long)0xffff);
  500.  
  501.                 if ((pass == 2) && (tmpval > (long)0x7fff || tmpval < 0xffff8000)) {
  502.                         opnwc = 7;
  503.                         error(404);
  504.                         return opnwc;
  505.                 }
  506.  
  507.                 if (isindex) {
  508.                         if ((opnwrd[1] & 0x3f) != 0x3b) {
  509.                                 if (tmpval > 127l || tmpval < -128l) {
  510.                                         opnwc = 7;
  511.                                         error(408);
  512.                                         return opnwc;
  513.                                 }
  514.  
  515.                                 opnwrd[2] = opnwrd[2] & 0xff |
  516.                     ((opnwrd[1] << 12) & 0x7000) | 0x8000;
  517.                                 opnwrd[1] = opnwrd[1] & 0xffc0 | 0x3b;
  518.                         }
  519.                         opnwc = 1;
  520.                         return opnwc;
  521.                 }
  522.  
  523.                 opnwrd[1] = 0x3a;
  524.                 opnwc = 1;
  525.                 return opnwc;
  526.         }
  527.  
  528.         /* PROCESS IMMEDIATE DATA */
  529.  
  530.         opnwrd[2] = (unsigned)(symval & (long)0xffff);
  531.         opnwrd[3] = (unsigned)((symval >> 16) & (long)0xffff);
  532.  
  533.         if (imd == 1) {
  534.                 opnwc = 1;
  535.  
  536.                 if (imode == 3)
  537.                         opnwc = 2;
  538.  
  539.                 opnwrd[1] = 0x3c;
  540.                 return opnwc;
  541.         }
  542.  
  543.         /* PROCESS disp(AN) */
  544.  
  545.         if (isindex)
  546.                 return opnwc;
  547.  
  548.         /* PROCESS ABSOLUTE ADR */
  549.         /* GENERATE LONG ADR FORM IF INSTR MODE LONG */
  550.  
  551.         if (opnflg != TRUE && opnwrd[3] == 0) {
  552.                 opnwc = 1;
  553.                 opnwrd[1] = 0x38;
  554.                 return opnwc;
  555.         }
  556.  
  557.         opnwc = 2;
  558.         opnwrd[1] = 0x39;
  559.         return opnwc;
  560. }
  561.  
  562.  
  563. chksym(imd,op,tmpval)
  564. int     imd,*op;
  565. long    *tmpval;
  566. {
  567.         char    tmpsym[SYMSZ1];
  568.         int     n,iop;
  569.  
  570.         for (n = 0,iop = *op; iop < (*op)+SYMSIZ; ++n, ++iop) {
  571.                 if ((srclne[iop] >= '0' && srclne[iop] <= '9') ||
  572.                     (srclne[iop] >= 'A' && srclne[iop] <= 'Z') ||
  573.                     (srclne[iop] == '_' || srclne[iop] == '@'))
  574.                         tmpsym[n] = srclne[iop];
  575.                 else
  576.                         break;
  577.         }
  578.  
  579.         tmpsym[n] = EOS;
  580.         while ((srclne[iop] >= '0' && srclne[iop] <= '9') ||
  581.               (srclne[iop] >= 'A' && srclne[iop] <= 'Z') ||
  582.               (srclne[iop] == '_' || srclne[iop] == '@'))
  583.                 ++iop;
  584.  
  585.         *op = iop;
  586.  
  587.         /* SEARCH SYMBOL TBL */
  588.  
  589.         symtbl(1,0l,tmpsym);
  590.  
  591.         /* IF symlin LESS THAN CURRENT LINE AND NOT 0 */
  592.         /* THEN SYMBOL IS DEFINED AND IS NOT A FWD REF*/
  593.  
  594.         if (symlin[stind] > nocard || symlin[stind] == 0)
  595.  
  596.                 /* CHECK FOR UNDEFINED SYMBOL */
  597.  
  598.                 if (symlin[stind] != 0)
  599.  
  600.                         /* WE GET TO HERE IF THE */
  601.                         /* SYMBOL IS DEFINED */
  602.                         /* BUT WASNT AS OF THIS LINE IN THE */
  603.                         /* ASSEMBLY DURING pass ONE */
  604.  
  605.                         opnflg = TRUE;
  606.  
  607.         if (symlin[stind] != 0)
  608.  
  609.                 /* LABEL HAS BEEN DEFINED */
  610.                 /* GET VALUE OF LABEL AND PUT IN tmpval */
  611.  
  612.                 *tmpval = symadr[stind];
  613.         else {
  614.  
  615.                 /* GO HERE ON UNDEFINED FIRST */
  616.                 /* AND SECOND pass SYMBOLS */
  617.  
  618.                 if (pass == 2)
  619.                         error(407);
  620.  
  621.                 /*
  622.                      IF THIS IS THE FIRST pass, THEN THE LENGTH
  623.                      OF ALL OPERANDS OTHER THAN
  624.                      IMMEDIATE BYTE AND WORD
  625.                      ARE FORCED TO TWO WORDS
  626.                 */
  627.  
  628.                 opnflg = TRUE;
  629.  
  630.                 if ((imd == 1) && (imode != 3))
  631.                         opnwc = 1;
  632.                 else
  633.                         opnwc = 2;
  634.         }
  635.  
  636.         return opnflg;
  637. }
  638.  
  639.  
  640. chkreg(imd,op,symval)
  641. int     imd,*op;
  642. long    symval;
  643. {
  644.         if (imd == 1) {
  645.                 opnwc = 7;
  646.                 scanpt = *op;
  647.                 return opnwc;
  648.         }
  649.  
  650.         if (srclne[(*op) + 3] == ')') {
  651.  
  652.                 /* disp(AN) or disp(DN) */
  653.  
  654.                 if ((srclne[(*op)+1] != 'A' && srclne[(*op)+1] != 'D') ||
  655.                     srclne[(*op)+2] < '0' ||
  656.                     srclne[(*op)+2] > '7') {
  657.                         opnwc = 7;
  658.                         scanpt = *op;
  659.                         return opnwc;
  660.                 }
  661.  
  662.                 opnwc = 1;
  663.                 if (srclne[(*op)+1] == 'D')
  664.                         opnwrd[1] = ((srclne[(*op) + 2] - '0') << 12) | 0x3b;
  665.                 else
  666.                         opnwrd[1] = (srclne[(*op) + 2] - '0') | 0x28;
  667.  
  668.                 opnwrd[2] = (unsigned)(symval & (long)0xffff);
  669.                 opnwrd[3] = (unsigned)((symval >> 16) & (long)0xffff);
  670.                 *op += 4;
  671.                 return opnwc;
  672.         }
  673.  
  674.         /* disp(AN,RN.L) or disp(RN.L) */
  675.  
  676.         opnwrd[2] = (unsigned)(symval & (long)0xffff);
  677.         opnwrd[3] = (unsigned)((symval >> 16) & (long)0xffff);
  678.  
  679.         if (symval < -128l || symval > 127l) {
  680.                 error(408);
  681.                 return opnwc;
  682.         }
  683.  
  684.         opnwrd[2] &= 0xff;
  685.  
  686.         /* imdEX OK..DO THE REST */
  687.  
  688.         if (srclne[(*op) + 3] == '.' && srclne[(*op) + 4] == 'L') {
  689.                 opnwc = 1;
  690.                 if (srclne[(*op) + 2] != 'A' && srclne[(*op) + 2] != 'D') {
  691.                         opnwc = 7;
  692.                         scanpt = *op;
  693.                         return opnwc;
  694.                 }
  695.  
  696.                 if (srclne[(*op) + 2] == 'A')
  697.                         opnwrd[2] |= 0x8000;
  698.  
  699.         if (srclne[(*op) + 3] < '0' || srclne[(*op) + 3] > '7') {
  700.                         opnwc = 7;
  701.                         scanpt = *op;
  702.                         return opnwc;
  703.                 }
  704.  
  705.                 opnwrd[2] |= ((srclne[(*op) + 3] - '0') << 12);
  706.                 opnwrd[2] |= 0x800;
  707.                 *op += 6;
  708.                 return opnwc;
  709.         }
  710.         
  711.         opnwc = 1;
  712.  
  713.         if (srclne[(*op)+1] != 'A' || srclne[(*op)+2] < '0' || srclne[(*op)+2] > '7') {
  714.                 opnwc = 7;
  715.                 scanpt = *op;
  716.                 return opnwc;
  717.         }
  718.  
  719.         opnwrd[1] = (srclne[(*op) + 2] - '0') | 0x30;
  720.  
  721.         /* CHECK FOR DATA OR ADR reg */
  722.                 
  723.         if (srclne[(*op) + 4] != 'A' && srclne[(*op) + 4] != 'D') {
  724.                 opnwc = 7;
  725.                 scanpt = *op;
  726.                 return opnwc;
  727.         }
  728.  
  729.         if (srclne[(*op) + 4] == 'A')
  730.                 opnwrd[2] |= 0x8000;
  731.  
  732.         if (srclne[(*op) + 5] < '0' || srclne[(*op) + 5] > '7') {
  733.                 opnwc = 7;
  734.                 scanpt = *op;
  735.                 return opnwc;
  736.         }
  737.  
  738.         opnwrd[2] = opnwrd[2] + (srclne[(*op) + 5] - '0') * 0x1000;
  739.         *op += 6;
  740.  
  741.         if (srclne[(*op) + 6] == '.' && srclne[(*op) + 7] == 'L') {
  742.                 *op += 2;
  743.                 opnwrd[2] |= 0x800;
  744.         }
  745.         ++(*op);
  746.         return opnwc;
  747. }
  748.  
  749.  
  750. eatyp(op,reg)
  751. unsigned    op,*reg;
  752. {
  753.  
  754. /*
  755.      DETERMINE GENERAL typE OF OPERAND
  756.  IN:
  757.      op  = POINTER TO START OF OPERAND
  758.  
  759.  OUT:
  760.  returns:
  761.        0       = NOT regISTER OR IMMEDIATE EA
  762.        1       = DN
  763.        2       = AN
  764.        3       = (AN)
  765.        4       = (AN)+
  766.        5       = -(AN)
  767.        6       = DATA
  768.        7       = SR
  769.        8       = CCR
  770.        9       = USP
  771.        10      = error DETECTED
  772.  
  773.  reg REG  0-7
  774. */
  775.         char            io;
  776.         unsigned    typ;
  777.  
  778.         typ = 0;
  779.         switch (srclne[op]) {
  780.                 case '#':
  781.                         return 6;
  782.                 case '(':
  783.                         if (srclne[op + 1] == 'A' && (srclne[op + 2] >= '0' &&
  784.               srclne[op + 2] <= '7') && srclne[op + 3] == ')') {
  785.                                 *reg = srclne[op + 2] - '0';
  786.  
  787.                                 if (srclne[op + 4] == '+') {
  788.                                         typ = 4;
  789.                                         io = srclne[op + 5];
  790.                                 }
  791.                                 else {
  792.                                         typ = 3;
  793.                                         io = srclne[op + 4];
  794.                                 }
  795.                                 break;
  796.  
  797.                         }
  798.             else
  799.             if (srclne[op + 1] == 'S' && srclne[op + 2] == 'P' &&
  800.               srclne[op + 3] == ')')  {
  801.                 *reg = 7;
  802.  
  803.                                 if (srclne[op + 4] == '+') {
  804.                                         typ = 4;
  805.                                         io = srclne[op + 5];
  806.                                 }
  807.                                 else {
  808.                                         typ = 3;
  809.                                         io = srclne[op + 4];
  810.                                 }
  811.                                 break;
  812.             }
  813.                         else
  814.                                 return 0;
  815.                 case '-':
  816.                         if (srclne[op + 1] == '(' && srclne[op + 2] == 'A' &&
  817.               srclne[op + 3] >= '0' && srclne[op + 3] <= '7' &&
  818.               srclne[op + 4] == ')') {
  819.                                 typ = 5;
  820.                                 *reg = srclne[op + 3] - '0';
  821.                                 io = srclne[op + 5];
  822.                                 break;
  823.                         }
  824.             else
  825.             if (srclne[op + 1] == '(' && srclne[op + 2] == 'S' &&
  826.               srclne[op + 3] == 'P' && srclne[op + 4] == ')')  {
  827.                 typ = 5;
  828.                 *reg = 7;
  829.                 io = srclne[op + 5];
  830.                 break;
  831.             }
  832.                         else
  833.                                 return 0;
  834.                 case 'D':
  835.                 case 'A':
  836.                         if (srclne[op + 1] < '0' || srclne[op + 1] > '7')
  837.                                 return 0;
  838.  
  839.                         *reg = srclne[op + 1] - '0';
  840.                         io = srclne[op + 2];
  841.  
  842.                         if (srclne[op] == 'D')
  843.                                 typ = 1;
  844.                         else
  845.                                 typ = 2;
  846.                         break;
  847.                 case 'S':
  848.                         if (srclne[op + 1] == 'R') {
  849.                                 typ = 7;
  850.                                 io = srclne[op + 2];
  851.                                 break;
  852.                         }
  853.             else
  854.             if (srclne[op + 1] == 'P')  {
  855.                 typ = 2;
  856.                 io = srclne[op + 2];
  857.                 break;                
  858.             }
  859.                         else
  860.                                 return 0;
  861.                 case 'C':
  862.                         if (srclne[op + 1] == 'C' && srclne[op + 2] == 'R') {
  863.                                 typ = 8;
  864.                                 io = srclne[op + 3];
  865.                                 break;
  866.                         }
  867.                         else
  868.                                 return 0;
  869.                 case 'U':
  870.                         if (srclne[op + 1] == 'S' && srclne[op + 2] == 'P') {
  871.                                 typ = 9;
  872.                                 io = srclne[op + 3];
  873.                                 break;
  874.                         }
  875.                 default:
  876.                         return 0;
  877.         }
  878.  
  879.         if (io == 0 || io == ' ' || io == '\t' || io == ',')
  880.                 return typ;
  881.  
  882.         if (typ <= 5 && typ >= 3)
  883.                 return 10;
  884.         else
  885.                 return 0;
  886. }
  887.