home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / jas / cpy.c < prev    next >
C/C++ Source or Header  |  1991-02-22  |  5KB  |  215 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15.  
  16. #define R_ABS    0
  17. #define R_DAT    1
  18. #define R_TXT    2
  19. #define R_BSS    3
  20. #define R_EXT    4
  21. #define R_UPPER    5
  22. #define R_FIRST    7
  23.  
  24. #define RBLEN 256
  25.  
  26. typedef struct _reloc {
  27.     struct _reloc *next;
  28.     unsigned short cnt;
  29.     unsigned short reloc[RBLEN];
  30. } RELOC;
  31.     
  32. RELOC *relptr = (RELOC *) NULL;
  33. RELOC *curptr;
  34.  
  35. extern SYM dot;
  36. extern long newdot;
  37.  
  38. #define SEG(p) ( (p)->flags & SEGMT )
  39.  
  40. #ifdef UNIXHOST
  41. char *mklowbyte(), *mklowshort(), *mklowlong();
  42. #endif
  43.  
  44. translate( seg, null )
  45.     unsigned short seg;
  46.     int null;
  47. {
  48.     register unsigned short stype;
  49.     register CBUF *code;
  50.     register unsigned short rval, orval;
  51.     int havebyte = 0;
  52.     int cline = 0;
  53.     extern CBUF *cget();
  54.  
  55.     if ( relptr == (RELOC *) NULL ) {
  56.         relptr = ALLO(RELOC);
  57.         curptr = relptr;
  58.     }
  59.  
  60.     rval = R_ABS;
  61.     for ( ; code = cget( seg ); newdot += code->nbits / 8 ) {
  62.         cline = code->line;
  63.         orval = rval;
  64.         rval = R_ABS;
  65.         if ( code->action == GENSTMT )
  66.             dot.value = newdot;
  67.         
  68.         stype = UNK;
  69.         if ( code->value.psym ) {
  70.             stype = SEG(code->value.psym);
  71.             switch ( stype ) {
  72.             case DAT:
  73.                 rval = R_DAT;
  74.                 break;
  75.             case TXT:
  76.                 rval = R_TXT;
  77.                 break;
  78.             case BSS:
  79.                 rval = R_BSS;
  80.                 break;
  81.             default:
  82.                 rval = R_EXT;
  83.                 break;
  84.             }
  85.             if ( code->value.psym->flags & EQUATED ) {
  86.                 stype = EQUATED;
  87.                 rval = R_ABS;
  88.             }
  89.         }
  90.         if ( code->action == GENPCREL ) {
  91.             if ( code->value.psym && stype != TXT )
  92.                 warn( cline, "illegal pc-relative reference" );
  93.             rval = R_ABS;
  94.             stype = UNK;
  95.             code->value.value -= (dot.value + 2);
  96.         }
  97.  
  98.         if ( code->value.psym ) {
  99.             if ( code->value.psym->flags & (SEGMT|EQUATED) )
  100.                 code->value.value += code->value.psym->value;
  101.         }
  102.  
  103.         /* don't check anything right now ...
  104.             chkvalue( code );
  105.         ... */
  106.  
  107. #ifndef UNIXHOST
  108.         code->value.value <<= (32 - code->nbits);
  109.         output( (char *) &code->value.value, sizeof (char),
  110.                             (int) code->nbits/8 );
  111. #else
  112.         switch (code->nbits) {
  113.         case 8:
  114.             output( mklowbyte(code->value.value), sizeof (char),
  115.                 1 );
  116.             break;
  117.         case 16:
  118.             output( mklowshort(code->value.value), sizeof (char),
  119.                 2 );
  120.             break;
  121.         case 32:
  122.             output( mklowlong(code->value.value), sizeof (char),
  123.                 4 );
  124.             break;
  125.         default:
  126.             error( cline, "internal size error" );
  127.         }
  128. #endif
  129.         if ( rval == R_EXT )
  130.             rval |= ( code->value.psym->index << 3 );
  131.  
  132.         if ( havebyte == 1 && code->nbits != 8 )
  133.             error( cline, "relocation alignment error" );
  134.         if ( havebyte == 1 && rval == R_ABS && orval == R_FIRST )
  135.             rval = R_FIRST;
  136.         if ( havebyte == 1 && rval != orval )
  137.             error( cline, "bytes not separately relocatable" );
  138.  
  139.         if ( code->action == GENSTMT && rval != R_ABS )
  140.             error( cline, "relocatable operation word" );
  141.         if ( code->action == GENSTMT )
  142.             rval = R_FIRST;
  143.         if ( code->nbits == 8 && havebyte == 0 ) {
  144.             if ( rval != R_ABS && rval != R_FIRST )
  145.                 error( cline,
  146.                     "bytes not separately relocatable" );
  147.             havebyte = 1;
  148.             continue;
  149.         }
  150.         havebyte = 0;
  151.  
  152.         if ( code->nbits == 32 ) {
  153.             addrel( R_UPPER );
  154.         }
  155.         addrel( rval );
  156.     }
  157.  
  158.     dot.value = newdot += null;
  159.     while ( null-- ) {
  160.         char zip = 0;
  161.  
  162.         output( (char *) &zip, sizeof (char), 1 );
  163.         if ( havebyte && rval != R_ABS )
  164.             error( cline, "bytes not separately relocatable" );
  165.         if ( havebyte == 0 ) {
  166.             havebyte = 1;
  167.             rval = R_ABS;
  168.             continue;
  169.         }
  170.         havebyte = 0;
  171.         addrel( rval );
  172.     }
  173.     if ( havebyte ) 
  174.         error( cline, "internal relocation alignment error" );
  175. }
  176.  
  177. addrel( rval )
  178.     unsigned short rval;
  179. {
  180.     if ( curptr->cnt == RBLEN ) {
  181.         curptr->next = ALLO(RELOC);
  182.         curptr = curptr->next;
  183.     }
  184.     curptr->reloc[curptr->cnt++] = rval;
  185. }
  186.  
  187. dumprel()
  188. {
  189.     register RELOC *rp;
  190.  
  191.     for ( rp = relptr; rp; rp = rp->next ) {
  192. #ifdef UNIXHOST
  193.         swapw( rp->reloc, rp->cnt );
  194. #endif
  195.         output( (char *) rp->reloc, sizeof (unsigned short),
  196.                                 (int) rp->cnt );
  197.     }
  198.     return;
  199.  
  200. chkvalue( code )
  201.     CBUF *code;
  202. {
  203.     long value;
  204.  
  205.     value = code->value.value;
  206.  
  207.     if ( code->nbits != 32 ) {
  208.         value <<= (32 - code->nbits);
  209.         value >>= (32 - code->nbits);
  210.         if ( value != code->value.value )
  211.             warn( code->line, "value overflows byte/word" );
  212.     }
  213. }
  214.