home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 338_01 / asetc.c < prev    next >
Text File  |  1988-02-25  |  11KB  |  427 lines

  1. /* asetc.c - misc routines
  2.  * parse statement for label and instruction, find operand field
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include "as68.h"
  8.  
  9. /* state types */
  10. #define    START 1
  11. #define    LBL 2
  12. #define    LIM 3
  13. #define    STOP 4
  14.  
  15. /* character types */
  16. #define    LIM_C 1
  17. #define    LM_C 2
  18. #define    LBLTRM_C 3
  19. #define    WS_C 4
  20. #define    STMEND_C 5
  21. #define    CMNT_C 6
  22. #define    ILGL_C 7
  23.  
  24. extern char *stmnt_ptr;        /* moved to root */
  25. extern char statement[STMNT_SIZE];
  26. extern char instr[32];
  27. extern char label[32];
  28. extern char *opfld_ptr;
  29. extern char lcksm;
  30. extern char pass;
  31. extern int src_level;
  32. extern int loc_plus;
  33. extern int wrap;
  34. extern unsigned line_count;
  35. extern long loc_counter;
  36. extern FLAG nolist;
  37. extern FLAG lcon;
  38. extern FLAG llst;
  39. extern FLAG lfile;
  40. extern FLAG obj_open;
  41. extern FLAG trunc;
  42. extern FILE *_src[SRCLEVELS];
  43. extern FILE *lst_d;
  44. extern FILE *lst_f;
  45. extern FILE *obj_f;
  46.  
  47. /* types */
  48.  
  49. char *nextfield();
  50.  
  51. /* code begins */
  52.  
  53. preparse()
  54. {
  55.     char *sbuf_ptr = statement;        /* pointer to statement    buffer */
  56.     char *field_ptr = NULL;        /* pointer to present field */
  57.     int field_len = 0;             /* length of present scanned field */
  58.     register FLAG state = START;     /* present state */
  59.     FLAG bad_field = NO;
  60.  
  61.     label[0] = label[31] = instr[0] = instr[31]    = NULL;
  62.     opfld_ptr = NULL;
  63.     stmnt_ptr = statement;        /* init for get_source() */
  64.  
  65. /* LIM_C:    'A'-'Z','a'-'z','.'    */
  66. /* LM_C:    '0'-'9','_',?'-'?,'$'    */
  67. /* LBLTRM_C:    ':'            */
  68. /* WS_C:    ' ','\t'        */
  69. /* STMEND_C:    '\n'            */
  70. /* CMNT_C:    '*'            */
  71. /* ILGL_C:    <anything else>     */
  72.  
  73. /* START state */
  74.  
  75.     switch (nextc(&sbuf_ptr)) {
  76.     case CMNT_C:
  77.     case STMEND_C:
  78.     opfld_ptr = statement;        /* operands or comment */
  79.     return COMMENT;            /* nothing here... */
  80.     case ILGL_C:            /* illegal character */
  81.     case LM_C:              /* LM_C's can't start label */
  82.     label[31] = YES;        /* bad label char in label field */
  83.     case LIM_C:
  84.     field_ptr = sbuf_ptr - 1;    /* nextc already inc. sbuf_ptr */
  85.     ++field_len;            /* got 1 so far */
  86.     state = LBL;            /* enter LBL state */
  87.     break;
  88.     case WS_C:
  89.     field_ptr = nextfield(&sbuf_ptr);    /* skip the white space */
  90.     if (*field_ptr == '*' || *field_ptr == '\n') {
  91.         opfld_ptr = statement;        /* operands or comment */
  92.         return COMMENT;
  93.     }
  94.     state = LIM;
  95.     break;                    /* try again */
  96.     }
  97.  
  98. /* LBL state */
  99.  
  100.     while (state == LBL) {
  101.     switch(nextc(&sbuf_ptr)) {
  102.     case ILGL_C:
  103.         label[31] = YES;            /* got a bad char */
  104.     case LIM_C:
  105.     case LM_C:
  106.         ++field_len;            /* one more label char */
  107.         continue;                /* still in LBL state */
  108.     case STMEND_C:
  109.         state = STOP;
  110.     case LBLTRM_C:                /* label ended... */
  111.     case WS_C:
  112.         savefield(field_ptr, field_len, label); /* save the label */
  113.         if (state != STOP) {
  114.         field_len = NULL;            /* starting    fresh */
  115.         field_ptr = nextfield(&sbuf_ptr);   /* get a new field */
  116. /**f3*/        state = (*field_ptr == '*') ? STOP : LIM;
  117.         }
  118.     }
  119.     }
  120.  
  121. /* LIM state */
  122.  
  123.     while (state == LIM) {
  124.     switch(nextc(&sbuf_ptr)) {
  125.     case LM_C:
  126.     case LIM_C:
  127.         ++field_len;
  128.         continue;                /* try another */
  129.     case STMEND_C:
  130.     case WS_C:
  131.         state = STOP;
  132.         savefield(field_ptr, field_len,    instr);    /* save legal instr */
  133.         instr[31] = bad_field;
  134.         break;
  135.     case LBLTRM_C:
  136.         savefield(field_ptr, field_len,    label);    /* save label */
  137.         label[31] = bad_field;
  138.         bad_field = field_len = NULL;        /* going for instr */
  139.         field_ptr = nextfield(&sbuf_ptr);    /* look for it */
  140.         continue;                /* still LIM state */
  141.     case ILGL_C:
  142.         bad_field = YES;            /* bad char */
  143.         ++field_len;
  144.         continue;                /* try another */
  145.     }
  146.     }
  147.  
  148.  
  149. /* STOP state */
  150.  
  151.     nextfield(&sbuf_ptr);                /* get to next field */
  152.     opfld_ptr =  sbuf_ptr;                /* operands    or comment */
  153.     return OK;
  154. }
  155.  
  156. /* return type of char pointed to, bump pointer    */
  157.  
  158. nextc(ptr)
  159. register char **ptr;
  160. {
  161.     register char c;
  162.  
  163.     c = *(*ptr)++;  /* get the buf ptr, post inc., get char it points to */
  164.     if (isalpha(c) || (c == '.'))
  165.     return LIM_C;
  166.     if (isdigit(c) || (c == '_') || (c == '$'))
  167.     return LM_C;            /** || (c == '-') ??? **/
  168.     switch (c) {
  169.     case '\n':  return STMEND_C;
  170.     case ' ':
  171.     case '\t':  return WS_C;
  172.     case ':':   return LBLTRM_C;
  173.     case '*':   return CMNT_C;
  174.     default:    return ILGL_C;
  175.     }
  176. }
  177.  
  178. /* align pointer on next char other than ' ' or '\t' */
  179.  
  180. char *nextfield(ptr)
  181. register char **ptr;
  182. {
  183.     if (!**ptr)    return --(*ptr);
  184.     while                /* skips too much...? */
  185.     /*if*/ ((**ptr == ' ') || (**ptr == '\t'))
  186.     ++(*ptr);            /* bump buf ptr ???*/
  187.     return *ptr;            /* value of ptr ???*/
  188. }
  189.  
  190. /***
  191.     get a line of text into statement.    Allows nesting of source files and
  192.     input from stdin.
  193. ***/
  194.  
  195. char *
  196. nextline()
  197. {                        /* get a line into buffer */
  198.     while (!fgets(statement, STMNT_SIZE, _src[src_level])) {
  199.     if (src_level) {            /* in an included file */
  200.         fclose(_src[src_level--]);        /* close file, pop stack */
  201.         continue;                /* try level above */
  202.     }   
  203.     if (++pass > 2) return NULL;        /* end second pass main file */
  204.     loc_counter = loc_plus = 0;         /* set counter to default */
  205.     line_count = 0;             /* rewind for second pass */
  206.     for ( ; src_level; fclose(_src[src_level--]));/* close include files */
  207.     fseek(_src[0], 0L, 0);          /* rewind the source file */
  208.     /* err_out(FLUSH); */            /* get rid of pending errors */
  209.     continue;                /* start second pass */
  210.     }
  211.     ++line_count;                /* count the line */
  212.     return statement;                /* anything    but NULL would work */
  213. }
  214.  
  215. /* save the field pointed to by ptr, max field length is 30 + NULL */
  216.  
  217. savefield(ptr, len, dest)
  218. register char *ptr;
  219. int len;
  220. register char *dest;
  221. {
  222.     register int x;
  223.     for (x = 30; x && len; --x, --len)        /* dec. x and len each time */
  224.     *dest++    = *ptr++;
  225.     *dest = '\0';            /* terminate string */
  226. }
  227.  
  228. /*** aztec can't...
  229. #undef START
  230. #undef LBL
  231. #undef LIM
  232. #undef STOP
  233.  
  234. #undef LIM_C
  235. #undef LM_C
  236. #undef LBLTRM_C
  237. #undef WS_C
  238. #undef STMEND_C
  239. #undef CMNT_C
  240. #undef ILGL_C
  241. ***/                            /* end of preparse() */
  242.  
  243. /***
  244.     send data for present line here, dump when appropriate
  245.  
  246. line format:
  247.  
  248.      1         2         3         4     5         6         7
  249. 1234567890123456789012345678901234567890123456789012345678901234567890123456789
  250. |  | |    | |  | |       | |       |     |     | |             | |            |
  251. line locval opcd 1st  word 2nd  word     instrct operand field.. .comment field
  252.  
  253. 1234 123456 1234 1234 1234 1234 1234    123456789223456789323456789423456789...
  254.        [---- ---- ---- ---- ----]    [-----------------------------------..]
  255.  
  256. ***/
  257.  
  258. /*
  259.     raw code is sent here as it is produced by the system. this
  260.     function will send it to appropriate places, in the correct    form.
  261. */
  262. /* send buffer to all open list channels */
  263.  
  264. list_dump(buf)
  265. char *buf;
  266. {
  267.     if (nolist)    return;
  268.     if (lcon) puts(buf);
  269.     if (llst) fputs(buf, lst_d);
  270.     if (lfile) fputs(buf, lst_f);
  271. }
  272.  
  273. obj_out(action,    cdp, size)
  274. int action;
  275. char *cdp;
  276. int size;
  277. {
  278.     register int y;
  279.     extern long s_lc;
  280.     extern char s_buf[48];    /* init first char, room to spare */
  281.     extern int s_cnt;        /* bytes in current buffer */
  282.     extern int s_x;        /* index into s_buf */
  283.  
  284.     if (!obj_open) return NULL;         /* put into obj file */
  285.     switch (action) {
  286.     case CODE:
  287.     case DATA:
  288.     s_lc = 0L;
  289.     case MDATA:
  290. top:
  291.     for (y = 0; size && (s_cnt < 16); --size,    ++s_cnt) {
  292. /**f4*/        lcksm += cdp[y++];                /* line checksum */
  293.     }
  294.     hex_byt(s_buf + s_x, cdp, y);            /* get them in buf */
  295.     s_x += y * 2;                     /* bump x */
  296.     s_lc += y;
  297.     if (s_cnt == 16) {                /* time to flush */
  298.         flush_rcrd(s_buf, s_cnt, s_x);
  299.         new_rcrd(s_buf, s_lc, &s_x);
  300.         s_cnt = 0;
  301.         if (size) {                 /* more to buffer */
  302.         cdp += y;                /* skip already    done */
  303.         goto top;
  304.         }
  305.     }
  306.     break;
  307.     case SYNC:
  308. /**f4*/    flush_rcrd(s_buf, s_cnt, s_x);        /* flush s_buf */
  309.     new_rcrd(s_buf,    0L, &s_x);
  310.     s_cnt = 0;
  311.     break;
  312.     case OPEN:
  313.     fputs("S0030000FC\n", obj_f);            /* header record */
  314. /**f4*/    new_rcrd(s_buf,    0L, &s_x);
  315.     s_cnt = 0;
  316.     break;
  317.     case CLOSE:
  318.     flush_rcrd(s_buf, s_cnt, s_x);        /* flush s_buf */
  319. /**f4*/    fputs("S9020000\n", obj_f);
  320. /**    fprintf(obj_f, "S9030000%02x\n", fcksm);*/
  321.     break;
  322.     case MSG:   break;
  323.     default:    return ERROR;
  324.     }
  325.     return NULL;
  326. }
  327.  
  328. new_rcrd(s_buf,    lc, x)
  329. char *s_buf;
  330. long lc;
  331. int *x;
  332. {
  333. /**f4*/
  334.     long temp;
  335.  
  336.     temp = loc_counter + lc;
  337.     if (temp & ~0xffffL) {
  338.     sprintf(s_buf + 1, "200%06lx", temp);
  339. /**f4?*/
  340.     lcksm = (temp >> 16) + (temp >> 8) + temp;
  341.     *x = 10;
  342.     }
  343.     else {
  344.     sprintf(s_buf + 1, "100%04lx", temp);
  345.     lcksm = (temp >> 8) + temp;
  346.     *x = 8;
  347.     }
  348. }
  349.  
  350. flush_rcrd(s_buf, cnt, x)
  351. char *s_buf;
  352. char cnt;
  353. char x;
  354. {
  355.     register char *c;
  356.  
  357.     if (!cnt) return NULL;            /* empty record */
  358. /** fixed 12/20/83 tnx m hitch */
  359.     cnt += 1 + ((s_buf[1] == '2') ? 3 : 2);    /* add byte count */
  360.     hex_byt(s_buf + 2, &cnt, 1);        /* place in s_buf */
  361.     lcksm = 0xff - (lcksm + cnt);        /* add checksum    */
  362.     hex_byt(&s_buf[x], &lcksm, 1);        /* place it in s_buf */
  363.     strcpy(&s_buf[x+2],    "\n");            /* terminate record */
  364. /** lc fix */
  365.     for (c = s_buf; *c; ++c)    /* some printf()'s make a-f lowercase  */
  366.     if (*c >= 'a' && *c <= 'f') *c -= ('a' - 'A');          
  367.     fputs(s_buf, obj_f);
  368.     return TRUE;
  369. }
  370.  
  371. /**
  372.     given a pointer to an array of bytes, convert each to a 2 byte
  373.     ascii rep, and place into char array pointed at by ap, for len
  374.     bytes
  375. **/
  376.  
  377. hex_byt(ap, bp, len)
  378. register unsigned char *ap;
  379. register unsigned char *bp;
  380. register int len;
  381. {
  382.     for ( ; len; --len, ++bp, ap += 2) {
  383.     ap[0] = (*bp >> 4) & 0x0f;
  384.     ap[0] += (ap[0] > 9) ? 55 : 48; /* ':' + ('A' - ':') : '0' */
  385.     ap[1] = *bp & 0x0f;
  386.     ap[1] += (ap[1] > 9) ? 55 : 48;
  387.     }
  388. }
  389.  
  390. /***
  391.     gets up to wrap - 40 chars from statement, places into buf.
  392. ***/
  393.  
  394. get_source(buf)
  395. register char *buf;
  396. {
  397.     register int size, cnt = 1;
  398.     int x;
  399.  
  400.     if ((stmnt_ptr != statement) && trunc) return (int)(buf[0] = '\0');
  401.     for (size = wrap - (40 + 1); --size; ++cnt) {
  402.     switch (*stmnt_ptr) {
  403.     case NULL:  return (int)(buf[0]    = '\0');
  404.     case '\n':
  405.         break;
  406.     case '\t':
  407.         size -= (x = 7 - (cnt % 8));    /* 7 'cause loop subs 1 */
  408.         if (size < 1) {             /* tab would overflow.. */
  409.         size = 1;            /* ..so cause exit without */
  410.         continue;            /* placing tab into buffer */
  411.         }
  412.         cnt += x;               /* fall thru to default */
  413.     default:
  414.         *buf++ = *stmnt_ptr++;
  415.         continue;
  416.     }
  417.     }
  418.     *buf++ = '\n';
  419.     *buf = '\0';
  420.     if (*stmnt_ptr == '\n') ++stmnt_ptr;    /* make NULL for next call */
  421.     return TRUE;
  422. }
  423.  
  424. /* endcode */
  425.  
  426.  
  427.