home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / motasm / src_c_as < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-04  |  22.8 KB  |  599 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. /* #include <kernel.h> */
  6.  
  7. #include "mselect.h"            /* external selection of microprocessor
  8.                                  * symbol table */
  9. #include "proto.h"
  10. #include "as.h"
  11. #include "structs.h"
  12. #include "glovars.h"
  13.  
  14. void            stable(struct nlist * ptr);
  15. void            cross(struct nlist * point);
  16.  
  17. /*
  18.  * as --- cross assembler main program
  19.  *
  20.  * Note: Compile with define DEBUG for function module debug statements. Compile
  21.  * with define DEBUG2 for version 2 debug statements only.  Compile with
  22.  * define IBM to use original, non- Amiga, non-MAC, non-UNIX fgets()
  23.  * function.  Amiga version will accept IBM generated source code but not the
  24.  * other way around. Note added version (TER) 2.01 19 June 1989.
  25.  */
  26.  
  27. int
  28. main(int argc, char **argv)
  29. {
  30.         char          **np,**npthrow;
  31.         char           *i;
  32.         int             j = 0, l = 0;
  33.  
  34.         fprintf(stderr, "Freeware 8 bit Microcontroller Assembler -  (c) Motorola\n");
  35.         fprintf(stderr, "Archimedes porting by Maurizio Ferrari   -  version 3.03");
  36. #if     MC68HC11
  37.         fprintf (stderr, " - MC68HC11\n\n");
  38. #elif   MC68HC05
  39.         fprintf (stderr, " - MC68HC05\n\n");
  40. #elif   MC6809
  41.         fprintf (stderr, " - MC6809\n\n");
  42. #else
  43.         #error undefined target processor, please define MICRO
  44. #endif
  45.  
  46.  
  47.         if (argc < 2) {
  48.                 fprintf(stderr, "Usage:   %s [files] [-options]\n", argv[j]);
  49.                 fprintf(stderr, "Example: %s FILE1.ASM FILE2.ASM -o <Obj_name> -cpp <cpp_options> -noasm -x|cre -list|l <List_name> -cyc -p 50 -crlf -split -end\n", argv[j]);
  50.                 exit(1);
  51.         }
  52.         Argv = argv;
  53.         while ((*argv[j] != '-') && (j < argc)) {
  54. #ifdef DEBUG
  55.                 printf("%s\n", argv[j]);
  56. #endif
  57.                 j++;
  58.         }
  59.         N_files = j - 1;
  60.         /*
  61.          * cppnp = (char **) malloc(sizeof(char *)*(N_files)); if (cppnp ==
  62.          * NULL) fatal("Cannot allocate space for cpp file name");
  63.          */
  64.         Lflag = 0;
  65.         Cflag = 0;
  66.         Sflag = 0;
  67.         Pflag = 0;
  68.         CREflag = 0;
  69.         Splitflag = 0;
  70.         if (j < argc) {
  71.                 while (j < argc) {
  72.                         for (i = argv[j]; *i != 0; i++)
  73.                                 if ((*i <= 'Z') && (*i >= 'A'))
  74.                                         *i = *i + 32;
  75.                         if (strcmp(argv[j], "-list") == 0) {
  76.                                 Lflag = 1;
  77.                         } else if (strcmp(argv[j], "-l") == 0) {
  78.                                 Lflag = 1;
  79.                         } else if (strcmp(argv[j], "-cyc") == 0) {
  80.                                 Cflag = 1;
  81.                         } else if (strcmp(argv[j], "-sym") == 0) {
  82.                                 Sflag = 1;
  83.                         } else if (strcmp(argv[j], "-s") == 0) {
  84.                                 Sflag = 1;
  85.                         } else if (strcmp(argv[j], "-noasm") == 0) {
  86.                                 NoAflag = 1;
  87.                         } else if (strcmp(argv[j], "-split") == 0) {
  88.                                 Splitflag = 1;
  89.                         } else if (strcmp(argv[j], "-cpp") == 0) {
  90.                                 Pflag = 1;
  91.                         } else if (strcmp(argv[j], "-x") == 0) {
  92.                                 CREflag = 1;
  93.                         } else if (strcmp(argv[j], "-cre") == 0) {
  94.                                 CREflag = 1;
  95.                         } else if (strcmp(argv[j], "-end") == 0) {
  96.                                 ENDflag = 1;
  97.                         } else if (strcmp(argv[j], "-crlf") == 0) {     /* test for crlf option */
  98.                                 CRflag = 1;
  99.                         } else if (strcmp(argv[j], "-p") == 0) {        /* page every <PageLen>
  100.                                                                          * lines */
  101.                                 Pflag50 = 1;
  102.                                 PageLen = atoi(argv[++j]);
  103.                         } else if (strcmp(argv[j], "-o") == 0) {
  104.                                 ObjFilePos = ++j;
  105.                         } else if (strcmp(argv[j], "-c") == 0) {
  106.                                 cppargpos[l++] = j;
  107.                                 cppargc++;
  108.                         } else if (strcmp(argv[j], "-e") == 0) {
  109.                                 cppargpos[l++] = j;
  110.                                 cppargc++;
  111.                         } else if (strcmp(argv[j], "-n") == 0) {
  112.                                 cppargpos[l++] = j;
  113.                                 cppargc++;
  114.                         } else if ((argv[j][0] == '-') && (argv[j][1] == 'x') && (strlen(argv[j]) > 2)) {
  115.                                 cppargpos[l++] = j;
  116.                                 cppargc++;
  117.                         } else if ((argv[j][0] == '-') && (argv[j][1] == 'i') && (strlen(argv[j]) > 2)) {
  118.                                 cppargpos[l++] = j;
  119.                                 cppargc++;
  120.                         } else if ((argv[j][0] == '-') && (argv[j][1] == 'd') && (strlen(argv[j]) > 2)) {
  121.                                 cppargpos[l++] = j;
  122.                                 cppargc++;
  123.                         } else if ((argv[j][0] == '-') && (argv[j][1] == 's') && (strlen(argv[j]) > 2)) {
  124.                                 cppargpos[l++] = j;
  125.                                 cppargc++;
  126.                         } else if ((argv[j][0] == '-') && (argv[j][1] == 'u') && (strlen(argv[j]) > 2)) {
  127.                                 cppargpos[l++] = j;
  128.                                 cppargc++;
  129.                         } else if (*argv[j]) {
  130.                                 fprintf(stderr, "\nUnrecognized option '%s' on command line\n", argv[j]);
  131.                                 fprintf(stderr, "Valid options are:");
  132.                                 fprintf(stderr, "  -list|l  -cyc  -sym  -x|cre  -cpp <cpp_options> -crlf -p <pages> -o <Obj name> -split\n\n");
  133.                                 exit(1);
  134.                         }
  135.                         j++;
  136.                 }
  137.         }
  138.         if (ObjFilePos == 0)
  139.                 fatal("\nmust specify output file");
  140.         /* errorInit(throwback,SourceFileName); */
  141.         fwdinit();              /* forward ref init */
  142.         initialize();
  143.         root = NULL;
  144.         Cfn = 0;
  145.         np = argv;
  146.         Line_num = 0;           /* reset line number */
  147.         Local_Line_num = 0;     /* reset line number */
  148.         if (Pflag != 0) {
  149.                 preprocess();
  150.                 if (NoAflag !=0 ) {
  151.                         fprintf(stderr, "preprocessing complete - exiting");
  152.                         exit(0);}
  153.                 np = cppnp;
  154.         }
  155.         else {
  156.                if (NoAflag != 0) {warn("No c preprocessing, -noasm flag with no effect");}
  157.         }
  158.         while (++Cfn <= N_files)
  159.                 if ((Fd = fopen(*++np, "r")) == NULL) {
  160.                         fprintf(stderr, "as: can't open %s\n", *np);
  161.                         fatal("\n");
  162.                 } else {
  163.                         npthrow=&argv[Cfn];
  164.                         errorInit(1, *npthrow);
  165.                         make_pass();
  166.                         fclose(Fd);
  167.                         errorFinish();
  168.                         Local_Line_num = 0;     /* reset line number */
  169.                 }
  170.         if (Err_count == 0) {
  171.                 Pass++;
  172.                 re_init();
  173.                 Cfn = 0;
  174.                 np = argv;
  175.                 if (Pflag != 0) {
  176.                         np = cppnp;
  177.                 }
  178.                 Line_num = 0;
  179.                 Local_Line_num = 0;
  180.                 FdCount = 0;    /* Resets INCLUDE file nesting ver TER_2.0
  181.                                  * 6/17/89 */
  182.                 while (++Cfn <= N_files)
  183.                         if ((Fd = fopen(*++np, "r")) != NULL) {
  184.                                 fprintf(stderr, "\nAssembling %s\n", *np);
  185.                 npthrow=&argv[Cfn];
  186.                                 errorInit(1, *npthrow);
  187.                                 make_pass();
  188.                                 fclose(Fd);
  189.                                 errorFinish();
  190.                                 if ((!end_found) && ENDflag) {warn ("END directive not found");}
  191.                                 end_found=NO;
  192.                                 Local_Line_num = 0;     /* reset Line_num for
  193.                                                          * throwback */
  194.                         }
  195.                 fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
  196.                 fprintf(stderr, "Error count = %d\n\n", Err_count);     /* rel TER_2.0 */
  197.                 if (Sflag == 1) {
  198.                         fprintf(stderr, "Writing Symbols file\n");
  199.                         stable(root);
  200.                         if (Splitflag != 0) {
  201.                                 fclose(Mapfil);
  202.                         }
  203.                 }
  204.                 if (CREflag == 1) {
  205.                         fprintf(stderr, "Writing Xref file\n");
  206.                         cross(root);
  207.                         if (Splitflag != 0) {
  208.                                 fclose(Xfil);
  209.                         }
  210.                 }
  211.                 if (CRflag == 1)
  212.                         fprintf(Objfil, "S9030000FC%c\n", CR);  /* ver TER_1.1 print w
  213.                                                                  * <CR> */
  214.                 else
  215.                         fprintf(Objfil, "S9030000FC\n");        /* at least give a
  216.                                                                  * decent ending */
  217.                 fclose(Objfil); /* close file correctly ver TER_1.1 */
  218.                 fclose(Listfil);/* close file */
  219.         } else {                /* just note errors, TER_2.0 */
  220.                 fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
  221.                 fprintf(stderr, "Error count = %d\n\n", Err_count);
  222.                 fclose(Listfil);/* close file */
  223.         }
  224.         fwd_done();
  225.         errorFinish();
  226.         exit(Err_count);        /* neat for UNIX cuz can test return value in
  227.                                  * script but on other systems like Amiga,
  228.                                  * mostly just makes further script
  229.                                  * statements fail if >10, else nothing.
  230.                                  * Therefore, printed out byte count and
  231.                                  * error level. ver (TER) 2.02 19 Jun 89 */
  232. }
  233.  
  234. void
  235. preprocess(void)
  236. {
  237.         char           *proot, *leafname, *cppstring;   /* !cpp command line
  238.                                                          * shell commands */
  239.         int             i = 0, j = 0, cppsize = 0, appoCfn, maxlenCfn = 0;
  240.  
  241.  
  242.         for (appoCfn = 1; appoCfn <= N_files; appoCfn++) {
  243.                 maxlenCfn = (maxlenCfn >= strlen(Argv[appoCfn])) ? maxlenCfn : strlen(Argv[appoCfn]);
  244.         }
  245.         proot = (char *) malloc(maxlenCfn + 10);
  246.         if (proot == NULL) {
  247.                 fatal("Cannot allocate space for cpp file name");
  248.         }
  249.         for (appoCfn = 1; appoCfn <= N_files; appoCfn++) {
  250.                 cppnp[appoCfn] = (char *) malloc(maxlenCfn + 10);
  251.                 if (cppnp[appoCfn] == NULL) {
  252.                         fatal("Cannot allocate space for .p file name");
  253.                 }
  254.         }
  255.         cppsize = 0;
  256.         for (j = 0; j < cppargc; j++) {
  257.                 cppsize += strlen(Argv[cppargpos[j]]);
  258.         }
  259.         cppsize = cppsize + 2 * maxlenCfn + strlen("<asmcpp$dir>.!cpp ") + 100;
  260.         /* + 100 allows for spaces and errors... */
  261. #ifdef DEBUG
  262.         for (j = 0; j < cppargc; j++) {
  263.                 printf("cppargpos = %d\n", cppargpos[j]);
  264.         }
  265. #endif
  266.         cppstring = (char *) malloc(cppsize);
  267.         if (cppstring == NULL) {
  268.                 fatal("Cannot allocate space for cpp command line");
  269.         }
  270.         for (appoCfn = 1; appoCfn <= N_files; appoCfn++) {
  271.                 leafname = strrchr(Argv[appoCfn], '.');
  272.                 if (leafname == NULL) {
  273.                         fatal("cannot decipher leafname: empty ?");
  274.                 }
  275.                 i = strlen(Argv[appoCfn]);
  276.                 do {
  277.                         i--;
  278.                 } while (Argv[appoCfn][i - 1] != '.');
  279.                 do {
  280.                         i--;
  281.                 } while (Argv[appoCfn][i - 1] != '.');
  282.                 strncpy(proot, Argv[appoCfn], i - 1);
  283.                 proot[i - 1] = EOS;
  284.                 proot = strcat(proot, ".p");
  285.                 proot = strcat(proot, leafname);
  286.  
  287.                 strcpy(cppnp[appoCfn], proot);
  288.  
  289.                 cppstring[0] = '\0';
  290.                 cppstring = strcat(cppstring, "call: <asmcpp$dir>.!cpp ");
  291.                 for (j = 0; j < cppargc; j++) {
  292.                         cppstring = strcat(cppstring, " ");
  293.                         cppstring = strcat(cppstring, Argv[cppargpos[j]]);
  294.                 }
  295.                 cppstring = strcat(cppstring, " ");
  296.                 cppstring = strcat(cppstring, Argv[appoCfn]);
  297.                 cppstring = strcat(cppstring, " > ");
  298.                 cppstring = strcat(cppstring, proot);
  299.                 fprintf(stderr, "Preprocessing:\n %s\n", cppstring);
  300.                 switch (system(cppstring)) {
  301.                 case -2:
  302.                         fatal("Not enough space to run !cpp or unknown <asmcpp$dir>\n Try to increase overall WimpSlot size and check if <asmcpp$dir> exists.\n");
  303.                         break;
  304.                 case 1:
  305.                         fatal("!cpp errors detected, compilation aborted\n");
  306.                         break;
  307.                 case 0:
  308.                 default:
  309.                         break;
  310.                 }
  311.         }
  312.         return;
  313. }
  314.  
  315.  
  316.  
  317. void
  318. initialize()
  319. {
  320.         char            c;
  321.         char           *leafname, *maproot, *xroot, *lroot;
  322.         /* input file leaf and output names */
  323.         int             i = 0;
  324.  
  325. #ifdef DEBUG
  326.         printf("Initializing\n");
  327. #endif
  328.         Err_count = 0;
  329.         Pc = 0;
  330.         Pass = 1;
  331.         Ctotal = 0;
  332.         N_page = 0;
  333.         Line[MAXBUF - 1] = NEWLINE;
  334.         if (strlen(Argv[ObjFilePos]) > FILENAME_MAX)
  335.                 fatal("obj_file name too long ");
  336.         Obj_name = (char *) malloc(strlen(Argv[ObjFilePos]));
  337.         lroot = (char *) malloc(strlen(Argv[1]));
  338.         maproot = (char *) malloc(strlen(Argv[1]));
  339.         xroot = (char *) malloc(strlen(Argv[1]));
  340.         if (Obj_name == NULL)
  341.                 fatal("Cannot allocate space for obj name");
  342.         if (lroot == NULL)
  343.                 fatal("Cannot allocate space for list file name");
  344.         if (maproot == NULL)
  345.                 fatal("Cannot allocate space for  map file name");
  346.         if (xroot == NULL)
  347.                 fatal("Cannot allocate space for xref file name");
  348. #ifdef DEBUG
  349.         printf("%d, %d\n", strlen(Argv[ObjFilePos]), sizeof(char));
  350.         printf("Oun =%s-\n", Obj_name);
  351.  
  352. #endif
  353.         do {                    /* copy -o <file name> into Obj_name */
  354.                 c = Obj_name[i] = Argv[ObjFilePos][i];
  355.                 i++;
  356.         } while (c && (i < FILENAME_MAX));
  357.  
  358. #ifdef DEBUG
  359.         printf("Fwd =%s\n", Fwd_name);
  360.         printf("Obj =%s\n", Obj_name);
  361. #endif
  362.         Obj_name[--i] = EOS;
  363.         printf("S19 Obj file:  %s\n", Obj_name);
  364.         if ((Objfil = fopen(Obj_name, "w")) == NULL) {
  365.                 fatal("Can't create object file");
  366.         }
  367.         leafname = strrchr(Argv[1], '.');
  368.         if (leafname == NULL) {
  369.                 fatal("cannot decipher leafname: empty ?");
  370.         }
  371.         i = strlen(Argv[1]);
  372.         do {
  373.                 i--;
  374.         } while (Argv[1][i - 1] != '.');
  375.         do {
  376.                 i--;
  377.         } while (Argv[1][i - 1] != '.');
  378.         /* if (Lflag != 0) */
  379.         {
  380.                 strncpy(lroot, Argv[1], i - 1);
  381.                 lroot[i - 1] = EOS;
  382.                 lroot = strcat(lroot, ".l");
  383.                 lroot = strcat(lroot, leafname);
  384.         }
  385.         /* if (Sflag != 0 ) */
  386.         {
  387.                 strncpy(maproot, Argv[1], i - 1);
  388.                 maproot[i - 1] = EOS;
  389.                 maproot = strcat(maproot, ".m");
  390.                 maproot = strcat(maproot, leafname);
  391.         }
  392.         /* if (CREflag != 0) */
  393.         {
  394.                 strncpy(xroot, Argv[1], i - 1);
  395.                 xroot[i - 1] = EOS;
  396.                 xroot = strcat(xroot, ".x");
  397.                 xroot = strcat(xroot, leafname);
  398.         }
  399.  
  400.         if (Splitflag == 0) {
  401.                 if ((Sflag != 0) || (Lflag != 0) || (CREflag != 0)) {
  402.                         if ((Listfil = fopen(lroot, "w")) == NULL) {
  403.                                 fatal("Panic! Can't create listing file. Does 'l' dir exist? File open?");
  404.                         }
  405.                         Mapfil = Listfil;
  406.                         Xfil = Listfil;
  407.                         if (Lflag != 0) {
  408.                                 printf("Listing file: %s\n", lroot);
  409.                         }
  410.                         if (CREflag != 0) {
  411.                                 printf("Xref file   : %s\n", lroot);
  412.                         }
  413.                         if (Sflag != 0) {
  414.                                 printf("Symbols file: %s\n", lroot);
  415.                         }
  416.                 } else {
  417.                         printf("No List, Xref or Symbols file selected\n");
  418.                 }
  419.         } else {
  420.                 if (Lflag != 0) {
  421.                         if ((Listfil = fopen(lroot, "w")) == NULL) {
  422.                                 fatal("Panic! Can't create listing file. Does 'l' dir exist? File open?");
  423.                         }
  424.                         printf("Listing file: %s\n", lroot);
  425.                 }
  426.                 if (Sflag != 0) {
  427.                         if ((Mapfil = fopen(maproot, "w")) == NULL) {
  428.                                 fatal("Panic! Can't create symbols map file. Does 'm' dir exist? File open?");
  429.                         }
  430.                         printf("Symbols file: %s\n", maproot);
  431.                 }
  432.                 if (CREflag != 0) {
  433.                         if ((Xfil = fopen(xroot, "w")) == NULL) {
  434.                                 fatal("Panic! Can't create xref file. Does 'x' dir exist? File open?");
  435.                         }
  436.                         printf("Xref file   : %s\n", xroot);
  437.                 }
  438.         }
  439.  
  440.         localinit();            /* target machine specific init. */
  441. }
  442.  
  443. void
  444. re_init(void)
  445. {
  446. #ifdef DEBUG
  447.         printf("Reinitializing\n");
  448. #endif
  449.         Pc = 0;
  450.         E_total = 0;
  451.         P_total = 0;
  452.         Ctotal = 0;
  453.         N_page = 0;
  454.         fwdreinit();
  455. }
  456.  
  457. void
  458. make_pass(void)
  459. {
  460.         /*
  461.          * #ifdef IBM char *fgets();
  462.          *//* the original line */
  463.         /* #else */
  464.         /* char *FGETS(); *//* use own FGETS which is rewrite of lib function */
  465.         /* such that it discards <CR> so can read code */
  466.         /* generated on IBM */
  467.         /* June 3, 1989 rev TER_1.1 */
  468.         /* #endif */
  469.  
  470. #ifdef DEBUG
  471.         printf("Pass %d\n", Pass);
  472. #endif
  473.         while (FGETS(Line, MAXBUF - 1, Fd) != (char *) NULL) {  /* changed to FGETS */
  474.                 /* which does not pass on <CR>  June 3, 1989 */
  475.                 /* rev TER_1.1 */
  476.                 Line_num++;
  477.                 Local_Line_num++;
  478.                 P_force = 0;    /* No force unless bytes emitted */
  479.                 N_page = 0;
  480.                 if (parse_line())
  481.                         process();
  482.                 if (Pass == 2 && Lflag && !N_page)
  483.                         print_line();
  484.                 P_total = 0;    /* reset byte count */
  485.                 Cycles = 0;     /* and per instruction cycle count */
  486.         }
  487.         f_record();
  488. }
  489.  
  490.  
  491. /*
  492.  * parse_line --- split input line into label, op and operand
  493.  */
  494. int
  495. parse_line(void)
  496. {
  497.         register char  *ptrfrm = Line;
  498.         register char  *ptrto = Label;
  499.         /* char *skip_white(); */
  500.  
  501.         if (*ptrfrm == '*' || *ptrfrm == '\n' || *ptrfrm == ';')
  502.                 /* added check for ';' ver TER_1.1 */
  503.                 /* June 3, 1989 */
  504.                 return (0);     /* a comment line */
  505.  
  506.         while (delim(*ptrfrm) == NO)    /* parsing Label */
  507.                 *ptrto++ = *ptrfrm++;
  508.         if (*--ptrto != ':')
  509.                 ptrto++;        /* allow trailing : */
  510.         *ptrto = EOS;
  511.  
  512.         ptrfrm = skip_white(ptrfrm);
  513.         if (*ptrfrm == ';') {   /* intercept comment after label, ver TER_2.0 */
  514.                 *Op = *Operand = EOS;   /* comment, no Opcode or Operand */
  515.                 return (1);
  516.         }
  517.         ptrto = Op;
  518.  
  519.         while (delim(*ptrfrm) == NO)    /* parsing Opcode */
  520.                 *ptrto++ = mapdn(*ptrfrm++);
  521.         *ptrto = EOS;
  522.  
  523.         ptrfrm = skip_white(ptrfrm);
  524.         if (*ptrfrm == ';') {   /* intercept comment, ver TER_2.0 */
  525.                 *Operand = EOS; /* comment, no Operand */
  526.                 return (1);
  527.         }
  528.         ptrto = Operand;
  529.         while ((*ptrfrm != NEWLINE) && ((*ptrfrm != ';') || (Op != "fcc")))    /* ver TER_2.0 */
  530.                 *ptrto++ = *ptrfrm++;   /* kill comments *//* buggy: if FCC
  531.                                          * ';' error reported removed 27/6/93 */
  532.         *ptrto = EOS;
  533.  
  534. #ifdef DEBUG
  535.         printf("Label-%s-\n", Label);
  536.         printf("Op----%s-\n", Op);
  537.         printf("Operand-%s-\n", Operand);
  538. #endif
  539.         return (1);
  540. }
  541.  
  542. /*
  543.  * process --- determine mnemonic class and act on it
  544.  */
  545. void
  546. process(void)
  547. {
  548.         register struct oper *i;
  549.         /* struct oper *mne_look(); */
  550.  
  551.         Old_pc = Pc;            /* setup `old' program counter */
  552.         Optr = Operand;         /* point to beginning of operand field */
  553.  
  554.         if (*Op == EOS) {       /* no mnemonic */
  555.                 if (*Label != EOS)
  556.                         install(Label, Pc);
  557.         } else if ((i = mne_look(Op)) == NULL)
  558.                 error("Unrecognized Mnemonic");
  559.         else if (i->class == PSEUDO)
  560.                 do_pseudo(i->opcode);
  561.         else {
  562.                 if (*Label)
  563.                         install(Label, Pc);
  564.                 if (Cflag)
  565.                         Cycles = i->cycles;
  566.                 do_op(i->opcode, i->class);
  567.                 if (Cflag)
  568.                         Ctotal += Cycles;
  569.         }
  570. }
  571.  
  572. #ifndef IBM
  573. char           *
  574. FGETS(char *s, int n, register FILE * iop)
  575. {                               /* get at most n chars from iop */
  576.         /* Added rev TER_1.1 June 3, 1989 */
  577.         /* Adapted from Kernighan & Ritchie */
  578.         /*
  579.          * An fgets() that is IBM proof. Not needed if this IS an IBM
  580.          */
  581.         register int    c;
  582.         register char  *cs;
  583.  
  584.         cs = s;
  585.         while (--n > 0 && (c = getc(iop)) != EOF) {     /* read chars if not
  586.                                                          * file end */
  587.                 if ((*cs = c) != CR)
  588.                         cs++;   /* incr buffer pointer if not CR */
  589.                 /* If CR, leave to be written over */
  590.                 if (c == '\n')
  591.                         break;
  592.         }
  593.         *cs = '\0';             /* replace NEWLINE with NULL as in standard
  594.                                  * fgets() */
  595.         return ((c == EOF && cs == s) ? NULL : s);      /* return NULL if this
  596.                                                          * is EOF */
  597. }
  598. #endif
  599.