home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
compiler
/
nasm20b
/
nasm_src
/
process.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-19
|
14KB
|
626 lines
/* ---------------------------------------------------------------------- */
/* Copyright (C) 1991 by Natürlich! */
/* This file is copyrighted! */
/* Refer to the documentation for details. */
/* ---------------------------------------------------------------------- */
#define __BIG_GENERATOR__
#include "defines.h"
#include "nasm.h"
#include OSBIND
#include "labels.h"
#include "seg.h"
#include NMALLOC_H
#include "object.h"
#include "fix.h"
#include "process.h"
#include "code.h"
#include "op.h"
/*#if DEBUG*/
#include <stdio.h>
#include "debug.h"
/*#endif*/
#if ! DORECLAIM
# define expr_tryfree( x)
#endif
extern byte scrtab[];
extern int runnable, better, show_open;
extern seg huge *h_seg, huge *sp;
extern imm huge *cip;
byte huge *__program, huge *__p, huge *ptohead;
byte __c;
word __pc, __x;
lword __lx;
static char
invadr[] = "Instruction can't use that addressing mode",
data_loss[] = "Something's amiss after instruction",
modi_loss[] = "No forward references in the modifier",
org_loss[] = "Can't set * with a forward reference",
ds_loss[] = "No fwd reference with a reserve-memory directive";
void pro_init()
{
ENTER("pro_init");
__p = __program = nmalloc( MAXMODULE + 6 + MAX_SAFETY);
__pc = DEFORG; /* default org */
if( runnable)
{
dpoke( __p, 0xFFFF);
_advance( 2);
dpoke( __p, __pc);
_advance( 4);
}
build_rseg( S_UNKNOWN, 0);
LEAVE();
}
void pro_exit()
{
ENTER("pro_exit");
if( h_seg == sp && sis_unknown( sp))
nerror("Not a single byte was generated");
if( runnable)
if( sis_unknown( sp))
_retreat( 4);
else
{
register byte huge *p = &__program[ sp->index - 2];
dpoke( p, __pc - 1);
}
else
if( sis_code( sp))
sp->size = calc_index();
LEAVE();
}
#if ! VERSION
void do_patch( p)
register expr huge *p;
{
if( ! runnable)
if( e_pcrel( p))
if( unvalued( p))
{
save_patch( calc_index(), p->op, 0);
}
else
save_patch( calc_index(), p->op & O_BITS, p->aux);
}
#else
# define do_patch( p) \
if( ! runnable) \
if( e_pcrel( p)) \
if( unvalued( p)) \
{ \
save_patch( calc_index(), p->op, 0); \
} \
else \
save_patch( calc_index(), p->op & O_BITS, p->aux)
#endif
static void wgen_error()
{
nerror( data_loss);
wdeposit( 0);
}
static void gen_error()
{
nerror( data_loss);
deposit( 0);
}
void generate( tab, mode, ex)
register byte huge *tab;
register int mode;
register expr huge *ex;
{
register int flag = 0;
ENTER("generate");
IMESS("ex = $%lX", (lword) ex, 4);
check_fseg( sp, S_RCODE);
if( mode == C_ABS && tab[ mode] == 255)
mode = C_RELA;
if( ex)
if( ((flag = valued( ex)) && ex->val < 0x100) || ex->op & O_ZEROP)
if( mode >= C_ABS && mode <= C_RELY)
mode -= (C_ABS - C_ABS0);
switch( mode)
{
case C_IMPL :
case C_ACCU :
if( tab[ mode] == 255)
{
deposit( 0); /* is a BRK */
}
else
{
cmddeposit( tab, mode);
}
break;
case C_IMM :
cmddeposit( tab, C_IMM);
ex_chk( ex);
do_patch( ex);
ex_deposit( ex, cip, flag);
break;
case C_RELA :
cmddeposit( tab, mode);
if( flag)
{
if( (mode = ex->val - __pc - 1) < -127)
nerror("Backward branch out of range");
deposit( mode);
expr_tryfree( ex);
break;
}
ex_chk( ex);
fix_up( ex, (imm huge *) 0, FIX_BRANCH);
deposit( 0);
ex->aux = __pc;
break;
case C_INDX :
if( tab[ mode] == 124)
{
deposit( 124);
wex_chk( ex);
wex_deposit( ex, flag);
break;
}
case C_INDY :
cmddeposit( tab, mode);
ex_chk( ex);
ex_deposit( ex, 0, flag);
if( ex->val >= 0x100)
nerror("(adr),y or (adr,x) adr was not ZEROPAGE.");
/* might have been a warning as well */
break;
case C_RELX0 :
case C_RELY0 :
case C_ABS0 :
if( __c = tab[mode])
{
deposit( __c);
ex_chk( ex);
ex_deposit( ex, 0, flag);
break;
}
mode += (C_ABS - C_ABS0); /* and fall thru */
case C_RELX :
case C_RELY :
case C_ABS :
there:
cmddeposit( tab, mode);
wex_chk( ex);
wex_deposit( ex, flag);
break;
case C_IND :
if( tab[ mode] == 108) /* is it a jump */
goto there;
cmddeposit( tab, mode);
ex_chk( ex);
ex_deposit( ex, 0, flag);
if( ex->val >= 0x100)
nerror("(adr) - 65C02 BTW - was not ZEROPAGE.");
}
LEAVE();
return;
}
void dropbytes( ex, l, cflag)
expr huge *ex;
register lexpr huge *l;
int cflag;
{
register word i,
offset = 0;
register byte huge *p;
ENTER("dropbytes");
if( ex)
if( valued( ex))
offset = ex->val;
else
{
nerror( modi_loss);
LEAVE();
return;
}
check_fseg( sp, S_SDATA);
while( l)
{
if( p = (byte huge *) l->string)
{
i = pdbeek( p);
IMESS("dropping string of size %d", (lword) i, 2);
if( i)
{
while( i-- > 1)
{
deposit( *p++ + offset);
}
if( cflag)
{
deposit( (*p++ ^ 0x80) + offset);
}
else
{
deposit( *p++ + offset);
}
}
else
nwarning("empty string");
}
else
{
register expr huge *p;
p = l->expr;
do_patch( p);
if( valued( p))
{
deposit( p->val + offset);
expr_tryfree( p);
}
else
{
fix_up( p, cip, FIX_ZCODE);
deposit( offset);
}
}
l = l->next;
}
LEAVE();
}
void dropsbytes( ex, l)
expr huge *ex;
register lexpr huge *l;
{
register word i,
offset = 0;
register byte huge *p;
ENTER("dropsbytes");
if( ex)
if( valued( ex))
offset = ex->val;
else
{
nerror( modi_loss);
LEAVE();
return;
}
check_fseg( sp, S_SDATA);
while( l)
{
if( p = (byte *) l->string)
{
i = pdbeek( p);
IMESS("dropping string of size %d", (lword) i, 2);
if( i)
do
{
deposit( scrtab[*p++] + offset);
}
while( --i);
else
nwarning("empty string");
}
else
{
register expr huge *p;
p = l->expr;
MESS("was expr");
do_patch( p);
if( valued( p)) /* get rid of switch */
{
deposit( scrtab[ p->val] + offset);
expr_tryfree( p);
}
else
{
check_fseg( sp, e_pcrel( p) ? S_RDATA : S_SDATA);
fix_up( p, cip, FIX_SZCODE);
deposit( offset);
}
}
l = l->next;
}
LEAVE();
}
void dropwords( l)
register lexpr huge *l;
{
register expr huge *p;
ENTER("dropwords");
while( l)
{
p = l->expr;
MESS("cheking expr");
if( valued( p)) /* get rid of switch */
{
if( e_pcrel( p))
{
check_fseg( sp, S_RDATA);
}
else
{
check_fseg( sp, S_SDATA);
}
wdeposit( p->val);
expr_tryfree( p);
}
else
{
check_fseg( sp, e_pcrel( p) ? S_RDATA : S_SDATA);
fix_up( p, (imm *) 0, FIX_WCODE);
IMESS("FIX_WCODE @$%8.8lX", (lword) __p, 4);
wdeposit( 0);
}
l = l->next;
}
LEAVE();
}
void dropdbytes( l)
register lexpr huge *l;
{
register expr huge *p;
ENTER("dropdbytes");
IMESS("Got lexpr @$%8.8X", (lword) l, 4);
while( l)
{
p = l->expr;
IMESS("Got expr @$%8.8X", (lword) p, 4);
if( valued( p)) /* get rid of switch */
{
MESS("wddepositing value");
if( e_pcrel( p))
{
check_fseg( sp, S_TDATA);
}
else
{
check_fseg( sp, S_SDATA);
}
wddeposit( p->val);
expr_tryfree( p);
}
else
{
MESS("needs fixup");
check_fseg( sp, e_pcrel( p) ? S_TDATA : S_SDATA);
fix_up( p, (imm *) 0, FIX_DCODE);
IMESS("FIX_DCODE @$%8.8lX", (lword) __p, 4);
wdeposit( 0);
}
l = l->next;
}
LEAVE();
}
static warnflag;
void dropfloat( s)
char *s;
{
extern char page0[];
int i;
ENTER("dropfloat");
if( ! warnflag++)
nwarning("Floats are for losers");
check_fseg( sp, S_SDATA);
if( ab_ascin( s))
nserror("Floating point value malformed", s);
else
for( i = 0; i != 6; i++)
deposit( page0[ 0xD4 + i]);
LEAVE();
}
void real_setorg( newpc)
register word newpc;
{
ENTER("real_setorg");
if( sis_unknown( sp)) /* if old *= didn't do anything */
{
register byte huge *p = &__program[ sp->index - 4];
__pc = newpc; /* reset START */
dpoke( p, __pc);
}
else
if( better)
{
register word diff;
if( (diff = newpc - __pc) < DS_THRESHOLD)
{
check_fseg( sp, S_SDATA);
advance( diff);
LEAVE();
return;
}
}
else
{
register byte huge *p = &__program[ sp->index - 2];
dpoke( p, __pc - 1);
__pc = newpc;
dpoke( __p, __pc);
_advance(4);
build_rseg( S_UNKNOWN, 0);
}
LEAVE();
}
void setorg( ex, offset)
register expr *ex;
register word offset;
{
ENTER("setorg");
if( runnable)
if( valued( ex)) /* get rid of switch */
{
real_setorg( ex->val + offset);
expr_tryfree( ex);
}
else
nerror( org_loss);
else
nerror("You can't use origins in relocatable code");
LEAVE();
}
void reserve( ex)
register expr *ex;
{
ENTER("reserve");
if( valued( ex))
{
register word val = ex->val;
if( runnable)
{
real_setorg( val + __pc);
expr_tryfree( ex);
}
else
{
check_dseg( sp, S_DS, val);
__pc += val;
/* advance( val); */
}
}
else
nerror( ds_loss);
LEAVE();
}
static obj_h header;
#if ! VERSION
extern char x1[], x2[], x3[], x4[], x5[], x6[];
#endif
extern word alignment;
void write_results( fd)
{
lword bytes = calc_ind( __p);
static char err[] = "Write to output file failed (Disk full??)";
ENTER("write_results");
if( runnable)
{
if( Fwrite( fd, bytes, __program) != bytes)
nferror( err);
}
else
{
register byte huge *p = (byte *) &header;
lword max = MAXMODULE,
ebytes, ibytes, rbytes, sbytes, ybytes, fbytes;
plbyte( p, OBJMAGIC); /* sort of stupid */
fpdbyte( p, DVERSION);
fpdbyte( p, ASMREVISION);
fpdbyte( p, alignment);
fpdbyte( p, bytes);
clean_labels();
if( (sbytes = seg_size()) > max)
max = sbytes;
plbyte( p, sbytes);
if( (ibytes = imm_size()) > max)
max = ibytes;
plbyte( p, ibytes);
if( (rbytes = rel_size()) > max)
max = rbytes;
plbyte( p, rbytes);
if( (ebytes = exp_size()) > max)
max = ebytes;
plbyte( p, ebytes);
if( (ybytes = sym_size()) > max)
max = ybytes;
plbyte( p, ybytes);
if( (fbytes = fix_size()) > max)
max = fbytes;
plbyte( p, fbytes);
if( Fwrite( fd, sizeof( obj_h), &header) != sizeof( obj_h) ||
Fwrite( fd, bytes, __program) != bytes)
nferror( err);
if( max != MAXMODULE)
{
nfree( (void *) __program);
__program = nmalloc( max);
}
if(
#if ! VERSION
Fwrite( fd, 10L, x1) != 10 ||
#endif
( seg_makbuf(), Fwrite( fd, sbytes, __program) != sbytes) ||
#if ! VERSION
Fwrite( fd, 10L, x2) != 10 ||
#endif
( ibytes &&
(imm_makbuf(), Fwrite( fd, ibytes, __program) != ibytes)) ||
#if ! VERSION
Fwrite( fd, 10L, x3) != 10 ||
#endif
( rbytes &&
(rel_makbuf(), Fwrite( fd, rbytes, __program) != rbytes)) ||
#if ! VERSION
Fwrite( fd, 10L, x4) != 10 ||
#endif
( ebytes &&
(exp_makbuf(), Fwrite( fd, ebytes, __program) != ebytes)) ||
#if ! VERSION
Fwrite( fd, 10L, x5) != 10 ||
#endif
( ybytes &&
(sym_makbuf(), Fwrite( fd, ybytes, __program) != ybytes)) ||
#if ! VERSION
Fwrite( fd, 10L, x6) != 10 ||
#endif
( fbytes &&
(fix_makbuf(), Fwrite( fd, fbytes, __program) != fbytes)))
nferror( err);
}
Fclose( fd);
if( show_open)
dump_open();
LEAVE();
}