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

  1. /*
  2.     as68k.c
  3.  
  4.     MC68000 Cross-Assembler
  5.  
  6.     Version 2.1    First Pass at clean-up by Steve Sampson
  7.     Version 2.0    Converted to C by Ken Presser
  8.     Version 1.0    Fortran program by Allen Kossow
  9.  
  10.     REFERENCE:
  11.     Fortran version Printed in Oct, Nov 1982 Dr. Dobbs Journal
  12.  
  13.     NOTES:
  14.     Symbols are unique to 8 characters
  15.     Motorola S-Record Format (3-Byte Address) for Object File.
  16.  
  17.     EXCEPTIONS:
  18.     1) No Macros.
  19.     2) No PC relative addressing (except Branches).
  20.     3) Doesn't handle Address Registers as special cases
  21.        (i.e. MOVEA is just a MOVE).
  22.  
  23.     This version is for Software Toolworks C/80 Version 3.0
  24. */
  25.  
  26. #define    MAIN
  27.  
  28. #include "a:printf.h"        /* C/80 Specific    */
  29. #include "a:stdio.h"        /* Standard I/O Defines */
  30. #include "as.h"            /* Globals and Defines    */
  31.  
  32.  
  33. main(argc,argv)
  34. int     argc;
  35. char    *argv[];
  36. {
  37.     unsigned ah, al, cksum;
  38.         int     i, printer, ext;
  39.     char    exten[5], *s;
  40.  
  41.     /* initalize the command line switches */
  42.     no_list = no_object = no_symbol = printer = ext = FALSE;
  43.  
  44.     while (--argc > 0 && argv[1][0] == '-')  {
  45.         ++argv;
  46.         for (s = argv[0]+1; *s != '\0'; s++)  {
  47.             switch(toupper(*s))  {
  48.                 case 'L':
  49.                     no_list = TRUE;
  50.                     break;
  51.                 case 'O':
  52.                     no_object = TRUE;
  53.                     break;
  54.                 case 'S':
  55.                     no_symbol = TRUE;
  56.                     break;
  57.                 case 'P':
  58.                     strcpy(lstnam,"LST:");
  59.                     listdev = printer = TRUE;
  60.                     no_list = FALSE;
  61.             }
  62.         }
  63.     }
  64.  
  65.     if (argc != 1)  {
  66.         fprintf(stderr,"Usage: as68k [-losp] file\n");
  67.         exit();
  68.     }
  69.  
  70.     strcpy(srcnam,*++argv);
  71.  
  72.     for (s = *argv, i = 0; *s != '\0'; s++, i++)  {
  73.         if (*s == '.')  {
  74.             strcpy(exten,s);
  75.             ext = TRUE;
  76.             srcnam[i] = argv[0][i] = '\0';
  77.             break;
  78.         }
  79.     }
  80.  
  81.     if (!ext)
  82.         strcat(srcnam,".S");
  83.     else
  84.         strcat(srcnam,exten);
  85.  
  86.     if ( !printer && !no_list )  {
  87.         strcpy(lstnam,*argv);
  88.         strcat(lstnam,".PRN");
  89.     }
  90.  
  91.     if (!no_object)  {
  92.         strcpy(objnam,*argv);
  93.         strcat(objnam,".OBJ");
  94.     }
  95.  
  96.     if (!no_symbol)  {
  97.         strcpy(symnam,*argv);
  98.         strcat(symnam,".SYM");
  99.     }
  100.  
  101.         if (((symadr = alloc(MAXSYM * 4)) == ERR) ||
  102.             ((symlin = alloc(MAXSYM * 2)) == ERR) ||
  103.             ((symflg = alloc(MAXSM1)) == ERR) ||
  104.             ((symsym = alloc(MAXSYM * 2)) == ERR)) {
  105.                 printf("Not enough memory for symbol table\n");
  106.         printf("Re-compile using smaller table\n");
  107.                 exit();
  108.         }
  109.  
  110.  
  111.         /* open files */
  112.  
  113.     if ((sunit = fopen(srcnam,"r")) == NULL) {
  114.         fprintf(stderr,"Unable to open %s",srcnam);
  115.         exit();
  116.     }
  117.  
  118.     if (!no_list)
  119.                 if ((lunit = fopen(lstnam,"w")) == NULL) {
  120.                         fprintf(stderr,"Unable to open %s\n",lstnam);
  121.                         no_list = TRUE;
  122.         }
  123.  
  124.         if (!no_object)  {
  125.                 if ((ounit = fopen(objnam,"w")) == NULL) {
  126.                         fprintf(stderr,"Unable to open %s\n",objnam);
  127.                         no_object = TRUE;
  128.         }
  129.                 else
  130.                         fprintf(ounit,"S00600004844521B\n");
  131.     }
  132.  
  133.         if (!no_symbol)
  134.                 if ((munit = fopen(symnam,"w")) == NULL) {
  135.                         fprintf(stderr,"Unable to open %s\n",symnam);
  136.                         no_symbol = TRUE;
  137.         }
  138.  
  139.         /* do pass 1 */
  140.  
  141.         nosym = nocard = nopage = 0;
  142.         pass = rflg = 1;
  143.         pc = endval = 0l;
  144.         name[0] = EOS;
  145.  
  146.         while (1)  {
  147.                 newpc = 0l;
  148.                 source(1);        /* read one line of source file */
  149.  
  150.                 if (iserr == TRUE)    /* if EOF detected do pass 2 */
  151.                         break;
  152.  
  153.         meflg = 0;        /* reset multiple error flag */
  154.         parse();        /* parse source line */
  155.  
  156.                 if (prflg == 0)        /* if NULL line get next line */
  157.                         continue;
  158.  
  159.         prcess();        /* process source line */
  160.  
  161.                 if (iserr == TRUE)    /* if end detected do pass 2 */
  162.                         break;
  163.  
  164.                 pc += newpc;
  165.         }
  166.  
  167.         /* do pass 2 */
  168.  
  169.         source(2);            /* rewind source, reset PC */
  170.         iercnt = endflg = hexwc = 0;    /* initialize object buffer */
  171.         pc = hexpc = oldpc = 0l;
  172.         pass = 2;
  173.  
  174.         if (!no_list)
  175.                 newpag();
  176.  
  177.         while (1) {
  178.                 newpc = 0l;
  179.                 objwc = 0;
  180.                 source(1);        /* read one line of source file */
  181.  
  182.                 if (iserr == TRUE)    /* EOF detected */
  183.                         break;
  184.  
  185.                 meflg = 0;        /* reset multiple error flag */
  186.                 parse();        /* parse line */
  187.  
  188.                 if (!cmtflg) {
  189.                         if (prflg == 0)    /* check for parsing errors */
  190.                                 continue;
  191.                         prcess();    /* process it */
  192.  
  193.                 }
  194.  
  195.                 if (!no_list)
  196.             lstlne();    /* generate listing */
  197.  
  198.                 /* check if there is object code to generate */
  199.  
  200.                 if (!no_object && objwc)
  201.                         bldobj();
  202.  
  203.                 if (iserr == TRUE)    /* do next line if not end */
  204.                         break;
  205.  
  206.                 pc += newpc;
  207.         }
  208.  
  209.         /* end of assembly, output balance of object buffer */
  210.  
  211.         endflg = TRUE;
  212.     if (!no_object)  {
  213.             bldobj();
  214.                 ah = (unsigned)((endval >> 16) & (long)0x00ff);
  215.                 al = (unsigned)(endval & (long)0xffff);
  216.                 cksum = 4 + ah + ((al >> 8) & 0xff) + (al & 0xff);
  217.                 fprintf(ounit,"S804%02x%04x%02x\n",ah,al,(~cksum)&0xff);
  218.         }
  219.  
  220.         /* print symbol table and error report */
  221.  
  222.         pst();
  223.  
  224.     /* close files */
  225.  
  226.     fclose(sunit);
  227.  
  228.     if (!no_list)
  229.         fclose(lunit);
  230.     if (!no_object)
  231.         fclose(ounit);
  232.     if (!no_symbol)
  233.         fclose(munit);
  234. }
  235.  
  236.  
  237. source(icode)
  238. int     icode;
  239. {
  240.  
  241. /*
  242.     icode = 1 => read one line from source file into srclne and lpline,
  243.              trailing blanks are deleted.  Zero Character
  244.              is inserted at the end of the line.
  245.         2 => rewind source file.
  246.  
  247.     lpline = line printer line
  248.     srclne = source line
  249.     lnelen = length of source line
  250.     iserr  = TRUE if EOF on read, FALSE otherwise
  251.     nocard = card number read from source
  252. */
  253.         int     i;
  254.  
  255.         switch (icode) {
  256.         case 1:        /* read source line */
  257.             iserr = FALSE;
  258.                         if (newline(sunit) == NULL) {
  259.                                 iserr = TRUE;
  260.                                 return;
  261.                         }
  262.                         ++nocard;
  263.  
  264.             /* copy listing line into parsing line */
  265.  
  266.                         for (i = 0; i < lnelen; ++i)
  267.                 srclne[i] = lpline[i];
  268.  
  269.                     /* convert all characters */
  270.  
  271.             for (i = 0; i < lnelen; ++i)  {
  272.                 if (srclne[i] == '\'')
  273.                     while (srclne[++i] != '\'')
  274.                         ;
  275.                                 if (srclne[i] == '\t' ||
  276.                     (srclne[i] >= 32 && srclne[i] < 96))
  277.                     continue;
  278.                                 else if (srclne[i] < 32)
  279.                     srclne[i] = 32;
  280.                 else
  281.                                         srclne[i] -= 32;
  282.                         }
  283.  
  284.                     /* remove trailing blanks */
  285.  
  286.                         if (lnelen)
  287.                                 while (srclne[--lnelen] == ' ')
  288.                                         if (!lnelen)
  289.                                                 break;
  290.  
  291.                         srclne[++lnelen] = EOS;
  292.                         return;
  293.  
  294.         case 2:        /* rewind source file */
  295.             fclose(sunit);
  296.                         if ((sunit = fopen(srcnam,"r")) == NULL) {
  297.                                 fprintf(stderr,"Unable to re-open %s",srcnam);
  298.                                 exit();
  299.                         }
  300.                         nocard = 0;
  301.                         return;
  302.         }
  303. }
  304.  
  305.  
  306. newline(fd)
  307. FILE    fd;
  308. {
  309.         char    *cp;
  310.         int     c;
  311.  
  312.         lnelen = 0;
  313.         cp = lpline;
  314.         while ((c = getc(fd)) != EOF && c != '\n') {
  315.                 *cp++ = c;
  316.                 if (++lnelen == 80)
  317.                         while ((c = getc(fd)) != EOF && c != '\n')
  318.                 ;
  319.         }
  320.  
  321.         *cp = EOS;
  322.  
  323.         if (cp == lpline && c == EOF)
  324.                 return NULL;
  325.         else
  326.                 return lpline;
  327. }
  328.  
  329.  
  330. symtbl(scode,iaddr,symstr)
  331. int     scode;
  332. long    iaddr;
  333. char    *symstr;
  334. {
  335.  
  336. /*
  337.        scode = 1 =>    find operand in symbol table.
  338.             if not found it is entered as
  339.             referenced but not defined.
  340.             the index in the table is returned in 'stind'.
  341.                2 =>    find label in symbol table.
  342.             if found and already defined and first pass,
  343.             the multiple defined bit is set in 'symflg'.
  344.             if found but only previously referenced,
  345.             the defined but previously referenced bit is set,
  346.             and the referenced bit is cleared.
  347.             if not found it is entered and the defined bit is set.
  348.        iaddr =        address of symbol for entering into symbol table.
  349.        symbol=        symbol to look up or enter in symbol table.
  350.        stind =        index into symbol table for symbol.
  351.  
  352.  FORMAT:    BIT   MEANING IF SET
  353.         0    referenced but not defined.
  354.         1    defined and referenced before definition.
  355.         2    defined and no previous reference.
  356.         3    multiple defined.
  357.         4    equated value.
  358. */
  359.         char    *sptr;
  360.         int     i,found,movflg,itemp;
  361.  
  362.         /* search for symbol in symbol table */
  363.  
  364.         found = movflg = FALSE;
  365.         for (stind = 0; stind < nosym; ++stind) {
  366.                 if ((i = strcmp(symsym[stind],symstr)) < 0)
  367.                         continue;
  368.                 else if (i == 0) {
  369.                         found = TRUE;
  370.                         break;
  371.                 }
  372.                 else {
  373.                         movflg = TRUE;
  374.                         break;
  375.                 }
  376.         }
  377.  
  378.         if (!found) {
  379.  
  380.                 /* symbol was not found */
  381.  
  382.                 if (nosym >= MAXSYM) {
  383.                         error(221);
  384.                         stind = MAXSYM;
  385.                         return stind;
  386.                 }
  387.  
  388.                 if (movflg) {
  389.                         for (itemp = nosym; itemp > stind; --itemp) {
  390.                                 symsym[itemp]=symsym[itemp-1];
  391.                                 symadr[itemp]=symadr[itemp-1];
  392.                                 symflg[itemp]=symflg[itemp-1];
  393.                                 symlin[itemp]=symlin[itemp-1];
  394.                         }
  395.                 }
  396.  
  397.                 ++nosym;
  398.                 if ((symsym[stind] = alloc(SYMSZ1)) == ERR) {
  399.                         fprintf(stderr,"Symbol Table Overflow\n");
  400.                         exit();
  401.                 }
  402.  
  403.                 sptr = symsym[stind];
  404.                 for (i = 0; i < SYMSZ1; ++i)
  405.                         *sptr++ = *symstr++;
  406.  
  407.                 if (scode != 1) {
  408.                         symflg[stind] = 4;
  409.                         symadr[stind] = iaddr;
  410.                         symlin[stind] = nocard;
  411.                 }
  412.                 else {
  413.                         symadr[stind] = 0;
  414.                         symflg[stind] = 1;
  415.                         symlin[stind] = 0;
  416.                 }
  417.  
  418.                 return stind;
  419.         }
  420.         else {
  421.  
  422.                 /* symbol found */
  423.  
  424.                 if (pass == 2 || scode == 1)
  425.                         return stind;
  426.  
  427.                 if (symflg[stind] == 1) {
  428.                         symflg[stind] = 2;
  429.                         symadr[stind] = iaddr;
  430.                         symlin[stind] = nocard;
  431.                         return stind;
  432.                 }
  433.  
  434.                 symflg[stind] |= 8;
  435.                 return stind;
  436.         }
  437. }
  438.  
  439.  
  440. pst()
  441. {
  442.         int             i,idx,ipt,iftmp;
  443.         unsigned    ah,al;
  444.  
  445.         if (nosym == 0)
  446.                 return;
  447.  
  448.         if (!no_symbol)
  449.                 wst();
  450.  
  451.         if (no_list) {
  452.                 sumitup();
  453.                 return;
  454.         }
  455.  
  456.         newpag();               /* goto top of page */
  457.  
  458.         /* generate the symbol list a line at a time */
  459.  
  460.         for (i = 0; i < nosym; i += 3) {
  461.                 fprintf(lunit,"\n    ");
  462.                 for(idx = 0; idx < 3; ++idx) {
  463.                         if (i + idx < nosym) {
  464.                                 fprintf(lunit,"%s",symsym[i+idx]);
  465.  
  466.                                 ipt = strlen(symsym[i+idx]);
  467.                                 while (++ipt < 9)
  468.                                         putc(' ',lunit);
  469.  
  470.                                 ah = (unsigned)((symadr[i+idx] >> 16) & 0xffff);
  471.                                 al = (unsigned)(symadr[i+idx] & 0xffff);
  472.                                 fprintf(lunit," %04x%04x",ah,al);
  473.  
  474.                                 iftmp = symflg[i+idx];
  475.                                 if (iftmp & 0x10)
  476.                                         fprintf(lunit," EQ    ");
  477.                                 else if (iftmp & 0x08)
  478.                                         fprintf(lunit," MU    ");
  479.                                 else if (iftmp & 0x01)
  480.                                         fprintf(lunit," UN    ");
  481.                                 else if ((iftmp & 0x19) == 0)
  482.                                         fprintf(lunit,"       ");
  483.                                 else
  484.                                         fprintf(lunit," %02x    ",iftmp);
  485.                         }
  486.                 }
  487.  
  488.                 if (--noline == 0)
  489.                         newpag();
  490.         }
  491.         sumitup();
  492. }
  493.  
  494.  
  495. sumitup()
  496. {
  497.         if (pass == 2)  {
  498.         if (!no_list)
  499.                     fprintf(lunit,"\n\n %d Symbols, %d Errors detected\n",
  500.                         nosym,iercnt);
  501.         printf("\n%d Symbols, %d Errors detected\n",nosym,iercnt);
  502.     }
  503. }
  504.  
  505.  
  506. wst()
  507. {
  508.         unsigned    i,ah,al;
  509.  
  510.         for (i = 0; i < nosym; ++i) {
  511.                 ah = (unsigned)((symadr[i] >> 16) & (long)0xffff);
  512.                 al = (unsigned)(symadr[i] & (long)0xffff);
  513.                 fprintf(munit,"%s,%04x%04x,%02x\n",symsym[i],ah,al,symflg[i]);
  514.         }
  515. }
  516.  
  517.  
  518. newpag()
  519. {
  520.         fprintf(lunit,"\n\n\f%s\t\tMC68000 Cross-Assembler 2.1\t\tPage  %d\n",
  521.         name,++nopage);
  522.         noline = 58;
  523. }
  524.  
  525.  
  526. error(ierr)
  527. int     ierr;
  528. {
  529.         int     i, j, k;
  530.         char    s[80];
  531.  
  532.         /* errors are ignored on first pass */
  533.  
  534.         if (pass == 1)
  535.                 return;
  536.  
  537.         switch (ierr) {
  538.         case 202:       strcpy(s,"Invalid char for label start");
  539.                         break;
  540.         case 204:       strcpy(s,"Reserved word");
  541.                         break;
  542.         case 205:       strcpy(s,"Label too long");
  543.                         break;
  544.         case 206:       strcpy(s,"Parsing error");
  545.                         break;
  546.         case 207:       strcpy(s,"Invalid mode");
  547.                         break;
  548.         case 221:       strcpy(s,"Symbol table overflow");
  549.                         break;
  550.         case 400:       strcpy(s,"Undefined Opcode");
  551.                         break;
  552.         case 401:       strcpy(s,"Operand missing");
  553.                         break;
  554.         case 402:       strcpy(s,"Label missing or required");
  555.                         break;
  556.         case 403:       strcpy(s,"DC, DS or ORG operand error");
  557.                         break;
  558.         case 404:       strcpy(s,"Range error");
  559.                         break;
  560.         case 405:       strcpy(s,"Too many operands");
  561.                         break;
  562.         case 406:       strcpy(s,"Syntax error");
  563.                         break;
  564.         case 407:       strcpy(s,"Undefined symbol");
  565.                         break;
  566.         case 408:       strcpy(s,"Index size error");
  567.                         break;
  568.         case 409:       strcpy(s,"Multiply defined symbol");
  569.                         break;
  570.         default:        s[0] = EOS;
  571.                         break;
  572.         }
  573.  
  574.         prflg = 3;
  575.  
  576.         /* require two lines remaining to print error */
  577.  
  578.         if (!no_list && noline < 2)
  579.                 newpag();
  580.  
  581.         /* if this is not the first error then don't print the line */
  582.  
  583.         if (!meflg) {
  584.                 if (!no_list)
  585.                       fprintf(lunit,"\n%5d                                   ",
  586.                         nocard);
  587.  
  588.                 for (i = 41,j = 0; i < 132; ++j) {
  589.                         if (!lpline[j])
  590.                                 break;
  591.  
  592.                         if (!no_list) {
  593.                                 if (lpline[j] == '\t') {
  594.                                         if (listdev) {
  595.                                                 k = ((i | 7) + 1) - i;
  596.                                                 while (k--)
  597.                                                         putc(' ',lunit);
  598.                                         }
  599.                                         else
  600.                                                 putc('\t',lunit);
  601.  
  602.                                         i = (i | 7) + 1;
  603.                                 }
  604.                                 else {
  605.                                         putc(lpline[j],lunit);
  606.                                         ++i;
  607.                                 }
  608.                         }
  609.  
  610.                 }
  611.                 --noline;
  612.         }
  613.  
  614.         if (s[0]) {
  615.                 if (!no_list)
  616.                         fprintf(lunit,"\n+++++  ERROR  %s",s);
  617.  
  618.                 for (i = strlen(s); i < 27; ++i)
  619.                         if (!no_list)
  620.                                 putc(' ',lunit);
  621.         }
  622.         else {
  623.                 if (!no_list)
  624.                     fprintf(lunit,"\n+++++  ERROR  %3d                       ",
  625.                            ierr);
  626.         }
  627.  
  628.         for (i = 41,j = 0; j < scanpt; ++j) {
  629.                 if (lpline[j] == '\t')  {
  630.                         if (listdev)
  631.                                 k = ((i | 7) + 1) - i;
  632.  
  633.                         i = (i | 7) + 1;
  634.                 }
  635.                 else
  636.                         ++i;
  637.  
  638.                 if (i >= 132) {
  639.                         if (!no_list)
  640.                                 putc('>',lunit);
  641.  
  642.                         break;
  643.                 }
  644.  
  645.                 if (lpline[j] == '\t') {
  646.                         if (!no_list) {
  647.                                 if (listdev)
  648.                                         while (k--)
  649.                                                 putc(' ',lunit);
  650.                                 else
  651.                                         putc('\t',lunit);
  652.                         }
  653.                 }
  654.                 else if (!no_list)
  655.                      putc(' ',lunit);
  656.         }
  657.  
  658.         if (i < 132)
  659.                 if (!no_list)
  660.                         putc('^',lunit);
  661.  
  662.         --noline;
  663.         ++iercnt;
  664.         meflg = 1;
  665. }
  666.  
  667.  
  668. lstlne()
  669. {
  670.  
  671. /*
  672.        Build line (or lines if DC.B DC.W DC.L) for display
  673.  
  674.        prflg = 0 errors detected (print line as read)
  675.                1 no errors detected (print normally)
  676.                2 DC.W / DC.L directives
  677.                3 suppress printout of line
  678.                4 DC.B directive
  679.                5 NAM / END / MON directives
  680.                6 EQU / SET directives
  681.                7 ORG / RORG directives
  682.                8 DS directive
  683.                9 PAGE directive
  684. */
  685.  
  686.         int             i, lswrds;
  687.         unsigned    ah, al;
  688.  
  689.         if (pass == 1 || no_list)
  690.                 return;
  691.  
  692.         /* only print 5 words of an instruction */
  693.  
  694.         if (objwc > 5)
  695.                 lswrds = 5;
  696.     else
  697.             lswrds = objwc;
  698.  
  699.         /* check if we have to go to next page */
  700.  
  701.         if (!noline)
  702.                 newpag();
  703.  
  704.     /* check for a comment line */
  705.  
  706.         if (lpline[0] == '*')
  707.                 prflg = 5;
  708.  
  709.         switch (prflg) {
  710.                 case 0:         /* errors */
  711.                 case 1:         /* normal */
  712.                 case 2:         /* DC.W,DC.L */
  713.                 case 7:         /* ORG,RORG */
  714.                 case 8:         /* DS */
  715.                 case 4:         /* DC.B */
  716.                         ah = (unsigned)((pc >> 16) & (long)0xffff);
  717.                         al = (unsigned)(pc & (long)0xffff);
  718.  
  719.                         fprintf(lunit,"\n%5d   %02x%04x ",nocard,ah,al);
  720.  
  721.                         for (i = 1; i <= 5; ++i) {
  722.                                 if (i <= lswrds)
  723.                                         fprintf(lunit,"%04x ",objbuf[i]);
  724.                                 else
  725.                                         fprintf(lunit,"     ");
  726.                         }
  727.             lst1();
  728.                         break;
  729.  
  730.                 case 5:         /* NAM,END,MON and Remarks */
  731.                       fprintf(lunit,"\n%5d                                   ",
  732.                 nocard);
  733.             lst1();
  734.                         break;
  735.  
  736.                 case 6:         /* EQU,SET */
  737.                        fprintf(lunit,"\n%5d = %4x%04x                        ",
  738.                                nocard,opnwrd[3],opnwrd[2]);
  739.             lst1();
  740.             break;
  741.  
  742.                 case 9:         /* page */
  743.                         newpag();
  744.  
  745.                 case 3:         /* suppress print */
  746.                         return;
  747.         }
  748.         --noline;
  749. }
  750.  
  751.  
  752. lst1()
  753. {
  754.     int    i, j, k;
  755.  
  756.     for (i = 41,j = 0; lpline[j]; ++j)  {
  757.         if (lpline[j] == '\t') {
  758.             if (listdev)
  759.                 k = ((i | 7) + 1) - i;
  760.             i = (i | 7) + 1;
  761.         }
  762.         else
  763.             ++i;
  764.  
  765.         if (i >= 132)
  766.             break;
  767.  
  768.         if (listdev && lpline[j] == '\t')
  769.             while (k--)
  770.                 putc(' ',lunit);
  771.         else
  772.             putc(lpline[j],lunit);
  773.     }
  774. }
  775.  
  776.  
  777. bldobj()
  778. {
  779.         int    i;
  780.         long    newval;
  781.  
  782.         /* check for the end of assembly flag            */
  783.         /* if set, output the balance of the object buffer    */
  784.  
  785.         if (endflg)  {
  786.                 if (hexwc)
  787.                         wrtobj();
  788.                 return;
  789.     }
  790.  
  791.         /* check the PC value with that of the one saved    */
  792.         /* if the two are not equal then output the balance    */
  793.         /* of the object buffer and start at the new PC value    */
  794.  
  795.         if (pc != oldpc) {
  796.                 if (hexwc)
  797.                         wrtobj();
  798.  
  799.                 hexpc = oldpc = pc;
  800.         }
  801.  
  802.         /* transfer object buffer to internal buffer.      */
  803.     /* If the internal buffer is full then output it. */
  804.  
  805.         for (i = 1; i <= objwc; ++i) {
  806.                 hexbuf[++hexwc] = objbuf[i];
  807.                 if (hexwc >= 8) {
  808.  
  809.                         /* output buffer is full */
  810.  
  811.                         wrtobj();
  812.  
  813.                         /* calculate new PC for internal buffer */
  814.  
  815.                         newval = (long)i * 2;
  816.                         hexpc = pc + newval;
  817.                 }
  818.         }
  819.  
  820.         /* calculate new PC by adding object word count to current PC */
  821.  
  822.         oldpc += newpc;
  823. }
  824.  
  825.  
  826. wrtobj()
  827. {
  828.  
  829. /*
  830.        Output the contents of the Object buffer
  831.  
  832.        hexpc = starting PC for buffer
  833.        hexwc = number of words used in buffer
  834.        hexbuf= 8 word Object buffer
  835. */
  836.     int      i;
  837.         unsigned  ah,al,cksum;
  838.  
  839.         ah = (unsigned)((hexpc >> 16) & (long)0xff);
  840.         al = (unsigned)(hexpc & (long)0xffff);
  841.         fprintf(ounit,"S2%02x%02x%04x",hexwc*2+4,ah,al);
  842.         cksum=((hexwc * 2 + 4) & 0xff) + ah + ((al >> 8) & 0xff) + (al & 0xff);
  843.  
  844.         for (i = 1; i <= hexwc; ++i) {
  845.                 fprintf(ounit,"%04x",hexbuf[i]);
  846.                 cksum += ((hexbuf[i] >> 8) & 0xff) + (hexbuf[i] & 0xff);
  847.         }
  848.  
  849.         fprintf(ounit,"%02x\n",(~cksum) & 0xff);
  850.         hexwc = 0;
  851. }
  852.  
  853.  
  854. long
  855. asn(wrd2,wrd3)
  856. unsigned    wrd2,wrd3;
  857. {
  858.     return ( ((wrd3 << 16) & 0xffff0000) | (wrd2 & (long)0x0ffff) );
  859. }
  860.