[comp.sources.amiga] v02i028: dasm - small systems cross assembler V2.0, Part02/03

page@swan.ulowell.edu (Bob Page) (10/27/88)

Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
Posting-number: Volume 2, Issue 28
Archive-name: languages/dasm20.2

# This is a shell archive.  Remove anything before this line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
#	src/asm.h
#	src/ops.c
#	src/mne6502.c
#	src/mne6811.c
#	src/main.c
#
if `test ! -d src`
then
  mkdir src
  echo "mkdir src"
fi
if `test ! -s src/asm.h`
then
echo "writing src/asm.h"
cat > src/asm.h << '\Rogue\Monster\'

/*
 *  ASM65.H
 *
 *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
 *
 *  Structures and definitions
 */

#include <stdio.h>

#ifdef UNIX
#define bmov(s,d,n) bcopy(s,d,n)
#define bset(s,n,c) xbset(s,n,c)
#endif

#ifdef IBM
#define bmov(s,d,n) movmem(s,d,(int)n)
#define bset(s,n,c) setmem(s,(int)n,(int)c)
#define bzero(s,n)  setmem(s,(int)n,0)
#endif

#ifdef IBM
typedef char	 ubyte;
typedef unsigned uword;
typedef long	 ulong;
typedef int	 void;
#else
typedef unsigned char ubyte;
typedef unsigned short uword;
typedef unsigned long ulong;
#endif

#define MNE	    struct _MNE
#define MACRO	    struct _MACRO
#define INCFILE     struct _INCFILE
#define REPLOOP     struct _REPLOOP
#define IFSTACK     struct _IFSTACK
#define SEGMENT     struct _SEGMENT
#define SYMBOL	    struct _SYMBOL
#define STRLIST     struct _STRLIST

#define DEFORGFILL  255
#define SHASHSIZE   1024
#define MHASHSIZE   1024
#define SHASHAND    0x03FF
#define MHASHAND    0x03FF
#define ALLOCSIZE   16384
#define MAXMACLEVEL 32
#define TAB	    9

#define OUTFORM1    0
#define OUTFORM2    1
#define OUTFORM3    2

#define AM_IMP		0	    /*	implied 	    */
#define AM_IMM8 	1	    /*	immediate 8  bits   */
#define AM_IMM16	2	    /*	immediate 16 bits   */
#define AM_BYTEADR	3	    /*	address 8 bits	    */
#define AM_BYTEADRX	4	    /*	address 16 bits     */
#define AM_BYTEADRY	5	    /*	relative 8 bits     */
#define AM_WORDADR	6	    /*	index x 0 bits	    */
#define AM_WORDADRX	7	    /*	index x 8 bits	    */
#define AM_WORDADRY	8	    /*	index x 16 bits     */
#define AM_REL		9	    /*	bit inst. special   */
#define AM_INDBYTEX	10	    /*	bit-bra inst. spec. */
#define AM_INDBYTEY	11	    /*	index y 0 bits	    */
#define AM_INDWORD	12	    /*	index y 8 bits	    */
#define AM_0X		13	    /*	index x 0 bits	    */
#define AM_0Y		14	    /*	index y 0 bits	    */
#define AM_BITMOD	15	    /*	ind addr 8 bits     */
#define AM_BITBRAMOD	16	    /*	ind addr 16 bits    */
#define NUMOC		17

#define AF_IMP		(1L << 0 )
#define AF_IMM8 	(1L << 1 )
#define AF_IMM16	(1L << 2 )
#define AF_BYTEADR	(1L << 3 )
#define AF_BYTEADRX	(1L << 4 )
#define AF_BYTEADRY	(1L << 5 )
#define AF_WORDADR	(1L << 6 )
#define AF_WORDADRX	(1L << 7 )
#define AF_WORDADRY	(1L << 8 )
#define AF_REL		(1L << 9 )
#define AF_INDBYTEX	(1L << 10)
#define AF_INDBYTEY	(1L << 11)
#define AF_INDWORD	(1L << 12)
#define AF_0X		(1L << 13)
#define AF_0Y		(1L << 14)
#define AF_BITMOD	(1L << 15)
#define AF_BITBRAMOD	(1L << 16)

#define AM_SYMBOL	(NUMOC+0)
#define AM_EXPLIST	(NUMOC+1)

#define AM_BYTE 	AM_BYTEADR
#define AM_WORD 	AM_WORDADR
#define AM_LONG 	(NUMOC+2)
#define AM_BSS		(NUMOC+3)


STRLIST {
    STRLIST *next;
    ubyte   buf[4];
};

#define MF_IF		0x04
#define MF_MACRO	0x08
#define MF_MASK 	0x10	/*  has mask argument (byte)    */
#define MF_REL		0x20	/*  has rel. address (byte)     */
#define MF_IMOD 	0x40	/*  instruction byte mod.	*/

MNE {
    MNE     *next;	    /*	hash		*/
    void    (*vect)();      /*  dispatch        */
    char    *name;	    /*	actual name	*/
    ubyte   flags;	    /*	special flags	*/
    ulong   okmask;
    uword   opcode[NUMOC];  /*	hex codes, byte or word (>xFF) opcodes  */
};

MACRO {
    MACRO   *next;
    void    (*vect)();
    ubyte   *name;
    ubyte   flags;
    STRLIST *strlist;
};

#define INF_MACRO   0x01

INCFILE {
    INCFILE *next;  /*	previously pushed context   */
    ubyte   *name;  /*	file name		    */
    FILE    *fi;    /*	file handle		    */
    ulong   lineno; /*	line number in file	    */
    ubyte   flags;  /*	flags (macro)               */

	/*  Only if Macro   */

    STRLIST *args;	/*  arguments to macro		*/
    STRLIST *strlist;	/*  current string list 	*/
    ulong   saveidx;	/*  save localindex		*/
};

#define RPF_UNKNOWN 0x01    /*	value unknown	    */

REPLOOP {
    REPLOOP *next;  /*	previously pushed context   */
    ulong   count;  /*	repeat count		    */
    ulong   seek;   /*	seek to top of repeat	    */
    ulong   lineno; /*	line number of line before  */
    INCFILE *file;  /*	which include file are we in*/
    ubyte   flags;
};

#define IFF_UNKNOWN 0x01    /*	value unknown	    */
#define IFF_BASE    0x04

IFSTACK {
    IFSTACK *next;  /*	previous IF		    */
    INCFILE *file;  /*	which include file are we in*/
    ubyte   flags;
    ubyte   true;   /*	1 if true, 0 if false			*/
    ubyte   acctrue;/*	accumulatively true (not incl this one) */
};

#define SF_UNKNOWN  0x01    /*	ORG unknown			*/
#define SF_REF	    0x04    /*	ORG referenced			*/
#define SF_BSS	    0x10    /*	uninitialized area (U flag)     */
#define SF_RORG     0x20    /*	relocatable origin active	*/

SEGMENT {
    SEGMENT *next;  /*	next segment in segment list	*/
    ubyte   *name;  /*	name of segment 		*/
    ubyte   flags;  /*	for ORG 			*/
    ubyte   rflags; /*	for RORG			*/
    ulong   org;    /*	current org			*/
    ulong   rorg;   /*	current rorg			*/
    ulong   initorg;
    ulong   initrorg;
    ubyte   initflags;
    ubyte   initrflags;
};

#define SYM_UNKNOWN 0x01    /*	value unknown		*/
#define SYM_REF     0x04    /*	referenced		*/
#define SYM_STRING  0x08    /*	result is a string	*/
#define SYM_SET     0x10    /*	SET instruction used	*/
#define SYM_MACRO   0x20    /*	symbol is a macro	*/
#define SYM_MASREF  0x40    /*	master reference	*/

SYMBOL {
    SYMBOL  *next;	/*  next symbol in hash list	    */
    ubyte   *name;	/*  symbol name or string if expr.  */
    ubyte   *string;	/*  if symbol is actually a string  */
    ubyte   flags;	/*  flags			    */
    ubyte   addrmode;	/*  addressing mode (expressions)   */
    ulong   value;	/*  current value		    */
    uword   namelen;	/*  name length 		    */
};

extern SYMBOL	*SHash[];
extern MNE	*MHash[];
extern INCFILE	*Incfile;
extern REPLOOP	*Reploop;
extern SEGMENT	*Seglist;
extern IFSTACK	*Ifstack;

extern SEGMENT	*Csegment;  /*	current segment */
extern ubyte	*Av[];
extern ubyte	Avbuf[];
extern uword	Adrbytes[];
extern uword	Cvt[];
extern uword	Opsize[];
extern uword	Mnext;	    /*	mnemonic extension  */
extern uword	Mlevel;

extern void	fseek();
extern long	ftell();

extern ubyte	*malloc(), *zmalloc(), *strcpy(), *permalloc();
extern ubyte	*sftos();
extern SYMBOL	*allocsymbol();
extern ubyte	Xtrace;
extern ubyte	Xdebug;
extern ubyte	MsbOrder;
extern ubyte	Outputformat;
extern ulong	Redo, Redo_why, Redo_eval;
extern ulong	Localindex, Lastlocalindex;

extern ubyte	F_format;
extern ubyte	F_verbose;
extern char	*F_outfile;
extern char	*F_listfile;
extern char	*F_symfile;
extern char	*F_temppath;
extern FILE	*FI_listfile;
extern FILE	*FI_temp;
extern ubyte	Fisclear;
extern ulong	Plab, Pflags;
extern char	Inclevel;
extern char	ListMode;
extern ulong	Processor;

extern SYMBOL	*findsymbol(), *createsymbol(), *eval();

extern uword _fmode;
extern ulong  CheckSum;

\Rogue\Monster\
else
  echo "will not over write src/asm.h"
fi
if [ `wc -c src/asm.h | awk '{printf $1}'` -ne 6790 ]
then
echo `wc -c src/asm.h | awk '{print "Got " $1 ", Expected " 6790}'`
fi
if `test ! -s src/ops.c`
then
echo "writing src/ops.c"
cat > src/ops.c << '\Rogue\Monster\'

/*
 *  OPS.C
 *
 *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
 *
 *  Handle mnemonics and pseudo ops
 *
 */

#include "asm.h"

ubyte	Gen[256];
ubyte	OrgFill = DEFORGFILL;
short	Glen;

extern void generate();
extern void genfill();
extern void pushif();

/*
 *  An opcode modifies the SEGMENT flags in the following ways:
 */

void
v_processor(str)
register char *str;
{
    extern MNE	Mne6502[];
    extern MNE	Mne6803[];
    extern MNE	MneHD6303[];
    extern MNE	Mne68705[];
    extern MNE	Mne68HC11[];
    register short none = 1;
    static int	called;

    if (called)
	return;
    called = 1;
    if (strcmp(str,"6502") == 0) {
	addhashtable(Mne6502);
	MsbOrder = 0;	   /*  lsb,msb */
	Processor = 6502;
    }
    if (strcmp(str,"6803") == 0) {
	addhashtable(Mne6803);
	MsbOrder = 1;	   /*  msb,lsb */
	Processor = 6803;
    }
    if (strcmp(str,"HD6303") == 0 || strcmp(str, "hd6303") == 0) {
	addhashtable(Mne6803);
	addhashtable(MneHD6303);
	MsbOrder = 1;	   /*  msb,lsb */
	Processor = 6303;
    }
    if (strcmp(str,"68705") == 0) {
	addhashtable(Mne68705);
	MsbOrder = 1;	   /*  msb,lsb */
	Processor = 68705;
    }
    if (strcmp(str,"68HC11") == 0 || strcmp(str, "68hc11") == 0) {
	addhashtable(Mne68HC11);
	MsbOrder = 1;	   /*  msb,lsb */
	Processor = 6811;
    }
    if (!Processor)
	asmerr(20,1);
}

#define badcode(mne,adrmode)  (!(mne->okmask & (1L << adrmode)))

void
v_mnemonic(str,mne)
register MNE *mne;
ubyte *str;
{
    register uword addrmode;
    register SYMBOL *sym;
    register uword opcode;
    short opidx;
    SYMBOL *symbase;
    short   opsize;

    Csegment->flags |= SF_REF;
    programlabel();
    symbase = eval(str);

    if (Xtrace)
	printf("PC: %04lx  MNE: %s  addrmode: %d  ", Csegment->org, mne->name, symbase->addrmode);
    for (sym = symbase; sym; sym = sym->next) {
	if (sym->flags & SYM_UNKNOWN) {
	    ++Redo;
	    Redo_why |= 1 << 0;
	}
    }
    sym = symbase;

    if (mne->flags & MF_IMOD) {
	if (sym->next) {
	    sym->addrmode = AM_BITMOD;
	    if ((mne->flags & MF_REL) && sym->next)
		sym->addrmode = AM_BITBRAMOD;
	}
    }
    addrmode = sym->addrmode;
    if ((sym->flags & SYM_UNKNOWN) || sym->value >= 0x100)
	opsize = 2;
    else
	opsize = (sym->value) ? 1 : 0;
    while (badcode(mne,addrmode) && Cvt[addrmode])
	addrmode = Cvt[addrmode];
    if (Xtrace)
	printf("mnemask: %08lx adrmode: %d  Cvt[am]: %d\n", mne->okmask, addrmode, Cvt[addrmode]);
    if (badcode(mne,addrmode)) {
	asmerr(5,0);
	freesymbollist(symbase);
	return;
    }
    if (Mnext >= 0 && Mnext < NUMOC) {          /*  Force   */
	addrmode = Mnext;
	if (badcode(mne,addrmode)) {
	    asmerr(19,0);
	    freesymbollist(symbase);
	    return;
	}
    }
    if (Xtrace)
	printf("final addrmode = %d\n", addrmode);
    while (opsize > Opsize[addrmode]) {
	if (Cvt[addrmode] == 0 || badcode(mne,Cvt[addrmode])) {
	    if (sym->flags & SYM_UNKNOWN)
		break;
	    asmerr(14,0);
	    break;
	}
	addrmode = Cvt[addrmode];
    }
    opcode = mne->opcode[addrmode];
    opidx = 1 + (opcode > 0xFF);
    if (opidx == 2) {
	Gen[0] = opcode >> 8;
	Gen[1] = opcode;
    } else {
	Gen[0] = opcode;
    }
    switch(addrmode) {
    case AM_BITMOD:
	sym = symbase->next;
	if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
	    asmerr(14,0);
	Gen[opidx++] = sym->value;
	if (!(symbase->flags & SYM_UNKNOWN)) {
	    if (symbase->value > 7)
		asmerr(15,0);
	    else
		Gen[0] += symbase->value << 1;
	}
	break;
    case AM_BITBRAMOD:
	if (!(symbase->flags & SYM_UNKNOWN)) {
	    if (symbase->value > 7)
		asmerr(15,0);
	    else
		Gen[0] += symbase->value << 1;
	}
	sym = symbase->next;
	if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
	    asmerr(14,0);
	Gen[opidx++] = sym->value;
	sym = sym->next;
	break;
    case AM_REL:
	break;
    default:
	if (Opsize[addrmode] > 0)
	    Gen[opidx++] = sym->value;
	if (Opsize[addrmode] == 2) {
	    if (MsbOrder) {
		Gen[opidx-1] = sym->value >> 8;
		Gen[opidx++] = sym->value;
	    } else {
		Gen[opidx++] = sym->value >> 8;
	    }
	}
	sym = sym->next;
	break;
    }
    if (mne->flags & MF_MASK) {
	if (sym) {
	    if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
		asmerr(14,0);
	    Gen[opidx] = sym->value;
	    sym = sym->next;
	} else {
	    asmerr(16, 1);
	}
	++opidx;
    }
    if ((mne->flags & MF_REL) || addrmode == AM_REL) {
	++opidx;		/*  to end of instruction   */
	if (!sym)
	    asmerr(16, 1);
	else
	if (!(sym->flags & SYM_UNKNOWN)) {
	    long    pc;
	    ubyte   pcf;
	    long    dest;
	    pc = (Csegment->flags & SF_RORG) ? Csegment->rorg : Csegment->org;
	    pcf= (Csegment->flags & SF_RORG) ? Csegment->rflags : Csegment->flags;
	    if ((pcf & 3) == 0) {
		dest = sym->value - pc - opidx;
		if (dest >= 128 || dest < -128)
		    asmerr(10,0);
	    }
	    Gen[opidx-1] = dest & 0xFF;     /*	byte before end of inst.    */
	}
    }
    Glen = opidx;
    generate();
    freesymbollist(symbase);
}


v_trace(str)
char *str;
{
    if (str[1] == 'n')
	Xtrace = 1;
    else
	Xtrace = 0;
}

v_list(str)
char *str;
{
    programlabel();

    Glen = 0;		/*  Only so outlist() works */
    if (strncmp(str, "off", 2) == 0 || strncmp(str, "OFF", 2) == 0)
	ListMode = 0;
    else
	ListMode = 1;
}

v_include(str)
char *str;
{
    char    *buf;

    programlabel();
    if (*str == '\"') {
	buf = (char *)malloc(strlen(str));
	strcpy(buf, str+1);
	for (str = buf; *str && *str != '\"'; ++str);
	*str = 0;
	pushinclude(buf);
	free(buf);
    } else {
	pushinclude(str);
    }
}

v_seg(str)
char *str;
{
    register SEGMENT *seg;

    for (seg = Seglist; seg; seg = seg->next) {
	if (strcmp(str, seg->name) == 0) {
	    Csegment = seg;
	    programlabel();
	    return;
	}
    }
    Csegment = seg = (SEGMENT *)zmalloc(sizeof(SEGMENT));
    seg->next = Seglist;
    seg->name = strcpy(malloc(strlen(str)+1), str);
    seg->flags= seg->rflags = seg->initflags = seg->initrflags = SF_UNKNOWN;
    Seglist = seg;
    if (Mnext == AM_BSS)
	seg->flags |= SF_BSS;
    programlabel();
}

v_hex(str)
register char *str;
{
    register int i;
    register int result;

    programlabel();
    Glen = 0;
    for (i = 0; str[i]; ++i) {
	if (str[i] == ' ')
	    continue;
	result = (gethexdig(str[i]) << 4) + gethexdig(str[i+1]);
	if (str[++i] == 0)
	    break;
	Gen[Glen++] = result;
    }
    generate();
}

gethexdig(c)
{
    if (c >= '0' && c <= '9')
	return(c - '0');
    if (c >= 'a' && c <= 'f')
	return(c - 'a' + 10);
    if (c >= 'A' && c <= 'F')
	return(c - 'A' + 10);
    asmerr(0,0);
    puts("(Must be a valid hex digit)");
    if (F_listfile)
	fputs("(Must be a valid hex digit)\n", FI_listfile);
    return(0);
}

v_err()
{
    programlabel();
    asmerr(11, 1);
    exit(1);
}

v_dc(str,mne)
char *str;
MNE *mne;
{
    register SYMBOL *sym;
    register SYMBOL *tmp;
    register ulong  value;
    char *macstr;
    char vmode = 0;

    Glen = 0;
    programlabel();
    if (mne->name[1] == 'v') {
	register short i;
	vmode = 1;
	for (i = 0; str[i] && str[i] != ' '; ++i);
	tmp = findsymbol(str, i);
	str += i;
	if (tmp == NULL) {
	    puts("EQM label not found");
	    return;
	}
	if (tmp->flags & SYM_MACRO) {
	    macstr = (char *)tmp->string;
	} else {
	    puts("must specify EQM label for DV");
	    return;
	}
    }
    sym = eval(str);
    for (; sym; sym = sym->next) {
	value = sym->value;
	if (sym->flags & SYM_UNKNOWN) {
	    ++Redo;
	    Redo_why |= (1 << 2);
	}
	if (sym->flags & SYM_STRING) {
	    register ubyte *ptr = (ubyte *)sym->string;
	    while (value = *ptr) {
		if (vmode) {
		    setspecial(value, 0);
		    tmp = eval(macstr);
		    value = tmp->value;
		    if (tmp->flags & SYM_UNKNOWN) {
			++Redo;
			Redo_why |= (1 << 3);
		    }
		    freesymbollist(tmp);
		}
		switch(Mnext) {
		default:
		case AM_BYTE:
		    Gen[Glen++] = value & 0xFF;
		    break;
		case AM_WORD:
		    if (MsbOrder) {
			Gen[Glen++] = (value >> 8) & 0xFF;
			Gen[Glen++] = value & 0xFF;
		    } else {
			Gen[Glen++] = value & 0xFF;
			Gen[Glen++] = (value >> 8) & 0xFF;
		    }
		    break;
		case AM_LONG:
		    if (MsbOrder) {
			Gen[Glen++] = (value >> 24)& 0xFF;
			Gen[Glen++] = (value >> 16)& 0xFF;
			Gen[Glen++] = (value >> 8) & 0xFF;
			Gen[Glen++] = value & 0xFF;
		    } else {
			Gen[Glen++] = value & 0xFF;
			Gen[Glen++] = (value >> 8) & 0xFF;
			Gen[Glen++] = (value >> 16)& 0xFF;
			Gen[Glen++] = (value >> 24)& 0xFF;
		    }
		    break;
		}
		++ptr;
	    }
	} else {
	    if (vmode) {
		setspecial(value, sym->flags);
		tmp = eval(macstr);
		value = tmp->value;
		if (tmp->flags & SYM_UNKNOWN) {
		    ++Redo;
		    Redo_why |= 1 << 4;
		}
		freesymbollist(tmp);
	    }
	    switch(Mnext) {
	    default:
	    case AM_BYTE:
		Gen[Glen++] = value & 0xFF;
		break;
	    case AM_WORD:
		if (MsbOrder) {
		    Gen[Glen++] = (value >> 8) & 0xFF;
		    Gen[Glen++] = value & 0xFF;
		} else {
		    Gen[Glen++] = value & 0xFF;
		    Gen[Glen++] = (value >> 8) & 0xFF;
		}
		break;
	    case AM_LONG:
		if (MsbOrder) {
		    Gen[Glen++] = (value >> 24)& 0xFF;
		    Gen[Glen++] = (value >> 16)& 0xFF;
		    Gen[Glen++] = (value >> 8) & 0xFF;
		    Gen[Glen++] = value & 0xFF;
		} else {
		    Gen[Glen++] = value & 0xFF;
		    Gen[Glen++] = (value >> 8) & 0xFF;
		    Gen[Glen++] = (value >> 16)& 0xFF;
		    Gen[Glen++] = (value >> 24)& 0xFF;
		}
		break;
	    }
	}
    }
    generate();
    freesymbollist(sym);
}

v_ds(str)
char *str;
{
    register SYMBOL *sym;
    int mult = 1;
    long filler = 0;

    if (Mnext == AM_WORD)
	mult = 2;
    if (Mnext == AM_LONG)
	mult = 4;
    programlabel();
    if (sym = eval(str)) {
	if (sym->next)
	    filler = sym->next->value;
	if (sym->flags & SYM_UNKNOWN) {
	    ++Redo;
	    Redo_why |= 1 << 5;
	} else {
	    if (sym->next && sym->next->flags & SYM_UNKNOWN) {
		++Redo;
		Redo_why |= 1 << 5;
	    }
	    genfill(filler, sym->value, mult);
	}
	freesymbollist(sym);
    }
}

v_org(str)
char *str;
{
    register SYMBOL *sym;

    sym = eval(str);
    Csegment->org = sym->value;
    if (sym->flags & SYM_UNKNOWN)
	Csegment->flags |= SYM_UNKNOWN;
    else
	Csegment->flags &= ~SYM_UNKNOWN;
    if (Csegment->initflags & SYM_UNKNOWN) {
	Csegment->initorg = sym->value;
	Csegment->initflags = sym->flags;
    }
    if (sym->next) {
	OrgFill = sym->next->value;
	if (sym->next->flags & SYM_UNKNOWN)
	    asmerr(18,1);
    }
    programlabel();
    freesymbollist(sym);
}

v_rorg(str)
char *str;
{
    register SYMBOL *sym = eval(str);

    Csegment->flags |= SF_RORG;
    if (sym->addrmode != AM_IMP) {
	Csegment->rorg = sym->value;
	if (sym->flags & SYM_UNKNOWN)
	    Csegment->rflags |= SYM_UNKNOWN;
	else
	    Csegment->rflags &= ~SYM_UNKNOWN;
	if (Csegment->initrflags & SYM_UNKNOWN) {
	    Csegment->initrorg = sym->value;
	    Csegment->initrflags = sym->flags;
	}
    }
    programlabel();
    freesymbollist(sym);
}

v_rend()
{
    programlabel();
    Csegment->flags &= ~SF_RORG;
}

v_align(str)
char *str;
{
    SYMBOL *sym = eval(str);
    ubyte   fill = 0;
    ubyte   rorg = Csegment->flags & SF_RORG;

    if (rorg)
	Csegment->rflags |= SF_REF;
    else
	Csegment->flags |= SF_REF;
    if (sym->next) {
	if (sym->next->flags & SYM_UNKNOWN) {
	    ++Redo;
	    Redo_why |= 1 << 6;
	} else {
	    fill = sym->value;
	}
    }
    if (rorg) {
	if ((Csegment->rflags | sym->flags) & SYM_UNKNOWN) {
	    ++Redo;
	    Redo_why |= 1 << 7;
	} else {
	    register long n = sym->value - (Csegment->rorg % sym->value);
	    if (n != sym->value)
		genfill(fill, n, 1);
	}
    } else {
	if ((Csegment->flags | sym->flags) & SYM_UNKNOWN) {
	    ++Redo;
	    Redo_why |= 1 << 8;
	} else {
	    register long n = sym->value - (Csegment->org % sym->value);
	    if (n != sym->value)
		genfill(fill, n, 1);
	}
    }
    freesymbollist(sym);
    programlabel();
}

v_subroutine()
{
    ++Lastlocalindex;
    Localindex = Lastlocalindex;
    programlabel();
}

v_equ(str)
char *str;
{
    SYMBOL *sym = eval(str);
    SYMBOL *lab;

    lab = findsymbol(Av[0], strlen(Av[0]));
    if (!lab)
	lab = createsymbol(Av[0], strlen(Av[0]));
    if (!(lab->flags & SYM_UNKNOWN)) {
	if (sym->flags & SYM_UNKNOWN) {
	    ++Redo;
	    Redo_why |= 1 << 9;
	} else {
	    if (lab->value != sym->value) {
		asmerr(13,0);
		printf("old value: $%04lx  new value: $%04lx\n", lab->value, sym->value);
		++Redo;
		Redo_why |= 1 << 10;
	    }
	}
    }
    lab->value = sym->value;
    lab->flags = sym->flags & (SYM_UNKNOWN|SYM_STRING);
    lab->string = sym->string;
    sym->flags &= ~(SYM_STRING|SYM_MACRO);
    freesymbollist(sym);
}

v_eqm(str)
char *str;
{
    register SYMBOL *lab;
    register int len = strlen(Av[0]);

    if (lab = findsymbol(Av[0], len)) {
	if (lab->flags & SYM_STRING)
	    free(lab->string);
    } else {
	lab = createsymbol(Av[0], len);
    }
    lab->value = 0;
    lab->flags = SYM_STRING | SYM_SET | SYM_MACRO;
    lab->string = strcpy(malloc(strlen(str)+1), str);
}

v_echo(str)
char *str;
{
    SYMBOL *sym = eval(str);
    SYMBOL *s;
    char buf[256];

    for (s = sym; s; s = s->next) {
	if (!(s->flags & SYM_UNKNOWN)) {
	    if (s->flags & (SYM_MACRO|SYM_STRING))
		sprintf(buf,"%s", s->string);
	    else
		sprintf(buf,"$%lx", s->value);
	    if (FI_listfile)
		fprintf(FI_listfile, " %s", buf);
	    printf(" %s", buf);
	}
    }
    puts("");
    if (FI_listfile)
	putc('\n', FI_listfile);
}

v_set(str)
char *str;
{
    SYMBOL *sym = eval(str);
    SYMBOL *lab;

    lab = findsymbol(Av[0], strlen(Av[0]));
    if (!lab)
	lab = createsymbol(Av[0], strlen(Av[0]));
    lab->value = sym->value;
    lab->flags = sym->flags & (SYM_UNKNOWN|SYM_STRING);
    lab->string = sym->string;
    sym->flags &= ~(SYM_STRING|SYM_MACRO);
    freesymbollist(sym);
}

v_execmac(str,mac)
char *str;
MACRO *mac;
{
    register INCFILE *inc;
    STRLIST *base;
    register STRLIST **psl, *sl;
    register char *s1, *s2;

    programlabel();

    if (Mlevel == MAXMACLEVEL) {
	puts("infinite macro recursion");
	return(0);
    }
    ++Mlevel;
    base = (STRLIST *)malloc(strlen(str)+5);
    base->next = NULL;
    strcpy(base->buf, str);
    psl = &base->next;
    while (*str && *str != '\n') {
	s1 = str;
	while (*str && *str != '\n' && *str != ',')
	    ++str;
	sl = (STRLIST *)malloc(5+(str-s1));
	sl->next = NULL;
	*psl = sl;
	psl = &sl->next;
	bmov(s1, sl->buf, (str-s1));
	sl->buf[str-s1] = 0;
	if (*str == ',')
	    ++str;
	while (*str == ' ')
	    ++str;
    }

    inc = (INCFILE *)zmalloc(sizeof(INCFILE));
    inc->next = Incfile;
    inc->name = mac->name;
    inc->fi   = Incfile->fi;	/* garbage */
    inc->lineno = 0;
    inc->flags = INF_MACRO;
    inc->saveidx = Localindex;
    inc->strlist = mac->strlist;
    inc->args	 = base;
    Incfile = inc;

    ++Lastlocalindex;
    Localindex = Lastlocalindex;
}

void
v_end()
{
    puts("END not implemented yet");
}

void
v_endm()
{
    register INCFILE *inc = Incfile;
    register STRLIST *args, *an;

    programlabel();
    if (inc->flags & INF_MACRO) {
	--Mlevel;
	for (args = inc->args; args; args = an) {
	    an = args->next;
	    free(args);
	}
	Localindex = inc->saveidx;
	Incfile = inc->next;
	free(inc);
	return;
    }
    puts("not within a macro");
}

v_mexit()
{
    v_endm();
}

v_ifconst(str)
char *str;
{
    SYMBOL *sym;

    programlabel();
    sym = eval(str);
    pushif(sym->flags == 0);
    freesymbollist(sym);
}

v_ifnconst(str)
char *str;
{
    SYMBOL *sym;

    programlabel();
    sym = eval(str);
    pushif(sym->flags != 0);
    freesymbollist(sym);
}

void
v_if(str)
char *str;
{
    SYMBOL *sym;

    if (!Ifstack->true || !Ifstack->acctrue) {
	pushif(0);
	return;
    }
    programlabel();
    sym = eval(str);
    if (sym->flags) {
	++Redo;
	Redo_why |= 1 << 11;
	pushif(0);
	Ifstack->acctrue = 0;
    } else {
	pushif((short)!!sym->value);
    }
    freesymbollist(sym);
}

v_else()
{
    if (Ifstack->acctrue && !(Ifstack->flags & IFF_BASE)) {
	programlabel();
	Ifstack->true = !Ifstack->true;
    }
}

v_endif()
{
    IFSTACK *ifs = Ifstack;

    if (!(ifs->flags & IFF_BASE)) {
	if (ifs->acctrue)
	    programlabel();
	if (ifs->file != Incfile) {
	    puts("too many endif's");
	} else {
	    Ifstack = ifs->next;
	    free(ifs);
	}
    }
}

v_repeat(str)
char *str;
{
    register REPLOOP *rp;
    register SYMBOL *sym;

    if (!Ifstack->true || !Ifstack->acctrue) {
	pushif(0);
	return;
    }
    programlabel();
    sym = eval(str);
    if (sym->value == 0) {
	pushif(0);
	freesymbollist(sym);
	return;
    }
    rp = (REPLOOP *)zmalloc(sizeof(REPLOOP));
    rp->next = Reploop;
    rp->file = Incfile;
    if (Incfile->flags & INF_MACRO)
	rp->seek = (long)Incfile->strlist;
    else
	rp->seek = ftell(Incfile->fi);
    rp->lineno = Incfile->lineno;
    rp->count = sym->value;
    if (rp->flags = sym->flags) {
	++Redo;
	Redo_why |= 1 << 12;
    }
    Reploop = rp;
    freesymbollist(sym);
    pushif(1);
}

void
v_repend()
{
    if (!Ifstack->true || !Ifstack->acctrue) {
	v_endif();
	return;
    }
    if (Reploop && Reploop->file == Incfile) {
	if (Reploop->flags == 0 && --Reploop->count) {
	    if (Incfile->flags & INF_MACRO)
		Incfile->strlist = (STRLIST *)Reploop->seek;
	    else
		fseek(Incfile->fi,Reploop->seek,0);
	    Incfile->lineno = Reploop->lineno;
	} else {
	    rmnode(&Reploop, sizeof(REPLOOP));
	    v_endif();
	}
	return;
    }
    puts("no repeat");
}

static long Seglen;
static long Seekback;

void
generate()
{
    long seekpos;
    static ulong org;
    short i;

    if (!Redo) {
	if (!(Csegment->flags & SF_BSS)) {
	    for (i = Glen - 1; i >= 0; --i)
		CheckSum += Gen[i];
	    if (Fisclear) {
		Fisclear = 0;
		if (Csegment->flags & SF_UNKNOWN) {
		    ++Redo;
		    Redo_why |= 1 << 1;
		    return;
		}
		org = Csegment->org;
		if (F_format < 3) {
		    putc((short)(org & 0xFF), FI_temp);
		    putc((short)((org >> 8) & 0xFF), FI_temp);
		    if (F_format == 2) {
			Seekback = ftell(FI_temp);
			Seglen = 0;
			putc(0, FI_temp);
			putc(0, FI_temp);
		    }
		}
	    }
	    switch(F_format) {
	    default:
	    case 3:
	    case 1:
		if (Csegment->org < org) {
		    printf("segment: %s %s  vs current org: %04lx\n", Csegment->name, sftos(Csegment->org, Csegment->flags), org);
		    asmerr(12, 1);
		    exit(1);
		}
		while (Csegment->org != org) {
		    putc(OrgFill, FI_temp);
		    ++org;
		}
		fwrite(Gen, Glen, 1, FI_temp);
		break;
	    case 2:
		if (org != Csegment->org) {
		    org = Csegment->org;
		    seekpos = ftell(FI_temp);
		    fseek(FI_temp, Seekback, 0);
		    putc((short)(Seglen & 0xFF), FI_temp);
		    putc((short)((Seglen >> 8) & 0xFF), FI_temp);
		    fseek(FI_temp, seekpos, 0);
		    putc((short)(org & 0xFF), FI_temp);
		    putc((short)((org >> 8) & 0xFF), FI_temp);
		    Seekback = ftell(FI_temp);
		    Seglen = 0;
		    putc(0, FI_temp);
		    putc(0, FI_temp);
		}
		fwrite(Gen, Glen, 1, FI_temp);
		Seglen += Glen;
	    }
	    org += Glen;
	}
    }
    Csegment->org += Glen;
    if (Csegment->flags & SF_RORG)
	Csegment->rorg += Glen;
}

void
closegenerate()
{
    if (!Redo) {
	if (F_format == 2) {
	    fseek(FI_temp, Seekback, 0);
	    putc((short)(Seglen & 0xFF), FI_temp);
	    putc((short)((Seglen >> 8) & 0xFF), FI_temp);
	    fseek(FI_temp, 0L, 2);
	}
    }
}

void
genfill(fill, entries, size)
long fill, entries;
{
    register long bytes = entries;  /*	multiplied later    */
    register short i;
    register ubyte c3,c2,c1,c0;

    if (!bytes)
	return;
    c3 = fill >> 24;
    c2 = fill >> 16;
    c1 = fill >> 8;
    c0 = fill;
    switch(size) {
    case 1:
	bset(Gen, sizeof(Gen), c0);
	break;
    case 2:
	bytes <<= 1;
	for (i = 0; i < sizeof(Gen); i += 2) {
	    if (MsbOrder) {
		Gen[i+0] = c1;
		Gen[i+1] = c0;
	    } else {
		Gen[i+0] = c0;
		Gen[i+1] = c1;
	    }
	}
	break;
    case 4:
	bytes <<= 2;
	for (i = 0; i < sizeof(Gen); i += 4) {
	    if (MsbOrder) {
		Gen[i+0] = c3;
		Gen[i+1] = c2;
		Gen[i+2] = c1;
		Gen[i+3] = c0;
	    } else {
		Gen[i+0] = c0;
		Gen[i+1] = c1;
		Gen[i+2] = c2;
		Gen[i+3] = c3;
	    }	 
	}
	break;
    }
    for (Glen = sizeof(Gen); bytes > sizeof(Gen); bytes -= sizeof(Gen))
	generate();
    Glen = bytes;
    generate();
}

void
pushif(bool)
{
    register IFSTACK *ifs = (IFSTACK *)zmalloc(sizeof(IFSTACK));
    ifs->next = Ifstack;
    ifs->file = Incfile;
    ifs->flags = 0;
    ifs->true  = bool;
    ifs->acctrue = Ifstack->acctrue && Ifstack->true;
    Ifstack = ifs;
}

\Rogue\Monster\
else
  echo "will not over write src/ops.c"
fi
if [ `wc -c src/ops.c | awk '{printf $1}'` -ne 20291 ]
then
echo `wc -c src/ops.c | awk '{print "Got " $1 ", Expected " 20291}'`
fi
if `test ! -s src/mne6502.c`
then
echo "writing src/mne6502.c"
cat > src/mne6502.c << '\Rogue\Monster\'

/*
 *  MNE6502.C
 *
 *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
 *
 */

#include "asm.h"

extern void v_mnemonic();

#define ASTD	AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX|\
		AF_WORDADRY|AF_INDBYTEX|AF_INDBYTEY

MNE Mne6502[] = {
    NULL, v_mnemonic, "adc", 0, AF_IMM8|ASTD,
    { 0x69, 0x65, 0x75, 0x6D, 0x7D, 0x79, 0x61, 0x71 },
    NULL, v_mnemonic, "and", 0, AF_IMM8|ASTD,
    { 0x29, 0x25, 0x35, 0x2D, 0x3D, 0x39, 0x21, 0x31 },
    NULL, v_mnemonic, "asl", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX,
    { 0x0A, 0x06, 0x16, 0x0E, 0x1E },
    NULL, v_mnemonic, "bcc", 0, AF_REL, { 0x90 },
    NULL, v_mnemonic, "bcs", 0, AF_REL, { 0xB0 },
    NULL, v_mnemonic, "beq", 0, AF_REL, { 0xF0 },
    NULL, v_mnemonic, "bit", 0, AF_BYTEADR|AF_WORDADR,
    { 0x24, 0x2C },
    NULL, v_mnemonic, "bmi", 0, AF_REL, { 0x30 },
    NULL, v_mnemonic, "bne", 0, AF_REL, { 0xD0 },
    NULL, v_mnemonic, "bpl", 0, AF_REL, { 0x10 },
    NULL, v_mnemonic, "brk", 0, AF_IMP, { 0x00 },
    NULL, v_mnemonic, "bvc", 0, AF_REL, { 0x50 },
    NULL, v_mnemonic, "bvs", 0, AF_REL, { 0x70 },
    NULL, v_mnemonic, "clc", 0, AF_IMP, { 0x18 },
    NULL, v_mnemonic, "cld", 0, AF_IMP, { 0xD8 },
    NULL, v_mnemonic, "cli", 0, AF_IMP, { 0x58 },
    NULL, v_mnemonic, "clv", 0, AF_IMP, { 0xB8 },
    NULL, v_mnemonic, "cmp", 0, AF_IMM8|ASTD,
    { 0xC9, 0xC5, 0xD5, 0xCD, 0xDD, 0xD9, 0xC1, 0xD1 },
    NULL, v_mnemonic, "cpx", 0, AF_IMM8|AF_BYTEADR|AF_WORDADR,
    { 0xE0, 0xE4, 0xEC },
    NULL, v_mnemonic, "cpy", 0, AF_IMM8|AF_BYTEADR|AF_WORDADR,
    { 0xC0, 0xC4, 0xCC },
    NULL, v_mnemonic, "dec", 0, AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX,
    { 0xC6, 0xD6, 0xCE, 0xDE },
    NULL, v_mnemonic, "dex", 0, AF_IMP, { 0xCA },
    NULL, v_mnemonic, "dey", 0, AF_IMP, { 0x88 },
    NULL, v_mnemonic, "eor", 0, AF_IMM8|ASTD,
    { 0x49, 0x45, 0x55, 0x4D, 0x5D, 0x59, 0x41,0x51 },
    NULL, v_mnemonic, "inc", 0, AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX,
    { 0xE6, 0xF6, 0xEE, 0xFE },
    NULL, v_mnemonic, "inx", 0, AF_IMP, { 0xE8 },
    NULL, v_mnemonic, "iny", 0, AF_IMP, { 0xC8 },
    NULL, v_mnemonic, "jmp", 0, AF_WORDADR|AF_INDWORD,
    { 0x4C, 0x6C },
    NULL, v_mnemonic, "jsr", 0, AF_WORDADR, { 0x20 },
    NULL, v_mnemonic, "lda", 0, AF_IMM8|ASTD,
    { 0xA9, 0xA5, 0xB5, 0xAD, 0xBD, 0xB9, 0xA1, 0xB1 },
    NULL, v_mnemonic, "ldx", 0, AF_IMM8|AF_BYTEADR|AF_BYTEADRY|AF_WORDADR|AF_WORDADRY,
    { 0xA2, 0xA6, 0xB6, 0xAE, 0xBE },
    NULL, v_mnemonic, "ldy", 0, AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX,
    { 0xA0, 0xA4, 0xB4, 0xAC, 0xBC },
    NULL, v_mnemonic, "lsr", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX,
    { 0x4A, 0x46, 0x56, 0x4E, 0x5E },
    NULL, v_mnemonic, "nop", 0, AF_IMP, { 0xEA },
    NULL, v_mnemonic, "ora", 0, AF_IMM8|ASTD,
    { 0x09, 0x05, 0x15, 0x0D, 0x1D, 0x19, 0x01, 0x11 },
    NULL, v_mnemonic, "pha", 0, AF_IMP, { 0x48 },
    NULL, v_mnemonic, "php", 0, AF_IMP, { 0x08 },
    NULL, v_mnemonic, "pla", 0, AF_IMP, { 0x68 },
    NULL, v_mnemonic, "plp", 0, AF_IMP, { 0x28 },
    NULL, v_mnemonic, "rol", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX,
    { 0x2A, 0x26, 0x36, 0x2E, 0x3E },
    NULL, v_mnemonic, "ror", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX,
    { 0x6A, 0x66, 0x76, 0x6E, 0x7E },
    NULL, v_mnemonic, "rti", 0, AF_IMP, { 0x40 },
    NULL, v_mnemonic, "rts", 0, AF_IMP, { 0x60 },
    NULL, v_mnemonic, "sbc", 0, AF_IMM8|ASTD,
    { 0xE9, 0xE5, 0xF5, 0xED, 0xFD, 0xF9, 0xE1, 0xF1 },
    NULL, v_mnemonic, "sec", 0, AF_IMP, { 0x38 },
    NULL, v_mnemonic, "sed", 0, AF_IMP, { 0xF8 },
    NULL, v_mnemonic, "sei", 0, AF_IMP, { 0x78 },
    NULL, v_mnemonic, "sta", 0, ASTD,
    { 0x85, 0x95, 0x8D, 0x9D, 0x99, 0x81, 0x91 },
    NULL, v_mnemonic, "stx", 0, AF_BYTEADR|AF_BYTEADRY|AF_WORDADR,
    { 0x86, 0x96, 0x8E },
    NULL, v_mnemonic, "sty", 0, AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
    { 0x84, 0x94, 0x8C },
    NULL, v_mnemonic, "tax", 0, AF_IMP, { 0xAA },
    NULL, v_mnemonic, "tay", 0, AF_IMP, { 0xA8 },
    NULL, v_mnemonic, "tsx", 0, AF_IMP, { 0xBA },
    NULL, v_mnemonic, "txa", 0, AF_IMP, { 0x8A },
    NULL, v_mnemonic, "txs", 0, AF_IMP, { 0x9A },
    NULL, v_mnemonic, "tya", 0, AF_IMP, { 0x98 },
    NULL
};



\Rogue\Monster\
else
  echo "will not over write src/mne6502.c"
fi
if [ `wc -c src/mne6502.c | awk '{printf $1}'` -ne 4254 ]
then
echo `wc -c src/mne6502.c | awk '{print "Got " $1 ", Expected " 4254}'`
fi
if `test ! -s src/mne6811.c`
then
echo "writing src/mne6811.c"
cat > src/mne6811.c << '\Rogue\Monster\'

/*
 *  MNE6811.C
 *
 *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
 *
 *  68HC11 processor
 *
 *  addressing modes:
 *	AF_IMM8
 *	AF_IMM16
 *	AF_BYTEADR
 *	AF_WORDADR
 *	AF_BYTEADRX
 *	AF_BYTEADRY
 *	AF_IMP
 *	AF_REL
 *
 *  flags:
 *	MF_MASK     contains additional byte argument
 *	MF_REL	    contains additional relative argument
 */

#include "asm.h"

extern void v_mnemonic();

#define AF_STD	 (AF_BYTEADR|AF_BYTEADRX|AF_BYTEADRY|AF_WORDADR)
#define AF_STDI  (AF_IMM8|AF_STD)
#define AF_STDD  (AF_IMM16|AF_STD)
#define AF_ASL	 (AF_BYTEADRX|AF_BYTEADRY|AF_WORDADR)
#define AF_BCLR  (AF_BYTEADR|AF_BYTEADRX|AF_BYTEADRY)

MNE Mne68HC11[] = {
    NULL, v_mnemonic, "aba",    0, AF_IMP, { 0x1B },
    NULL, v_mnemonic, "abx",    0, AF_IMP, { 0x3A },
    NULL, v_mnemonic, "aby",    0, AF_IMP, { 0x183A },
    NULL, v_mnemonic, "adca",   0, AF_STDI,{ 0x89, 0x99, 0xA9, 0x18A9, 0xB9 },
    NULL, v_mnemonic, "adcb",   0, AF_STDI,{ 0xC9, 0xD9, 0xE9, 0x18E9, 0xF9 },
    NULL, v_mnemonic, "adda",   0, AF_STDI,{ 0x8B, 0x9B, 0xAB, 0x18AB, 0xBB },
    NULL, v_mnemonic, "addb",   0, AF_STDI,{ 0xCB, 0xDB, 0xEB, 0x18EB, 0xFB },
    NULL, v_mnemonic, "addd",   0, AF_STDD,{ 0xC3, 0xD3, 0xE3, 0x18E3, 0xF3 },
    NULL, v_mnemonic, "anda",   0, AF_STDI,{ 0x84, 0x94, 0xA4, 0x18A4, 0xB4 },
    NULL, v_mnemonic, "andb",   0, AF_STDI,{ 0xC4, 0xD4, 0xE4, 0x18E4, 0xF4 },
    NULL, v_mnemonic, "asla",   0, AF_IMP, { 0x48 },
    NULL, v_mnemonic, "aslb",   0, AF_IMP, { 0x58 },
    NULL, v_mnemonic, "asl",    0, AF_ASL, { 0x68, 0x1868, 0x78 },
    NULL, v_mnemonic, "asld",   0, AF_IMP, { 0x05 },
    NULL, v_mnemonic, "asra",   0, AF_IMP, { 0x47 },
    NULL, v_mnemonic, "asrb",   0, AF_IMP, { 0x57 },
    NULL, v_mnemonic, "asr",    0, AF_ASL, { 0x67, 0x1867, 0x77 },
    /*	no asrd */
    NULL, v_mnemonic, "bcc",    0, AF_REL, { 0x24 },
    NULL, v_mnemonic, "bclr",   MF_MASK, AF_BCLR, { 0x15, 0x1D, 0x181D },
    NULL, v_mnemonic, "bcs",    0, AF_REL, { 0x25 },
    NULL, v_mnemonic, "beq",    0, AF_REL, { 0x27 },
    NULL, v_mnemonic, "bge",    0, AF_REL, { 0x2C },
    NULL, v_mnemonic, "bgt",    0, AF_REL, { 0x2E },
    NULL, v_mnemonic, "bhi",    0, AF_REL, { 0x22 },
    NULL, v_mnemonic, "bhs",    0, AF_REL, { 0x24 },
    NULL, v_mnemonic, "bita",   0, AF_STDI,{ 0x85, 0x95, 0xA5, 0x18A5, 0xB5 },
    NULL, v_mnemonic, "bitb",   0, AF_STDI,{ 0xC5, 0xD5, 0xE5, 0x18E5, 0xF5 },
    NULL, v_mnemonic, "ble",    0, AF_REL, { 0x2F },
    NULL, v_mnemonic, "blo",    0, AF_REL, { 0x25 },
    NULL, v_mnemonic, "bls",    0, AF_REL, { 0x23 },
    NULL, v_mnemonic, "blt",    0, AF_REL, { 0x2D },
    NULL, v_mnemonic, "bmi",    0, AF_REL, { 0x2B },
    NULL, v_mnemonic, "bne",    0, AF_REL, { 0x26 },
    NULL, v_mnemonic, "bpl",    0, AF_REL, { 0x2A },
    NULL, v_mnemonic, "bra",    0, AF_REL, { 0x20 },
    NULL, v_mnemonic, "brclr",  MF_MASK|MF_REL, AF_BCLR,{ 0x13, 0x1F, 0x181F },
    NULL, v_mnemonic, "brn",    0, AF_REL, { 0x21 },
    NULL, v_mnemonic, "brset",  MF_MASK|MF_REL, AF_BCLR,{ 0x12, 0x1E, 0x181E },
    NULL, v_mnemonic, "bset",   MF_MASK, AF_BCLR, { 0x14, 0x1C, 0x181C },
    NULL, v_mnemonic, "bsr",    0, AF_REL, { 0x8D },
    NULL, v_mnemonic, "bvc",    0, AF_REL, { 0x28 },
    NULL, v_mnemonic, "bvs",    0, AF_REL, { 0x29 },
    NULL, v_mnemonic, "cba",    0, AF_IMP, { 0x11 },
    NULL, v_mnemonic, "clc",    0, AF_IMP, { 0x0C },
    NULL, v_mnemonic, "cli",    0, AF_IMP, { 0x0E },
    NULL, v_mnemonic, "clra",   0, AF_IMP, { 0x4F },
    NULL, v_mnemonic, "clrb",   0, AF_IMP, { 0x5F },
    NULL, v_mnemonic, "clr",    0, AF_ASL, { 0x6F, 0x186F, 0x7F },
    NULL, v_mnemonic, "clv",    0, AF_IMP, { 0x0A },
    NULL, v_mnemonic, "cmpa",   0, AF_STDI,{ 0x81, 0x91, 0xA1, 0x18A1, 0xB1 },
    NULL, v_mnemonic, "cmpb",   0, AF_STDI,{ 0xC1, 0xD1, 0xE1, 0x18E1, 0xF1 },
    NULL, v_mnemonic, "coma",   0, AF_IMP, { 0x43 },
    NULL, v_mnemonic, "comb",   0, AF_IMP, { 0x53 },
    NULL, v_mnemonic, "com",    0, AF_ASL, { 0x63, 0x1863, 0x73 },
    NULL, v_mnemonic, "cpd",    0, AF_STDD,{ 0x1A83, 0x1A93, 0x1AA3, 0xCDA3, 0x1AB3 },
    NULL, v_mnemonic, "cpx",    0, AF_STDD,{ 0x8C, 0x9C, 0xAC, 0xCDAC, 0xBC },
    NULL, v_mnemonic, "cpy",    0, AF_STDD,{ 0x188C, 0x189C, 0x1AAC, 0x18AC, 0x18BC },
    NULL, v_mnemonic, "daa",    0, AF_IMP, { 0x19 },
    NULL, v_mnemonic, "deca",   0, AF_IMP, { 0x4A },
    NULL, v_mnemonic, "decb",   0, AF_IMP, { 0x5A },
    NULL, v_mnemonic, "dec",    0, AF_ASL, { 0x6A, 0x186A, 0x7A },
    NULL, v_mnemonic, "des",    0, AF_IMP, { 0x34 },
    NULL, v_mnemonic, "dex",    0, AF_IMP, { 0x09 },
    NULL, v_mnemonic, "dey",    0, AF_IMP, { 0x1809 },
    NULL, v_mnemonic, "eora",   0, AF_STDI,{ 0x88, 0x98, 0xA8, 0x18A8, 0xB8 },
    NULL, v_mnemonic, "eorb",   0, AF_STDI,{ 0xC8, 0xD8, 0xE8, 0x18E8, 0xF8 },
    NULL, v_mnemonic, "fdiv",   0, AF_IMP, { 0x03 },
    NULL, v_mnemonic, "idiv",   0, AF_IMP, { 0x02 },
    NULL, v_mnemonic, "inca",   0, AF_IMP, { 0x4C },
    NULL, v_mnemonic, "incb",   0, AF_IMP, { 0x5C },
    NULL, v_mnemonic, "inc",    0, AF_ASL, { 0x6C, 0x186C, 0x7C },
    NULL, v_mnemonic, "ins",    0, AF_IMP, { 0x31 },
    NULL, v_mnemonic, "inx",    0, AF_IMP, { 0x08 },
    NULL, v_mnemonic, "iny",    0, AF_IMP, { 0x1808 },
    NULL, v_mnemonic, "jmp",    0, AF_ASL, { 0x6E, 0x186E, 0x7E },
    NULL, v_mnemonic, "jsr",    0, AF_STD, { 0x9D, 0xAD, 0x18AD, 0xBD },
    NULL, v_mnemonic, "ldaa",   0, AF_STDI,{ 0x86, 0x96, 0xA6, 0x18A6, 0xB6 },
    NULL, v_mnemonic, "ldab",   0, AF_STDI,{ 0xC6, 0xD6, 0xE6, 0x18E6, 0xF6 },
    NULL, v_mnemonic, "ldd",    0, AF_STDD,{ 0xCC, 0xDC, 0xEC, 0x18EC, 0xFC },
    NULL, v_mnemonic, "lds",    0, AF_STDD,{ 0x8E, 0x9E, 0xAE, 0x18AE, 0xBE },
    NULL, v_mnemonic, "ldx",    0, AF_STDD,{ 0xCE, 0xDE, 0xEE, 0xCDEE, 0xFE },
    NULL, v_mnemonic, "ldy",    0, AF_STDD,{ 0x18CE, 0x18DE, 0x1AEE, 0x18EE, 0x18FE },
    NULL, v_mnemonic, "lsla",   0, AF_IMP, { 0x48 },
    NULL, v_mnemonic, "lslb",   0, AF_IMP, { 0x58 },
    NULL, v_mnemonic, "lsl",    0, AF_ASL, { 0x68, 0x1868, 0x78 },
    NULL, v_mnemonic, "lsld",   0, AF_IMP, { 0x05 },
    NULL, v_mnemonic, "lsra",   0, AF_IMP, { 0x44 },
    NULL, v_mnemonic, "lsrb",   0, AF_IMP, { 0x54 },
    NULL, v_mnemonic, "lsr",    0, AF_ASL, { 0x64, 0x1864, 0x74 },
    NULL, v_mnemonic, "lsrd",   0, AF_IMP, { 0x04 },
    NULL, v_mnemonic, "mul",    0, AF_IMP, { 0x3D },
    NULL, v_mnemonic, "nega",   0, AF_IMP, { 0x40 },
    NULL, v_mnemonic, "negb",   0, AF_IMP, { 0x50 },
    NULL, v_mnemonic, "neg",    0, AF_ASL, { 0x60, 0x1860, 0x70 },
    NULL, v_mnemonic, "nop",    0, AF_IMP, { 0x01 },
    NULL, v_mnemonic, "oraa",   0, AF_STDI,{ 0x8A, 0x9A, 0xAA, 0x18AA, 0xBA },
    NULL, v_mnemonic, "orab",   0, AF_STDI,{ 0xCA, 0xDA, 0xEA, 0x18EA, 0xFA },
    NULL, v_mnemonic, "psha",   0, AF_IMP, { 0x36 },
    NULL, v_mnemonic, "pshb",   0, AF_IMP, { 0x37 },
    NULL, v_mnemonic, "pshx",   0, AF_IMP, { 0x3C },
    NULL, v_mnemonic, "pshy",   0, AF_IMP, { 0x183C },
    NULL, v_mnemonic, "pula",   0, AF_IMP, { 0x32 },
    NULL, v_mnemonic, "pulb",   0, AF_IMP, { 0x33 },
    NULL, v_mnemonic, "pulx",   0, AF_IMP, { 0x38 },
    NULL, v_mnemonic, "puly",   0, AF_IMP, { 0x1838 },
    NULL, v_mnemonic, "rola",   0, AF_IMP, { 0x49 },
    NULL, v_mnemonic, "rolb",   0, AF_IMP, { 0x59 },
    NULL, v_mnemonic, "rol",    0, AF_ASL, { 0x69, 0x1869, 0x79 },
    NULL, v_mnemonic, "rora",   0, AF_IMP, { 0x46 },
    NULL, v_mnemonic, "rorb",   0, AF_IMP, { 0x56 },
    NULL, v_mnemonic, "ror",    0, AF_ASL, { 0x66, 0x1866, 0x76 },
    NULL, v_mnemonic, "rti",    0, AF_IMP, { 0x3B },
    NULL, v_mnemonic, "rts",    0, AF_IMP, { 0x39 },
    NULL, v_mnemonic, "sba",    0, AF_IMP, { 0x10 },
    NULL, v_mnemonic, "sbca",   0, AF_STDI,{ 0x82, 0x92, 0xA2, 0x18A2, 0xB2 },
    NULL, v_mnemonic, "sbcb",   0, AF_STDI,{ 0xC2, 0xD2, 0xE2, 0x18E2, 0xF2 },
    NULL, v_mnemonic, "sec",    0, AF_IMP, { 0x0D },
    NULL, v_mnemonic, "sei",    0, AF_IMP, { 0x0F },
    NULL, v_mnemonic, "sev",    0, AF_IMP, { 0x0B },
    NULL, v_mnemonic, "staa",   0, AF_STD, { 0x97, 0xA7, 0x18A7, 0xB7 },
    NULL, v_mnemonic, "stab",   0, AF_STD, { 0xD7, 0xE7, 0x18E7, 0xF7 },
    NULL, v_mnemonic, "std",    0, AF_STD, { 0xDD, 0xED, 0x18ED, 0xFD },
    NULL, v_mnemonic, "stop",   0, AF_IMP, { 0xCF },
    NULL, v_mnemonic, "sts",    0, AF_STD, { 0x9F, 0xAF, 0x18AF, 0xBF },
    NULL, v_mnemonic, "stx",    0, AF_STD, { 0xDF, 0xEF, 0xCDEF, 0xFF },
    NULL, v_mnemonic, "sty",    0, AF_STD, { 0x18DF, 0x1AEF, 0x18EF, 0x18FF },
    NULL, v_mnemonic, "suba",   0, AF_STDI,{ 0x80, 0x90, 0xA0, 0x18A0, 0xB0 },
    NULL, v_mnemonic, "subb",   0, AF_STDI,{ 0xC0, 0xD0, 0xE0, 0x18E0, 0xF0 },
    NULL, v_mnemonic, "subd",   0, AF_STDD,{ 0x83, 0x93, 0xA3, 0x18A3, 0xB3 },
    NULL, v_mnemonic, "swi",    0, AF_IMP, { 0x3F },
    NULL, v_mnemonic, "tab",    0, AF_IMP, { 0x16 },
    NULL, v_mnemonic, "tap",    0, AF_IMP, { 0x06 },
    NULL, v_mnemonic, "tba",    0, AF_IMP, { 0x17 },
    NULL, v_mnemonic, "test",   0, AF_IMP, { 0x00 },
    NULL, v_mnemonic, "tpa",    0, AF_IMP, { 0x07 },
    NULL, v_mnemonic, "tsta",   0, AF_IMP, { 0x4D },
    NULL, v_mnemonic, "tstb",   0, AF_IMP, { 0x5D },
    NULL, v_mnemonic, "tst",    0, AF_ASL, { 0x6D, 0x186D, 0x7D },
    NULL, v_mnemonic, "tsx",    0, AF_IMP, { 0x30 },
    NULL, v_mnemonic, "tsy",    0, AF_IMP, { 0x1830 },
    NULL, v_mnemonic, "txs",    0, AF_IMP, { 0x35 },
    NULL, v_mnemonic, "tys",    0, AF_IMP, { 0x1835 },
    NULL, v_mnemonic, "wai",    0, AF_IMP, { 0x3E },
    NULL, v_mnemonic, "xgdx",   0, AF_IMP, { 0x8F },
    NULL, v_mnemonic, "xgdy",   0, AF_IMP, { 0x188F },
    NULL
};



\Rogue\Monster\
else
  echo "will not over write src/mne6811.c"
fi
if [ `wc -c src/mne6811.c | awk '{printf $1}'` -ne 9593 ]
then
echo `wc -c src/mne6811.c | awk '{print "Got " $1 ", Expected " 9593}'`
fi
if `test ! -s src/main.c`
then
echo "writing src/main.c"
cat > src/main.c << '\Rogue\Monster\'

/*
 *  MAIN.C
 *
 *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
 *     Freely Distributable (for non-profit) ONLY.  No redistribution
 *     of any modified text files or redistribution of a subset of the
 *     source is allowed.  Redistribution of modified binaries IS allowed
 *     under the above terms.
 *
 *  DASM   sourcefile
 *
 *  NOTE: must handle mnemonic extensions and expression decode/compare.
 */

#include "asm.h"

#define MAXLINE 256
#define ISEGNAME    "code"

extern uword hash1();
extern MNE   *findmne();
extern MNE   Ops[];
extern void  findext();
extern void  clearsegs(), clearrefs();
extern SYMBOL *eval();
extern char *cleanup();

uword _fmode = 0;	/*  was trying to port to 16 bit IBM-PC lattice C */
			/*  but failed	*/

ubyte	Disable_me;
ubyte	StopAtEnd = 0;
ubyte	*Extstr;

main(ac, av)
ubyte *av[];
{
    ubyte buf[MAXLINE];
    uword pass, i;
    register ubyte *ptr;
    register MNE *mne;
    register ulong oldredo = -1;
    register ulong oldwhy = 0;
    register ulong oldeval = 0;

    addhashtable(Ops);
    pass = 1;

    if (ac < 2) {
fail:
	puts("DASM V2.11, high level Macro Assembler");
	puts("(C)Copyright 1988 by Matthew Dillon, All Rights Reserved");
	puts("redistributable for non-profit only");
	puts("");
	puts("DASM sourcefile [options]");
	puts(" -f#      output format");
	puts(" -oname   output file");
	puts(" -lname   list file");
	puts(" -sname   symbol dump");
	puts(" -v#      verboseness");
	puts(" -Dname=exp   define label");
	exit(1);
    }
    puts("DASM V2.11, (c)Copyright 1988 Matthew Dillon, All Rights Reserved");
    puts("Warning: The meaning of <exp & >exp has been reversed in this release");
    for (i = 2; i < ac; ++i) {
	if (av[i][0] == '-') {
	    register ubyte *str = av[i]+2;
	    switch(av[i][1]) {
	    case 'd':
		Xdebug = atoi(str);
		printf("Xdebug = %ld\n", Xdebug);
		break;
	    case 'D':
		while (*str && *str != '=')
		    ++str;
		if (*str == '=') {
		    *str = 0;
		    ++str;
		} else {
		    str = (ubyte *)"0";
		}
		Av[0] = av[i]+2;
		v_set(str);
		break;
	    case 'f':   /*  F_format    */
		F_format = atoi(str);
		if (F_format < 1 || F_format > 3)
		    panic("Illegal format specification");
		break;
	    case 'o':   /*  F_outfile   */
		F_outfile = (char *)str;
nofile:
		if (*str == 0)
		    panic("need file name for specified option");
		break;
	    case 'l':   /*  F_listfile  */
		F_listfile = (char *)str;
		goto nofile;
	    case 's':   /*  F_symfile   */
		F_symfile = (char *)str;
		goto nofile;
	    case 'v':   /*  F_verbose   */
		F_verbose = atoi(str);
		break;
	    case 't':   /*  F_temppath  */
		F_temppath = (char *)str;
		break;
	    default:
		goto fail;
	    }
	    continue;
	}
	goto fail;
    }

    /*	INITIAL SEGMENT */

    {
	register SEGMENT *seg = (SEGMENT *)permalloc(sizeof(SEGMENT));
	seg->name = strcpy(permalloc(sizeof(ISEGNAME)), ISEGNAME);
	seg->flags= seg->rflags = seg->initflags = seg->initrflags = SF_UNKNOWN;
	Csegment = Seglist = seg;
    }
    /*	TOP LEVEL IF	*/
    {
	register IFSTACK *ifs = (IFSTACK *)zmalloc(sizeof(IFSTACK));
	ifs->file = NULL;
	ifs->flags = IFF_BASE;
	ifs->acctrue = 1;
	ifs->true  = 1;
	Ifstack = ifs;
    }
nextpass:
    Localindex = Lastlocalindex = 0;
    _fmode = 0x8000;
    FI_temp = fopen(F_outfile, "w");
    _fmode = 0;
    Fisclear = 1;
    CheckSum = 0;
    if (FI_temp == NULL) {
	printf("unable to [re]open '%s'\n", F_outfile);
	exit(1);
    }
    if (F_listfile) {
	FI_listfile = fopen(F_listfile, "w");
	if (FI_listfile == NULL) {
	    printf("unable to [re]open '%s'\n", F_listfile);
	    exit(1);
	}
    }
    pushinclude(av[1]);
    while (Incfile) {
	for (;;) {
	    char *comment;
	    if (Incfile->flags & INF_MACRO) {
		if (Incfile->strlist == NULL) {
		    Av[0] = (ubyte *)"";
		    v_mexit();
		    continue;
		}
		strcpy(buf, Incfile->strlist->buf);
		Incfile->strlist = Incfile->strlist->next;
	    } else {
		if (fgets(buf, MAXLINE, Incfile->fi) == NULL)
		    break;
	    }
	    if (Xdebug)
		printf("%08lx %s\n", Incfile, buf);
	    comment = cleanup(buf);
	    if (Xdebug)
		printf("ok1 "), fflush(stdout);
	    ++Incfile->lineno;
	    parse(buf);
	    if (Xdebug)
		printf("ok2 "), fflush(stdout);
	    if (Av[1][0]) {
		findext(Av[1]);
		if (mne = findmne(Av[1])) {
		    if ((mne->flags & MF_IF) || (Ifstack->true && Ifstack->acctrue))
			(*mne->vect)(Av[2], mne);
		} else {
		    if (Ifstack->true && Ifstack->acctrue) {
			printf("unknown mnemonic: '%s'\n", Av[1]);
			asmerr(4,0);
		    }
		}
	    } else {
		if (Ifstack->true && Ifstack->acctrue)
		    programlabel();
	    }
	    if (Xdebug)
		printf("ok3 "), fflush(stdout);
	    if (F_listfile && ListMode)
		outlistfile(comment);
	}
	while (Reploop && Reploop->file == Incfile)
	    rmnode(&Reploop, sizeof(REPLOOP));
	while (Ifstack->file == Incfile)
	    rmnode(&Ifstack, sizeof(IFSTACK));
	fclose(Incfile->fi);
	free(Incfile->name);
	--Inclevel;
	rmnode(&Incfile, sizeof(INCFILE));
	if (Incfile) {
	    /*
	    if (F_verbose > 1)
		printf("back to: %s\n", Incfile->name);
	    */
	    if (F_listfile)
		fprintf(FI_listfile, "------- FILE %s\n", Incfile->name);
	}
    }
    if (F_verbose >= 1) {
	SEGMENT *seg;
	char *bss;

	puts("");
	printf("END OF PASS: %d\n", pass);
	puts("Segment---     init-pc  init-rpc finl-pc  finl-rpc");
	for (seg = Seglist; seg; seg = seg->next) {
	    bss = (seg->flags & SF_BSS) ? "[u]" : "   ";
	    printf("%10s %3s ", seg->name, bss);
	    printf("%s %s ", sftos(seg->initorg, seg->initflags), sftos(seg->initrorg, seg->initrflags));
	    printf("%s %s\n", sftos(seg->org, seg->flags), sftos(seg->rorg, seg->rflags));
	}
	printf("Reasons: %4ld,%4ld   Reasoncode: %08lx\n", Redo, Redo_eval, Redo_why);
    }
    if (F_verbose >= 3) {
	SYMBOL *sym;
	short i;
	short j = 0;

	if (F_verbose == 3)
	    puts("SYMBOLIST:  (Unresolved symbols only)");
	else
	    puts("SYMBOLIST");
	for (i = 0; i < SHASHSIZE; ++i) {
	    for (sym = SHash[i]; sym; sym = sym->next) {
		if (F_verbose > 3 || (sym->flags & SYM_UNKNOWN)) {
		    printf("%10s %s\n", sym->name, sftos(sym->value, sym->flags));
		    j = 1;
		}
	    }
	}
	if (j == 0)
	    puts("NO SYMBOLS");
	else
	    puts("ENDSYMBOLIST");
    }
    closegenerate();
    fclose(FI_temp);
    if (FI_listfile)
	fclose(FI_listfile);
    if (Redo) {
	if (Redo == oldredo && Redo_why == oldwhy && Redo_eval == oldeval) {
	    puts("Error: source is not resolvable.");
	    if (F_verbose < 2)
		puts("re-run with verbose option 2 or higher to determine problem");
	    exit(1);
	}
	oldredo = Redo;
	oldwhy = Redo_why;
	oldeval = Redo_eval;
	Redo = 0;
	Redo_why = 0;
	Redo_eval = 0;
	++pass;
	if (StopAtEnd) {
	    printf("Unrecoverable error in pass, aborting assembly!\n");
	} else if (pass > 10) {
	    printf("More than 10 passes, something *must* be wrong!\n");
	    exit(1);
	} else {
	    clearrefs();
	    clearsegs();
	    goto nextpass;
	}
    }
    if (F_symfile) {
	FILE *fi = fopen(F_symfile, "w");
	if (fi) {
	    register SYMBOL *sym;
	    puts("dumping symbols...");
	    for (i = 0; i < SHASHSIZE; ++i) {
		for (sym = SHash[i]; sym; sym = sym->next) {
		    fprintf(fi, "%-15s %s", sym->name, sftos(sym->value, sym->flags));
		    if (sym->flags & SYM_STRING)
			fprintf(fi, " \"%s\"", sym->string);
		    putc('\n', fi);
		}
	    }
	    fclose(fi);
	} else {
	    printf("unable to open symbol dump file '%s'\n", F_symfile);
	}
    }
}

static
outlistfile(comment)
char *comment;
{
    extern ubyte Gen[];
    extern short Glen;
    char c = (Pflags & SF_BSS) ? 'U' : ' ';
    static char buf1[MAXLINE+32];
    static char buf2[MAXLINE+32];
    ubyte *ptr = Extstr;
    char *dot = "";
    register int i, j;

    if (ptr)
	dot = ".";
    else
	ptr = (ubyte *)"";

    sprintf(buf1, "%6ld %c%s", Incfile->lineno, c, sftos(Plab, Pflags & 7));
    j = strlen(buf1);
    for (i = 0; i < Glen && i < 4; ++i, j += 3)
	sprintf(buf1+j, "%02x ", Gen[i]);
    if (i < Glen && i == 4)
	buf1[j-1] = '*';
    for (; i < 4; ++i) {
	buf1[j] = buf1[j+1] = buf1[j+2] = ' ';
	j += 3;
    }
    sprintf(buf1+j, "%-10s  %s%s%s\011%s\n", Av[0], Av[1], dot, ptr, Av[2]);
    if (comment[0]) { /*  tab and comment */
	j = strlen(buf1) - 1;
	sprintf(buf1+j, "\011;%s", comment);
    }
    fwrite(buf2, tabit(buf1,buf2), 1, FI_listfile);
    Glen = 0;
    Extstr = NULL;
}

tabit(buf1, buf2)
char *buf1, *buf2;
{
    register char *bp, *ptr;
    register short j, k;

    bp = buf2;
    ptr= buf1;
    for (j = 0; *ptr; ++ptr, ++bp, j = (j+1)&7) {
	*bp = *ptr;
	if (*ptr == 9)
	    j = 0;
	if (j == 7 && *bp == ' ' && *(bp-1) == ' ') {
	    k = j;
	    while (k-- >= 0 && *bp == ' ')
		--bp;
	    *++bp = 9;
	}
    }
    while (bp != buf2 && bp[-1] == ' ' || bp[-1] == 9)
	--bp;
    *bp = *ptr;
    return((int)(bp - buf2));
}


ubyte *
sftos(val, flags)
long val;
short flags;
{
    static char buf[64];
    static char c;
    register char *ptr = (c) ? buf : buf + 32;

    c = 1 - c;
    sprintf(ptr, "%04lx", val);
    if (flags & SYM_UNKNOWN)
	strcpy(ptr, "????");
    if (flags & SYM_STRING)
	strcpy(ptr, "str ");
    if (flags & SYM_MACRO)
	strcpy(ptr, "eqm ");
    strcpy(ptr+4, "    ");
    if (flags & (SYM_MASREF|SYM_SET)) {
	ptr[4] = '(';
	ptr[7] = ')';
    }
    if (flags & (SYM_MASREF))
	ptr[5] = 'r';
    if (flags & (SYM_SET))
	ptr[6] = 's';
    return((ubyte *)ptr);
}

void
clearsegs()
{
    register SEGMENT *seg;

    for (seg = Seglist; seg; seg = seg->next) {
	seg->flags = (seg->flags & SF_BSS) | SF_UNKNOWN;
	seg->rflags= seg->initflags = seg->initrflags = SF_UNKNOWN;
    }
}

void
clearrefs()
{
    register SYMBOL *sym;
    register short i;

    for (i = 0; i < SHASHSIZE; ++i)
	for (sym = SHash[i]; sym; sym = sym->next)
	    sym->flags &= ~SYM_REF;
}

static
char *
cleanup(buf)
register ubyte *buf;
{
    register ubyte *str;
    register STRLIST *strlist;
    register short arg, add;
    char *comment = "";

    for (str = buf; *str; ++str) {
	switch(*str) {
	case ';':
	    comment = (char *)str + 1;
	    /*	FALL THROUGH	*/
	case '\r':
	case '\n':
	    goto br2;
	case TAB:
	    *str = ' ';
	    break;
	case '\'':
	    ++str;
	    if (*str == TAB)
		*str = ' ';
	    if (*str == '\n' || *str == 0) {
		str[0] = ' ';
		str[1] = 0;
	    }
	    if (str[0] == ' ')
		str[0] = 0x80;
	    break;
	case '\"':
	    ++str;
	    while (*str && *str != '\"') {
		if (*str == ' ')
		    *str = 0x80;
		++str;
	    }
	    if (*str != '\"') {
		asmerr(0,0);
		--str;
	    }
	    break;
	case '{':
	    if (Disable_me)
		break;
	    if (Xdebug)
		printf("macro tail: '%s'\n", str);
	    arg = atoi(str+1);
	    for (add = 0; *str && *str != '}'; ++str)
		--add;
	    if (*str != '}') {
		puts("end brace required");
		--str;
		break;
	    }
	    --add;
	    ++str;
	    if (Xdebug)
		printf("add/str: %d '%s'\n", add, str);
	    for (strlist = Incfile->args; arg && strlist;) {
		--arg;
		strlist = strlist->next;
	    }
	    if (strlist) {
		add += strlen(strlist->buf);
		if (Xdebug)
		    printf("strlist: '%s' %d\n", strlist->buf, strlen(strlist->buf));
		if (str + add + strlen(str) + 1 > buf + MAXLINE) {
		    if (Xdebug)
			printf("str %8ld buf %8ld (add/strlen(str)): %d %ld\n", str, buf, add, strlen(str));
		    panic("failure1");
		}
		bmov(str, str + add, strlen(str)+1);
		str += add;
		if (str - strlen(strlist->buf) < buf)
		    panic("failure2");
		bmov(strlist->buf, str - strlen(strlist->buf), strlen(strlist->buf));
		str -= strlen(strlist->buf);
		if (str < buf || str >= buf + MAXLINE)
		    panic("failure 3");
		--str;	/*  for loop increments string	*/
	    } else {
		asmerr(7,0);
		goto br2;
	    }
	    break;
	}
    }
br2:
    while(str != buf && *(str-1) == ' ')
	--str;
    *str = 0;
    return(comment);
}

panic(str)
char *str;
{
    puts(str);
    exit(1);
}

/*
 *  .dir    direct		    x
 *  .ext    extended		    x
 *  .r	    relative		    x
 *  .x	    index, no offset	    x
 *  .x8     index, byte offset	    x
 *  .x16    index, word offset	    x
 *  .bit    bit set/clr
 *  .bbr    bit and branch
 *  .imp    implied (inherent)      x
 *  .b				    x
 *  .w				    x
 *  .l				    x
 *  .u				    x
 */


void
findext(str)
register ubyte *str;
{
    Mnext = -1;
    Extstr = NULL;
    while (*str && *str != '.')
	++str;
    if (*str) {
	*str = 0;
	++str;
	Extstr = str;
	switch(str[0]|0x20) {
	case '0':
	case 'i':
	    Mnext = AM_IMP;
	    switch(str[1]|0x20) {
	    case 'x':
		Mnext = AM_0X;
		break;
	    case 'y':
		Mnext = AM_0Y;
		break;
	    case 'n':
		Mnext = AM_INDWORD;
		break;
	    }
	    return;
	case 'd':
	case 'b':
	case 'z':
	    switch(str[1]|0x20) {
	    case 'x':
		Mnext = AM_BYTEADRX;
		break;
	    case 'y':
		Mnext = AM_BYTEADRY;
		break;
	    case 'i':
		Mnext = AM_BITMOD;
		break;
	    case 'b':
		Mnext = AM_BITBRAMOD;
		break;
	    default:
		Mnext = AM_BYTEADR;
		break;
	    }
	    return;
	case 'e':
	case 'w':
	case 'a':
	    switch(str[1]|0x20) {
	    case 'x':
		Mnext = AM_WORDADRX;
		break;
	    case 'y':
		Mnext = AM_WORDADRY;
		break;
	    default:
		Mnext = AM_WORDADR;
		break;
	    }
	    return;
	case 'l':
	    Mnext = AM_LONG;
	    return;
	case 'r':
	    Mnext = AM_REL;
	    return;
	case 'u':
	    Mnext = AM_BSS;
	    return;
	}
    }
}

/*
 *  bytes arg will eventually be used to implement a linked list of free
 *  nodes.
 */

rmnode(base, bytes)
ulong **base;
{
    ulong *node;

    if (node = *base) {
	*base = *(ulong **)node;
	free(node);
    }
}

/*
 *  Parse into three arguments: Av[0], Av[1], Av[2]
 */

parse(buf)
register ubyte *buf;
{
    register short i, j;

    i = j = 0;
    Av[0] = Avbuf;
    while (buf[i] && buf[i] != ' ') {
	if (buf[i] == 0x80)
	    buf[i] = ' ';
	Avbuf[j++] = buf[i++];
    }
    Avbuf[j++] = 0;
    while (buf[i] == ' ')
	++i;
    Av[1] = Avbuf + j;
    while (buf[i] && buf[i] != ' ') {
	if (buf[i] == 0x80)
	    buf[i] = ' ';
	Avbuf[j++] = buf[i++];
    }
    Avbuf[j++] = 0;
    while (buf[i] == ' ')
	++i;
    Av[2] = Avbuf + j;
    while (buf[i]) {
	if (buf[i] == ' ') {
	    while(buf[i+1] == ' ')
		++i;
	}
	if (buf[i] == 0x80)
	    buf[i] = ' ';
	Avbuf[j++] = buf[i++];
    }
    Avbuf[j] = 0;
}



MNE *
findmne(str)
register ubyte *str;
{
    register uword i;
    register ubyte c;
    register MNE *mne;
    ubyte buf[128];

    for (i = 0; c = str[i]; ++i) {
	if (c >= 'A' && c <= 'Z')
	    c += 'a' - 'A';
	buf[i] = c;
    }
    buf[i] = 0;
    for (mne = MHash[hash1(buf)]; mne; mne = mne->next) {
	if (strcmp(buf, mne->name) == 0)
	    break;
    }
    return(mne);
}

v_macro(str)
char *str;
{
    extern void v_execmac();
    extern void v_endm();
    STRLIST *base;
    ubyte defined = 0;
    register STRLIST **slp, *sl;
    register MACRO *mac;
    register MNE   *mne;
    register uword i;
    ubyte buf[MAXLINE];
    ubyte skipit = !(Ifstack->true && Ifstack->acctrue);

    if (skipit) {
	defined = 1;
    } else {
	defined = (findmne(str) != NULL);
	if (F_listfile && ListMode)
	    outlistfile("");
    }
    if (!defined) {
	base = NULL;
	slp = &base;
	mac = (MACRO *)permalloc(sizeof(MACRO));
	i = hash1(str);
	mac->next = (MACRO *)MHash[i];
	mac->vect = v_execmac;
	mac->name = strcpy(permalloc(strlen(str)+1), str);
	mac->flags = MF_MACRO;
	MHash[i] = (MNE *)mac;
    }
    while (fgets(buf, MAXLINE, Incfile->fi)) {
	char *comment;

	if (Xdebug)
	    printf("%08lx %s\n", Incfile, buf);
	++Incfile->lineno;
	Disable_me = 1;
	comment = cleanup(buf);
	Disable_me = 0;
	if (parse(buf), Av[1][0]) {
	    findext(Av[1]);
	    mne = findmne(Av[1]);
	    if (mne->vect == v_endm) {
		if (!defined)
		    mac->strlist = base;
		return;
	    }
	}
	if (Xdebug)
	    printf("ok1"), fflush(stdout);
	if (!skipit && F_listfile && ListMode)
	    outlistfile(comment);
	if (Xdebug)
	    printf("ok2"), fflush(stdout);
	if (!defined) {
	    sl = (STRLIST *)permalloc(5+strlen(buf));
	    strcpy(sl->buf, buf);
	    *slp = sl;
	    slp = &sl->next;
	}
	if (Xdebug)
	    printf("ok3\n"), fflush(stdout);
    }
    asmerr(8,1);
}

addhashtable(mne)
MNE *mne;
{
    register uword i, j;
    uword opcode[NUMOC];

    for (; mne->vect; ++mne) {
	bmov(mne->opcode, opcode, sizeof(mne->opcode));
	for (i = j = 0; i < NUMOC; ++i) {
	    mne->opcode[i] = 0;     /* not really needed */
	    if (mne->okmask & (1L << i))
		mne->opcode[i] = opcode[j++];
	}
	i = hash1(mne->name);
	mne->next = MHash[i];
	MHash[i] = mne;
    }
}


static uword
hash1(str)
register ubyte *str;
{
    register uword result = 0;

    while (*str)
	result = (result << 2) ^ *str++;
    return(result & MHASHAND);
}

pushinclude(str)
char *str;
{
    register INCFILE *inf;
    register FILE *fi;

    if (fi = fopen(str, "r")) {
	if (F_verbose > 1) {
#ifdef IBM
	    printf(" Include: %s\n", str);
#else
	    printf("%.*sInclude: %s\n", Inclevel*4, "", str);
#endif
	}
	++Inclevel;
	if (F_listfile)
	    fprintf(FI_listfile, "------- FILE %s\n", str);
	inf = (INCFILE *)zmalloc(sizeof(INCFILE));
	inf->next   = Incfile;
	inf->name   = strcpy(malloc(strlen(str)+1), str);
	inf->fi     = fi;
	inf->lineno = 0;
	Incfile = inf;
	return(1);
    }
    printf("unable to open %s\n", str);
}

char Stopend[] = {
    1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,0,0,1,1
};

char *Errors[] = {
    "Syntax Error",
    "Expression table overflow",
    "Unbalanced Braces []",
    "Division by zero",
    "Unknown Mnemonic",
    "Illegal Addressing mode",
    "Illegal forced Addressing mode",   /*  nu  */
    "Not enough args passed to Macro",
    "Premature EOF",
    "Illegal character",
    "Branch out of range",
    "ERR pseudo-op encountered",
    "Origin Reverse-indexed",           /*  12  */
    "EQU: Value mismatch",
    "Address must be <$100",            /*  nu  */
    "Illegal bit specification",
    "Not enough args",                  /*  16  */
    "Label Mismatch",                   /*  17  */
    "Value Undefined",
    "Illegal Forced Address mode",      /*  19  */
    "Processor not supported",          /*  20  */
    NULL
};

asmerr(err, abort)
short err, abort;
{
    ubyte *ptr;
    ubyte *str;
    INCFILE *incfile;

    if (Stopend[err])
	StopAtEnd = 1;
    for (incfile = Incfile; incfile->flags & INF_MACRO; incfile=incfile->next);
    str = (ubyte *)Errors[err];
    if (F_listfile)
	fprintf(FI_listfile, "*line %4ld %-10s %s\n", incfile->lineno, incfile->name, str);
    printf("line %4ld %-10s %s\n", incfile->lineno, incfile->name, str);
    if (abort) {
	puts("Aborting assembly");
	if (F_listfile)
	    fputs("Aborting assembly\n", FI_listfile);
	exit(1);
    }
}

ubyte *
zmalloc(bytes)
uword bytes;
{
    ubyte *ptr = malloc(bytes);
    if (ptr) {
	bzero(ptr, bytes);
	return(ptr);
    }
    panic("unable to malloc");
}

ubyte *
permalloc(bytes)
uword bytes;
{
    static ubyte *buf;
    static int left;
    ubyte *ptr;

    bytes = (bytes + 1) & ~1;
    if (bytes > left) {
	if ((buf = malloc(ALLOCSIZE)) == NULL)
	    panic("unable to malloc");
	bzero(buf, ALLOCSIZE);
	left = ALLOCSIZE;
	if (bytes > left)
	    panic("software error");
    }
    ptr = buf;
    buf += bytes;
    left -= bytes;
    return(ptr);
}


#ifdef UNIX
xbset(s,n,c)
register ubyte *s;
register ulong n;
register ubyte c;
{
    while (n--)
	*s++ = c;
}
#endif

#ifdef IBM
bcmp(s,d,n)
ubyte *s, *d;
uword n;
{
    uword i;
    for (i = 0; i < n; ++i) {
	if (s[i] != d[i])
	    return(0);
    }
    return(1);
}

#endif



\Rogue\Monster\
else
  echo "will not over write src/main.c"
fi
if [ `wc -c src/main.c | awk '{printf $1}'` -ne 19306 ]
then
echo `wc -c src/main.c | awk '{print "Got " $1 ", Expected " 19306}'`
fi
echo "Finished archive 2 of 3"
# if you want to concatenate archives, remove anything after this line
exit
-- 
Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
Have five nice days.