home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff287.lzh / DAsm / src / ops.c < prev    next >
C/C++ Source or Header  |  1989-12-06  |  21KB  |  1,082 lines

  1.  
  2. /*
  3.  *  OPS.C
  4.  *
  5.  *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  Handle mnemonics and pseudo ops
  8.  *
  9.  */
  10.  
  11. #include "asm.h"
  12.  
  13. ubyte    Gen[256];
  14. ubyte    OrgFill = DEFORGFILL;
  15. short    Glen;
  16.  
  17. /*
  18.  *  An opcode modifies the SEGMENT flags in the following ways:
  19.  */
  20.  
  21. void
  22. v_processor(str, mne)
  23. register char *str;
  24. MNE *mne;
  25. {
  26.     extern MNE    Mne6502[];
  27.     extern MNE    Mne6803[];
  28.     extern MNE    MneHD6303[];
  29.     extern MNE    Mne68705[];
  30.     extern MNE    Mne68HC11[];
  31.     static int    called;
  32.  
  33.     if (called)
  34.     return;
  35.     called = 1;
  36.     if (strcmp(str,"6502") == 0) {
  37.     addhashtable(Mne6502);
  38.     MsbOrder = 0;       /*  lsb,msb */
  39.     Processor = 6502;
  40.     }
  41.     if (strcmp(str,"6803") == 0) {
  42.     addhashtable(Mne6803);
  43.     MsbOrder = 1;       /*  msb,lsb */
  44.     Processor = 6803;
  45.     }
  46.     if (strcmp(str,"HD6303") == 0 || strcmp(str, "hd6303") == 0) {
  47.     addhashtable(Mne6803);
  48.     addhashtable(MneHD6303);
  49.     MsbOrder = 1;       /*  msb,lsb */
  50.     Processor = 6303;
  51.     }
  52.     if (strcmp(str,"68705") == 0) {
  53.     addhashtable(Mne68705);
  54.     MsbOrder = 1;       /*  msb,lsb */
  55.     Processor = 68705;
  56.     }
  57.     if (strcmp(str,"68HC11") == 0 || strcmp(str, "68hc11") == 0) {
  58.     addhashtable(Mne68HC11);
  59.     MsbOrder = 1;       /*  msb,lsb */
  60.     Processor = 6811;
  61.     }
  62.     if (!Processor)
  63.     asmerr(20,1);
  64. }
  65.  
  66. #define badcode(mne,adrmode)  (!(mne->okmask & (1L << adrmode)))
  67.  
  68. void
  69. v_mnemonic(str, mne)
  70. char *str;
  71. register MNE *mne;
  72. {
  73.     register uword addrmode;
  74.     register SYMBOL *sym;
  75.     register uword opcode;
  76.     short opidx;
  77.     SYMBOL *symbase;
  78.     short   opsize;
  79.  
  80.     Csegment->flags |= SF_REF;
  81.     programlabel();
  82.     symbase = eval(str);
  83.  
  84.     if (Xtrace)
  85.     printf("PC: %04lx  MNE: %s  addrmode: %d  ", Csegment->org, mne->name, symbase->addrmode);
  86.     for (sym = symbase; sym; sym = sym->next) {
  87.     if (sym->flags & SYM_UNKNOWN) {
  88.         ++Redo;
  89.         Redo_why |= 1 << 0;
  90.     }
  91.     }
  92.     sym = symbase;
  93.  
  94.     if (mne->flags & MF_IMOD) {
  95.     if (sym->next) {
  96.         sym->addrmode = AM_BITMOD;
  97.         if ((mne->flags & MF_REL) && sym->next)
  98.         sym->addrmode = AM_BITBRAMOD;
  99.     }
  100.     }
  101.     addrmode = sym->addrmode;
  102.     if ((sym->flags & SYM_UNKNOWN) || sym->value >= 0x100)
  103.     opsize = 2;
  104.     else
  105.     opsize = (sym->value) ? 1 : 0;
  106.     while (badcode(mne,addrmode) && Cvt[addrmode])
  107.     addrmode = Cvt[addrmode];
  108.     if (Xtrace)
  109.     printf("mnemask: %08lx adrmode: %d  Cvt[am]: %d\n", mne->okmask, addrmode, Cvt[addrmode]);
  110.     if (badcode(mne,addrmode)) {
  111.     asmerr(5,0);
  112.     freesymbollist(symbase);
  113.     return;
  114.     }
  115.     if (Mnext >= 0 && Mnext < NUMOC) {          /*  Force   */
  116.     addrmode = Mnext;
  117.     if (badcode(mne,addrmode)) {
  118.         asmerr(19,0);
  119.         freesymbollist(symbase);
  120.         return;
  121.     }
  122.     }
  123.     if (Xtrace)
  124.     printf("final addrmode = %d\n", addrmode);
  125.     while (opsize > Opsize[addrmode]) {
  126.     if (Cvt[addrmode] == 0 || badcode(mne,Cvt[addrmode])) {
  127.         if (sym->flags & SYM_UNKNOWN)
  128.         break;
  129.         asmerr(14,0);
  130.         break;
  131.     }
  132.     addrmode = Cvt[addrmode];
  133.     }
  134.     opcode = mne->opcode[addrmode];
  135.     opidx = 1 + (opcode > 0xFF);
  136.     if (opidx == 2) {
  137.     Gen[0] = opcode >> 8;
  138.     Gen[1] = opcode;
  139.     } else {
  140.     Gen[0] = opcode;
  141.     }
  142.     switch(addrmode) {
  143.     case AM_BITMOD:
  144.     sym = symbase->next;
  145.     if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
  146.         asmerr(14,0);
  147.     Gen[opidx++] = sym->value;
  148.     if (!(symbase->flags & SYM_UNKNOWN)) {
  149.         if (symbase->value > 7)
  150.         asmerr(15,0);
  151.         else
  152.         Gen[0] += symbase->value << 1;
  153.     }
  154.     break;
  155.     case AM_BITBRAMOD:
  156.     if (!(symbase->flags & SYM_UNKNOWN)) {
  157.         if (symbase->value > 7)
  158.         asmerr(15,0);
  159.         else
  160.         Gen[0] += symbase->value << 1;
  161.     }
  162.     sym = symbase->next;
  163.     if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
  164.         asmerr(14,0);
  165.     Gen[opidx++] = sym->value;
  166.     sym = sym->next;
  167.     break;
  168.     case AM_REL:
  169.     break;
  170.     default:
  171.     if (Opsize[addrmode] > 0)
  172.         Gen[opidx++] = sym->value;
  173.     if (Opsize[addrmode] == 2) {
  174.         if (MsbOrder) {
  175.         Gen[opidx-1] = sym->value >> 8;
  176.         Gen[opidx++] = sym->value;
  177.         } else {
  178.         Gen[opidx++] = sym->value >> 8;
  179.         }
  180.     }
  181.     sym = sym->next;
  182.     break;
  183.     }
  184.     if (mne->flags & MF_MASK) {
  185.     if (sym) {
  186.         if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
  187.         asmerr(14,0);
  188.         Gen[opidx] = sym->value;
  189.         sym = sym->next;
  190.     } else {
  191.         asmerr(16, 1);
  192.     }
  193.     ++opidx;
  194.     }
  195.     if ((mne->flags & MF_REL) || addrmode == AM_REL) {
  196.     ++opidx;        /*  to end of instruction   */
  197.     if (!sym)
  198.         asmerr(16, 1);
  199.     else
  200.     if (!(sym->flags & SYM_UNKNOWN)) {
  201.         long    pc;
  202.         ubyte   pcf;
  203.         long    dest;
  204.         pc = (Csegment->flags & SF_RORG) ? Csegment->rorg : Csegment->org;
  205.         pcf= (Csegment->flags & SF_RORG) ? Csegment->rflags : Csegment->flags;
  206.         if ((pcf & 3) == 0) {
  207.         dest = sym->value - pc - opidx;
  208.         if (dest >= 128 || dest < -128)
  209.             asmerr(10,0);
  210.         }
  211.         Gen[opidx-1] = dest & 0xFF;     /*    byte before end of inst.    */
  212.     }
  213.     }
  214.     Glen = opidx;
  215.     generate();
  216.     freesymbollist(symbase);
  217. }
  218.  
  219. void
  220. v_trace(str, mne)
  221. char *str;
  222. MNE *mne;
  223. {
  224.     if (str[1] == 'n')
  225.     Xtrace = 1;
  226.     else
  227.     Xtrace = 0;
  228. }
  229.  
  230. void
  231. v_list(str, mne)
  232. char *str;
  233. MNE *mne;
  234. {
  235.     programlabel();
  236.  
  237.     Glen = 0;        /*  Only so outlist() works */
  238.     if (strncmp(str, "off", 2) == 0 || strncmp(str, "OFF", 2) == 0)
  239.     ListMode = 0;
  240.     else
  241.     ListMode = 1;
  242. }
  243.  
  244. void
  245. v_include(str, mne)
  246. char *str;
  247. MNE *mne;
  248. {
  249.     char    *buf;
  250.  
  251.     programlabel();
  252.     if (*str == '\"') {
  253.     buf = (char *)malloc(strlen(str));
  254.     strcpy(buf, str+1);
  255.     for (str = buf; *str && *str != '\"'; ++str);
  256.     *str = 0;
  257.     pushinclude(buf);
  258.     free(buf);
  259.     } else {
  260.     pushinclude(str);
  261.     }
  262. }
  263.  
  264. void
  265. v_seg(str, mne)
  266. char *str;
  267. MNE *mne;
  268. {
  269.     register SEGMENT *seg;
  270.  
  271.     for (seg = Seglist; seg; seg = seg->next) {
  272.     if (strcmp(str, seg->name) == 0) {
  273.         Csegment = seg;
  274.         programlabel();
  275.         return;
  276.     }
  277.     }
  278.     Csegment = seg = (SEGMENT *)zmalloc(sizeof(SEGMENT));
  279.     seg->next = Seglist;
  280.     seg->name = (ubyte *)strcpy(malloc(strlen(str)+1), str);
  281.     seg->flags= seg->rflags = seg->initflags = seg->initrflags = SF_UNKNOWN;
  282.     Seglist = seg;
  283.     if (Mnext == AM_BSS)
  284.     seg->flags |= SF_BSS;
  285.     programlabel();
  286. }
  287.  
  288. void
  289. v_hex(str, mne)
  290. register char *str;
  291. MNE *mne;
  292. {
  293.     register int i;
  294.     register int result;
  295.  
  296.     programlabel();
  297.     Glen = 0;
  298.     for (i = 0; str[i]; ++i) {
  299.     if (str[i] == ' ')
  300.         continue;
  301.     result = (gethexdig(str[i]) << 4) + gethexdig(str[i+1]);
  302.     if (str[++i] == 0)
  303.         break;
  304.     Gen[Glen++] = result;
  305.     }
  306.     generate();
  307. }
  308.  
  309. int
  310. gethexdig(c)
  311. int c;
  312. {
  313.     if (c >= '0' && c <= '9')
  314.     return(c - '0');
  315.     if (c >= 'a' && c <= 'f')
  316.     return(c - 'a' + 10);
  317.     if (c >= 'A' && c <= 'F')
  318.     return(c - 'A' + 10);
  319.     asmerr(0,0);
  320.     puts("(Must be a valid hex digit)");
  321.     if (F_listfile)
  322.     fputs("(Must be a valid hex digit)\n", FI_listfile);
  323.     return(0);
  324. }
  325.  
  326. void
  327. v_err(str, mne)
  328. char *str;
  329. MNE *mne;
  330. {
  331.     programlabel();
  332.     asmerr(11, 1);
  333.     exit(1);
  334. }
  335.  
  336. void
  337. v_dc(str, mne)
  338. char *str;
  339. MNE *mne;
  340. {
  341.     register SYMBOL *sym;
  342.     register SYMBOL *tmp;
  343.     register ulong  value;
  344.     char *macstr;
  345.     char vmode = 0;
  346.  
  347.     Glen = 0;
  348.     programlabel();
  349.     if (mne->name[1] == 'v') {
  350.     register short i;
  351.     vmode = 1;
  352.     for (i = 0; str[i] && str[i] != ' '; ++i);
  353.     tmp = findsymbol(str, i);
  354.     str += i;
  355.     if (tmp == NULL) {
  356.         puts("EQM label not found");
  357.         return;
  358.     }
  359.     if (tmp->flags & SYM_MACRO) {
  360.         macstr = (char *)tmp->string;
  361.     } else {
  362.         puts("must specify EQM label for DV");
  363.         return;
  364.     }
  365.     }
  366.     sym = eval(str);
  367.     for (; sym; sym = sym->next) {
  368.     value = sym->value;
  369.     if (sym->flags & SYM_UNKNOWN) {
  370.         ++Redo;
  371.         Redo_why |= (1 << 2);
  372.     }
  373.     if (sym->flags & SYM_STRING) {
  374.         register ubyte *ptr = (ubyte *)sym->string;
  375.         while (value = *ptr) {
  376.         if (vmode) {
  377.             setspecial(value, 0);
  378.             tmp = eval(macstr);
  379.             value = tmp->value;
  380.             if (tmp->flags & SYM_UNKNOWN) {
  381.             ++Redo;
  382.             Redo_why |= (1 << 3);
  383.             }
  384.             freesymbollist(tmp);
  385.         }
  386.         switch(Mnext) {
  387.         default:
  388.         case AM_BYTE:
  389.             Gen[Glen++] = value & 0xFF;
  390.             break;
  391.         case AM_WORD:
  392.             if (MsbOrder) {
  393.             Gen[Glen++] = (value >> 8) & 0xFF;
  394.             Gen[Glen++] = value & 0xFF;
  395.             } else {
  396.             Gen[Glen++] = value & 0xFF;
  397.             Gen[Glen++] = (value >> 8) & 0xFF;
  398.             }
  399.             break;
  400.         case AM_LONG:
  401.             if (MsbOrder) {
  402.             Gen[Glen++] = (value >> 24)& 0xFF;
  403.             Gen[Glen++] = (value >> 16)& 0xFF;
  404.             Gen[Glen++] = (value >> 8) & 0xFF;
  405.             Gen[Glen++] = value & 0xFF;
  406.             } else {
  407.             Gen[Glen++] = value & 0xFF;
  408.             Gen[Glen++] = (value >> 8) & 0xFF;
  409.             Gen[Glen++] = (value >> 16)& 0xFF;
  410.             Gen[Glen++] = (value >> 24)& 0xFF;
  411.             }
  412.             break;
  413.         }
  414.         ++ptr;
  415.         }
  416.     } else {
  417.         if (vmode) {
  418.         setspecial(value, sym->flags);
  419.         tmp = eval(macstr);
  420.         value = tmp->value;
  421.         if (tmp->flags & SYM_UNKNOWN) {
  422.             ++Redo;
  423.             Redo_why |= 1 << 4;
  424.         }
  425.         freesymbollist(tmp);
  426.         }
  427.         switch(Mnext) {
  428.         default:
  429.         case AM_BYTE:
  430.         Gen[Glen++] = value & 0xFF;
  431.         break;
  432.         case AM_WORD:
  433.         if (MsbOrder) {
  434.             Gen[Glen++] = (value >> 8) & 0xFF;
  435.             Gen[Glen++] = value & 0xFF;
  436.         } else {
  437.             Gen[Glen++] = value & 0xFF;
  438.             Gen[Glen++] = (value >> 8) & 0xFF;
  439.         }
  440.         break;
  441.         case AM_LONG:
  442.         if (MsbOrder) {
  443.             Gen[Glen++] = (value >> 24)& 0xFF;
  444.             Gen[Glen++] = (value >> 16)& 0xFF;
  445.             Gen[Glen++] = (value >> 8) & 0xFF;
  446.             Gen[Glen++] = value & 0xFF;
  447.         } else {
  448.             Gen[Glen++] = value & 0xFF;
  449.             Gen[Glen++] = (value >> 8) & 0xFF;
  450.             Gen[Glen++] = (value >> 16)& 0xFF;
  451.             Gen[Glen++] = (value >> 24)& 0xFF;
  452.         }
  453.         break;
  454.         }
  455.     }
  456.     }
  457.     generate();
  458.     freesymbollist(sym);
  459. }
  460.  
  461. void
  462. v_ds(str, mne)
  463. char *str;
  464. MNE *mne;
  465. {
  466.     register SYMBOL *sym;
  467.     int mult = 1;
  468.     long filler = 0;
  469.  
  470.     if (Mnext == AM_WORD)
  471.     mult = 2;
  472.     if (Mnext == AM_LONG)
  473.     mult = 4;
  474.     programlabel();
  475.     if (sym = eval(str)) {
  476.     if (sym->next)
  477.         filler = sym->next->value;
  478.     if (sym->flags & SYM_UNKNOWN) {
  479.         ++Redo;
  480.         Redo_why |= 1 << 5;
  481.     } else {
  482.         if (sym->next && sym->next->flags & SYM_UNKNOWN) {
  483.         ++Redo;
  484.         Redo_why |= 1 << 5;
  485.         }
  486.         genfill(filler, sym->value, mult);
  487.     }
  488.     freesymbollist(sym);
  489.     }
  490. }
  491.  
  492. void
  493. v_org(str, mne)
  494. char *str;
  495. MNE *mne;
  496. {
  497.     register SYMBOL *sym;
  498.  
  499.     sym = eval(str);
  500.     Csegment->org = sym->value;
  501.     if (sym->flags & SYM_UNKNOWN)
  502.     Csegment->flags |= SYM_UNKNOWN;
  503.     else
  504.     Csegment->flags &= ~SYM_UNKNOWN;
  505.     if (Csegment->initflags & SYM_UNKNOWN) {
  506.     Csegment->initorg = sym->value;
  507.     Csegment->initflags = sym->flags;
  508.     }
  509.     if (sym->next) {
  510.     OrgFill = sym->next->value;
  511.     if (sym->next->flags & SYM_UNKNOWN)
  512.         asmerr(18,1);
  513.     }
  514.     programlabel();
  515.     freesymbollist(sym);
  516. }
  517.  
  518. void
  519. v_rorg(str, mne)
  520. char *str;
  521. MNE *mne;
  522. {
  523.     register SYMBOL *sym = eval(str);
  524.  
  525.     Csegment->flags |= SF_RORG;
  526.     if (sym->addrmode != AM_IMP) {
  527.     Csegment->rorg = sym->value;
  528.     if (sym->flags & SYM_UNKNOWN)
  529.         Csegment->rflags |= SYM_UNKNOWN;
  530.     else
  531.         Csegment->rflags &= ~SYM_UNKNOWN;
  532.     if (Csegment->initrflags & SYM_UNKNOWN) {
  533.         Csegment->initrorg = sym->value;
  534.         Csegment->initrflags = sym->flags;
  535.     }
  536.     }
  537.     programlabel();
  538.     freesymbollist(sym);
  539. }
  540.  
  541. void
  542. v_rend(str, mne)
  543. char *str;
  544. MNE *mne;
  545. {
  546.     programlabel();
  547.     Csegment->flags &= ~SF_RORG;
  548. }
  549.  
  550. void
  551. v_align(str, mne)
  552. char *str;
  553. MNE *mne;
  554. {
  555.     SYMBOL *sym = eval(str);
  556.     ubyte   fill = 0;
  557.     ubyte   rorg = Csegment->flags & SF_RORG;
  558.  
  559.     if (rorg)
  560.     Csegment->rflags |= SF_REF;
  561.     else
  562.     Csegment->flags |= SF_REF;
  563.     if (sym->next) {
  564.     if (sym->next->flags & SYM_UNKNOWN) {
  565.         ++Redo;
  566.         Redo_why |= 1 << 6;
  567.     } else {
  568.         fill = sym->value;
  569.     }
  570.     }
  571.     if (rorg) {
  572.     if ((Csegment->rflags | sym->flags) & SYM_UNKNOWN) {
  573.         ++Redo;
  574.         Redo_why |= 1 << 7;
  575.     } else {
  576.         register long n = sym->value - (Csegment->rorg % sym->value);
  577.         if (n != sym->value)
  578.         genfill(fill, n, 1);
  579.     }
  580.     } else {
  581.     if ((Csegment->flags | sym->flags) & SYM_UNKNOWN) {
  582.         ++Redo;
  583.         Redo_why |= 1 << 8;
  584.     } else {
  585.         register long n = sym->value - (Csegment->org % sym->value);
  586.         if (n != sym->value)
  587.         genfill(fill, n, 1);
  588.     }
  589.     }
  590.     freesymbollist(sym);
  591.     programlabel();
  592. }
  593.  
  594. void
  595. v_subroutine(str, mne)
  596. char *str;
  597. MNE *mne;
  598. {
  599.     Localindex = Incfile->lineno;
  600.     programlabel();
  601. }
  602.  
  603. void
  604. v_equ(str, mne)
  605. char *str;
  606. MNE *mne;
  607. {
  608.     SYMBOL *sym = eval(str);
  609.     SYMBOL *lab;
  610.  
  611.     lab = findsymbol(Av[0], strlen(Av[0]));
  612.     if (!lab)
  613.     lab = createsymbol(Av[0], strlen(Av[0]));
  614.     if (!(lab->flags & SYM_UNKNOWN)) {
  615.     if (sym->flags & SYM_UNKNOWN) {
  616.         ++Redo;
  617.         Redo_why |= 1 << 9;
  618.     } else {
  619.         if (lab->value != sym->value) {
  620.         asmerr(13,0);
  621.         printf("old value: $%04lx  new value: $%04lx\n", lab->value, sym->value);
  622.         ++Redo;
  623.         Redo_why |= 1 << 10;
  624.         }
  625.     }
  626.     }
  627.     lab->value = sym->value;
  628.     lab->flags = sym->flags & (SYM_UNKNOWN|SYM_STRING);
  629.     lab->string = sym->string;
  630.     sym->flags &= ~(SYM_STRING|SYM_MACRO);
  631.     freesymbollist(sym);
  632. }
  633.  
  634. void
  635. v_eqm(str, mne)
  636. char *str;
  637. MNE *mne;
  638. {
  639.     register SYMBOL *lab;
  640.     register int len = strlen(Av[0]);
  641.  
  642.     if (lab = findsymbol(Av[0], len)) {
  643.     if (lab->flags & SYM_STRING)
  644.         free(lab->string);
  645.     } else {
  646.     lab = createsymbol(Av[0], len);
  647.     }
  648.     lab->value = 0;
  649.     lab->flags = SYM_STRING | SYM_SET | SYM_MACRO;
  650.     lab->string = (ubyte *)strcpy(malloc(strlen(str)+1), str);
  651. }
  652.  
  653. void
  654. v_echo(str, mne)
  655. char *str;
  656. MNE *mne;
  657. {
  658.     SYMBOL *sym = eval(str);
  659.     SYMBOL *s;
  660.     char buf[256];
  661.  
  662.     for (s = sym; s; s = s->next) {
  663.     if (!(s->flags & SYM_UNKNOWN)) {
  664.         if (s->flags & (SYM_MACRO|SYM_STRING))
  665.         sprintf(buf,"%s", s->string);
  666.         else
  667.         sprintf(buf,"$%lx", s->value);
  668.         if (FI_listfile)
  669.         fprintf(FI_listfile, " %s", buf);
  670.         printf(" %s", buf);
  671.     }
  672.     }
  673.     puts("");
  674.     if (FI_listfile)
  675.     putc('\n', FI_listfile);
  676. }
  677.  
  678. void
  679. v_set(str, mne)
  680. char *str;
  681. MNE *mne;
  682. {
  683.     SYMBOL *sym = eval(str);
  684.     SYMBOL *lab;
  685.  
  686.     lab = findsymbol(Av[0], strlen(Av[0]));
  687.     if (!lab)
  688.     lab = createsymbol(Av[0], strlen(Av[0]));
  689.     lab->value = sym->value;
  690.     lab->flags = sym->flags & (SYM_UNKNOWN|SYM_STRING);
  691.     lab->string = sym->string;
  692.     sym->flags &= ~(SYM_STRING|SYM_MACRO);
  693.     freesymbollist(sym);
  694. }
  695.  
  696. void
  697. v_execmac(str, mac)
  698. char *str;
  699. MACRO *mac;
  700. {
  701.     register INCFILE *inc;
  702.     STRLIST *base;
  703.     register STRLIST **psl, *sl;
  704.     register char *s1;
  705.  
  706.     programlabel();
  707.  
  708.     if (Mlevel == MAXMACLEVEL) {
  709.     puts("infinite macro recursion");
  710.     return;
  711.     }
  712.     ++Mlevel;
  713.     base = (STRLIST *)malloc(strlen(str)+5);
  714.     base->next = NULL;
  715.     strcpy(base->buf, str);
  716.     psl = &base->next;
  717.     while (*str && *str != '\n') {
  718.     s1 = str;
  719.     while (*str && *str != '\n' && *str != ',')
  720.         ++str;
  721.     sl = (STRLIST *)malloc(5+(str-s1));
  722.     sl->next = NULL;
  723.     *psl = sl;
  724.     psl = &sl->next;
  725.     BMov(s1, sl->buf, (str-s1));
  726.     sl->buf[str-s1] = 0;
  727.     if (*str == ',')
  728.         ++str;
  729.     while (*str == ' ')
  730.         ++str;
  731.     }
  732.  
  733.     inc = (INCFILE *)zmalloc(sizeof(INCFILE));
  734.     inc->next = Incfile;
  735.     inc->name = mac->name;
  736.     inc->fi   = Incfile->fi;    /* garbage */
  737.     inc->lineno = 0;
  738.     inc->flags = INF_MACRO;
  739.     inc->saveidx = Localindex;
  740.     inc->strlist = mac->strlist;
  741.     inc->args     = base;
  742.     Incfile = inc;
  743.  
  744.     Localindex = 0;
  745. }
  746.  
  747. void
  748. v_end(str, mne)
  749. char *str;
  750. MNE *mne;
  751. {
  752.     puts("END not implemented yet");
  753. }
  754.  
  755. void
  756. v_endm(str, mne)
  757. char *str;
  758. MNE *mne;
  759. {
  760.     register INCFILE *inc = Incfile;
  761.     register STRLIST *args, *an;
  762.  
  763.     programlabel();
  764.     if (inc->flags & INF_MACRO) {
  765.     --Mlevel;
  766.     for (args = inc->args; args; args = an) {
  767.         an = args->next;
  768.         free(args);
  769.     }
  770.     Localindex = inc->saveidx;
  771.     Incfile = inc->next;
  772.     free(inc);
  773.     return;
  774.     }
  775.     puts("not within a macro");
  776. }
  777.  
  778. void
  779. v_mexit(str, mne)
  780. char *str;
  781. MNE *mne;
  782. {
  783.     v_endm(NULL,NULL);
  784. }
  785.  
  786. void
  787. v_ifconst(str, mne)
  788. char *str;
  789. MNE *mne;
  790. {
  791.     SYMBOL *sym;
  792.  
  793.     programlabel();
  794.     sym = eval(str);
  795.     pushif(sym->flags == 0);
  796.     freesymbollist(sym);
  797. }
  798.  
  799. void
  800. v_ifnconst(str, mne)
  801. char *str;
  802. MNE *mne;
  803. {
  804.     SYMBOL *sym;
  805.  
  806.     programlabel();
  807.     sym = eval(str);
  808.     pushif(sym->flags != 0);
  809.     freesymbollist(sym);
  810. }
  811.  
  812. void
  813. v_if(str, mne)
  814. char *str;
  815. MNE *mne;
  816. {
  817.     SYMBOL *sym;
  818.  
  819.     if (!Ifstack->true || !Ifstack->acctrue) {
  820.     pushif(0);
  821.     return;
  822.     }
  823.     programlabel();
  824.     sym = eval(str);
  825.     if (sym->flags) {
  826.     ++Redo;
  827.     Redo_why |= 1 << 11;
  828.     pushif(0);
  829.     Ifstack->acctrue = 0;
  830.     } else {
  831.     pushif((short)!!sym->value);
  832.     }
  833.     freesymbollist(sym);
  834. }
  835.  
  836. void
  837. v_else(str, mne)
  838. char *str;
  839. MNE *mne;
  840. {
  841.     if (Ifstack->acctrue && !(Ifstack->flags & IFF_BASE)) {
  842.     programlabel();
  843.     Ifstack->true = !Ifstack->true;
  844.     }
  845. }
  846.  
  847. void
  848. v_endif(str, mne)
  849. char *str;
  850. MNE *mne;
  851. {
  852.     IFSTACK *ifs = Ifstack;
  853.  
  854.     if (!(ifs->flags & IFF_BASE)) {
  855.     if (ifs->acctrue)
  856.         programlabel();
  857.     if (ifs->file != Incfile) {
  858.         puts("too many endif's");
  859.     } else {
  860.         Ifstack = ifs->next;
  861.         free(ifs);
  862.     }
  863.     }
  864. }
  865.  
  866. void
  867. v_repeat(str, mne)
  868. char *str;
  869. MNE *mne;
  870. {
  871.     register REPLOOP *rp;
  872.     register SYMBOL *sym;
  873.  
  874.     if (!Ifstack->true || !Ifstack->acctrue) {
  875.     pushif(0);
  876.     return;
  877.     }
  878.     programlabel();
  879.     sym = eval(str);
  880.     if (sym->value == 0) {
  881.     pushif(0);
  882.     freesymbollist(sym);
  883.     return;
  884.     }
  885.     rp = (REPLOOP *)zmalloc(sizeof(REPLOOP));
  886.     rp->next = Reploop;
  887.     rp->file = Incfile;
  888.     if (Incfile->flags & INF_MACRO)
  889.     rp->seek = (long)Incfile->strlist;
  890.     else
  891.     rp->seek = ftell(Incfile->fi);
  892.     rp->lineno = Incfile->lineno;
  893.     rp->count = sym->value;
  894.     if (rp->flags = sym->flags) {
  895.     ++Redo;
  896.     Redo_why |= 1 << 12;
  897.     }
  898.     Reploop = rp;
  899.     freesymbollist(sym);
  900.     pushif(1);
  901. }
  902.  
  903. void
  904. v_repend(str, mne)
  905. char *str;
  906. MNE *mne;
  907. {
  908.     if (!Ifstack->true || !Ifstack->acctrue) {
  909.     v_endif(NULL,NULL);
  910.     return;
  911.     }
  912.     if (Reploop && Reploop->file == Incfile) {
  913.     if (Reploop->flags == 0 && --Reploop->count) {
  914.         if (Incfile->flags & INF_MACRO)
  915.         Incfile->strlist = (STRLIST *)Reploop->seek;
  916.         else
  917.         fseek(Incfile->fi,Reploop->seek,0);
  918.         Incfile->lineno = Reploop->lineno;
  919.     } else {
  920.         rmnode((ulong **)&Reploop, sizeof(REPLOOP));
  921.         v_endif(NULL,NULL);
  922.     }
  923.     return;
  924.     }
  925.     puts("no repeat");
  926. }
  927.  
  928. static long Seglen;
  929. static long Seekback;
  930.  
  931. void
  932. generate()
  933. {
  934.     long seekpos;
  935.     static ulong org;
  936.     short i;
  937.  
  938.     if (!Redo) {
  939.     if (!(Csegment->flags & SF_BSS)) {
  940.         for (i = Glen - 1; i >= 0; --i)
  941.         CheckSum += Gen[i];
  942.         if (Fisclear) {
  943.         Fisclear = 0;
  944.         if (Csegment->flags & SF_UNKNOWN) {
  945.             ++Redo;
  946.             Redo_why |= 1 << 1;
  947.             return;
  948.         }
  949.         org = Csegment->org;
  950.         if (F_format < 3) {
  951.             putc((short)(org & 0xFF), FI_temp);
  952.             putc((short)((org >> 8) & 0xFF), FI_temp);
  953.             if (F_format == 2) {
  954.             Seekback = ftell(FI_temp);
  955.             Seglen = 0;
  956.             putc(0, FI_temp);
  957.             putc(0, FI_temp);
  958.             }
  959.         }
  960.         }
  961.         switch(F_format) {
  962.         default:
  963.         case 3:
  964.         case 1:
  965.         if (Csegment->org < org) {
  966.             printf("segment: %s %s  vs current org: %04lx\n", Csegment->name, sftos(Csegment->org, Csegment->flags), org);
  967.             asmerr(12, 1);
  968.             exit(1);
  969.         }
  970.         while (Csegment->org != org) {
  971.             putc(OrgFill, FI_temp);
  972.             ++org;
  973.         }
  974.         fwrite(Gen, Glen, 1, FI_temp);
  975.         break;
  976.         case 2:
  977.         if (org != Csegment->org) {
  978.             org = Csegment->org;
  979.             seekpos = ftell(FI_temp);
  980.             fseek(FI_temp, Seekback, 0);
  981.             putc((short)(Seglen & 0xFF), FI_temp);
  982.             putc((short)((Seglen >> 8) & 0xFF), FI_temp);
  983.             fseek(FI_temp, seekpos, 0);
  984.             putc((short)(org & 0xFF), FI_temp);
  985.             putc((short)((org >> 8) & 0xFF), FI_temp);
  986.             Seekback = ftell(FI_temp);
  987.             Seglen = 0;
  988.             putc(0, FI_temp);
  989.             putc(0, FI_temp);
  990.         }
  991.         fwrite(Gen, Glen, 1, FI_temp);
  992.         Seglen += Glen;
  993.         }
  994.         org += Glen;
  995.     }
  996.     }
  997.     Csegment->org += Glen;
  998.     if (Csegment->flags & SF_RORG)
  999.     Csegment->rorg += Glen;
  1000. }
  1001.  
  1002. void
  1003. closegenerate()
  1004. {
  1005.     if (!Redo) {
  1006.     if (F_format == 2) {
  1007.         fseek(FI_temp, Seekback, 0);
  1008.         putc((short)(Seglen & 0xFF), FI_temp);
  1009.         putc((short)((Seglen >> 8) & 0xFF), FI_temp);
  1010.         fseek(FI_temp, 0L, 2);
  1011.     }
  1012.     }
  1013. }
  1014.  
  1015. void
  1016. genfill(fill, entries, size)
  1017. long fill, entries;
  1018. int size;
  1019. {
  1020.     register long bytes = entries;  /*    multiplied later    */
  1021.     register short i;
  1022.     register ubyte c3,c2,c1,c0;
  1023.  
  1024.     if (!bytes)
  1025.     return;
  1026.     c3 = fill >> 24;
  1027.     c2 = fill >> 16;
  1028.     c1 = fill >> 8;
  1029.     c0 = fill;
  1030.     switch(size) {
  1031.     case 1:
  1032.     BSet(Gen, sizeof(Gen), c0);
  1033.     break;
  1034.     case 2:
  1035.     bytes <<= 1;
  1036.     for (i = 0; i < sizeof(Gen); i += 2) {
  1037.         if (MsbOrder) {
  1038.         Gen[i+0] = c1;
  1039.         Gen[i+1] = c0;
  1040.         } else {
  1041.         Gen[i+0] = c0;
  1042.         Gen[i+1] = c1;
  1043.         }
  1044.     }
  1045.     break;
  1046.     case 4:
  1047.     bytes <<= 2;
  1048.     for (i = 0; i < sizeof(Gen); i += 4) {
  1049.         if (MsbOrder) {
  1050.         Gen[i+0] = c3;
  1051.         Gen[i+1] = c2;
  1052.         Gen[i+2] = c1;
  1053.         Gen[i+3] = c0;
  1054.         } else {
  1055.         Gen[i+0] = c0;
  1056.         Gen[i+1] = c1;
  1057.         Gen[i+2] = c2;
  1058.         Gen[i+3] = c3;
  1059.         }
  1060.     }
  1061.     break;
  1062.     }
  1063.     for (Glen = sizeof(Gen); bytes > sizeof(Gen); bytes -= sizeof(Gen))
  1064.     generate();
  1065.     Glen = bytes;
  1066.     generate();
  1067. }
  1068.  
  1069. void
  1070. pushif(bool)
  1071. int bool;
  1072. {
  1073.     register IFSTACK *ifs = (IFSTACK *)zmalloc(sizeof(IFSTACK));
  1074.     ifs->next = Ifstack;
  1075.     ifs->file = Incfile;
  1076.     ifs->flags = 0;
  1077.     ifs->true  = bool;
  1078.     ifs->acctrue = Ifstack->acctrue && Ifstack->true;
  1079.     Ifstack = ifs;
  1080. }
  1081.  
  1082.