home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 190_01 / psdo.c < prev    next >
Text File  |  1985-11-14  |  11KB  |  514 lines

  1. /******************************************************************
  2.     psdo.c, the psdo op code for the as68 assembler.
  3. */
  4.  
  5. /*        (C) Copyright 1982 Steve Passe        */
  6. /*        All Rights Reserved                    */
  7.  
  8. /* version 1.00 */
  9. /* created 11/25/82 */
  10.  
  11. /* version 1.01
  12.  
  13.     8/30/83    ver. 1.01 modified for Aztec ver. 1.05g    smp
  14.     12/26/83    added include psdo    smp
  15.  
  16. */
  17.  
  18. /* begincode */
  19.  
  20. /* includes */
  21.  
  22. #define AZTECZII 1
  23.  
  24. #ifndef AZTECZII
  25. #include <stdio.h>
  26. #else
  27. #include "stdio.h"                                /* with aztecII compiler */
  28. #endif
  29. #include "b:as68.h"
  30.  
  31. /* externals */
  32.  
  33. extern char fatal;
  34. extern char pass;
  35. extern unsigned line_count;
  36. extern long loc_counter;
  37. extern int loc_plus;
  38. extern FLAG abs_long;
  39. extern FLAG rorg;
  40. extern FLAG do_label;
  41. extern char label[];
  42. extern char instr[];
  43. extern char code[];
  44. extern int src_level;
  45. extern FILE *_src[];
  46. extern char *opfld_ptr;
  47. extern struct _oprnd op1;
  48. extern struct _symbol *symtbl;
  49. extern FLAG nolist;
  50.  
  51. /*** note - external pseudo-op table is defined at the end of this file ***/
  52.  
  53. px_dc(psdo, arg)
  54. char *psdo;
  55. int arg;
  56. {
  57.     register int x;
  58.     int size, result, cx = 0;
  59.     int dmp_typ = DATA;
  60.  
  61.     for (x = 0; x < 12; code[x++] = 0)                /* clear code */
  62.         ;
  63.     size = arg;
  64.     x = 1;
  65. top:
  66.     result = eval(size, cx);                    /* while args are left */
  67.     if (x++ > 10/size) {                        /* line is full (code) */
  68.         if (pass == 2) {
  69.             dump_code(dmp_typ, code, cx);        /* dump code */
  70.             for (x = 0; x < size; ) code[x++] = code[cx++]; /* save xtra */
  71.             while (x < 12) code[x++] = 0;        /* clear rest of code */
  72.             dmp_typ = MDATA;
  73.         }
  74.         x = 2;                                    /* reset the indexes */
  75.         cx = 0;
  76.     }
  77.     switch (result) {
  78.     case _address:
  79.         loc_plus += size;
  80.         cx += size;                                    /* bump code index */
  81.         goto top;
  82.     case NULL:                                        /* no more operands */
  83.         if ((size == 1) && ((loc_counter + loc_plus) % 2)) { /* need to pad? */
  84.         /** look ahead for another dc.b, o joy! */
  85.             if (!moredcb()) {
  86.                 ++cx;                                /* pad code */
  87.                 ++loc_plus;                            /* bump loc */
  88.             }
  89.         }
  90.         if (pass == 2) {
  91.             if (cx) {                            /* addition since last dump */
  92.                 dump_code(dmp_typ, code, cx);        /* dump code */
  93.             }
  94.             dump_code(FLUSH, code, 0);                /* flush line */
  95.         }
  96.         return;
  97.     default:                                        /* error of somesort */
  98.         if (pass == 2) err_out(result);
  99.         loc_plus += size;
  100.         cx += size;                                    /* bump code index */
  101.         goto top;
  102.     }
  103. }
  104.  
  105. px_ds(psdo, arg)
  106. char *psdo;
  107. int arg;
  108. {
  109.     char size;                    /* default to word size (2 bytes) */
  110.     int cx = 0;
  111.  
  112.     size = arg;
  113.     if (eval(4, cx) == _address) {
  114. /**f4*/    if (pass == 2) dump_code(MSG, code, 4);
  115.         if (label[0] && do_label) label_do();
  116.         if (op1._addr) {
  117.             loc_counter += size * op1._addr;    /* add this much to loc */
  118.         }
  119.         else {                                    /* must be 0 */
  120.             if (loc_counter % 2) ++loc_counter;    /* for alignment purposes */
  121.         }
  122.         obj_out(SYNC, 0, 0);                    /* flush and new */
  123.         return OK;
  124.     }
  125.     else {
  126.         if (pass == 2) {
  127.             err_out(OPRND_EVAL);
  128.             dump_code(MSG, code, 4);
  129.         }
  130.         return ERROR;
  131.     }
  132. }
  133.  
  134. p1_equ(psdo, arg)
  135. char *psdo;
  136. int arg;
  137. {
  138.     do_label = NO;                        /* don't process label in main */
  139. /** need work here to signal second pass of problem */
  140.     if (eval(4, 0) != _address) return EQU_EVAL;        /* get a long value */
  141. /* determine whether to enter as absolute or relocatable from result */
  142.     if (symenter(label, op1._addr, (op1._rel_lbl) ? 'r' : 'a')
  143.         == ERROR) {
  144.         puts("\007\nsymbol table FULL!\007");
  145.         fatal = TRUE;                    /* mark a fatal system ERROR */
  146.         return SYMTFULL;
  147.     }
  148.     return OK;
  149. }
  150.  
  151. p2_equ(psdo, arg)
  152. char *psdo;
  153. int arg;
  154. {
  155.     register int x;
  156.     char acode[8];
  157.  
  158.     do_label = NO;                        /* don't process label in main */
  159.     if (x = symsearch(label)) {
  160.         if (symtbl[x]._atr & 4) {                /* redefined */
  161.             err_out(REDEF);
  162.         }
  163.     }
  164.     else {
  165.         err_out(UNDEF_SYMBOL);    /* label never defined */
  166.     }
  167.     code[0] = symtbl[x]._val >> 24;                /* evaluate operand */
  168.     code[1] = symtbl[x]._val >> 16;
  169.     code[2] = symtbl[x]._val >> 8;
  170.     code[3] = symtbl[x]._val;
  171.     dump_code(MSG, code, 4);                    /* a long value */
  172. }
  173.  
  174. p1_set(psdo, arg)
  175. char *psdo;
  176. int arg;
  177. {
  178.     do_label = NO;                        /* don't process label in main */
  179. /** need work here to signal second pass of problem */
  180.     if (eval(4, 0) != _address) return SET_EVAL;        /* get a long value */
  181. /* determine whether to enter as absolute or relocatable from result */
  182.     if (symadd(label, op1._addr, (op1._rel_lbl) ? 0x02 : 0, YES)
  183.         == ERROR) {
  184.         puts("\007\nsymbol table FULL!\007");
  185.         fatal = TRUE;                    /* mark a fatal system ERROR */
  186.         return SYMTFULL;
  187.     }
  188.     return OK;
  189. }
  190.  
  191. p2_set(psdo, arg)
  192. char *psdo;
  193. int arg;
  194. {
  195.     register int x;
  196.     char acode[8];
  197.  
  198.     do_label = NO;                        /* don't process label in main */
  199.     if (eval(4, 0) != _address) err_out(SET_EVAL);        /* get a long value */
  200.     else {
  201.         if (x = symsearch(label)) {
  202.             if (symtbl[x]._atr & 1) {                /* redefined */
  203.                 err_out(REDEF);
  204.             }
  205.             else {
  206.                 symtbl[x]._val = op1._addr;
  207.                 symtbl[x]._atr |= (op1._rel_lbl) ? 0x02 : 0;
  208.             }
  209.         }
  210.         else {
  211.             err_out(UNDEF_SYMBOL);    /* label never defined */
  212.         }
  213.     }
  214.     code[0] = symtbl[x]._val >> 24;                /* evaluate operand */
  215.     code[1] = symtbl[x]._val >> 16;
  216.     code[2] = symtbl[x]._val >> 8;
  217.     code[3] = symtbl[x]._val;
  218.     dump_code(MSG, code, 4);                    /* a long value */
  219. }
  220.  
  221. px_orgx(psdo, arg)
  222. char *psdo;
  223. int arg;
  224. {
  225.     int size;
  226.     long mask;
  227.  
  228.     size = (arg % 2) ? 2 : 4;                    /* long or short org */
  229.     if (size == 2) mask = ~0xffffL;
  230.     else mask = ~0xffffffL;
  231.     if (pass == 2 && label[0]) {
  232.         err_out(LABEL_USE);                        /* labels not allowed */
  233.     }
  234.     if (eval(size, 0) == _address) {            /* should be type _address */
  235.         if (op1._addr & mask) {    /* range */
  236.             if (pass == 2) {
  237.                 err_out(LBL_RANGE);                /* fails range test */
  238.                 dump_code(MSG, code, size);
  239.             }
  240.             return ERROR;
  241.         }
  242.         else {
  243.             loc_counter = op1._addr;
  244.             if (pass == 2) {
  245.                 obj_out(SYNC, 0, 0);
  246.                 dump_code(MSG, code, size);
  247.             }
  248.             abs_long = (size == 2) ? NO : YES;
  249.             rorg = (arg > 2) ? YES : NO;
  250.             return OK;
  251.         }
  252.     }
  253.     if (pass == 2) {
  254.         err_out(OPRND_EVAL);
  255.         dump_code(MSG, code, 0);
  256.     }
  257.     return ERROR;
  258. }
  259.  
  260. px_end(psdo, arg)    /* close include file(s), rewind source */
  261. char *psdo;
  262. int arg;
  263. {
  264.     for ( ; src_level; fclose(_src[src_level--]));    /* close include files */
  265.     fseek(_src[0], 0L, 0);                            /* rewind the source */
  266.     if (pass == 2 && label[0]) err_out(LABEL_USE);
  267.     if (pass++ == 2) {
  268.         obj_out(CLOSE, 0, 0);
  269.         dump_code(MSG, code, 0);
  270.     }
  271.     loc_counter = loc_plus = line_count = 0;
  272.     abs_long = YES;
  273.     rorg = NO;
  274. }
  275.  
  276. px_incl(psdo, arg)
  277. char *psdo;
  278. int arg;
  279. {
  280.     char name[FNAME_SIZE];
  281.  
  282.     word_copy(name, FNAME_SIZE, opfld_ptr);            /* get filename */
  283.     if (!(_src[++src_level] = fopen(name, "r"))) {
  284.         --src_level;                                /* backup */
  285.         err_out(INCL_OPEN);                            /* report it */
  286.     }
  287.     if (pass == 2) {
  288.         dump_code(MSG, code, 0);
  289.     }
  290. }
  291.  
  292. p1_ifeq(psdo, arg)
  293. char *psdo;
  294. int arg;
  295. {
  296. }
  297.  
  298. p2_ifeq(psdo, arg)
  299. char *psdo;
  300. int arg;
  301. {
  302. err_out(UNREC_INSTR);
  303.     if (label[0]) err_out(LABEL_USE);
  304.     dump_code(MSG, code, 0);
  305. }
  306.  
  307. p1_ifne(psdo, arg)
  308. char *psdo;
  309. int arg;
  310. {
  311. }
  312.  
  313. p2_ifne(psdo, arg)
  314. char *psdo;
  315. int arg;
  316. {
  317. err_out(UNREC_INSTR);
  318.     if (label[0]) err_out(LABEL_USE);
  319.     dump_code(MSG, code, 0);
  320. }
  321.  
  322. p1_endc(psdo, arg)
  323. char *psdo;
  324. int arg;
  325. {
  326. }
  327.  
  328. p2_endc(psdo, arg)
  329. char *psdo;
  330. int arg;
  331. {
  332. err_out(UNREC_INSTR);
  333.     if (label[0]) err_out(LABEL_USE);
  334.     dump_code(MSG, code, 0);
  335. }
  336.  
  337. p2_xlst(psdo, arg)
  338. char *psdo;
  339. int arg;
  340. {
  341.     nolist = (*psdo == 'n');
  342. }
  343.  
  344. no_action(psdo, arg)
  345. char *psdo;
  346. int arg;
  347. {
  348.     return OK;    /* no action required! */
  349. }
  350.  
  351. eval(size, cx)
  352. int size;
  353. int cx;
  354. {
  355.     static FLAG ascii_mode = NO;
  356.     register int x, y;
  357.     int result;
  358.  
  359. top:
  360.     if (!*opfld_ptr || *opfld_ptr == '\n') return NULL;
  361.     if (!ascii_mode) {
  362.         switch (*opfld_ptr) {
  363.         case '\t':
  364.         case ' ':
  365.             return NULL;
  366.         case '\'':
  367.             ++opfld_ptr;
  368.             ascii_mode = YES;
  369.             break;
  370.         case ',':
  371.             ++opfld_ptr;
  372.             goto top;
  373.         }
  374.     }
  375.     if (ascii_mode) {
  376.         op1._addr = 0L;
  377.         op1._rel_lbl = NO;
  378.         for (y = 0; y < size; ++y) {
  379.             if (*opfld_ptr == '\'') {
  380.                 ++opfld_ptr;                    /* pass it */
  381.                 if (*opfld_ptr != '\'') {        /* end of ascii str */
  382.                     ascii_mode = NO;
  383.                     if (y == 0) goto top;        /* first char was end */
  384.                     return _address;
  385.                 }
  386.             }
  387.             op1._addr *= 256;
  388.             op1._addr += *opfld_ptr;
  389.             code[cx++] = *opfld_ptr++;
  390.         }
  391.         return _address;
  392.     }
  393.     switch (result = op_eval(&op1)) {
  394.     case _address:
  395.         switch (size) {
  396.         case 4:
  397.             code[cx++] = op1._addr >> 24;
  398.             code[cx++] = op1._addr >> 16;
  399.         case 2:
  400.             code[cx++] = op1._addr >> 8;
  401.         case 1:
  402.             code[cx] = op1._addr;
  403.         }
  404.         return _address;
  405.     case _none:
  406.         return NULL;
  407.     default:
  408.         return OPRND_EVAL;
  409.     }
  410. }
  411.  
  412. /** look at next line to determine if it is a 'dc.b' statement
  413.     if "dc.b" or "dcb.b" exists in comment field this will fail,
  414.     also, if at end of included file and next statement of next
  415.     layer is a dc.b it will fail...
  416. */
  417.  
  418. moredcb()
  419. {
  420.     long place, ftell();
  421.     int answer = NO;
  422.     char tbuf[STMNT_SIZE];
  423.  
  424.     place = ftell(_src[src_level]);                /* present position */
  425.     if (fgets(tbuf, STMNT_SIZE, _src[src_level])) {/* get next statement */
  426.         if (token(tbuf, "dc.b") || token(tbuf, "dcb.b")) answer = YES;
  427.     }
  428.     fseek(_src[src_level], place, 0);            /* get back to last line */
  429.     return answer;
  430. }
  431.  
  432. token(str, tkn)
  433. char *str;
  434. char *tkn;
  435. {
  436.     register char *x;
  437.     register char *y;
  438.  
  439.     for ( ; *str; ++str) {
  440.         if (tolower(*str) == *tkn) {
  441.             x = str+1;
  442.             y = tkn+1;
  443.             while (TRUE) {
  444.                 if (!*y) return str;
  445.                 if (tolower(*x++) != *y++) break;
  446.             }
  447.         }
  448.     }
  449.     return NULL;
  450. }
  451.  
  452. #define PTSIZE 21                /* number of structures in pseudo-op table */
  453.  
  454. struct _ptable ptable[PTSIZE] = {
  455.      "dc",        px_dc,        px_dc,        2,
  456.      "dc.b",    px_dc,        px_dc,        1,
  457.      "dc.l",    px_dc,        px_dc,        4,
  458.      "dc.w",    px_dc,        px_dc,        2,
  459. /**
  460.      "dcb",        px_dcb,        px_dcb,        2,
  461.      "dcb.b",    px_dcb,        px_dcb,        1,
  462.      "dcb.l",    px_dcb,        px_dcb,        4,
  463.      "dcb.w",    px_dcb,        px_dcb,        2,
  464. **/
  465.      "ds",        px_ds,        px_ds,        2,
  466.      "ds.b",    px_ds,        px_ds,        1,
  467.      "ds.l",    px_ds,        px_ds,        4,
  468.      "ds.w",    px_ds,        px_ds,        2,
  469.      "end",        px_end,        px_end,        NULL,
  470.      "endc",    p1_endc,    p2_endc,    NULL,
  471.      "equ",        p1_equ,        p2_equ,        NULL,
  472.      "ifeq",    p1_ifeq,    p2_ifeq,    NULL,
  473.      "ifne",    p1_ifne,    p2_ifne,    NULL,
  474.      "include", px_incl,    px_incl,    NULL,
  475.      "list",    no_action,    p2_xlst,    NULL,
  476.      "nolist",    no_action,    p2_xlst,    NULL,
  477.      "org",        px_orgx,    px_orgx,    1,
  478.      "org.l",    px_orgx,    px_orgx,    2,
  479.      "rorg",    px_orgx,    px_orgx,    3,
  480.      "rorg.l",    px_orgx,    px_orgx,    4,
  481.      "set",        p1_set,        p2_set,        NULL
  482. };
  483.  
  484. /** search the pseudo-op table for "psdo"
  485.     return pointer to struct of type _ptable.
  486. */
  487.  
  488. struct _ptable *
  489. psdosearch(psdo)
  490. char *psdo;
  491. {
  492.     register int result;
  493.     struct _ptable *bottom = &ptable[0];
  494.     struct _ptable *top = &ptable[PTSIZE - 1];
  495.     struct _ptable *middle;
  496.  
  497.     if (strlen(psdo) > 7) return NULL;
  498.  
  499.     while (bottom <= top) {
  500.         middle = bottom + (top - bottom) / 2;
  501.         if ((result = a1strcmp(psdo, middle->_psdo)) < 0)
  502.             top = middle - 1;
  503.         else if (result > 0)
  504.             bottom = middle + 1;
  505.         else return middle;
  506.     }
  507.     return NULL;
  508. }
  509.  
  510. /* endcode */
  511.     px_end,        px_end,        NULL,
  512.      "endc",    p1_endc,    p2_endc,    NULL,
  513.      "equ",        p1_equ,        p2_equ,        NULL,
  514.      "ifeq",    p