home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / process.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  14KB  |  626 lines

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #define __BIG_GENERATOR__
  7. #include "defines.h"
  8. #include "nasm.h"
  9. #include OSBIND
  10. #include "labels.h"
  11. #include "seg.h"
  12. #include NMALLOC_H
  13. #include "object.h"
  14. #include "fix.h"
  15. #include "process.h"
  16. #include "code.h"
  17. #include "op.h"
  18.  
  19. /*#if DEBUG*/
  20. #include <stdio.h>
  21. #include "debug.h"
  22. /*#endif*/
  23.  
  24. #if ! DORECLAIM
  25. # define          expr_tryfree( x)
  26. #endif
  27.  
  28. extern byte       scrtab[];
  29. extern int        runnable, better, show_open;
  30. extern seg huge   *h_seg, huge *sp;
  31. extern imm huge   *cip;
  32. byte huge         *__program, huge *__p, huge *ptohead;
  33. byte              __c;
  34. word              __pc, __x;
  35. lword             __lx;
  36.  
  37.  
  38. static char
  39.    invadr[]    = "Instruction can't use that addressing mode",
  40.    data_loss[] = "Something's amiss after instruction",
  41.    modi_loss[] = "No forward references in the modifier",
  42.    org_loss[]  = "Can't set  *  with a forward reference",
  43.    ds_loss[]   = "No fwd reference with a reserve-memory directive";
  44.  
  45.  
  46. void pro_init()
  47. {
  48.    ENTER("pro_init");
  49.    __p  = __program = nmalloc( MAXMODULE + 6 + MAX_SAFETY);
  50.    __pc = DEFORG;             /* default org */
  51.    if( runnable)
  52.    {
  53.       dpoke( __p, 0xFFFF);
  54.       _advance( 2);
  55.       dpoke( __p, __pc);
  56.       _advance( 4);
  57.    }
  58.    build_rseg( S_UNKNOWN, 0);
  59.    LEAVE();
  60. }
  61.  
  62. void pro_exit()
  63. {
  64.    ENTER("pro_exit");
  65.    if( h_seg == sp && sis_unknown( sp))
  66.       nerror("Not a single byte was generated");
  67.    if( runnable)
  68.       if( sis_unknown( sp))
  69.          _retreat( 4);
  70.       else
  71.       {
  72.          register byte huge *p = &__program[ sp->index - 2];
  73.  
  74.          dpoke( p, __pc - 1);
  75.       }
  76.    else
  77.       if( sis_code( sp))
  78.          sp->size = calc_index();
  79.    LEAVE();
  80. }
  81.  
  82. #if ! VERSION
  83. void do_patch( p)
  84. register expr huge   *p;
  85. {
  86.    if( ! runnable)
  87.       if( e_pcrel( p))
  88.          if( unvalued( p))
  89.          {
  90.             save_patch( calc_index(), p->op, 0);
  91.          }
  92.          else
  93.             save_patch( calc_index(), p->op & O_BITS, p->aux);
  94. }
  95. #else
  96. # define do_patch( p)                                             \
  97.    if( ! runnable)                                                \
  98.       if( e_pcrel( p))                                            \
  99.          if( unvalued( p))                                        \
  100.          {                                                        \
  101.             save_patch( calc_index(), p->op, 0);                  \
  102.          }                                                        \
  103.          else                                                     \
  104.             save_patch( calc_index(), p->op & O_BITS, p->aux)
  105. #endif
  106.  
  107.  
  108. static void wgen_error()
  109. {
  110.    nerror( data_loss);
  111.    wdeposit( 0);
  112. }
  113.  
  114. static void gen_error()
  115. {
  116.    nerror( data_loss);
  117.    deposit( 0);
  118. }
  119.  
  120.  
  121. void  generate( tab, mode, ex)
  122. register byte huge   *tab;
  123. register int         mode;
  124. register expr huge   *ex;
  125. {
  126.    register int   flag = 0;
  127.  
  128.    ENTER("generate");
  129.    IMESS("ex     = $%lX", (lword) ex, 4);
  130.    check_fseg( sp, S_RCODE);
  131.    if( mode == C_ABS && tab[ mode] == 255)
  132.       mode = C_RELA;
  133.    if( ex)
  134.       if( ((flag = valued( ex)) && ex->val < 0x100) || ex->op & O_ZEROP)
  135.          if( mode >= C_ABS && mode <= C_RELY)
  136.             mode -= (C_ABS - C_ABS0);
  137.  
  138.    switch( mode)
  139.    {
  140.       case C_IMPL  :
  141.       case C_ACCU  :
  142.          if( tab[ mode] == 255)
  143.          {
  144.             deposit( 0);      /* is a BRK */
  145.          }
  146.          else
  147.          {
  148.             cmddeposit( tab, mode);
  149.          }
  150.          break;
  151.  
  152.       case C_IMM   :
  153.          cmddeposit( tab, C_IMM);
  154.          ex_chk( ex);
  155.          do_patch( ex);
  156.          ex_deposit( ex, cip, flag);
  157.          break;
  158.  
  159.       case C_RELA  :
  160.          cmddeposit( tab, mode);
  161.          if( flag)
  162.          {
  163.             if( (mode = ex->val - __pc - 1) < -127)
  164.                nerror("Backward branch out of range");
  165.             deposit( mode);
  166.             expr_tryfree( ex);
  167.             break;
  168.          }
  169.          ex_chk( ex);
  170.          fix_up( ex, (imm huge *) 0, FIX_BRANCH);
  171.          deposit( 0);
  172.          ex->aux = __pc;
  173.          break;
  174.  
  175.       case C_INDX  :
  176.          if( tab[ mode] == 124)
  177.          {
  178.             deposit( 124);
  179.             wex_chk( ex);
  180.             wex_deposit( ex, flag);
  181.             break;
  182.          }
  183.  
  184.       case C_INDY  :
  185.          cmddeposit( tab, mode);
  186.          ex_chk( ex);
  187.          ex_deposit( ex, 0, flag);
  188.          if( ex->val >= 0x100)
  189.             nerror("(adr),y or (adr,x) adr was not ZEROPAGE.");
  190.                                     /* might have been a warning as well */
  191.          break;
  192.  
  193.       case C_RELX0 :
  194.       case C_RELY0 :
  195.       case C_ABS0  :
  196.          if( __c = tab[mode])
  197.          {
  198.             deposit( __c);
  199.             ex_chk( ex);
  200.             ex_deposit( ex, 0, flag);
  201.             break;
  202.          }
  203.          mode += (C_ABS - C_ABS0);     /* and fall thru */
  204.  
  205.       case C_RELX  :
  206.       case C_RELY  :
  207.       case C_ABS   :
  208. there:
  209.          cmddeposit( tab, mode);
  210.          wex_chk( ex);
  211.          wex_deposit( ex, flag);
  212.          break;
  213.  
  214.       case C_IND   :
  215.          if( tab[ mode] == 108)        /* is it a jump */
  216.             goto there;
  217.          cmddeposit( tab, mode);
  218.          ex_chk( ex);
  219.          ex_deposit( ex, 0, flag);
  220.          if( ex->val >= 0x100)
  221.             nerror("(adr) - 65C02 BTW - was not ZEROPAGE.");
  222.  
  223.    }
  224.    LEAVE();
  225.    return;
  226. }
  227.  
  228.  
  229. void  dropbytes( ex, l, cflag)
  230. expr huge            *ex;
  231. register lexpr huge  *l;
  232. int              cflag;
  233. {
  234.    register word       i,
  235.                        offset = 0;
  236.    register byte huge  *p;
  237.  
  238.    ENTER("dropbytes");
  239.    if( ex)
  240.       if( valued( ex))
  241.          offset = ex->val;
  242.       else
  243.       {
  244.          nerror( modi_loss);
  245.          LEAVE();
  246.          return;
  247.       }
  248.  
  249.    check_fseg( sp, S_SDATA);
  250.    while( l)
  251.    {
  252.       if( p = (byte huge *) l->string)
  253.       {
  254.          i = pdbeek( p);
  255.          IMESS("dropping string of size %d", (lword) i, 2);
  256.          if( i)
  257.          {
  258.             while( i-- > 1)
  259.             {
  260.                deposit( *p++ + offset);
  261.             }
  262.             if( cflag)
  263.             {
  264.                deposit( (*p++ ^ 0x80) + offset);
  265.             }
  266.             else
  267.             {
  268.                deposit( *p++ + offset);
  269.             }
  270.          }
  271.          else
  272.             nwarning("empty string");
  273.       }
  274.       else
  275.       {
  276.          register expr huge *p;
  277.  
  278.          p = l->expr;
  279.          do_patch( p);
  280.          if( valued( p))
  281.          {
  282.             deposit( p->val + offset);
  283.             expr_tryfree( p);
  284.          }
  285.          else
  286.          {
  287.             fix_up( p, cip, FIX_ZCODE);
  288.             deposit( offset);
  289.          }
  290.       }
  291.       l = l->next;
  292.    }
  293.    LEAVE();
  294. }
  295.  
  296. void  dropsbytes( ex, l)
  297. expr huge            *ex;
  298. register lexpr huge  *l;
  299. {
  300.    register word        i,
  301.                         offset = 0;
  302.    register byte huge   *p;
  303.  
  304.    ENTER("dropsbytes");
  305.    if( ex)
  306.       if( valued( ex))
  307.          offset = ex->val;
  308.       else
  309.       {
  310.          nerror( modi_loss);
  311.          LEAVE();
  312.          return;
  313.       }
  314.  
  315.    check_fseg( sp, S_SDATA);
  316.    while( l)
  317.    {
  318.       if( p = (byte *) l->string)
  319.       {
  320.          i = pdbeek( p);
  321.          IMESS("dropping string of size %d", (lword) i, 2);
  322.          if( i)
  323.             do
  324.             {
  325.                deposit( scrtab[*p++] + offset);
  326.             }
  327.             while( --i);
  328.          else
  329.             nwarning("empty string");
  330.       }
  331.       else
  332.       {
  333.          register expr huge *p;
  334.  
  335.          p = l->expr;
  336.          MESS("was expr");
  337.          do_patch( p);
  338.          if( valued( p))      /* get rid of switch */
  339.          {
  340.             deposit( scrtab[ p->val] + offset);
  341.             expr_tryfree( p);
  342.          }
  343.          else
  344.          {
  345.             check_fseg( sp, e_pcrel( p) ? S_RDATA : S_SDATA);
  346.             fix_up( p, cip, FIX_SZCODE);
  347.             deposit( offset);
  348.          }
  349.       }
  350.       l = l->next;
  351.    }
  352.    LEAVE();
  353. }
  354.  
  355.  
  356. void  dropwords( l)
  357. register lexpr huge  *l;
  358. {
  359.    register expr huge   *p;
  360.  
  361.    ENTER("dropwords");
  362.    while( l)
  363.    {
  364.       p = l->expr;
  365.       MESS("cheking expr");
  366.       if( valued( p))      /* get rid of switch */
  367.       {
  368.          if( e_pcrel( p))
  369.          {
  370.             check_fseg( sp, S_RDATA);
  371.          }
  372.          else
  373.          {
  374.             check_fseg( sp, S_SDATA);
  375.          }
  376.          wdeposit( p->val);
  377.          expr_tryfree( p);
  378.       }
  379.       else
  380.       {
  381.          check_fseg( sp, e_pcrel( p) ? S_RDATA : S_SDATA);
  382.          fix_up( p, (imm *) 0, FIX_WCODE);
  383.          IMESS("FIX_WCODE @$%8.8lX", (lword) __p, 4);
  384.          wdeposit( 0);
  385.       }
  386.       l = l->next;
  387.    }
  388.    LEAVE();
  389. }
  390.  
  391.  
  392. void  dropdbytes( l)
  393. register lexpr huge  *l;
  394. {
  395.    register expr huge   *p;
  396.  
  397.    ENTER("dropdbytes");
  398.    IMESS("Got lexpr @$%8.8X", (lword) l, 4);
  399.    while( l)
  400.    {
  401.       p = l->expr;
  402.       IMESS("Got expr @$%8.8X", (lword) p, 4);
  403.       if( valued( p))              /* get rid of switch */
  404.       {
  405.          MESS("wddepositing value");
  406.          if( e_pcrel( p))
  407.          {
  408.             check_fseg( sp, S_TDATA);
  409.          }
  410.          else
  411.          {
  412.             check_fseg( sp, S_SDATA);
  413.          }
  414.          wddeposit( p->val);
  415.          expr_tryfree( p);
  416.       }
  417.       else
  418.       {
  419.          MESS("needs fixup");
  420.          check_fseg( sp, e_pcrel( p) ? S_TDATA : S_SDATA);
  421.          fix_up( p, (imm *) 0, FIX_DCODE);
  422.          IMESS("FIX_DCODE @$%8.8lX", (lword) __p, 4);
  423.          wdeposit( 0);
  424.       }
  425.       l = l->next;
  426.    }
  427.    LEAVE();
  428. }
  429.  
  430. static warnflag;
  431.  
  432. void  dropfloat( s)
  433. char  *s;
  434. {
  435.    extern char    page0[];
  436.    int   i;
  437.  
  438.    ENTER("dropfloat");
  439.    if( ! warnflag++)
  440.       nwarning("Floats are for losers");
  441.    check_fseg( sp, S_SDATA);
  442.    if( ab_ascin( s))
  443.       nserror("Floating point value malformed", s);
  444.    else
  445.       for( i = 0; i != 6; i++)
  446.          deposit( page0[ 0xD4 + i]);
  447.    LEAVE();
  448. }
  449.  
  450.  
  451. void real_setorg( newpc)
  452. register word  newpc;
  453. {
  454.    ENTER("real_setorg");
  455.    if( sis_unknown( sp))           /* if old *= didn't do anything */
  456.    {
  457.       register byte huge *p = &__program[ sp->index - 4];
  458.  
  459.       __pc = newpc;  /* reset START */
  460.       dpoke( p, __pc);
  461.    }
  462.    else
  463.       if( better)
  464.       {
  465.          register word  diff;
  466.  
  467.          if( (diff = newpc - __pc) < DS_THRESHOLD)
  468.          {
  469.             check_fseg( sp, S_SDATA);
  470.             advance( diff);
  471.             LEAVE();
  472.             return;
  473.          }
  474.       }
  475.       else
  476.       {
  477.          register byte huge *p = &__program[ sp->index - 2];
  478.  
  479.          dpoke( p, __pc - 1);
  480.          __pc = newpc;
  481.          dpoke( __p, __pc);
  482.          _advance(4);
  483.          build_rseg( S_UNKNOWN, 0);
  484.       }
  485.    LEAVE();
  486. }
  487.  
  488.  
  489. void setorg( ex, offset)
  490. register expr  *ex;
  491. register word  offset;
  492. {
  493.    ENTER("setorg");
  494.    if( runnable)
  495.       if( valued( ex))                        /* get rid of switch */
  496.       {
  497.          real_setorg( ex->val + offset);
  498.          expr_tryfree( ex);
  499.       }
  500.       else
  501.          nerror( org_loss);
  502.    else
  503.       nerror("You can't use origins in relocatable code");
  504.    LEAVE();
  505. }
  506.  
  507.  
  508. void reserve( ex)
  509. register expr *ex;
  510. {
  511.    ENTER("reserve");
  512.    if( valued( ex))
  513.    {
  514.       register word  val = ex->val;
  515.  
  516.       if( runnable)
  517.       {
  518.          real_setorg( val + __pc);
  519.          expr_tryfree( ex);
  520.       }
  521.       else
  522.       {
  523.          check_dseg( sp, S_DS, val);
  524.          __pc += val;
  525. /*         advance( val); */
  526.       }
  527.    }
  528.    else
  529.       nerror( ds_loss);
  530.    LEAVE();
  531. }
  532.  
  533. static obj_h   header;
  534. #if ! VERSION
  535. extern char x1[], x2[], x3[], x4[], x5[], x6[];
  536. #endif
  537. extern word  alignment;
  538.  
  539. void write_results( fd)
  540. {
  541.    lword  bytes = calc_ind( __p);
  542.    static char    err[] = "Write to output file failed (Disk full??)";
  543.  
  544.    ENTER("write_results");
  545.    if( runnable)
  546.    {
  547.       if( Fwrite( fd, bytes, __program) != bytes)
  548.          nferror( err);
  549.    }
  550.    else
  551.    {
  552.       register byte huge *p  = (byte *) &header;
  553.       lword              max = MAXMODULE,
  554.                          ebytes, ibytes, rbytes, sbytes, ybytes, fbytes;
  555.  
  556.       plbyte(  p, OBJMAGIC);     /* sort of stupid */
  557.       fpdbyte( p, DVERSION);
  558.       fpdbyte( p, ASMREVISION);
  559.       fpdbyte( p, alignment);
  560.       fpdbyte( p, bytes);
  561.       clean_labels();
  562.       if( (sbytes = seg_size()) > max)
  563.          max = sbytes;
  564.       plbyte( p, sbytes);
  565.       if( (ibytes = imm_size()) > max)
  566.          max = ibytes;
  567.       plbyte( p, ibytes);
  568.       if( (rbytes = rel_size()) > max)
  569.          max = rbytes;
  570.       plbyte( p, rbytes);
  571.       if( (ebytes = exp_size()) > max)
  572.          max = ebytes;
  573.       plbyte( p, ebytes);
  574.       if( (ybytes = sym_size()) > max)
  575.          max = ybytes;
  576.       plbyte( p, ybytes);
  577.       if( (fbytes = fix_size()) > max)
  578.          max = fbytes;
  579.       plbyte( p, fbytes);
  580.  
  581.       if( Fwrite( fd, sizeof( obj_h), &header) != sizeof( obj_h)     ||
  582.           Fwrite( fd, bytes, __program) != bytes)
  583.          nferror( err);
  584.       if( max != MAXMODULE)
  585.       {
  586.          nfree( (void *) __program);
  587.          __program = nmalloc( max);
  588.       }
  589.       if(
  590. #if ! VERSION
  591.           Fwrite( fd, 10L, x1) != 10                                 ||
  592. #endif
  593.           ( seg_makbuf(), Fwrite( fd, sbytes, __program) != sbytes)  ||
  594. #if ! VERSION
  595.           Fwrite( fd, 10L, x2) != 10                                 ||
  596. #endif
  597.           ( ibytes &&
  598.            (imm_makbuf(), Fwrite( fd, ibytes, __program) != ibytes)) ||
  599. #if ! VERSION
  600.           Fwrite( fd, 10L, x3) != 10                                 ||
  601. #endif
  602.           ( rbytes &&
  603.            (rel_makbuf(), Fwrite( fd, rbytes, __program) != rbytes)) ||
  604. #if ! VERSION
  605.           Fwrite( fd, 10L, x4) != 10                                 ||
  606. #endif
  607.           ( ebytes &&
  608.            (exp_makbuf(), Fwrite( fd, ebytes, __program) != ebytes)) ||
  609. #if ! VERSION
  610.           Fwrite( fd, 10L, x5) != 10                                 ||
  611. #endif
  612.           ( ybytes &&
  613.            (sym_makbuf(), Fwrite( fd, ybytes, __program) != ybytes)) ||
  614. #if ! VERSION
  615.           Fwrite( fd, 10L, x6) != 10                                 ||
  616. #endif
  617.           ( fbytes &&
  618.            (fix_makbuf(), Fwrite( fd, fbytes, __program) != fbytes)))
  619.          nferror( err);
  620.    }
  621.    Fclose( fd);
  622.    if( show_open)
  623.       dump_open();
  624.    LEAVE();
  625. }
  626.