home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
language
/
sozobon2
/
cpy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-23
|
4KB
|
189 lines
/*
* Copyright (c) 1988 by Sozobon, Limited. Author: Joseph M Treat
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to redistribute it freely, with the
* following restrictions:
* 1) No charge may be made other than reasonable charges for reproduction.
* 2) Modified versions must be clearly marked as such.
* 3) The authors are not responsible for any harmful consequences
* of using this software, even if they result from defects in it.
*/
#include "jas.h"
#define R_ABS 0
#define R_DAT 1
#define R_TXT 2
#define R_BSS 3
#define R_EXT 4
#define R_UPPER 5
#define R_FIRST 7
#define RBLEN 256
typedef struct _reloc {
struct _reloc *next;
unsigned short cnt;
unsigned short reloc[RBLEN];
} RELOC;
RELOC *relptr = (RELOC *) NULL;
RELOC *curptr;
extern SYM dot;
extern long newdot;
#define SEG(p) ( (p)->flags & SEGMT )
translate( seg, null )
unsigned short seg;
int null;
{
register unsigned short stype;
register CBUF *code;
register unsigned short rval, orval;
int havebyte = 0;
int cline = 0;
extern CBUF *cget();
if ( relptr == (RELOC *) NULL ) {
relptr = ALLO(RELOC);
curptr = relptr;
}
rval = R_ABS;
for ( ; code = cget( seg ); newdot += code->nbits / 8 ) {
cline = code->line;
orval = rval;
rval = R_ABS;
if ( code->action == GENSTMT )
dot.value = newdot;
stype = UNK;
if ( code->value.psym ) {
stype = SEG(code->value.psym);
switch ( stype ) {
case DAT:
rval = R_DAT;
break;
case TXT:
rval = R_TXT;
break;
case BSS:
rval = R_BSS;
break;
default:
rval = R_EXT;
break;
}
if ( code->value.psym->flags & EQUATED ) {
stype = EQUATED;
rval = R_ABS;
}
}
if ( code->action == GENPCREL ) {
if ( code->value.psym && stype != TXT )
warn( cline, "illegal pc-relative reference" );
rval = R_ABS;
stype = UNK;
code->value.value -= (dot.value + 2);
}
if ( code->value.psym ) {
if ( code->value.psym->flags & (SEGMT|EQUATED) )
code->value.value += code->value.psym->value;
}
/* don't check anything right now ...
chkvalue( code );
... */
code->value.value <<= (32 - code->nbits);
output( (char *) &code->value.value, sizeof (char),
(int) code->nbits/8 );
if ( rval == R_EXT )
rval |= ( code->value.psym->index << 3 );
if ( havebyte == 1 && code->nbits != 8 )
error( cline, "relocation alignment error" );
if ( havebyte == 1 && rval == R_ABS && orval == R_FIRST )
rval = R_FIRST;
if ( havebyte == 1 && rval != orval )
error( cline, "bytes not separately relocatable" );
if ( code->action == GENSTMT && rval != R_ABS )
error( cline, "relocatable operation word" );
if ( code->action == GENSTMT )
rval = R_FIRST;
if ( code->nbits == 8 && havebyte == 0 ) {
if ( rval != R_ABS && rval != R_FIRST )
error( cline,
"bytes not separately relocatable" );
havebyte = 1;
continue;
}
havebyte = 0;
if ( code->nbits == 32 ) {
addrel( R_UPPER );
}
addrel( rval );
}
dot.value = newdot += null;
while ( null-- ) {
char zip = 0;
output( (char *) &zip, sizeof (char), 1 );
if ( havebyte && rval != R_ABS )
error( cline, "bytes not separately relocatable" );
if ( havebyte == 0 ) {
havebyte = 1;
rval = R_ABS;
continue;
}
havebyte = 0;
addrel( rval );
}
if ( havebyte )
error( cline, "internal relocation alignment error" );
}
addrel( rval )
unsigned short rval;
{
if ( curptr->cnt == RBLEN ) {
curptr->next = ALLO(RELOC);
curptr = curptr->next;
}
curptr->reloc[curptr->cnt++] = rval;
}
dumprel()
{
register RELOC *rp;
for ( rp = relptr; rp; rp = rp->next ) {
output( (char *) rp->reloc, sizeof (unsigned short),
(int) rp->cnt );
}
return;
}
chkvalue( code )
CBUF *code;
{
long value;
value = code->value.value;
if ( code->nbits != 32 ) {
value <<= (32 - code->nbits);
value >>= (32 - code->nbits);
if ( value != code->value.value )
warn( code->line, "value overflows byte/word" );
}
}