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

  1. /* psdo.c, the psdo op code for the as68 assembler. (root part)
  2.  * 
  3.  *    (C) Copyright 1982 Steve Passe
  4.  *    All Rights Reserved
  5.  * 
  6.  * version 1.00
  7.  * created 11/25/82
  8.  * 
  9.  * version 1.01
  10.  * 
  11.  *    8/30/83 ver. 1.01 modified for Aztec ver. 1.05g smp
  12.  *    12/26/83    added include psdo  smp
  13.  * 
  14.  */
  15.  
  16. /* begincode */
  17.  
  18. /* includes */
  19.  
  20. #include <stdio.h>
  21. #include "as68.h"
  22.  
  23. /* externals */
  24.  
  25. extern char fatal;
  26. extern char pass;
  27. extern unsigned    line_count;
  28. extern long loc_counter;
  29. extern int loc_plus;
  30. extern FLAG abs_long;
  31. extern FLAG rorg;
  32. extern FLAG do_label;
  33. extern char label[];
  34. extern char instr[];
  35. extern char code[];
  36. extern int src_level;
  37. extern FILE *_src[];
  38. extern char *opfld_ptr;
  39. extern struct _oprnd op1;
  40. extern struct _symbol *symtbl;
  41. extern FLAG nolist;
  42.  
  43. /* types */
  44.  
  45. char *token();
  46.  
  47. /*** note - external pseudo-op table is defined    at the end of this file ***/
  48.  
  49. px_dc(psdo, arg)
  50. char *psdo;
  51. int arg;
  52. {
  53.     register int x;
  54.     register int size, result, cx = 0;
  55.     int dmp_typ    = DATA;
  56.  
  57.     for (x = 0; x < 12; code[x++] = 0)          /* clear code */
  58.     ;
  59.     size = arg;
  60.     x = 1;
  61. top:
  62.     result = eval(size,    cx);            /* while args are left */
  63.     if (x++ > 10/size) {            /* line is full (code) */
  64.     if (pass == 2) {
  65.         dump_code(dmp_typ, code, cx);    /* dump code */
  66.         for (x = 0; x < size; ) code[x++] = code[cx++]; /* save xtra */
  67.         while (x < 12) code[x++] = 0;    /* clear rest of code */
  68.         dmp_typ = MDATA;
  69.     }
  70.     x = 2;                  /* reset the indexes */
  71.     cx = 0;
  72.     }
  73.     switch (result) {
  74.     case _address:
  75.     loc_plus += size;
  76.     cx += size;                    /* bump code index */
  77.     goto top;
  78.     case NULL:                      /* no more operands    */
  79. #ifdef AUTO_PAD
  80.     if ((size == 1) && ((loc_counter + loc_plus) % 2)) { /* need to pad? */
  81.     /** look ahead for another dc.b, o joy! */
  82.         if (!moredcb()) {
  83.         ++cx;                    /* pad code */
  84.         ++loc_plus;                /* bump loc */
  85.         }
  86.     }
  87. #endif /*AUTO_PAD*/
  88.     if (pass == 2) {
  89.         if (cx) {               /* addition since last dump */
  90.         dump_code(dmp_typ, code, cx);       /* dump code */
  91.         }
  92.         dump_code(FLUSH, code, 0);          /* flush line */
  93.     }
  94.     return;
  95.     default:                        /* error of somesort */
  96.     if (pass == 2) err_out(result);
  97.     loc_plus += size;
  98.     cx += size;                    /* bump code index */
  99.     goto top;
  100.     }
  101. }
  102.  
  103. px_ds(psdo, arg)
  104. char *psdo;
  105. int arg;
  106. {
  107.     register int size;          /* default to word size (2 bytes) */
  108.     register int cx = 0;
  109.  
  110.     size = arg;
  111.     if (eval(4,    cx) == _address) {
  112. /**f4*/    if (pass == 2) dump_code(MSG, code, 4);
  113.     if (label[0] && do_label) label_do();
  114.     if (op1._addr) {
  115.         loc_counter    += size * op1._addr;    /* add this much to loc */
  116.     }
  117.     else {                  /* must be 0 */
  118.         if (loc_counter % 2) ++loc_counter;    /* for alignment purposes */
  119.     }
  120.     obj_out(SYNC, 0, 0);            /* flush and new */
  121.     return OK;
  122.     }
  123.     else {
  124.     if (pass == 2) {
  125.         err_out(OPRND_EVAL);
  126.         dump_code(MSG, code, 4);
  127.     }
  128.     return ERROR;
  129.     }
  130. }
  131.  
  132. px_orgx(psdo, arg)
  133. char *psdo;
  134. register int arg;
  135. {
  136.     register int size;
  137.     long mask;
  138.  
  139.     size = (arg % 2) ? 2 : 4;           /* long or short org */
  140.     if (size == 2) mask = ~0xffffL;
  141.     else mask = ~0xffffffL;
  142.     if (pass == 2 && label[0]) {
  143.     err_out(LABEL_USE);            /* labels not allowed */
  144.     }
  145.     if (eval(size, 0) == _address) {        /* should be type _address */
  146.     if (op1._addr & mask) { /* range */
  147.         if (pass == 2) {
  148.         err_out(LBL_RANGE);        /* fails range test */
  149.         dump_code(MSG, code, size);
  150.         }
  151.         return ERROR;
  152.     }
  153.     else {
  154.         loc_counter    = op1._addr;
  155.         if (pass == 2) {
  156.         obj_out(SYNC, 0, 0);
  157.         dump_code(MSG, code, size);
  158.         }
  159.         abs_long = (size == 2) ? NO : YES;
  160.         rorg = (arg > 2) ? YES : NO;
  161.         return OK;
  162.     }
  163.     }
  164.     if (pass == 2) {
  165.     err_out(OPRND_EVAL);
  166.     dump_code(MSG, code, 0);
  167.     }
  168.     return ERROR;
  169. }
  170.  
  171. px_end(psdo, arg)   /* close include file(s), rewind source */
  172. char *psdo;
  173. int arg;
  174. {
  175.     for ( ; src_level; fclose(_src[src_level--]));  /* close include files */
  176.     fseek(_src[0], 0L, 0);                /* rewind the source */
  177.     if (pass == 2 && label[0]) err_out(LABEL_USE);
  178.     if (pass++ == 2) {
  179.     obj_out(CLOSE, 0, 0);
  180.     dump_code(MSG, code, 0);
  181.     }
  182.     loc_counter    = loc_plus = line_count    = 0;
  183.     abs_long = YES;
  184.     rorg = NO;
  185. }
  186.  
  187. px_incl(psdo, arg)
  188. char *psdo;
  189. int arg;
  190. {
  191.     char name[FNAME_SIZE];
  192.  
  193.     word_copy(name, FNAME_SIZE,    opfld_ptr);        /* get filename */
  194.     if (!(_src[++src_level] = fopen(name, "r"))) {
  195.     --src_level;                    /* backup */
  196.     err_out(INCL_OPEN);                /* report it */
  197.     }
  198.     if (pass == 2) {
  199.     dump_code(MSG, code, 0);
  200.     }
  201. }
  202.  
  203. eval(size, cx)
  204. int size;
  205. register int cx;
  206. {
  207.     static FLAG ascii_mode = NO;
  208.     register int x, y;
  209.     int result;
  210.  
  211. top:
  212.     if (!*opfld_ptr || *opfld_ptr == '\n') return NULL;
  213.     if (!ascii_mode) {
  214.     switch (*opfld_ptr) {
  215.     case '\t':
  216.     case ' ':
  217.         return NULL;
  218.     case '\'':        /* ' starts an ASCII string */
  219.         ++opfld_ptr;
  220.         ascii_mode = YES;
  221.         break;
  222.     case ',':
  223.         ++opfld_ptr;
  224.         goto top;
  225.     }
  226.     }
  227.     if (ascii_mode) {
  228.     op1._addr = 0L;
  229.     op1._rel_lbl = NO;
  230.     for (y = 0; y < size; ++y) {
  231.         if (*opfld_ptr == '\'') {
  232.         ++opfld_ptr;            /* pass it */
  233.         if (*opfld_ptr != '\'') {    /* end of ascii str */
  234.             ascii_mode = NO;
  235.             if (y == 0) goto top;    /* first char was end */
  236.             return _address;
  237.         }
  238.         }
  239.         op1._addr *= 256;
  240.         op1._addr += *opfld_ptr;
  241.         code[cx++] = *opfld_ptr++;
  242.     }
  243.     return _address;
  244.     }
  245.     switch (result = op_eval(&op1)) {
  246.     case _address:
  247.     switch (size) {
  248.     case 4:
  249.         code[cx++] = op1._addr >> 24;
  250.         code[cx++] = op1._addr >> 16;
  251.     case 2:
  252.         code[cx++] = op1._addr >> 8;
  253.     case 1:
  254.         code[cx] = op1._addr;
  255.     }
  256.     return _address;
  257.     case _none:
  258.     return NULL;
  259.     default:
  260.     return OPRND_EVAL;
  261.     }
  262. }
  263.  
  264. #ifdef AUTO_PAD     /* This is REALLY messy - can't do it in the
  265.              * general case, and you really don't need it
  266.              * anyway. -srd 11-04-87
  267.              */
  268. /** look at next line to determine if it is a 'dc.b' statement
  269.     if "dc.b" or "dcb.b" exists in comment field this will fail,
  270.     also, if at end of included    file and next statement    of next
  271.     layer is a dc.b it will fail...
  272. */
  273.  
  274. moredcb()
  275. {
  276.     long place, ftell();
  277.     int answer = NO;
  278.     char tbuf[STMNT_SIZE];
  279.  
  280.     place = ftell(_src[src_level]);        /* present position */
  281.     if (fgets(tbuf, STMNT_SIZE,    _src[src_level])) {/* get next statement */
  282.     if (token(tbuf,    "dc.b")    || token(tbuf, "dcb.b")) answer = YES;
  283.     }
  284.     fseek(_src[src_level], place, 0);       /* get back to last line */
  285.     return answer;
  286. }
  287. #endif /*AUTO_PAD*/
  288.  
  289. char *token(str, tkn)
  290. register char *str;
  291. char *tkn;
  292. {
  293.     register char *x;
  294.     register char *y;
  295.  
  296.     for ( ; *str; ++str) {
  297.     if (tolower(*str) == *tkn) {    /* a clumsy 'strcmp' */
  298.         x = str+1;
  299.         y = tkn+1;
  300.         while (TRUE) {
  301.         if (!*y) return str;
  302.         if (tolower(*x) != *y) break;
  303.         x++;
  304.         y++;
  305.         }
  306.     }
  307.     }
  308.     return NULL;
  309. }
  310.  
  311. #define    PTSIZE 21        /* number of structures    in pseudo-op table */
  312.  
  313. p1_endc(), p2_endc(),        /* declare the fcns moved to overlays */
  314. p1_equ(), p2_equ(),
  315. p1_ifeq(), p2_ifeq(),
  316. p1_ifne(), p2_ifne(),
  317. no_action(), p2_xlst(),
  318. p1_set(), p2_set();
  319.  
  320. struct _ptable ptable[PTSIZE] = {
  321.      "dc",    px_dc,        px_dc,    2,
  322.      "dc.b",    px_dc,        px_dc,    1,
  323.      "dc.l",    px_dc,        px_dc,    4,
  324.      "dc.w",    px_dc,        px_dc,    2,
  325. /**
  326.      "dcb",    px_dcb,        px_dcb,    2,
  327.      "dcb.b",    px_dcb,        px_dcb,    1,
  328.      "dcb.l",    px_dcb,        px_dcb,    4,
  329.      "dcb.w",    px_dcb,        px_dcb,    2,
  330. **/
  331.      "ds",    px_ds,        px_ds,    2,
  332.      "ds.b",    px_ds,        px_ds,    1,
  333.      "ds.l",    px_ds,        px_ds,    4,
  334.      "ds.w",    px_ds,        px_ds,    2,
  335.      "end",    px_end,        px_end,    NULL,
  336.      "endc",    p1_endc,    p2_endc,    NULL,
  337.      "equ",    p1_equ,        p2_equ,    NULL,
  338.      "ifeq",    p1_ifeq,    p2_ifeq,    NULL,
  339.      "ifne",    p1_ifne,    p2_ifne,    NULL,
  340.      "include",    px_incl,    px_incl,    NULL,
  341.      "list",    no_action,  p2_xlst,    NULL,
  342.      "nolist",    no_action,  p2_xlst,    NULL,
  343.      "org",    px_orgx,    px_orgx,    1,
  344.      "org.l",    px_orgx,    px_orgx,    2,
  345.      "rorg",    px_orgx,    px_orgx,    3,
  346.      "rorg.l",    px_orgx,    px_orgx,    4,
  347.      "set",    p1_set,        p2_set,    NULL
  348. };
  349.  
  350. /** search the pseudo-op table for "psdo"
  351.     return pointer to struct of type _ptable.
  352. */
  353.  
  354. struct _ptable *
  355. psdosearch(psdo)
  356. char *psdo;
  357. {
  358.     register int result;
  359.     register struct _ptable *bottom = &ptable[0];
  360.     register struct _ptable *top = &ptable[PTSIZE - 1];
  361.     register struct _ptable *middle;
  362.  
  363.     if (strlen(psdo) > 7) return NULL;
  364.  
  365.     while (bottom <= top) {
  366.     middle = bottom + (top - bottom) / 2;
  367.     if ((result = a1strcmp(psdo, middle->_psdo)) < 0)
  368.         top = middle - 1;
  369.     else if (result    > 0)
  370.         bottom = middle + 1;
  371.     else return middle;
  372.     }
  373.     return NULL;
  374. }
  375. /* endcode */
  376.  
  377.