home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / OUTCO68.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-06  |  21.0 KB  |  824 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1996, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and sources are distributed along with any executables derived from them.
  11.  *
  12.  * The author is not responsible for damages, either direct or consequential,
  13.  * that may arise from use of this software.
  14.  *
  15.  * v1.5 August 1996
  16.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  17.  *
  18.  * Credits to Mathew Brandt for original K&R C compiler
  19.  *
  20.  */
  21. #include        <stdio.h>
  22. #include        "expr.h"
  23. #include        "c.h"
  24. #include        "gen.h"
  25. #include        "cglbdec.h"
  26.  
  27. /*      variable initialization         */
  28. extern HASHREC **globalhash;
  29.  
  30. enum e_gt { nogen, bytegen, wordgen, longgen, floatgen, doublegen, longdoublegen, srrefgen };
  31. enum e_sg { noseg, codeseg, dataseg, bssxseg,startupxseg,rundownxseg,cppxseg };
  32.  
  33. extern int    prm_asmfile;
  34. extern int prm_lines;
  35. extern int phiused;
  36.  
  37. int           gentype = nogen;        /* Current DC type */
  38. int           curseg = noseg;        /* Current seg */
  39. int        outcol = 0;                /* Curront col (roughly) */
  40. int              dataofs;                        /* Offset from last label */
  41. char dataname[40];                        /* Name of last label */
  42. static DATALINK *datahead, *datatail;    /* links for fixup gen */
  43. static int phiput;
  44.  
  45. /* Init module */
  46. void outcodeini(void)
  47. {
  48.     gentype = nogen;
  49.     curseg = noseg;
  50.     outcol = 0;
  51.     datahead = datatail = 0;
  52.     phiput = FALSE;
  53. }
  54. /* List of opcodes
  55.  * This list MUST be in the same order as the op_ enums 
  56.  */
  57. char *oplst[] = {
  58.                                 "LINE#","SEQ@", "DC",
  59.                 "MOVE", "MOVEQ", "ADD",
  60.                 "ADDI", "ADDQ", "SUB",
  61.                 "SUBI", "SUBQ", "MULS",
  62.                 "MULU", "DIVS", "DIVU",
  63.                                 "AND","ANDI","OR","ORI",
  64.                                 "EOR","ASL","ASR",
  65.                                 "JMP","JSR","MOVEM",
  66.                                 "RTS","RTE","BRA","BEQ",
  67.                                 "BNE","BLT","BLE",
  68.                                 "BGT","BGE","BHI",
  69.                                 "BHS","BLO","BLS",
  70.                                 "TST","EXT","LEA","SWAP",
  71.                                 "NEG","NOT","CMP","CLR",
  72.                                 "LINK","UNLK","???LABEL???",
  73.                                 "PEA","CMPI","DC","DC","BSR",
  74.                                 "DIVSL","DIVUL","EXG", "TRAP","LSL","LSR",
  75.                                 "BSET","BCLR","BTST","BFINS","BFEXTU","BFEXTS","BFCLR","BFTST",
  76.                                 "FMOVE","FMOVEM","FADD","FSUB","FMUL","FDIV","FMOD",
  77.                                 "FCMP", "FTST", "FNEG", "FBEQ","FBNE","FBGT","FBGE","FBLT","FBLE"
  78.  };
  79. /*
  80.  * Register a fixup 
  81.  */
  82. void datalink(int flag)
  83. {
  84.     DATALINK *p;
  85.     global_flag++;                            /* Global tab */
  86.     p = xalloc(sizeof(DATALINK));
  87.     p->string = litlate(dataname);
  88.     p->type = flag;
  89.     p->offset = dataofs;
  90.     p->next = 0;
  91.     if (datahead) {
  92.         datatail->next = p;
  93.         datatail=datatail->next;
  94.     }
  95.     else
  96.         datahead = datatail = p;
  97.     global_flag--;
  98. }
  99. /* Put an opcode
  100.  */
  101. void putop(int op)
  102. {       
  103.     if (op > op_fble)
  104.     diag("illegal opcode.");
  105.     else
  106.       fprintf(outputFile,"\t%s",oplst[op]);
  107. }
  108.  
  109. void putconst(ENODE *offset)
  110. /*
  111.  *      put a constant to the outputFile file.
  112.  */
  113. {       switch( offset->nodetype )
  114.                 {
  115.                                 case en_autoreg:
  116.                 case en_autocon:
  117.                 case en_icon:
  118.                         fprintf(outputFile,"$%lX",offset->v.i);
  119.                                                 break;
  120.                                 case en_acon:
  121.                         fprintf(outputFile,"$%lX",offset->v.i);
  122.                         break;
  123.                                 case en_rcon:
  124.                                                 fprintf(outputFile,"%f",offset->v.f);
  125.                                                 break;
  126.                                 case en_nalabcon:
  127.                 case en_labcon:
  128.                         fprintf(outputFile,"L_%ld",offset->v.i);
  129.                         break;
  130.                                 case en_napccon:
  131.                 case en_nacon:
  132.                         fprintf(outputFile,"%s",offset->v.p[0]);
  133.                         break;
  134.                                 case en_absacon:
  135.                                                 if (isshort(offset))
  136.                             fprintf(outputFile,"($%lX).W",offset->v.p[0]);
  137.                                                 else
  138.                             fprintf(outputFile,"($%lX).L",offset->v.p[0]);
  139.                                                 break;
  140.                 case en_add:
  141.                         putconst(offset->v.p[0]);
  142.                         fprintf(outputFile,"+");
  143.                         putconst(offset->v.p[1]);
  144.                         break;
  145.                 case en_sub:
  146.                         putconst(offset->v.p[0]);
  147.                         fprintf(outputFile,"-");
  148.                         putconst(offset->v.p[1]);
  149.                         break;
  150.                 case en_uminus:
  151.                         fprintf(outputFile,"-");
  152.                         putconst(offset->v.p[0]);
  153.                         break;
  154.                 default:
  155.                         diag("illegal constant node.");
  156.                         break;
  157.                 }
  158. }
  159. void putlen(int l)
  160. /*
  161.  *      append the length field to an instruction.
  162.  */
  163. {       switch( l )
  164.                 {
  165.                 case 0:
  166.                         break;  /* no length field */
  167.                 case 1:
  168.                         fprintf(outputFile,".B");
  169.                         break;
  170.                 case 2:
  171.                         fprintf(outputFile,".W");
  172.                         break;
  173.                 case 4:
  174.                         fprintf(outputFile,".L");
  175.                         break;
  176.                                 case 6:
  177.                                                 fprintf(outputFile,".S");
  178.                                                 break;
  179.                                 case 8:
  180.                                                 fprintf(outputFile,".D");
  181.                                                 break;
  182.                                 case 10:
  183.                                                 fprintf(outputFile,".X");
  184.                                                 break;
  185.                 default:
  186.                         diag("illegal length field.");
  187.                         break;
  188.                 }
  189. }
  190.  
  191. void putamode(AMODE *ap)
  192. /*
  193.  *      outputFile a general addressing mode.
  194.  */
  195. {       switch( ap->mode )
  196.                 {
  197.                                 case am_sr:
  198.                                                 fprintf(outputFile, "SR");
  199.                                                 break;
  200.                                 case am_bf:
  201.                                                 fprintf(outputFile," {%d:%d}",ap->preg,ap->sreg);
  202.                                                 break;
  203.                                 case am_divsl:
  204.                                                 fprintf(outputFile,"D%d:D%d",ap->preg, ap->sreg);
  205.                                                 break;
  206.                 case am_immed:
  207.                         fprintf(outputFile,"#");
  208.                 case am_direct:
  209.                         putconst(ap->offset);
  210.                         break;
  211.                 case am_areg:
  212.                         fprintf(outputFile,"A%d",ap->preg);
  213.                         break;
  214.                 case am_dreg:
  215.                         fprintf(outputFile,"D%d",ap->preg);
  216.                         break;
  217.                                 case am_freg:
  218.                                                 fprintf(outputFile,"FP%d",ap->preg);
  219.                                                 break;
  220.                 case am_ind:
  221.                         fprintf(outputFile,"(A%d)",ap->preg);
  222.                         break;
  223.                 case am_ainc:
  224.                         fprintf(outputFile,"(A%d)+",ap->preg);
  225.                         break;
  226.                 case am_adec:
  227.                         fprintf(outputFile,"-(A%d)",ap->preg);
  228.                         break;
  229.                 case am_indx:
  230.                         fprintf(outputFile,"(");
  231.                         putconst(ap->offset);
  232.                         fprintf(outputFile,",A%d)",ap->preg);
  233.                         break;
  234.                                 case am_pcindx:
  235.                         fprintf(outputFile,"(");
  236.                         putconst(ap->offset);
  237.                         fprintf(outputFile,",PC)");
  238.                         break;
  239.                 case am_xpc:
  240.                         fprintf(outputFile,"(");
  241.                         putconst(ap->offset);
  242.                         fprintf(outputFile,",PC,D%d.L)",ap->preg);
  243.                         break;
  244.                 case am_indx2:
  245.                         fprintf(outputFile,"(");
  246.                         putconst(ap->offset);
  247.                         fprintf(outputFile,",A%d,D%d.L)",ap->preg,ap->sreg);
  248.                         break;
  249.                 case am_indx3:
  250.                         fprintf(outputFile,"(");
  251.                         putconst(ap->offset);
  252.                         fprintf(outputFile,",A%d,A%d.L)",ap->preg,ap->sreg);
  253.                         break;
  254.                 case am_mask:
  255.                         put_mask((int)ap->offset, ap->preg);
  256.                         break;
  257.                                 case am_fmask:
  258.                         put_fmask((int)ap->offset, ap->preg);
  259.                         break;
  260.                 default:
  261.                         diag("illegal address mode.");
  262.                         break;
  263.                 }
  264. }
  265.  
  266. void put_code(int op,int len,AMODE *aps,AMODE *apd,AMODE *ape)
  267. /*
  268.  *      outputFile a generic instruction.
  269.  */
  270. {       
  271.         if (!prm_asmfile)    
  272.             return;
  273.         if (op == op_line) {
  274.             if (!prm_lines)
  275.                 return;
  276.             fprintf(outputFile,";\n; Line %d:\t%s\n;\n",len,(char *)aps);
  277.             return;
  278.         }
  279.         if( op == op_dcl)
  280.         {
  281.             putop(op);
  282.             putlen(len);
  283.       fprintf(outputFile,"\t");
  284.             putamode(aps);
  285.             fprintf(outputFile,"-*");
  286.             if (apd) {
  287.                 fprintf(outputFile,"-6\n");
  288.                 putop(op);
  289.                 putlen(4);
  290.           fprintf(outputFile,"\t");
  291.                 putamode(apd);
  292.             }
  293.       fprintf(outputFile,"\n");
  294.             return;
  295.         }
  296.     else
  297.         {    
  298.             putop(op);
  299.          putlen(len);
  300.         }
  301.     if( aps != 0 )
  302.     {
  303.       fprintf(outputFile,"\t");
  304.             if( op == op_cmp || op == op_cmpi )
  305.                 putamode( apd );
  306.             else
  307.                 putamode(aps);
  308.       if( apd != 0 )
  309.       {
  310.                 if (apd->mode != am_bf)
  311.           fprintf(outputFile,",");
  312.                 if( op == op_cmp || op == op_cmpi )
  313.                     putamode( aps );
  314.                 else
  315.              putamode(apd);
  316.                 if (ape) {
  317.                     if (ape->mode != am_bf)
  318.                         fprintf(outputFile,",");
  319.                     putamode(ape);
  320.                 }
  321.       }
  322.     }
  323.     if (op == op_dcr)
  324.         fprintf(outputFile,"-*-6\n");
  325.   fprintf(outputFile,"\n");
  326. }
  327.  
  328. void put_fmask(int mask, int reverse)
  329. /*
  330.  *      generate a register mask for floating restore and save.
  331.  */
  332. {
  333.                 unsigned put = FALSE,i,bit;
  334.                 if (!reverse) {
  335.                     bit = 0x80;
  336.                     for (i=0; i < 8; i++) {
  337.                         if (bit & (unsigned) mask) {
  338.                             if (put)
  339.                                 fputc('/', outputFile);
  340.                             put = TRUE;
  341.                             putreg(i+16);
  342.                         }
  343.                          bit >>= 1;
  344.                     }
  345.             
  346.                 }
  347.                 else{
  348.                      bit = 1;
  349.                     for (i=0; i < 8; i++) {
  350.                         if (bit & (unsigned)mask) {
  351.                             if (put)
  352.                                 fputc('/', outputFile);
  353.                             put = TRUE;
  354.                             putreg(i+16);
  355.                         }
  356.                         bit <<= 1;
  357.                     }
  358.                 }
  359. }
  360. void put_mask(int mask, int reverse)
  361. /*
  362.  *      generate a register mask for integer restore and save.
  363.  */
  364. {
  365.                 unsigned put = FALSE,i,bit;
  366.                 if (!reverse) {
  367.                     bit = 0x8000;
  368.                     for (i=0; i < 16; i++) {
  369.                         if (bit & (unsigned) mask) {
  370.                             if (put)
  371.                                 fputc('/', outputFile);
  372.                             put = TRUE;
  373.                             putreg(i);
  374.                         }
  375.                          bit >>= 1;
  376.                     }
  377.             
  378.                 }
  379.                 else{
  380.                      bit = 1;
  381.                     for (i=0; i < 16; i++) {
  382.                         if (bit & (unsigned)mask) {
  383.                             if (put)
  384.                                 fputc('/', outputFile);
  385.                             put = TRUE;
  386.                             putreg(i);
  387.                         }
  388.                         bit <<= 1;
  389.                     }
  390.                 }
  391. }
  392.  
  393. void putreg(int r)
  394. /*
  395.  *      generate a register name from a tempref number.
  396.  */
  397. {       if( r < 8 )
  398.                 fprintf(outputFile,"D%d",r);
  399.         else if (r <16)
  400.                 fprintf(outputFile,"A%d",r - 8);
  401.                 else fprintf(outputFile,"FP%d",r-16);
  402. }
  403.  
  404. void gen_strlab(char *s)
  405. /*
  406.  *      generate a named label.
  407.  */
  408. {
  409.         sprintf(dataname,"%s",s);
  410.         if (prm_asmfile)
  411.        fprintf(outputFile,"%s:\n",dataname);
  412.         dataofs = 0;
  413. }
  414.  
  415. void put_label(int lab)
  416. /*
  417.  *      outputFile a compiler generated label.
  418.  */
  419. {
  420.         sprintf(dataname,"L_%d",lab);
  421.        if (prm_asmfile)
  422.                     fprintf(outputFile,"%s:\n",dataname);
  423.         dataofs = 0;
  424. }
  425.  
  426. void genfloat(float val)
  427. /*
  428.  * Output a float value
  429.  */
  430. {         if (prm_asmfile)
  431.         if( gentype == floatgen && outcol < 60) {
  432.                 fprintf(outputFile,",%f",val);
  433.                 outcol += 8;
  434.                 }
  435.         else    {
  436.                 nl();
  437.                 fprintf(outputFile,"\tDC.S\t%f",val);
  438.                 gentype = floatgen;
  439.                 outcol = 19;
  440.                 }
  441.     dataofs+=4;
  442. }
  443.  
  444. void gendouble(double val)
  445. /*
  446.  * Output a double value
  447.  */
  448. {         if (prm_asmfile)
  449.         if( gentype == doublegen && outcol < 60) {
  450.                 fprintf(outputFile,",%f",val);
  451.                 outcol += 8;
  452.                 }
  453.         else    {
  454.                 nl();
  455.                 fprintf(outputFile,"\tDC.D\t%f",val);
  456.                 gentype = doublegen;
  457.                 outcol = 19;
  458.                 }
  459.     dataofs+=8;
  460. }
  461. void genlongdouble(long double val)
  462. /*
  463.  * Output a double value
  464.  */
  465. {         if (prm_asmfile)
  466.         if( gentype == longdoublegen && outcol < 60) {
  467.                 fprintf(outputFile,",%f",val);
  468.                 outcol += 8;
  469.                 }
  470.         else    {
  471.                 nl();
  472.                 fprintf(outputFile,"\tDT\t%f",val);
  473.                 gentype = longdoublegen;
  474.                 outcol = 19;
  475.                 }
  476.     dataofs+=8;
  477. }
  478.  
  479. void genbyte(long val)
  480. /*
  481.  * Output a byte value
  482.  */
  483. {         if (prm_asmfile)
  484.         if( gentype == bytegen && outcol < 60) {
  485.                 fprintf(outputFile,",$%X",val & 0x00ff);
  486.                 outcol += 4;
  487.                 }
  488.         else    {
  489.                 nl();
  490.                 fprintf(outputFile,"\tDC.B\t$%X",val & 0x00ff);
  491.                 gentype = bytegen;
  492.                 outcol = 19;
  493.                 }
  494.     dataofs+=1;
  495. }
  496.  
  497. void genword(long val)
  498. /*
  499.  * Output a word value
  500.  */
  501. {     if (prm_asmfile)
  502.         if( gentype == wordgen && outcol < 58) {
  503.                 fprintf(outputFile,",$%X",val & 0x0ffff);
  504.                 outcol += 6;
  505.                 }
  506.         else    {
  507.                 nl();
  508.                 fprintf(outputFile,"\tDC.W\t$%X",val & 0x0ffff);
  509.                 gentype = wordgen;
  510.                 outcol = 21;
  511.                 }
  512.     dataofs+=2;
  513. }
  514.  
  515. void genlong(long val)
  516. /*
  517.  * Output a long value
  518.  */
  519. {     if (prm_asmfile)
  520.         if( gentype == longgen && outcol < 56) {
  521.                 fprintf(outputFile,",$%lX",val);
  522.                 outcol += 10;
  523.                 }
  524.         else    {
  525.                 nl();
  526.                 fprintf(outputFile,"\tDC.L\t$%lX",val);
  527.                 gentype = longgen;
  528.                 outcol = 25;
  529.                 }
  530.     dataofs+=4;
  531. }
  532. void gensrref(char *name,int val)
  533. {
  534.             if (prm_asmfile)
  535.         if( gentype == srrefgen && outcol < 56) {
  536.                 fprintf(outputFile,",%s,%d",name,val);
  537.                 outcol += strlen(name)+1;
  538.                 }
  539.         else    {
  540.                 nl();
  541.                 fprintf(outputFile,"\tDC.L\t%s,%d",name,val);
  542.                 gentype = srrefgen;
  543.                 outcol = 25;
  544.                 }
  545. }
  546.  
  547. void genref(SYM *sp,int offset)
  548. /*
  549.  * Output a reference to the data area (also gens fixups )
  550.  */
  551. {       char    sign;
  552.             char buf[40];
  553.         if( offset < 0) {
  554.                 sign = '-';
  555.                 offset = -offset;
  556.                 }
  557.         else
  558.                 sign = '+';
  559.             sprintf(buf,"%s%c%d",sp->name,sign,offset);
  560.             datalink(FALSE);
  561.             if (prm_asmfile) {
  562.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  563.                 fprintf(outputFile,",%s",buf);
  564.                 outcol += (11 + strlen(sp->name));
  565.                 }
  566.         else    {
  567.                 nl();
  568.                 fprintf(outputFile,"\tDC.L\t%s",buf);
  569.                 outcol = 26 + strlen(sp->name);
  570.                 gentype = longgen;
  571.                 }
  572.             }
  573.     dataofs+=4;
  574. }
  575. void genpcref(SYM *sp,int offset)
  576. /*
  577.  * Output a reference to the code area (also gens fixups )
  578.  */
  579. {       char    sign;
  580.                 char buf[40];
  581.         if( offset < 0) {
  582.                 sign = '-';
  583.                 offset = -offset;
  584.                 }
  585.         else
  586.                 sign = '+';
  587.             sprintf(buf,"%s%c%d",sp->name,sign,offset);
  588.             datalink(TRUE);
  589.             if (prm_asmfile) {
  590.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  591.                 fprintf(outputFile,",%s",buf);
  592.                 outcol += (11 + strlen(sp->name));
  593.                 }
  594.         else    {
  595.                 nl();
  596.                 fprintf(outputFile,"\tDC.L\t%s",buf);
  597.                 outcol = 26 + strlen(sp->name);
  598.                 gentype = longgen;
  599.                 }
  600.             }
  601.     dataofs+=4;
  602. }
  603.  
  604. void genstorage(int nbytes)
  605. /*
  606.  * Output bytes of storage
  607.  */
  608. {            if (prm_asmfile) {
  609.         nl();
  610.         fprintf(outputFile,"\tDS.B\t$%X\n",nbytes);
  611.             }
  612.     dataofs+=nbytes;
  613. }
  614.  
  615. void gen_labref(int n)
  616. /*
  617.  * Generate a reference to a label
  618.  */
  619. {            if (prm_asmfile)
  620.         if( gentype == longgen && outcol < 58) {
  621.                 fprintf(outputFile,",L_%d",n);
  622.                 outcol += 6;
  623.                 }
  624.         else    {
  625.                 nl();
  626.                 fprintf(outputFile,"\tDC.L\tL_%d",n);
  627.                 outcol = 22;
  628.                 gentype = longgen;
  629.                 }
  630.     datalink(TRUE);
  631.     dataofs+=4;
  632. }
  633.  
  634. int     stringlit(char *s)
  635. /*
  636.  *      make s a string literal and return it's label number.
  637.  */
  638. {       struct slit     *lp;
  639.         ++global_flag;          /* always allocate from global space. */
  640.         lp = xalloc(sizeof(struct slit));
  641.         lp->label = nextlabel++;
  642.         lp->str = litlate(s);
  643.         lp->next = strtab;
  644.         strtab = lp;
  645.         --global_flag;
  646.         return lp->label;
  647. }
  648.  
  649. void dumplits(void)
  650. /*
  651.  *      dump the string literal pool.
  652.  */
  653. {       char            *cp;
  654.         while( strtab != 0) {
  655.                 cseg();
  656.                 nl();
  657.                 put_label(strtab->label);
  658.                 cp = strtab->str;
  659.                 while(*cp)
  660.                         genbyte(*cp++);
  661.                 genbyte(0);
  662.                 strtab = strtab->next;
  663.                 }
  664.         nl();
  665. }
  666.  
  667. void nl(void)
  668. /*
  669.  * New line
  670.  */
  671. {    if (prm_asmfile) {
  672.        if(outcol > 0) {
  673.                 fputc('\n',outputFile);
  674.                 outcol = 0;
  675.                 gentype = nogen;
  676.                 }
  677.              if (phiused && !phiput)
  678.                                 fputc(0x1f,outputFile);
  679.          }
  680. }
  681. /*
  682.  * Switch to cseg 
  683.  */
  684. void cseg(void)
  685. {            if (prm_asmfile)
  686.            if( curseg != codeseg) {
  687.                 nl();
  688.                 fprintf(outputFile,"\tSECTION\tcode\n");
  689.                 curseg = codeseg;
  690.                 }
  691. }
  692. /*
  693.  * Switch to dseg
  694.  */
  695. void dseg(void)
  696. {     if (prm_asmfile)  
  697.                 if( curseg != dataseg) {
  698.                 nl();
  699.                 fprintf(outputFile,"\tSECTION\tdata\n");
  700.                 curseg = dataseg;
  701.                 }
  702. }
  703. /*
  704.  * Switch to bssseg
  705.  */
  706. void bssseg(void)
  707. {     if (prm_asmfile)  
  708.                 if( curseg != bssxseg) {
  709.                 nl();
  710.                 fprintf(outputFile,"\tSECTION\tbss\n");
  711.                 curseg = bssxseg;
  712.                 }
  713. }
  714. /*
  715.  * Switch to startupseg
  716.  */
  717. void startupseg(void)
  718. {     if (prm_asmfile)  
  719.                 if( curseg != startupxseg) {
  720.                 nl();
  721.                 fprintf(outputFile,"\tSECTION\tcstartup\n");
  722.                 curseg = startupxseg;
  723.                 }
  724. }
  725. /*
  726.  * Switch to rundownseg
  727.  */
  728. void rundownseg(void)
  729. {     if (prm_asmfile)  
  730.                 if( curseg != rundownxseg) {
  731.                 nl();
  732.                 fprintf(outputFile,"\tSECTION\tcrundown\n");
  733.                 curseg = rundownxseg;
  734.                 }
  735. }
  736. /*
  737.  * Switch to cppseg
  738.  */
  739. void cppseg(void)
  740. {     if (prm_asmfile)  
  741.                 if( curseg != cppxseg) {
  742.                 nl();
  743.                 fprintf(outputFile,"\tSECTION\tcppinit\n");
  744.                 curseg = cppxseg;
  745.                 }
  746. }
  747. void gen_virtual(char *name)
  748. {
  749.     if (prm_asmfile) {
  750.         nl();
  751.         fprintf(outputFile,"@%s\tVIRTUAL",name);
  752.     }
  753. }
  754. void gen_endvirtual(char *name)
  755. {
  756.     if (prm_asmfile) {
  757.         nl();
  758.         fprintf(outputFile,"@%s\tENDVIRTUAL",name);
  759.     }
  760. }
  761. void genlongref(DATALINK *p)
  762. /*
  763.  * Generate a reference reference for fixup tables
  764.  */
  765. {
  766.         if( gentype == longgen && outcol < 56) {
  767.                 fprintf(outputFile,",%s+$%X",p->string,p->offset);
  768.                 outcol += 10;
  769.                 }
  770.         else    {
  771.                 nl();
  772.                 fprintf(outputFile,"\tDC.L\t%s+$%X",p->string,p->offset);
  773.                 gentype = longgen;
  774.                 outcol = 25;
  775.                 }
  776. }
  777. void putexterns(void)
  778. /*
  779.  * Output the fixup tables and the global/external list
  780.  */
  781. {       SYM     *sp;
  782.             DATALINK *p;
  783.             int i;
  784.             if (prm_asmfile){
  785.                 int started = FALSE;
  786.                 p = datahead;
  787.                 while (p) {
  788.                     if (p->type) {
  789.                         if (!started) {
  790.                 nl();
  791.                 fprintf(outputFile,"\tSECTION\tcodefix\n");
  792.                                 started = TRUE;
  793.                         }
  794.                         genlongref(p);
  795.                     }
  796.                     p = p->next;
  797.                 }
  798.                 started = FALSE;
  799.                 p = datahead;
  800.                 while (p) {
  801.                     if (!p->type) {
  802.                         if (!started) {
  803.                 nl();
  804.                 fprintf(outputFile,"\tSECTION\tdatafix\n");
  805.                                 started = TRUE;
  806.                         }
  807.                         genlongref(p);
  808.                     }
  809.                     p = p->next;
  810.                 }
  811.                 nl();
  812.                 for (i=0; i < HASHTABLESIZE; i++) {
  813.                     if ((sp=(SYM *) globalhash[i]) != 0) {
  814.                         while (sp) {
  815.                     if( sp->storage_class == sc_external && sp->extflag)
  816.                 fprintf(outputFile,"\tXREF\t%s\n",sp->name);
  817.                     else if( sp->storage_class == sc_global )
  818.                 fprintf(outputFile,"\tXDEF\t%s\n",sp->name);
  819.                      sp = sp->next;
  820.                         }
  821.                     }
  822.                 }
  823.             }
  824. }