[comp.sources.amiga] dasm

ain@j.cc.purdue.edu (Patrick White) (02/09/88)

Program Name:	dasm  (docs)
Submitted By:	dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon)
Summary:	A cross assembler for 6502, 68705, 6803, and HD6303 (extension
		of 6803)
Poster Boy:  Pat White  (ain@j.cc.purdue.edu)
Read :-)

NOTES:
   Matt suggests that one use the ram disk for everything... but one can
still use a floppy if one does not have that much free ram laying about.


-- Pat White   (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

========================================

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	README
#	DASM.DOC
#	FTOHEX.DOC
# This archive created: Mon Feb  8 13:11:21 1988
# By:	Patrick White (PUCC Land, USA)
echo shar: extracting README '(1526 characters)'
cat << \SHAR_EOF > README

    DASM    V2.0

    (c)Copyright 1988 Matthew Dillon, All Rights Reserved.


FILES:
	    README		this file

	    DASM.DOC		documentation for the assembler
	    FTOHEX.DOC		documentation for intel hex converter

	    DASM		The assembler
	    FTOHEX		assmblyoutput -> intelhex format converter
	    suite6502.asm	test suite for 6502
	    suite6303.asm	test suite for 6805/6303
	    suite68705.asm	test suite for 68705
	    example.asm 	example assembly file

	    Makefile		Makefile, Aztec C
	    *.c *.h		source code (in C). 32 bit ints, Aztec C.
	    ftohex.c		source code for FTOHEX 32 bit ints Aztec C.


	 --------------- SUPPORTED MICRO PROCESSORS ---------------


6502:	    ORDER LSB,MSB   A<7:0> X<7:0> Y<7:0>    RelAddr:   .+ilen+offset
68705:	    ORDER MSB,LSB   A<7:0> X<7:0>	    RelAddr:   .+ilen+offset
6805/6303:  ORDER MSB,LSB   A<7:0> B<7:0> X<15:0>   RelAddr:   .+ilen+offset


ADDRESSING MODES		6502	68705	6803
BYTES

 2  implied			x	x	x
 2  immediate.8     #byte	x	x	x
 3  immediate.16    #word			x
 2  byteaddr	    byte	x	x	x
 2  byteaddr,x	    byte,x	x	x	x
 2  byteaddr,y	    byte,y	x
 3  wordaddr	    word	x	x	x
 3  wordaddr,x	    word,x	x	x
 3  wordaddr,y	    word,y	x
 2  relative	    byte	x	x	x
 2  ind.byte.x	    (byte,x)    x
 2  ind.byte.y	    (byte),y    x
 3  ind.word	    (word)      x
 1  0,x 	    [0],x		x
 2  bitmod	    #no,badr		x		baseinst + 2*bitno
 3  bitbramod	    #no,badr,rel	x		baseinst + 2*bitno

NOTE:	6303 instruction extensions over the 6805 are:
	    AIM OIM EIM TIM XGDX SLP

SHAR_EOF
if test 1526 -ne "`wc -c README`"
then
echo shar: error transmitting README '(should have been 1526 characters)'
fi
echo shar: extracting DASM.DOC '(17291 characters)'
cat << \SHAR_EOF > DASM.DOC


DOCUMENTATION FOR DASM V2.0, a high level macro cross assembler for:

	-6502
	-68705
	-6803
	-HD6303 (extension of 6803)

	Soon will work for 68HC11 (next ver)

    (C)Copyright 1987,1988 Matthew Dillon, All Rights Reserved

    Publicly distributable for non-profit only.  Must be distributed
    as is, with NO CHANGES to the documentation or code.   Over the last
    year my work has included writing software to drive small single-chip
    microcomputers for various things (remote telemetry units, for
    instance).	I have had need to program quite a few different processors
    over that time.

    At the beginning, I used an awful macro assembler running on an IBM-PC.
    I *really* wanted to do it on my Amiga.  Thus the writing of this
    program.

    Feel free to suggest other similar processors for me to add to the list!
    The processor type is specified with a pseudo-op (see below).  This
    assembler produces only binary output in one of three formats described
    below.  In general, one has a master assembly file which INCLUDEs all
    the modules.

    Also provided is FTOHEX which converts an output file in one of the
    three formats to an intel-hex format suitable for many intelligent
    prom programmers (I have a GTEK).

    YES it's packed with features!

COMMAND LINE:

	asm srcfile [options]

	options:    -f#     select output format 1-3 (default 1, see below)
		    -oname  select output file name (else a.out)
		    -lname  select list file name   (else none generated)
		    -sname  select symbol dump file (else none generated)
		    -v#     select verboseness 0-4 (default 0, see below)
		    -d	    debug mode
		    -DSYMBOL		    predefine a symbol, set to 0
		    -DSYMBOL=EXPRESSION     predefine a symbol, set to exp

	Note: file names should be in RAM: for speed.  If a list file is
	specified, it should be in the RAM: disk (assembly is slowed down
	quite a bit anyway).

	Example:    asm master.asm -f2 -oram:out -lram:list -v3 -DVER=4

FORMAT OPTIONS:

    1  (DEFAULT)

	The output file contains a two byte origin in LSB,MSB order, then
	data until the end of the file.

	Restrictions:	Any instructions which generate output (within an
	initialized segment) must do so with an ascending PC.  Initialized
	segments must occur in ascending order.

    2  RAS (Random Access Segment)

	The output file contains one or more hunks.  Each hunk consists
	of a 2 byte origin (LSB,MSB), 2 byte length (LSB,MSB), and that
	number of data bytes.  The hunks occur in the same order as
	initialized segments in the assembly.  There are no restrictions
	to segment ordering.  The next hunk begins after the previous
	hunk's data, until the end of the file.

    3  RAW (Raw)

	The output file contains data only (format #1 without the 2 byte
	header).  Restrictions are the same as for format #1.

	Format 3    RAW (Raw format)
	    Same as format 1, but NO header origin is generated.  You get
	    nothing but data.

VERBOSE OPTIONS:

    0	(default)

	Only warnings and errors are generated

    1
	-Segment list information generated after each pass
	-Include file names are displayed
	-statistics on why the assembler is going to make another pass
	    R1,R2 reason code: R3
	    where R1 is the number of times the assembler encountered
	    something requiring another pass to resolve.  R2 is the
	    number of references to unknown symbols which occured in the
	    pass (but only R1 determines the need for another pass).  R3
	    is a BITMASK of the reasons why another pass is required.
	    See the end of this document for bit designations.

    2
	mismatches between program labels and equates are displayed
	on every pass (usually none occur in the first pass unless you
	have re-declared a symbol name).

	displayed information for symbols:
	    ???? = unknown value
	    str  = symbol is a string
	    eqm  = symbol is an eqm macro
	    (r)  = symbol has been referenced
	    (s)  = symbol created with SET or EQM pseudo-op

    3
	    Unresolved and unreferenced symbols are displayed every pass
	    (unsorted, sorry)

    4
	    An entire symbol list is displayed every pass to STDOUT.
	    (unsorted, sorry)

PROCESSOR MODEL:

    The processor model is chosen with the PROCESSOR pseudo-op and should
    be the first thing you do in your assembly file.   Different processor
    models use different integer formats (see below).  The word order does
    not effect the headers in the output files (-f1 and -f2), which are
    always LSB,MSB.  The word ordering effects all address, word, and
    long generation.

    Only one PROCESSOR pseudo-op may be declared in the entire assembly,
    and should be the first thing encountered.

	-6502	    LSB,MSB
	-68HC11     MSB,LSB (next release)
	-68705	    MSB,LSB
	-6803	    MSB,LSB
	-HD6303     MSB,LSB

SEGMENTS:
    The SEG pseudo-op creates/sets the current segment.  Each segment has
    it's own origin and is optionally an 'uninitialized' segment.
    Unitialized segments produce no output and have no restrictions.  This
    is useful for determining the size of a certain assembly sequence
    without generating code, and for assigning RAM to labels.

GENERAL:
    Most everything is recursive.  You cannot have a macro DEFINITION
    within a macro definition, but can nest macro calls, repeat loops,
    and include files.

    The other major feature in this assembler is the SUBROUTINE pseudo-op,
    which logically separates local labels (starting with a dot).  This
    allows you to reuse label names (for example, .1 .fail) rather than
    think up crazy combinations of the current subroutine to keep it all
    unique.

    Almost nothing need be resolved in pass 1.	The assembler will make
    multiple passes in an attempt to resolve the assembly (including just
    one pass if everything is resolved immediately).


PSEUDOPS:

	INCLUDE     "name"

	    Include another assembly file.

[label] SEG[.U]     name

	    This sets the current segment, creating it if neccessary.  If
	    a .U extension is specified on segment creation, the segment
	    is an UNINITIALIZED segment.  The .U is not needed when going
	    back to an already created uninitialized segment, though it
	    makes the code more readable.

[label] DC[.BWL]    exp,exp,exp ...

	    Declare data in the current segment.  No output is generated if
	    within a .U segment.  Note that the byte ordering for the
	    selected processor is used for each entry.

	    The default size extension is a byte.

[label] DS[.BWL]    exp[,filler]

	    declare space (default filler is 0). Data is not generated if
	    within an uninitialized segment.  Note that the number of bytes
	    generated is exp * entrysize (1,2, or 4)

	    The default size extension is a byte.

[label] DV[.BWL]    eqmlabel exp,exp,exp....

	    This is equivalent to DC, but each exp in the list is passed
	    through the symbolic expression specified by the EQM label.
	    The expression is held in a special symbol dotdot '..' on each
	    call to the EQM label.

	    See EQM below

[label] HEX	    hh hh hh..

	    This sets down raw HEX data.  Spaces are optional between bytes.
	    NO EXPRESSIONS are allowed.  Note that you do NOT place a $
	    in front of the digits.  This is a short form for creating
	    tables compactly.  Data is always layed down on a byte-by-byte
	    basis.

	    Example:	    HEX 1A45 45 13254F 3E12

	ERR

	    Abort assembly.

[label] ORG	    exp[,DefaultFillVal]

	    This pseudop sets the current origin.  You can also set the
	    default fill character (a byte value) with this pseudoop.  NOTE
	    that no filler is generated until the first data-generating
	    opcode/psueoop is encountered after this one.  Sequences like:

		org  0,255
		org  100,0
		org  200
		dc   23

	    will result in 200 zero's and a 23.  Use DS or ALIGN to
	    specifically generate data output.	This allows you to specify
	    some ORG, then change your mind and specify some other (lower
	    address) ORG without causing an error (assuming nothing is
	    generated inbetween).

[label] RORG	    exp

	    This activates the relocatable origin.  All generated
	    addresses, including '.', although physically placed at the
	    true origin, will use values from the relocatable origin.
	    While in effect both the physical origin and relocatable origin
	    are updated.

	    The relocatable origin can skip around (no limitations).  The
	    relocatable origin is a function of the segment.  That is, you
	    can still SEG to another segment that does not have a
	    relocatable origin activated, do other (independant) stuff
	    there, and then switch back to the current segment and continue
	    where you left off.

	PROCESSOR model

	    do not quote.  model is one of: 6502,6803,HD6303,68705,68HC11
	    Can only be executed once, and should be the first thing
	    encountered by the assembler.  the 68HC11 will be available
	    next release.

	ECHO exp,exp,exp

	    The expressions (which may also be strings), are echod on the
	    screen and into the list file

[label] REND

	    Deactivate the relocatable origin for the current segment.
	    Generation uses the real origin for reference.

[label] ALIGN	    N[,fill]

	    Align the current PC to an N byte boundry.	The default
	    fill character is 0.

[label] SUBROUTINE  name

	    This isn't really a subroutine, but a boundry between sets of
	    temporary labels (which begin with a dot).  Temporary label
	    names are unique within segments of code bounded by SUBROUTINE:

		CHARLIE subroutine
			ldx #10
		.1	dex
			bne .1
		BEN	subroutine
			ldx #20
		.1	dex
			bne .1

symbol	EQU	    exp

	    The expression is evaluated and the result assigned to the
	    symbol.

symbol	EQM	    exp

	    The STRING representing the expression is assigned to the
	    symbol. Occurances of the label in later expressions causes the
	    string to be evaluated for each occurance.	Also used in
	    conjuction with the DV psuedo-op.

symbol	SET	    exp

	    Same as EQU, but the symbol may be reassigned later.

	MAC	    name

	    Declare a macro.  lines between MAC and ENDM are the macro.
	    You cannot recursively declare a macro.  You CAN recursively
	    use a macro (reference a macro in a macro).  No label is
	    allowed to the left of MAC or ENDM.


	    Arguments passed to macros are referenced with: {#}.  The first
	    argument passed to a macro would thus be {1}.  You should
	    always use LOCAL labels (.name) inside macros which you use
	    more than once. {0} represents an EXACT substitution of the
	    ENTIRE argument line.

	ENDM

	    end of macro def.  NO LABEL ALLOWED ON THE LEFT!

	MEXIT

	    Used in conjuction with conditionals.  Exits the current macro
	    level.

[label] IFCONST     exp

	    Is TRUE if the expression result is defined.  No error is
	    generated if the expression is undefined.  Is FALSE otherwise.

[label] IFNCONST    exp

	    Is TRUE if the expression result is undefined.  No error is
	    generated if the expression is undefined.  Is FALSE otherwise.

[label] IF	    exp

	    Is TRUE if the expression result is defined AND non-zero.
	    Is FALSE if the expression result is defined AND zero.
	    Neither IF or ELSE will be executed if the expression result
	    is undefined.

[label] ELSE

	    ELSE the current IF.

[label] ENDIF
[label] EIF

	    Terminate an IF. ENDIF and EIF are equivalent.

[label] REPEAT	    exp
[label] REPEND

	    Repeat code between REPEAT/REPEND 'exp' times.  if exp == 0,
	    the code repeats forever.  exp is evaluated once.

		Y   SET     0
		    REPEAT  10
		X   SET     0
		    REPEAT  10
		    DC	    X,Y
		X   SET     X + 1
		    REPEND
		Y   SET     Y + 1
		    REPEND

	    generates an output table:	0,0 1,0 2,0 ... 9,0  0,1 1,1 2,1
	    ... 9,1, etc...

	    Labels within a REPEAT/REPEND should be temporary labels with a
	    SUBROUTINE pseudoop to keep them unique.

	    The Label to the left of REPEND is assigned AFTER the loop
	    FINISHES.


[label] XXX[.force] operand

	    XXX is some mnemonic, not necessarily three characters long.
	    The .FORCE optional extension is used to force specific
	    addressing modes (see below).

GENERAL:

    The label will be set to the current ORG/RORG either before or after
    a pseudo-op is executed.  Most of the time, the label to the left of a
    pseudo-op is the current ORG/RORG. The following pseudo-op's labels are
    created AFTER execution of the pseudo-op:

	SEG, ORG, RORG, REND, ALIGN

EXTENSIONS:

    FORCE extensions are used to force an addressing mode.  In some cases,
    you can optimize the assembly to take fewer passes by telling it the
    addressing mode.  Force extensions are also used with DS,DC, and DV
    to determine the element size.  NOT ALL EXTENSIONS APPLY TO ALL
    PROCESSORS!

	example:    lda.z   charlie

	i   -implied
	ind -indirect word
	0   -implied
	0x  -implied indexing (0,x)
	0y  -implied indexing (0,y)
	b   -byte address
	bx  -byte address indexed x
	by  -byte address indexed y
	w   -word address
	wx  -word address indexed x
	wy  -word address indexed y
	l   -longword (4 bytes) (DS/DC/DV)
	r   -relative
	u   -uninitialized (SEG)

	First character equivalent substitutions:

	b z d	    (byte, zeropage, direct)
	w e a	    (word, extended, absolute)


ASSEMBLER PASSES:
    The assembler may have to make several passes through the source
    code to resolve all generation.  The number of passes is not
    limited to two.  Since this may result in an unexpected, verbose
    option 2, 3, and 4 have been provided to allow determination of the
    cause. The assembler will give up if it thinks it can't do the
    assembly in *any* number of passes.

    Error reporting could be better....


EXPRESSIONS:
	[] may be used to group expressions.  The precedense of operators
	is the same as for the C language in almost all respects.  Use
	brackets [] when you are unsure.  The reason () cannot be used to
	group expressions is due to a conflict with the 6502 and other
	assembly languages.

	Some expressions, such as ||, can return a resolved value even if
	one of the expressions is not resolved.   Operators are as follows:

	NOTE WELL: Some operations will result in non-byte values when a
	byte value was wanted.	For example:	~1  is NOT $FF, but
	$FFFFFFFF.  Preceding it with a > (take LSB of) will solve the
	problem.  ALL OPERATIONS ARE CARRIED OUT IN 32 BITS.

	prec	    UNARY

	20  ~exp    one's complement.
	20  -exp    negation
	20  !exp    not expression (returns 0 if exp non-zero, 1 if exp zero)
	20  <exp    take MSB byte of a 16 bit expression
	20  >exp    take LSB byte of an expression

		    BINARY

	19  *	    multiplication
	19  /	    division
	19  %	    mod
	18  +	    addition
	18  -	    subtraction
	17  >>,<<   shift right, shift left
	16  >,>=    greater, greater equal
	16  <,<=    smaller, smaller equal
	15  ==	    equal to.  Try to use this instead of =
	15  =	    exactly the same as == (exists compatibility)
	15  !=	    not equal to
	14  &	    logical and
	13  ^	    logical xor
	12  |	    logical or
	11  &&	    left expression is true AND right expression is true
	10  ||	    left expression is true OR right expression is true
	 9  ?	    if left expression is true, result is right expression,
		    else result is 0.	[10 ? 20] returns 20
	 8  []	    group expressions
	 7  ,	    separate expressions in list (also used in
		    addressing mode resolution, BE CAREFUL!

    Constants:

	nnn	decimal
	0nnn	octal
	%nnn	binary
	$nnn	hex
	'c      character
	"cc.."  string (NOT zero terminated if in DC/DS/DV)
	[exp]d	the constant expressions is evaluated and it's decimal
		result turned into an ascii string.

    Symbols:

	..	-holds evaluated value in DV pseudo op
	.name	-represents a temporary symbol name.  Temporary symbols
		 may be reused inside MACROS and between SUBROUTINES
	.	-current program counter (as of the beginning of the
		 instruction).
	name	-beginning with an alpha character and containing letters,
		 numbers, or '_'.  Represents some global symbol name.


WHY codes:
    Each bit in the WHY word (verbose option 1) is a reason (why
    the assembler needs to do another pass), as follows:

    bit 0   expression in mnemonic not resolved
	1   -
	2   expression in a DC not resolved
	3   expression in a DV not resolved (probably in DV's EQM symbol)
	4   expression in a DV not resolved (could be in DV's EQM symbol)
	5   expression in a DS not resolved
	6   expression in an ALIGN not resolved
	7   ALIGN: Relocatable origin not known (if in RORG at the time)
	8   ALIGN: Normal origin not known	(if in ORG at the time)
	9   EQU:   expression not resolved
	10  EQU:   value mismatch from previous pass (phase error)
	11  IF:     expression not resolved
	12  REPEAT: expression not resolved

	13  a program label has been defined after it has been
	    referenced (forward reference) and thus we need another
	    pass
	14  a program label's value is different from that of the
	    previous pass (phase error)

    Certain errors will cause the assembly to abort immediately, others
    will wait until the current pass is other.	The remaining allow another
    pass to occur in the hopes the error will fix itself.




SHAR_EOF
if test 17291 -ne "`wc -c DASM.DOC`"
then
echo shar: error transmitting DASM.DOC '(should have been 17291 characters)'
fi
echo shar: extracting FTOHEX.DOC '(549 characters)'
cat << \SHAR_EOF > FTOHEX.DOC

FTOHEX	Convert assembly output file to INTEL-HEX format suitable for, say,
a GTEK prom programmer.

    FTOHEX format infile outfile

Example:
    DASM -f2 example.asm -oram:example.out
    FTOHEX 2 ram:example.out ram:example.hex

    This program converts and output file generated by DASM to the Intel
    hex-ascii format.  You must specify the format you used when you
    assembled the source for FTOHEX to properly read the out file.
    Generally format 2 is used for assembly (see DASM.DOC) as this
    generates the smallest hex file.



SHAR_EOF
if test 549 -ne "`wc -c FTOHEX.DOC`"
then
echo shar: error transmitting FTOHEX.DOC '(should have been 549 characters)'
fi
#	End of shell archive
exit 0

ain@j.cc.purdue.edu (Patrick White) (02/09/88)

Program Name:	dasm  (part 1 of 2)
Submitted By:	dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon)
Summary:	A cross assembler for 6502, 68705, 6803, and HD6303 (extension
		of 6803)
Poster Boy:  Pat White  (ain@j.cc.purdue.edu)
Untested.

NOTES:
   I didn't bother to compile these.


-- Pat White   (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

========================================

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	Makefile
#	asm.h
#	exp.c
#	ftohex.c
#	globals.c
#	main.c
#	mne6303.c
#	mne6502.c
# This archive created: Mon Feb  8 13:15:22 1988
# By:	Patrick White (PUCC Land, USA)
echo shar: extracting Makefile '(883 characters)'
cat << \SHAR_EOF > Makefile

#   DASM    -small systems cross assembler
#   (c)Copyright 1988 Matthew Dillon, All Rights Reserved.
#
#   Requires SUP32.LIB (Aztec C) and precompiled symbol table of */* (all
#   low level Amiga includes, none of the top level includes). remember
#   to compile symbol table with +L option.
#
#   However, shouldn't be too hard to modify to work with
#   lattice or without suplib.

CFLAGS=  +L +Iwork:include/symbols.m

OBJS= main.o ops.o globals.o exp.o symbols.o \
      mne6303.o mne6502.o mne68705.o mne6811.o
SRCS= main.c ops.c globals.c exp.c symbols.c \
      mne6303.c mne6502.c mne68705.c mne6811.c

all: dasm ftohex

dasm: $(OBJS)
    ln +Q $(OBJS) -lsup32 -lc32 -O c:dasm

ftohex: ftohex.o
    ln +Q ftohex.o -lsup32 -lc32 -O c:ftohex

example:
    dasm example.asm -oram:example.out -lram:example.list -f2
    ftohex 2 ram:example.out ram:example.hex

obj: $(OBJS)

SHAR_EOF
if test 883 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 883 characters)'
fi
echo shar: extracting asm.h '(6327 characters)'
cat << \SHAR_EOF > asm.h

/*
 *  ASM65.H
 *
 *  Structures and definitions
 */

#include <stdio.h>

#ifdef IBMPC
typedef char ubyte;
typedef unsigned uword;
typedef long ulong;
#define bzero(s,n) setmem(s,n,0)
#define bset(s,n,c) setmem(s,n,c)
#define bmov(s,d,n) movmem(s,d,n)
#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   4096
#define MHASHSIZE   1024
#define SHASHAND    0x0FFF
#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		(1 << 0 )
#define AF_IMM8 	(1 << 1 )
#define AF_IMM16	(1 << 2 )
#define AF_BYTEADR	(1 << 3 )
#define AF_BYTEADRX	(1 << 4 )
#define AF_BYTEADRY	(1 << 5 )
#define AF_WORDADR	(1 << 6 )
#define AF_WORDADRX	(1 << 7 )
#define AF_WORDADRY	(1 << 8 )
#define AF_REL		(1 << 9 )
#define AF_INDBYTEX	(1 << 10)
#define AF_INDBYTEY	(1 << 11)
#define AF_INDWORD	(1 << 12)
#define AF_0X		(1 << 13)
#define AF_0Y		(1 << 14)
#define AF_BITMOD	(1 << 15)
#define AF_BITBRAMOD	(1 << 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

MNE {
    MNE     *next;	    /*	hash		*/
    void    (*vect)();      /*  dispatch        */
    char    *name;	    /*	actual name	*/
    ubyte   flags;	    /*	special flags	*/
    ulong   okmask;
    ubyte   opcode[NUMOC];  /*	hex codes	*/
};

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 ulong	Processor;

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

extern uword _fmode;

SHAR_EOF
if test 6327 -ne "`wc -c asm.h`"
then
echo shar: error transmitting asm.h '(should have been 6327 characters)'
fi
echo shar: extracting exp.c '(13142 characters)'
cat << \SHAR_EOF > exp.c

/*
 *  EXP.C
 *
 *  Handle expression evaluation and addressing mode decode.
 *
 *  NOTE! If you use the string field in an expression you must clear
 *  the SYM_MACRO and SYM_STRING bits in the flags before calling
 *  freesymbollist()!
 */

#include "asm.h"

extern void doop(), evaltop(), stackarg();
extern void op_mult(), op_div(), op_mod(), op_add(), op_sub(),
	    op_shiftleft(), op_shiftright(), op_greater(), op_greatereq(),
	    op_smaller(), op_smallereq(), op_eqeq(), op_noteq(),
	    op_andand(), op_oror(), op_xor(), op_and(), op_or(),
	    op_negate(), op_invert(), op_not();
extern void op_takelsb(), op_takemsb(), op_question();


extern ubyte *pushsymbol(), *pushstr(), *pushbin(), *pushoct(),
	    *pushdec(), *pushhex(), *pushchar();

extern short alphanum();

/*
 *  evaluate an expression.  Figure out the addressing mode:
 *
 *		    implied
 *	#val	    immediate
 *	val	    zero page or absolute
 *	val,x	    zero,x or absolute,x
 *	val,y	    zero,y or absolute,y
 *	(val)       indirect
 *	(val,x)     zero indirect x
 *	(val),y     zero indirect y
 *
 *	exp, exp,.. LIST of expressions
 *
 *  an absolute may be returned as zero page
 *  a relative may be returned as zero page or absolute
 *
 *  unary:  - ~ ! < >
 *  binary: (^)(* / %)(+ -)(>> <<)(& |)(`)(&& ||)(== != < > <= >=)
 *
 *  values: symbol, octal, decimal, $hex, %binary, 'c "str"
 *
 */

#define MAXOPS	32
#define MAXARGS 64

ubyte Argflags[MAXARGS];
long  Argstack[MAXARGS];
ubyte *Argstring[MAXARGS];
short Oppri[MAXOPS];
void  (*Opdis[MAXOPS])();

uword	Argi, Opi, Lastwasop;
uword	Argibase, Opibase;

SYMBOL *
eval(str)
register char *str;
{
    register SYMBOL *base, *cur;
    uword oldargibase = Argibase;
    uword oldopibase = Opibase;
    uword scr;

    Argibase = Argi;
    Opibase = Opi;
    Lastwasop = 1;
    base = cur = allocsymbol();

    while (*str) {
	if (Xdebug)
	    printf("char '%c'\n", *str);
	switch(*str) {
	case ' ':
	case '\n':
	    ++str;
	    break;
	case '~':
	    if (Lastwasop)
		doop(op_invert, 128);
	    else
		asmerr(0,0);
	    ++str;
	    break;
	case '*':
	    doop(op_mult, 20);
	    ++str;
	    break;
	case '/':
	    doop(op_div, 20);
	    ++str;
	    break;
	case '%':
	    if (Lastwasop) {
		str = (char *)pushbin(str+1);
	    } else {
		doop(op_mod, 20);
		++str;
	    }
	    break;
	case '?':   /*  10      */
	    doop(op_question, 10);
	    ++str;
	    break;
	case '+':   /*  19      */
	    doop(op_add, 19);
	    ++str;
	    break;
	case '-':   /*  19: -   (or - unary)        */
	    if (Lastwasop) {
		doop(op_negate, 128);
	    } else {
		doop(op_sub, 19);
	    }
	    ++str;
	    break;
	case '>':   /*  18: >> <<  17: > >= <= <    */
	    if (Lastwasop) {
		doop(op_takelsb, 128);
		++str;
		break;
	    }

	    if (str[1] == '>') {
		doop(op_shiftright, 18);
		++str;
	    } else if (str[1] == '=') {
		doop(op_greatereq, 17);
		++str;
	    } else {
		doop(op_greater, 17);
	    }
	    ++str;
	    break;
	case '<':
	    if (Lastwasop) {
		doop(op_takemsb, 128);
		++str;
		break;
	    }
	    if (str[1] == '<') {
		doop(op_shiftleft, 18);
		++str;
	    } else if (str[1] == '=') {
		doop(op_smallereq, 17);
		++str;
	    } else {
		doop(op_smaller, 17);
	    }
	    ++str;
	    break;
	case '=':   /*  16: ==  (= same as ==)      */
	    if (str[1] == '=')
		++str;
	    doop(op_eqeq, 16);
	    ++str;
	    break;
	case '!':   /*  16: !=                      */
	    if (Lastwasop) {
		doop(op_not, 128);
	    } else {
		doop(op_noteq, 16);
		++str;
	    }
	    ++str;
	    break;
	case '&':   /*  15: &   12: &&              */
	    if (str[1] == '&') {
		doop(op_andand, 12);
		++str;
	    } else {
		doop(op_and, 15);
	    }
	    ++str;
	    break;
	case '^':   /*  14: ^                       */
	    doop(op_xor, 14);
	    ++str;
	    break;
	case '|':   /*  13: |   11: ||              */
	    if (str[1] == '|') {
		doop(op_oror, 11);
		++str;
	    } else {
		doop(op_or, 13);
	    }
	    ++str;
	    break;
	case '[':   /*  eventually an argument      */
	    if (Opi == MAXOPS)
		puts("too many ops");
	    else
		Oppri[Opi++] = 0;
	    ++str;
	    break;
	case ']':
	    while(Opi != Opibase && Oppri[Opi-1])
		evaltop();
	    if (Opi != Opibase)
		--Opi;
	    ++str;
	    if (Argi == Argibase) {
		puts("']' error, no arg on stack");
		break;
	    }
	    if (*str == 'd') {  /*  STRING CONVERSION   */
		char buf[32];
		++str;
		if (Argflags[Argi-1] == 0) {
		    sprintf(buf,"%ld",Argstack[Argi-1]);
		    Argstring[Argi-1] = strcpy(malloc(strlen(buf)+1),buf);
		}
	    }
	    break;
	case '#':
	    cur->addrmode = AM_IMM8;
	    ++str;
	    break;
	case '(':
	    cur->addrmode = AM_INDWORD;
	    ++str;
	    break;
	case ')':
	    if (cur->addrmode == AM_INDWORD && str[1] == ',' && (str[2]|0x20) == 'y') {
		cur->addrmode = AM_INDBYTEY;
		str += 2;
	    }
	    ++str;
	    break;
	case ',':
	    while(Opi != Opibase)
		evaltop();
	    Lastwasop = 1;
	    scr = str[1]|0x20;	/* to lower case */
	    if (cur->addrmode == AM_INDWORD && scr == 'x' && !alphanum(str[2])) {
		cur->addrmode = AM_INDBYTEX;
		++str;
	    } else if (scr == 'x' && !alphanum(str[2])) {
		cur->addrmode = AM_0X;
		++str;
	    } else if (scr == 'y' && !alphanum(str[2])) {
		cur->addrmode = AM_0Y;
		++str;
	    } else {
		register SYMBOL *new = allocsymbol();
		cur->next = new;
		--Argi;
		if (Argi < Argibase)
		    asmerr(0,0);
		if (Argi > Argibase)
		    asmerr(0,0);
		cur->value = Argstack[Argi];
		cur->flags = Argflags[Argi];
		if (cur->string= (void *)Argstring[Argi]) {
		    cur->flags |= SYM_STRING;
		    if (Xdebug)
			printf("STRING: %s\n", cur->string);
		}
		cur = new;
	    }
	    ++str;
	    break;
	case '$':
	    str = (char *)pushhex(str+1);
	    break;
	case '\'':
	    str = (char *)pushchar(str+1);
	    break;
	case '\"':
	    str = (char *)pushstr(str+1);
	    break;
	default:
	    if (*str == '0')
		str = (char *)pushoct(str);
	    else {
		if (*str > '0' && *str <= '9')
		    str = (char *)pushdec(str);
		else
		    str = (char *)pushsymbol(str);
	    }
	    break;
	}
    }
    while(Opi != Opibase)
	evaltop();
    if (Argi != Argibase) {
	short add = 0;
	--Argi;
	cur->value = Argstack[Argi];
	cur->flags = Argflags[Argi];
	if (cur->string= (void *)Argstring[Argi]) {
	    cur->flags |= SYM_STRING;
	    if (Xdebug)
		printf("STRING: %s\n", cur->string);
	}
	if (base->addrmode == 0)
	    base->addrmode = AM_BYTEADR;
    }
    if (Argi != Argibase || Opi != Opibase)
	asmerr(0,0);
    Argi = Argibase;
    Opi  = Opibase;
    Argibase = oldargibase;
    Opibase = oldopibase;
    return(base);
}

short
alphanum(c)
{
    return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'));
}

void
evaltop()
{
    if (Xdebug)
	printf("evaltop @(A,O) %ld %ld\n", Argi, Opi);
    if (Opi <= Opibase) {
	asmerr(0,0);
	Opi = Opibase;
	return;
    }
    --Opi;
    if (Oppri[Opi] == 128) {
	if (Argi < Argibase + 1) {
	    asmerr(0,0);
	    Argi = Argibase;
	    return;
	}
	--Argi;
	(*Opdis[Opi])(Argstack[Argi], Argflags[Argi]);
    } else {
	if (Argi < Argibase + 2) {
	    asmerr(0,0);
	    Argi = Argibase;
	    return;
	}
	Argi -= 2;
	(*Opdis[Opi])(Argstack[Argi], Argstack[Argi+1], Argflags[Argi], Argflags[Argi+1]);
    }
}

void
stackarg(val, flags)
long val;
short flags;
{
    ubyte *str = NULL;

    if (Xdebug)
	printf("stackarg %ld (@%d)\n", val, Argi);
    Lastwasop = 0;
    if (flags & SYM_STRING) {
	register ubyte *ptr = str = (ubyte *)val;
	register ubyte *new;
	register uword len;
	val = len = 0;
	while (*ptr && *ptr != '\"') {
	    val = (val << 8) | *ptr;
	    ++ptr;
	    ++len;
	}
	new = malloc(len + 1);
	bmov(str, new, len);
	new[len] = 0;
	flags &= ~SYM_STRING;
	str = new;
    }
    Argstack[Argi] = val;
    Argstring[Argi] = str;
    Argflags[Argi] = flags;
    if (++Argi == MAXARGS) {
	puts("stackarg: maxargs stacked");
	Argi = Argibase;
    }
    while (Opi != Opibase && Oppri[Opi-1] == 128)
	evaltop();
}

void
doop(func, pri)
void (*func)();
{
    if (Xdebug)
	puts("doop");
    Lastwasop = 1;
    if (Opi == Opibase || pri == 128) {
	if (Xdebug)
	    printf("doop @ %ld unary\n", Opi);
	Opdis[Opi] = func;
	Oppri[Opi] = pri;
	++Opi;
	return;
    }
    while (Opi != Opibase && Oppri[Opi-1] && pri <= Oppri[Opi-1])
	evaltop();
    if (Xdebug)
	printf("doop @ %ld\n", Opi);
    Opdis[Opi] = func;
    Oppri[Opi] = pri;
    ++Opi;
    if (Opi == MAXOPS) {
	puts("doop: too many operators");
	Opi = Opibase;
    }
    return;
}

void
op_takelsb(v1, f1)
long v1;
{
    stackarg(v1 & 0xFFL, f1);
}

void
op_takemsb(v1, f1)
long v1;
{
    stackarg((v1 >> 8) & 0xFF, f1);
}

void
op_negate(v1, f1)
long v1;
{
    stackarg(-v1, f1);
}

void
op_invert(v1, f1)
long v1;
{
    stackarg(~v1, f1);
}

void
op_not(v1, f1)
long v1;
{
    stackarg(!v1, f1);
}

void
op_mult(v1, v2, f1, f2)
long v1, v2;
{
    stackarg(v1 * v2, f1|f2);
}

void
op_div(v1, v2, f1, f2)
long v1, v2;
{
    if (f1|f2) {
	stackarg(0L, f1|f2);
	return;
    }
    if (v2 == 0) {
	puts("division by zero");
	stackarg(0L, 0);
    } else {
	stackarg(v1 / v2, 0);
    }
}

void
op_mod(v1, v2, f1, f2)
long v1, v2;
{
    if (f1|f2) {
	stackarg(0L, f1|f2);
	return;
    }
    if (v2 == 0)
	stackarg(v1, 0);
    else
	stackarg(v1 % v2, 0);
}

void
op_question(v1, v2, f1, f2)
long v1, v2;
{
    if (f1)
	stackarg(0L, f1);
    else
	stackarg((long)((v1) ? v2 : 0), ((v1) ? f2 : 0));
}

void
op_add(v1, v2, f1, f2)
long v1, v2;
{
    stackarg(v1 + v2, f1|f2);
}

void
op_sub(v1, v2, f1, f2)
long v1, v2;
{
    stackarg(v1 - v2, f1|f2);
}

void
op_shiftright(v1, v2, f1, f2)
long v1, v2;
{
    if (f1|f2)
	stackarg(0L, f1|f2);
    else
	stackarg((long)(v1 >> v2), 0);
}

void
op_shiftleft(v1, v2, f1, f2)
long v1, v2;
{
    if (f1|f2)
	stackarg(0L, f1|f2);
    else
	stackarg((long)(v1 << v2), 0);
}

void
op_greater(v1, v2, f1, f2)
long v1, v2;
{
    stackarg((long)(v1 > v2), f1|f2);
}

void
op_greatereq(v1, v2, f1, f2)
long v1, v2;
{
    stackarg((long)(v1 >= v2), f1|f2);
}

void
op_smaller(v1, v2, f1, f2)
long v1, v2;
{
    stackarg((long)(v1 < v2), f1|f2);
}

void
op_smallereq(v1, v2, f1, f2)
long v1, v2;
{
    stackarg((long)(v1 <= v2), f1|f2);
}

void
op_eqeq(v1, v2, f1, f2)
long v1, v2;
{
    stackarg((long)(v1 == v2), f1|f2);
}

void
op_noteq(v1, v2, f1, f2)
long v1, v2;
{
    stackarg((long)(v1 != v2), f1|f2);
}

void
op_andand(v1, v2, f1, f2)
long v1, v2;
{
    if ((!f1 && !v1) || (!f2 && !v2)) {
	stackarg(0L, 0);
	return;
    }
    stackarg(1L, f1|f2);
}

void
op_oror(v1, v2, f1, f2)
long v1, v2;
{
    if ((!f1 && v1) || (!f2 && v2)) {
	stackarg(1L, 0);
	return;
    }
    stackarg(0L, f1|f2);
}

void
op_xor(v1, v2, f1, f2)
long v1, v2;
{
    stackarg(v1^v2, f1|f2);
}

void
op_and(v1, v2, f1, f2)
long v1, v2;
{
    stackarg(v1&v2, f1|f2);
}

void
op_or(v1, v2, f1, f2)
long v1, v2;
{
    stackarg(v1|v2, f1|f2);
}

ubyte *
pushchar(str)
char *str;
{
    if (*str) {
	stackarg((long)*str, 0);
	++str;
    } else {
	stackarg((long)' ', 0);
    }
    return((ubyte *)str);
}

ubyte *
pushhex(str)
char *str;
{
    register long val = 0;
    for (;; ++str) {
	if (*str >= '0' && *str <= '9') {
	    val = (val << 4) + (*str - '0');
	    continue;
	}
	if ((*str >= 'a' && *str <= 'f') || (*str >= 'A' && *str <= 'F')) {
	    val = (val << 4) + ((*str&0x1F) + 9);
	    continue;
	}
	break;
    }
    stackarg(val, 0);
    return((ubyte *)str);
}

ubyte *
pushoct(str)
char *str;
{
    register long val = 0;
    while (*str >= '0' && *str <= '7') {
	val = (val << 3) + (*str - '0');
	++str;
    }
    stackarg(val, 0);
    return((ubyte *)str);
}

ubyte *
pushdec(str)
char *str;
{
    register long val = 0;
    while (*str >= '0' && *str <= '9') {
	val = (val * 10) + (*str - '0');
	++str;
    }
    stackarg(val, 0);
    return((ubyte *)str);
}

ubyte *
pushbin(str)
char *str;
{
    register long val = 0;
    while (*str == '0' || *str == '1') {
	val = (val << 1) | (*str - '0');
	++str;
    }
    stackarg(val, 0);
    return((ubyte *)str);
}

ubyte *
pushstr(str)
char *str;
{
    stackarg(str, SYM_STRING);
    while (*str && *str != '\"')
	++str;
    if (*str == '\"')
	++str;
    return((ubyte *)str);
}

ubyte *
pushsymbol(str)
ubyte *str;
{
    register SYMBOL *sym;
    register ubyte *ptr;
    ubyte macro = 0;

    for (ptr = str;
	*ptr == '_' ||
	*ptr == '.' ||
	(*ptr >= 'a' && *ptr <= 'z') ||
	(*ptr >= 'A' && *ptr <= 'Z') ||
	(*ptr >= '0' && *ptr <= '9');
	++ptr
    );
    if (ptr == str) {
	asmerr(9,0);
	printf("char = '%lc' %ld (-1: %ld)\n", *str, *str, *(str-1));
	if (F_listfile)
	    fprintf(FI_listfile, "char = '%lc' code %ld\n", *str, *str);
	return((ubyte *)str+1);
    }
    if (sym = findsymbol(str, ptr - str)) {
	if (sym->flags & SYM_UNKNOWN)
	    ++Redo_eval;
	if (sym->flags & SYM_MACRO) {
	    macro = 1;
	    sym = eval(sym->string);
	}
	if (sym->flags & SYM_STRING)
	    stackarg(sym->string, SYM_STRING);
	else
	    stackarg(sym->value, sym->flags & SYM_UNKNOWN);
	sym->flags |= SYM_REF|SYM_MASREF;
	if (macro)
	    freesymbollist(sym);
    } else {
	stackarg(0L, SYM_UNKNOWN);
	sym = createsymbol(str, ptr - str);
	sym->flags = SYM_REF|SYM_MASREF|SYM_UNKNOWN;
	++Redo_eval;
    }
    return(ptr);
}

SHAR_EOF
if test 13142 -ne "`wc -c exp.c`"
then
echo shar: error transmitting exp.c '(should have been 13142 characters)'
fi
echo shar: extracting ftohex.c '(2997 characters)'
cat << \SHAR_EOF > ftohex.c

/*
 *  FTOHEX.C
 *
 *  FTOHEX format infile [outfile]
 *
 *  format: format used when assembling (asm705/asm65)
 *	    1,2,3	    -generate straight hex file
 *
 *  compilable on an ibm-pc or amiga  _fmode is for Lattice C on the IBM,
 *  is IGNORED by Aztec C on the Amiga.  Note that INT and CHAR are not
 *  used as IBM's lattice C uses 16 bit ints and unsigned chars.
 */

#include <stdio.h>

#ifdef IBMPC
typedef char ubyte;
typedef unsigned uword;
#else
typedef unsigned char ubyte;
typedef unsigned short uword;
#endif

#define PERLINE 16

extern long ftell();
extern void fseek();
extern uword getwlh();
extern void  puth();

uword _fmode = 0;

main(ac, av)
ubyte *av[];
short ac;
{
    short format;
    FILE *infile;
    FILE *outfile;

    _fmode = 0x8000;
    if (ac < 3) {
	puts("FTOHEX format infile [outfile]");
	puts("format 1,2, or 3.  3=raw");
	puts("(C)Copyright 1987 by Matthew Dillon, All Rights Reserved");
	exit(1);
    }
    format = atoi(av[1]);
    if (format < 1 || format > 3)
	exiterr("specify infile format 1, 2, or 3");
    infile = fopen(av[2], "r");
    if (infile == NULL)
	exiterr("unable to open input file");
    outfile = (av[3]) ? fopen(av[3], "w") : stdout;
    if (outfile == NULL)
	exiterr("unable to open output file");
    convert(format, infile, outfile);
    fclose(infile);
    fclose(outfile);
}

exiterr(str)
ubyte *str;
{
    fputs(str, stderr);
    fputs("\n", stderr);
    exit(1);
}

/*
 *  Formats:
 *
 *  1:	origin (word:lsb,msb) + data
 *  2:	origin (word:lsb,msb) + length (word:lsb,msb) + data  (repeat)
 *  3:	data
 *
 *  Hex output:
 *
 *  :lloooo00(ll bytes hex code)cc        ll=# of bytes
 *					oooo=origin
 *					  cc=invert of checksum all codes
 */

convert(format, in, out)
short format;
FILE *in;
FILE *out;
{
    uword org = 0;
    uword idx;
    long len;
    ubyte buf[256];

    if (format < 3)
	org = getwlh(in);
    if (format == 2) {
	len = getwlh(in);
    } else {
	long begin = ftell(in);
	fseek(in, 0, 2);
	len = ftell(in) - begin;
	fseek(in, begin, 0);
    }
    for (;;) {
	while (len > 0) {
	    register ubyte chk;
	    register short i;

	    idx = (len > PERLINE) ? PERLINE : len;
	    fread(buf, idx, 1, in);
	    putc(':', out);
	    puth(idx, out);
	    puth(org >> 8, out);
	    puth(org & 0xFF, out);
	    putc('0', out);
	    putc('0', out);
	    chk = idx + (org >> 8) + (org & 0xFF);
	    for (i = 0; i < idx; ++i) {
		chk += buf[i];
		puth(buf[i], out);
	    }
	    puth((ubyte)-chk, out);
	    putc('\r', out);
	    putc('\n', out);
	    len -= idx;
	    org += idx;
	}
	if (format == 2) {
	    org = getwlh(in);
	    if (feof(in))
		break;
	    len = getwlh(in);
	} else {
	    break;
	}
    }
    fprintf(out, ":00000001FF\r\n");
}

uword
getwlh(in)
FILE *in;
{
    uword result;

    result = getc(in);
    result += getc(in) << 8;
    return(result);
}

void
puth(c, out)
ubyte c;
FILE *out;
{
    static ubyte dig[] = { "0123456789ABCDEF" };
    putc(dig[c>>4], out);
    putc(dig[c&15], out);
}

SHAR_EOF
if test 2997 -ne "`wc -c ftohex.c`"
then
echo shar: error transmitting ftohex.c '(should have been 2997 characters)'
fi
echo shar: extracting globals.c '(3208 characters)'
cat << \SHAR_EOF > globals.c

#include "asm.h"

extern void v_list(), v_include(), v_seg(), v_dc(), v_ds(),
	    v_org(), v_rorg(), v_rend(), v_align(), v_subroutine(),
	    v_equ(), v_eqm(), v_set(), v_macro(), v_endm(), v_mexit(),
	    v_ifconst(), v_ifnconst(), v_if(), v_else(),
	    v_endif(), v_repeat(), v_repend(), v_err(), v_hex(), v_trace();
extern void v_end(), v_echo(), v_processor();


SYMBOL	*SHash[SHASHSIZE];  /*	symbol hash table   */
MNE	*MHash[MHASHSIZE];  /*	mnemonic hash table */
INCFILE *Incfile;	    /*	include file stack  */
REPLOOP *Reploop;	    /*	repeat loop stack   */
SEGMENT *Seglist;	    /*	segment list	    */
SEGMENT *Csegment;	    /*	current segment     */
IFSTACK *Ifstack;	    /*	IF/ELSE/ENDIF stack */
ubyte	*Av[256];	    /*	up to 256 arguments */
ubyte	Avbuf[512];
ubyte	MsbOrder = 1;
uword	Mnext;
char	Inclevel;
uword	Mlevel;
ulong	Localindex;	    /*	to generate local variables */
ulong	Lastlocalindex;
ulong	Processor;
ubyte	Xdebug, Xtrace;
ubyte	Outputformat;
ulong	Redo, Redo_why;
ulong	Redo_eval;	    /*	infinite loop detection only	*/


ubyte	F_format = 1;
ubyte	F_verbose;
char	*F_outfile = "a.out";
char	*F_listfile;
char	*F_symfile;
char	*F_temppath = "ram:";
FILE	*FI_listfile;
FILE	*FI_temp;
ubyte	Fisclear;
ulong	Plab, Pflags;

uword	Adrbytes[]  = { 1, 2, 3, 2, 2, 2, 3, 3, 3, 2, 2, 2, 3, 1, 1, 2, 3 };
uword	Cvt[]	    = { 0, 2, 0, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 4, 5, 0, 0 };
uword	Opsize[]    = { 0, 1, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 0, 0, 1, 1 };

MNE Ops[] = {
    { NULL, v_list    , "list",           0,      0 },
    { NULL, v_include , "include",        0,      0 },
    { NULL, v_seg     , "seg",            0,      0 },
    { NULL, v_hex     , "hex",            0,      0 },
    { NULL, v_err     , "err",            0,      0 },
    { NULL, v_dc      , "dc",             0,      0 },
    { NULL, v_ds      , "ds",             0,      0 },
    { NULL, v_dc      , "dv",             0,      0 },
    { NULL, v_end     , "end",            0,      0 },
    { NULL, v_trace   , "trace",          0,      0 },
    { NULL, v_org     , "org",            0,      0 },
    { NULL, v_rorg    , "rorg",           0,      0 },
    { NULL, v_rend    , "rend",           0,      0 },
    { NULL, v_align   , "align",          0,      0 },
    { NULL, v_subroutine, "subroutine",   0,      0 },
    { NULL, v_equ     , "equ",            0,      0 },
    { NULL, v_eqm     , "eqm",            0,      0 },
    { NULL, v_set     , "set",            0,      0 },
    { NULL, v_macro   , "mac",            MF_IF,  0 },
    { NULL, v_endm    , "endm",           0,      0 },
    { NULL, v_mexit   , "mexit",          0,      0 },
    { NULL, v_ifconst , "ifconst",        MF_IF,  0 },
    { NULL, v_ifnconst, "ifnconst",       MF_IF,  0 },
    { NULL, v_if      , "if",             MF_IF,  0 },
    { NULL, v_else    , "else",           MF_IF,  0 },
    { NULL, v_endif   , "endif",          MF_IF,  0 },
    { NULL, v_endif   , "eif",            MF_IF,  0 },
    { NULL, v_repeat  , "repeat",         0,      0 },
    { NULL, v_repend  , "repend",         0,      0 },
    { NULL, v_echo    , "echo",           0,      0 },
    { NULL, v_processor,"processor",      0,      0 },
    NULL
};

SHAR_EOF
if test 3208 -ne "`wc -c globals.c`"
then
echo shar: error transmitting globals.c '(should have been 3208 characters)'
fi
echo shar: extracting main.c '(17019 characters)'
cat << \SHAR_EOF > main.c

/*
 *  MAIN.C
 *
 *  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(), cleanup();
extern void  clearsegs(), clearrefs();
extern SYMBOL *eval();

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.00, high level Macro Assembler");
	puts("(C)Copyright 1988 by Matthew Dillon, All Rights Reserved");
	puts("redistributable for non-profit only");
	puts("");
	puts("ASM65 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);
    }
    printf("DASM V2.00, (c)Copyright 1988 Matthew Dillon, All Rights Reserved\n");
    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);
		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 = -1;
	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;
    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 (;;) {
	    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;
	    }
	    cleanup(buf);
	    ++Incfile->lineno;
	    parse(buf);
	    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 (F_listfile)
		outlistfile();
	}
	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;

	if (F_verbose == 3)
	    puts("SYMBOLIST:  (Unreferenced and 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) || !(sym->flags & SYM_MASREF))
		    printf("%10s %s\n", sym->name, sftos(sym->value, sym->flags));
	    }
	}
	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()
{
    extern ubyte Gen[];
    extern short Glen;
    char c = (Pflags & SF_BSS) ? 'U' : ' ';
    ubyte *ptr = Extstr;
    char dot;
    int i;

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

    fprintf(FI_listfile, "%5ld %c%s  ", Incfile->lineno, c, sftos(Plab, Pflags & 7));
    for (i = 0; i < Glen && i < 4; ++i)
	fprintf(FI_listfile, "%02x ", Gen[i]);
    for (; i < 4; ++i)
	fwrite("   ", 3, 1, FI_listfile);
    fprintf(FI_listfile, "%-10s %5s%c%-3s %s\n", Av[0], Av[1], dot, ptr, Av[2]);
    Glen = 0;
    Extstr = NULL;
}


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;
}

void
cleanup(buf)
register ubyte *buf;
{
    register ubyte *str;
    register STRLIST *strlist;
    register short arg, add;

    for (str = buf; *str; ++str) {
	switch(*str) {
	case '\n':
	case ';':
	    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;
}

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)
	    outlistfile();
    }
    if (!defined) {
	base = NULL;
	slp = &base;
	mac = (MACRO *)permalloc(sizeof(MACRO));
	i = hash1(str);
	mac->next = (void *)MHash[i];
	mac->vect = v_execmac;
	mac->name = strcpy(permalloc(strlen(str)+1), str);
	mac->flags = MF_MACRO;
	MHash[i] = (void *)mac;
    }
    while (fgets(buf, MAXLINE, Incfile->fi)) {
	++Incfile->lineno;
	Disable_me = 1;
	cleanup(buf);
	Disable_me = 0;
	if (parse(buf) >= 2) {
	    findext(Av[1]);
	    mne = findmne(Av[1]);
	    if (mne->vect == v_endm) {
		if (!defined)
		    mac->strlist = base;
		return;
	    }
	}
	if (!skipit && F_listfile)
	    outlistfile();
	if (!defined) {
	    sl = (STRLIST *)permalloc(5+strlen(buf));
	    strcpy(sl->buf, buf);
	    *slp = sl;
	    slp = &sl->next;
	}
    }
    asmerr(8,1);
}

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

    for (; mne->vect; ++mne) {
	bmov(mne->opcode, opcode, NUMOC);
	for (i = j = 0; i < NUMOC; ++i) {
	    mne->opcode[i] = 0;     /* not really needed */
	    if (mne->okmask & (1 << 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)
	    printf("%.*sInclude: %s\n", Inclevel*4, "", str);
	++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);
}


SHAR_EOF
if test 17019 -ne "`wc -c main.c`"
then
echo shar: error transmitting main.c '(should have been 17019 characters)'
fi
echo shar: extracting mne6303.c '(9140 characters)'
cat << \SHAR_EOF > mne6303.c

#include "asm.h"

extern void v_mnemonic();

/*
 *  IMP IMM8 IMM16 BYTE BYTEX BYTEY WORD WORDX WORDY REL (,x) (),y (WORD)
 *   0	 1    2     3	 4	5    6	   7	 8    9   10   11    12
 *
 *  0,x 0,y BIT BITBRA
 *   13  14  15   16
 */

MNE Mne6803[] = {
    { NULL, v_mnemonic, "aba", 0,   AF_IMP,
	{ 0x1B }},
    { NULL, v_mnemonic, "abx", 0,   AF_IMP,
	{ 0x3A }},
    { NULL, v_mnemonic, "adca", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x89, 0x99, 0xA9, 0xB9 }},
    { NULL, v_mnemonic, "adcb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC9, 0xD9, 0xE9, 0xF9 }},
    { NULL, v_mnemonic, "adda", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x8B, 0x9B, 0xAB, 0xBB }},
    { NULL, v_mnemonic, "addb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xCB, 0xDB, 0xEB, 0xFB }},
    { NULL, v_mnemonic, "addd", 0,  AF_IMM16|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC3, 0xD3, 0xE3, 0xF3 }},
    { NULL, v_mnemonic, "anda", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x84, 0x94, 0xA4, 0xB4 }},
    { NULL, v_mnemonic, "andb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC4, 0xD4, 0xE4, 0xF4 }},
    { NULL, v_mnemonic, "bita", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x85, 0x95, 0xA5, 0xB5 }},
    { NULL, v_mnemonic, "bitb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC5, 0xD5, 0xE5, 0xF5 }},
    { NULL, v_mnemonic, "bra", 0,   AF_REL, { 0x20 }},
    { NULL, v_mnemonic, "brn", 0,   AF_REL, { 0x21 }},
    { NULL, v_mnemonic, "bcc", 0,   AF_REL, { 0x24 }},
    { 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, "ble", 0,   AF_REL, { 0x2F }},
    { 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, "bvc", 0,   AF_REL, { 0x28 }},
    { NULL, v_mnemonic, "bvs", 0,   AF_REL, { 0x29 }},
    { NULL, v_mnemonic, "bpl", 0,   AF_REL, { 0x2A }},
    { NULL, v_mnemonic, "bsr", 0,   AF_REL, { 0x8D }},
    { NULL, v_mnemonic, "clc", 0,   AF_IMP, { 0x0C }},
    { NULL, v_mnemonic, "cli", 0,   AF_IMP, { 0x0E }},
    { NULL, v_mnemonic, "clv", 0,   AF_IMP, { 0x0A }},
    { 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, "tap", 0,   AF_IMP, { 0x06 }},
    { NULL, v_mnemonic, "tpa", 0,   AF_IMP, { 0x07 }},
    { NULL, v_mnemonic, "clr", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x6F, 0x7F }},
    { NULL, v_mnemonic, "clra", 0,  AF_IMP, { 0x4F }},
    { NULL, v_mnemonic, "clrb", 0,  AF_IMP, { 0x5F }},
    { NULL, v_mnemonic, "cmpa", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x81, 0x91, 0xA1, 0xB1 }},
    { NULL, v_mnemonic, "cmpb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC1, 0xD1, 0xE1, 0xF1 }},
    { NULL, v_mnemonic, "cba", 0,   AF_IMP, { 0x11 }},
    { NULL, v_mnemonic, "com", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x63, 0x73 }},
    { NULL, v_mnemonic, "coma", 0,  AF_IMP, { 0x43 }},
    { NULL, v_mnemonic, "comb", 0,  AF_IMP, { 0x53 }},
    { NULL, v_mnemonic, "neg", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x60, 0x70 }},
    { NULL, v_mnemonic, "nega", 0,  AF_IMP, { 0x40 }},
    { NULL, v_mnemonic, "negb", 0,  AF_IMP, { 0x50 }},
    { NULL, v_mnemonic, "daa", 0,   AF_IMP, { 0x19 }},
    { NULL, v_mnemonic, "dec", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x6A, 0x7A }},
    { NULL, v_mnemonic, "deca", 0,  AF_IMP, { 0x4A }},
    { NULL, v_mnemonic, "decb", 0,  AF_IMP, { 0x5A }},
    { NULL, v_mnemonic, "eora", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x88, 0x98, 0xA8, 0xB8 }},
    { NULL, v_mnemonic, "eorb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC8, 0xD8, 0xE8, 0xF8 }},
    { NULL, v_mnemonic, "inc", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x6C, 0x7C }},
    { NULL, v_mnemonic, "inca", 0,  AF_IMP, { 0x4C }},
    { NULL, v_mnemonic, "incb", 0,  AF_IMP, { 0x5C }},
    { NULL, v_mnemonic, "jmp",  0,  AF_BYTEADRX|AF_WORDADR,
	{ 0x6E, 0x7E }},
    { NULL, v_mnemonic, "jsr",  0,  AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x9D, 0xAD, 0xBD }},
    { NULL, v_mnemonic, "ldaa", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x86, 0x96, 0xA6, 0xB6 }},
    { NULL, v_mnemonic, "ldab", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC6, 0xD6, 0xE6, 0xF6 }},
    { NULL, v_mnemonic, "ldd", 0,   AF_IMM16|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xCC, 0xDC, 0xEC, 0xFC }},
    { NULL, v_mnemonic, "mul", 0,   AF_IMP, { 0x3D }},
    { NULL, v_mnemonic, "nop", 0,   AF_IMP, { 0x01 }},
    { NULL, v_mnemonic, "oraa",0,   AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x8A, 0x9A, 0xAA, 0xBA }},
    { NULL, v_mnemonic, "orab", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xCA, 0xDA, 0xEA, 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, "pulx", 0,  AF_IMP, { 0x38 }},
    { NULL, v_mnemonic, "pula", 0,  AF_IMP, { 0x32 }},
    { NULL, v_mnemonic, "pulb", 0,  AF_IMP, { 0x33 }},
    { NULL, v_mnemonic, "rol", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x69, 0x79 }},
    { NULL, v_mnemonic, "rola", 0,  AF_IMP, { 0x49 }},
    { NULL, v_mnemonic, "rolb", 0,  AF_IMP, { 0x59 }},
    { NULL, v_mnemonic, "ror", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x66, 0x76 }},
    { NULL, v_mnemonic, "rora", 0,  AF_IMP, { 0x46 }},
    { NULL, v_mnemonic, "rorb", 0,  AF_IMP, { 0x56 }},
    { NULL, v_mnemonic, "rti", 0,   AF_IMP, { 0x3B }},
    { NULL, v_mnemonic, "rts", 0,   AF_IMP, { 0x39 }},
    { NULL, v_mnemonic, "swi", 0,   AF_IMP, { 0x3F }},
    { NULL, v_mnemonic, "wai", 0,   AF_IMP, { 0x3E }},
    { NULL, v_mnemonic, "asl", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x68, 0x78 }},
    { NULL, v_mnemonic, "asla", 0,  AF_IMP, { 0x48 }},
    { NULL, v_mnemonic, "aslb", 0,  AF_IMP, { 0x58 }},
    { NULL, v_mnemonic, "asld", 0,  AF_IMP, { 0x05 }},
    { NULL, v_mnemonic, "asr", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x67, 0x77 }},
    { NULL, v_mnemonic, "asra", 0,  AF_IMP, { 0x47 }},
    { NULL, v_mnemonic, "asrb", 0,  AF_IMP, { 0x57 }},
    { NULL, v_mnemonic, "cpx",  0,  AF_IMM16|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x8C, 0x9C, 0xAC, 0xBC }},
    { NULL, v_mnemonic, "dex", 0,   AF_IMP, { 0x09 }},
    { NULL, v_mnemonic, "des", 0,   AF_IMP, { 0x34 }},
    { NULL, v_mnemonic, "inx", 0,   AF_IMP, { 0x08 }},
    { NULL, v_mnemonic, "ins", 0,   AF_IMP, { 0x31 }},
    { NULL, v_mnemonic, "ldx", 0,   AF_IMM16|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xCE, 0xDE, 0xEE, 0xFE }},
    { NULL, v_mnemonic, "lds", 0,   AF_IMM16|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x8E, 0x9E, 0xAE, 0xBE }},
    { NULL, v_mnemonic, "lsr", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x64, 0x74 }},
    { NULL, v_mnemonic, "lsra", 0,  AF_IMP, { 0x44 }},
    { NULL, v_mnemonic, "lsrb", 0,  AF_IMP, { 0x54 }},
    { NULL, v_mnemonic, "lsrd", 0,  AF_IMP, { 0x04 }},
    { NULL, v_mnemonic, "staa", 0,  AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x97, 0xA7, 0xB7 }},
    { NULL, v_mnemonic, "stab", 0,  AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xD7, 0xE7, 0xF7 }},
    { NULL, v_mnemonic, "std", 0,   AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xDD, 0xED, 0xFD }},
    { NULL, v_mnemonic, "sts", 0,   AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x9F, 0xAF, 0xBF }},
    { NULL, v_mnemonic, "stx", 0,   AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xDF, 0xEF, 0xFF }},
    { NULL, v_mnemonic, "suba", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x80, 0x90, 0xA0, 0xB0 }},
    { NULL, v_mnemonic, "subb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC0, 0xD0, 0xE0, 0xF0 }},
    { NULL, v_mnemonic, "subd", 0,  AF_IMM16|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x83, 0x93, 0xA3, 0xB3 }},
    { NULL, v_mnemonic, "sba", 0,   AF_IMP, { 0x10 }},
    { NULL, v_mnemonic, "sbca", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0x82, 0x92, 0xA2, 0xB2 }},
    { NULL, v_mnemonic, "sbcb", 0,  AF_IMM8|AF_BYTEADR|AF_BYTEADRX|AF_WORDADR,
	{ 0xC2, 0xD2, 0xE2, 0xF2 }},
    { NULL, v_mnemonic, "tab", 0,   AF_IMP, { 0x16 }},
    { NULL, v_mnemonic, "tba", 0,   AF_IMP, { 0x17 }},
    { NULL, v_mnemonic, "tst", 0,   AF_BYTEADRX|AF_WORDADR,
	{ 0x6D, 0x7D }},
    { NULL, v_mnemonic, "tsta", 0,  AF_IMP, { 0x4D }},
    { NULL, v_mnemonic, "tstb", 0,  AF_IMP, { 0x5D }},
    { NULL, v_mnemonic, "tsx", 0,   AF_IMP, { 0x30 }},
    { NULL, v_mnemonic, "txs", 0,   AF_IMP, { 0x35 }},
    NULL
};

MNE MneHD6303[] = {
    { NULL, v_mnemonic, "slp", 0,   AF_IMP, { 0x1A }},
    { NULL, v_mnemonic, "aim", 0,   AF_BYTEADR|AF_BYTEADRX,
	{ 0x71, 0x61 }},
    { NULL, v_mnemonic, "oim", 0,   AF_BYTEADR|AF_BYTEADRX,
	{ 0x72, 0x62 }},
    { NULL, v_mnemonic, "eim", 0,   AF_BYTEADR|AF_BYTEADRX,
	{ 0x75, 0x65 }},
    { NULL, v_mnemonic, "tim", 0,   AF_BYTEADR|AF_BYTEADRX,
	{ 0x7B, 0x6B }},
    { NULL, v_mnemonic, "xgdx", 0,  AF_IMP, { 0x18 }},
    NULL
};


SHAR_EOF
if test 9140 -ne "`wc -c mne6303.c`"
then
echo shar: error transmitting mne6303.c '(should have been 9140 characters)'
fi
echo shar: extracting mne6502.c '(4166 characters)'
cat << \SHAR_EOF > mne6502.c

#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
};



SHAR_EOF
if test 4166 -ne "`wc -c mne6502.c`"
then
echo shar: error transmitting mne6502.c '(should have been 4166 characters)'
fi
#	End of shell archive
exit 0

ain@j.cc.purdue.edu (Patrick White) (02/09/88)

Program Name:	dasm  (part 2 of 2)
Submitted By:	dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon)
Summary:	A cross assembler for 6502, 68705, 6803, and HD6303 (extension
		of 6803)
Poster Boy:  Pat White  (ain@j.cc.purdue.edu)
Untested.

NOTES:
   I didn't bother to test compile this.


-- Pat White   (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

========================================

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	mne6811.c
#	mne68705.c
#	ops.c
#	suite6303.asm
#	suite6502.asm
#	suite68705.asm
#	symbols.c
# This archive created: Mon Feb  8 13:17:15 1988
# By:	Patrick White (PUCC Land, USA)
echo shar: extracting mne6811.c '(52 characters)'
cat << \SHAR_EOF > mne6811.c

#include "asm.h"

MNE Mne68HC11[] = {
    NULL
};

SHAR_EOF
if test 52 -ne "`wc -c mne6811.c`"
then
echo shar: error transmitting mne6811.c '(should have been 52 characters)'
fi
echo shar: extracting mne68705.c '(5699 characters)'
cat << \SHAR_EOF > mne68705.c

#include "asm.h"

#define AFSTD	AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX|AF_0X

extern void v_mnemonic();

MNE Mne68705[] = {
    NULL, v_mnemonic, "adc", 0, AF_IMM8|AFSTD,
	{ 0xA9, 0xB9, 0xE9, 0xC9, 0xD9, 0xF9 },
    NULL, v_mnemonic, "add", 0, AF_IMM8|AFSTD,
	{ 0xAB, 0xBB, 0xEB, 0xCB, 0xDB, 0xFB },
    NULL, v_mnemonic, "and", 0, AF_IMM8|AFSTD,
	{ 0xA4, 0xB4, 0xE4, 0xC4, 0xD4, 0xF4 },
    NULL, v_mnemonic, "asl", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x48, 0x38, 0x68, 0x78 },
    NULL, v_mnemonic, "asla", 0,AF_IMP, { 0x48 },
    NULL, v_mnemonic, "aslx", 0,AF_IMP, { 0x58 },
    NULL, v_mnemonic, "asr", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x47, 0x37, 0x67, 0x77 },
    NULL, v_mnemonic, "asra", 0,AF_IMP, { 0x47 },
    NULL, v_mnemonic, "asrx", 0,AF_IMP, { 0x57 },
    NULL, v_mnemonic, "bcc", 0, AF_REL, { 0x24 },
    NULL, v_mnemonic, "bclr", 0,AF_BITMOD, { 0x11 },
    NULL, v_mnemonic, "bcs", 0, AF_REL, { 0x25 },
    NULL, v_mnemonic, "beq", 0, AF_REL, { 0x27 },
    NULL, v_mnemonic, "bhcc", 0,AF_REL, { 0x28 },
    NULL, v_mnemonic, "bhcs", 0,AF_REL, { 0x29 },
    NULL, v_mnemonic, "bhi", 0, AF_REL, { 0x22 },
    NULL, v_mnemonic, "bhs", 0, AF_REL, { 0x24 },
    NULL, v_mnemonic, "bih", 0, AF_REL, { 0x2F },
    NULL, v_mnemonic, "bil", 0, AF_REL, { 0x2E },
    NULL, v_mnemonic, "bit", 0, AF_IMM8|AFSTD,
	{ 0xA5, 0xB5, 0xE5, 0xC5, 0xD5, 0xF5 },
    NULL, v_mnemonic, "blo", 0, AF_REL, { 0x25 },
    NULL, v_mnemonic, "bls", 0, AF_REL, { 0x23 },
    NULL, v_mnemonic, "bmc", 0, AF_REL, { 0x2C },
    NULL, v_mnemonic, "bmi", 0, AF_REL, { 0x2B },
    NULL, v_mnemonic, "bms", 0, AF_REL, { 0x2D },
    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, "brn", 0, AF_REL, { 0x21 },
    NULL, v_mnemonic, "brclr", 0,   AF_BITBRAMOD, { 0x01 },
    NULL, v_mnemonic, "brset", 0,   AF_BITBRAMOD, { 0x00 },
    NULL, v_mnemonic, "bset", 0,AF_BITMOD, { 0x10 },
    NULL, v_mnemonic, "bsr", 0, AF_REL, { 0xAD },
    NULL, v_mnemonic, "clc", 0, AF_IMP, { 0x98 },
    NULL, v_mnemonic, "cli", 0, AF_IMP, { 0x9A },
    NULL, v_mnemonic, "clr", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x4F, 0x3F, 0x6F, 0x7F },
    NULL, v_mnemonic, "clra", 0,AF_IMP, { 0x4F },
    NULL, v_mnemonic, "clrx", 0,AF_IMP, { 0x5F },
    NULL, v_mnemonic, "cmp", 0, AF_IMM8|AFSTD,
	{ 0xA1, 0xB1, 0xE1, 0xC1, 0xD1, 0xF1 },
    NULL, v_mnemonic, "com", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x43, 0x33, 0x63, 0x73 },
    NULL, v_mnemonic, "coma", 0,AF_IMP, { 0x43 },
    NULL, v_mnemonic, "comx", 0,AF_IMP, { 0x53 },
    NULL, v_mnemonic, "cpx", 0, AF_IMM8|AFSTD,
	{ 0xA3, 0xB3, 0xE3, 0xC3, 0xD3, 0xF3 },
    NULL, v_mnemonic, "dec", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x4A, 0x3A, 0x6A, 0x7A },
    NULL, v_mnemonic, "deca", 0,AF_IMP, { 0x4A },
    NULL, v_mnemonic, "decx", 0,AF_IMP, { 0x5A },
    NULL, v_mnemonic, "dex", 0, AF_IMP, { 0x5A },
    NULL, v_mnemonic, "eor", 0, AF_IMM8|AFSTD,
	{ 0xA8, 0xB8, 0xE8, 0xC8, 0xD8, 0xF8 },
    NULL, v_mnemonic, "inc", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x4C, 0x3C, 0x6C, 0x7C },
    NULL, v_mnemonic, "inca", 0,AF_IMP, { 0x4C },
    NULL, v_mnemonic, "incx", 0,AF_IMP, { 0x5C },
    NULL, v_mnemonic, "inx", 0, AF_IMP, { 0x5C },
    NULL, v_mnemonic, "jmp", 0, AFSTD,
	{ 0xBC, 0xEC, 0xCC, 0xDC, 0xFC },
    NULL, v_mnemonic, "jsr", 0, AFSTD,
	{ 0xBD, 0xED, 0xCD, 0xDD, 0xFD },
    NULL, v_mnemonic, "lda", 0, AF_IMM8|AFSTD,
	{ 0xA6, 0xB6, 0xE6, 0xC6, 0xD6, 0xF6 },
    NULL, v_mnemonic, "ldx", 0, AF_IMM8|AFSTD,
	{ 0xAE, 0xBE, 0xEE, 0xCE, 0xDE, 0xFE },
    NULL, v_mnemonic, "lsl", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x48, 0x38, 0x68, 0x78 },
    NULL, v_mnemonic, "lsla", 0,AF_IMP, { 0x48 },
    NULL, v_mnemonic, "lslx", 0,AF_IMP, { 0x58 },
    NULL, v_mnemonic, "lsr", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x44, 0x34, 0x64, 0x74 },
    NULL, v_mnemonic, "lsra", 0,AF_IMP, { 0x44 },
    NULL, v_mnemonic, "lsrx", 0,AF_IMP, { 0x54 },
    NULL, v_mnemonic, "neg", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x40, 0x30, 0x60, 0x70 },
    NULL, v_mnemonic, "nega", 0,AF_IMP, { 0x40 },
    NULL, v_mnemonic, "negx", 0,AF_IMP, { 0x50 },
    NULL, v_mnemonic, "nop", 0, AF_IMP, { 0x9D },
    NULL, v_mnemonic, "ora", 0, AF_IMM8|AFSTD,
	{ 0xAA, 0xBA, 0xEA, 0xCA, 0xDA, 0xFA },
    NULL, v_mnemonic, "rol", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x49, 0x39, 0x69, 0x79 },
    NULL, v_mnemonic, "rola", 0,AF_IMP, { 0x49 },
    NULL, v_mnemonic, "rolx", 0,AF_IMP, { 0x59 },
    NULL, v_mnemonic, "ror", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x46, 0x36, 0x66, 0x76 },
    NULL, v_mnemonic, "rora", 0,AF_IMP, { 0x46 },
    NULL, v_mnemonic, "rorx", 0,AF_IMP, { 0x56 },
    NULL, v_mnemonic, "rsp", 0, AF_IMP, { 0x9C },
    NULL, v_mnemonic, "rti", 0, AF_IMP, { 0x80 },
    NULL, v_mnemonic, "rts", 0, AF_IMP, { 0x81 },
    NULL, v_mnemonic, "sbc", 0, AF_IMM8|AFSTD,
	{ 0xA2, 0xB2, 0xE2, 0xC2, 0xD2, 0xF2 },
    NULL, v_mnemonic, "sec", 0, AF_IMP, { 0x99 },
    NULL, v_mnemonic, "sei", 0, AF_IMP, { 0x9B },
    NULL, v_mnemonic, "sta", 0, AFSTD,
	{ 0xB7, 0xE7, 0xC7, 0xD7, 0xF7 },
    NULL, v_mnemonic, "stx", 0, AFSTD,
	{ 0xBF, 0xEF, 0xCF, 0xDF, 0xFF },
    NULL, v_mnemonic, "sub", 0, AF_IMM8|AFSTD,
	{ 0xA0, 0xB0, 0xE0, 0xC0, 0xD0, 0xF0 },
    NULL, v_mnemonic, "swi", 0, AF_IMP, { 0x83 },
    NULL, v_mnemonic, "tax", 0, AF_IMP, { 0x97 },
    NULL, v_mnemonic, "tst", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
	{ 0x4D, 0x3D, 0x6D, 0x7D },
    NULL, v_mnemonic, "tsta", 0,AF_IMP, { 0x4D },
    NULL, v_mnemonic, "tstx", 0,AF_IMP, { 0x5D },
    NULL, v_mnemonic, "txa", 0, AF_IMP, { 0x9F },
    NULL
};

SHAR_EOF
if test 5699 -ne "`wc -c mne68705.c`"
then
echo shar: error transmitting mne68705.c '(should have been 5699 characters)'
fi
echo shar: extracting ops.c '(18260 characters)'
cat << \SHAR_EOF > ops.c

/*
 *  OPS.C
 *
 *  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 & (1 << adrmode)))

void
v_mnemonic(str,mne)
register MNE *mne;
ubyte *str;
{
    register uword addrmode;
    register SYMBOL *sym;
    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 (sym->addrmode == AM_IMM8 || sym->addrmode == AM_BYTEADR) {
	if (sym->next) {
	    sym->addrmode = AM_BITMOD;
	    if (sym->next->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: %ld  Cvt[am]: %ld\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];
    }
    Glen = Adrbytes[addrmode];
    Gen[0] = mne->opcode[addrmode];
    Gen[1] = sym->value;
    if (Opsize[addrmode] > 1) {
	if (MsbOrder) {
	    Gen[1] = sym->value >> 8;
	    Gen[2] = sym->value;
	} else {
	    Gen[2] = sym->value >> 8;
	}
    }
    switch(addrmode) {
    case AM_BITMOD:
	sym = symbase->next;
	if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
	    asmerr(14,0);
	Gen[1] = 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[1] = sym->value;
	sym = sym->next;
    case AM_REL:
	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 - Adrbytes[addrmode];
		if (dest >= 128 || dest < -128)
		    asmerr(10,0);
	    }
	    Gen[(addrmode == AM_REL) ? 1 : 2] = dest & 0xFF;
	}
	break;
    }
    generate();
    freesymbollist(symbase);
}

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

v_list(str)
{
    programlabel();
}

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 = (void *)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 = (void *)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 = 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);
	}
    } 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);
	}
    }
    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;

    programlabel();
    sym = eval(str);
    rp = (REPLOOP *)zmalloc(sizeof(REPLOOP));
    rp->next = Reploop;
    rp->file = Incfile;
    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);
}

void
v_repend()
{
    if (Reploop) {
	if (Reploop->file == Incfile) {
	    if (Reploop->flags == 0 && --Reploop->count) {
		fseek(Incfile->fi,Reploop->seek,0);
		Incfile->lineno = Reploop->lineno;
	    } else {
		rmnode(&Reploop, sizeof(REPLOOP));
		programlabel();
	    }
	    return;
	}
    }
    puts("no repeat");
}

static long Seglen;
static long Seekback;

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

    if (!Redo) {
	if (!(Csegment->flags & SF_BSS)) {
	    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, bytes)
long bytes;
{
    bset(Gen, sizeof(Gen), fill);
    while (bytes > sizeof(Gen)) {
	Glen = 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;
}

SHAR_EOF
if test 18260 -ne "`wc -c ops.c`"
then
echo shar: error transmitting ops.c '(should have been 18260 characters)'
fi
echo shar: extracting suite6303.asm '(4346 characters)'
cat << \SHAR_EOF > suite6303.asm

	processor   hd6303
	org 0

	adda	#10	;   8B 0A
	adda	10	;   9B 0A
	adda	10,x	;   AB 0A
	adda	1000	;   BB 03 E8
	addb	#10	;   CB 0A
	addb	10	;   DB 0A
	addb	10,x	;   EB 0A
	addb	1000	;   FB 03 E8
	addd	#1000	;   C3 03 E8
	addd	10	;   D3 0A
	addd	10,x	;   E3 0A
	addd	1000	;   F3 03 E8
	aba		;   1B
	adca	#10	;   89 0A
	adca	10	;   99 0A
	adca	10,x	;   A9 0A
	adca	1000	;   B9 03 E8
	adcb	#10	;   C9
	adcb	10	;   D9
	adcb	10,x	;   E9
	adcb	1000	;   F9 03 E8
	anda	#10	;   84 0A
	anda	10	;   94 0A
	anda	10,x	;   A4 0A
	anda	1000	;   B4 03 E8
	andb	#10	;   C4 0A
	andb	10	;   D4 0A
	andb	10,x	;   E4 0A
	andb	1000	;   F4 03 E8
	bita	#10	;   85 0A
	bita	10	;   95 0A
	bita	10,x	;   A5 0A
	bita	1000	;   B5 03 E8
	bitb	#10	;   C5 0A
	bitb	10	;   D5 0A
	bitb	10,x	;   E5 0A
	bitb	1000	;   F5 03 E8
	clr	10,x	;   6F 0A
	clr	1000	;   7F 03 E8
	clra		;   4F
	clrb		;   5F
	cmpa	#10	;   81 0A
	cmpa	10	;   91 0A
	cmpa	10,x	;   A1 0A
	cmpa	1000	;   B1 03 E8
	cmpb	#10	;   C1 0A
	cmpb	10	;   D1 0A
	cmpb	10,x	;   E1 0A
	cmpb	1000	;   F1 03 E8
	cba		;   11
	com	10,x	;   63 0A
	com	1000	;   73 03 E8
	coma		;   43
	comb		;   53
	neg	10,x	;   60 0A
	neg	1000	;   70 03 E8
	nega		;   40
	negb		;   50
	daa		;   19
	dec	10,x	;   6A 0A
	dec	1000	;   7A 03 E8
	deca		;   4A
	decb		;   5A
	eora	#10	;   88 0A
	eora	10	;   98 0A
	eora	10,x	;   A8 0A
	eora	1000	;   B8 03 E8
	eorb	#10	;   C8 0A
	eorb	10	;   D8 0A
	eorb	10,x	;   E8 0A
	eorb	1000	;   F8 03 E8
	inc	10,x	;   6C 0A
	inc	1000	;   7C 03 E8
	inca		;   4C
	incb		;   5C
	ldaa	#10	;   86 0A
	ldaa	10	;   96 0A
	ldaa	10,x	;   A6 0A
	ldaa	1000	;   B6 03 E8
	ldab	#10	;   C6 0A
	ldab	10	;   D6 0A
	ldab	10,x	;   E6 0A
	ldab	1000	;   F6 03 E8
	ldd	#1000	;   CC 03 E8
	ldd	10	;   DC 0A
	ldd	10,x	;   EC 0A
	ldd	1000	;   FC 03 E8
	mul		;   3D
	oraa	#10	;   8A 0A
	oraa	10	;   9A 0A
	oraa	10,x	;   AA 0A
	oraa	1000	;   BA 03 E8
	orab	#10	;   CA 0A
	orab	10	;   DA 0A
	orab	10,x	;   EA 0A
	orab	1000	;   FA 03 E8
	psha		;   36
	pshb		;   37
	pula		;   32
	pulb		;   33
	rol	10,x	;   69 0A
	rol	1000	;   79 03 E8
	rola		;   49
	rolb		;   59
	ror	10,x	;   66 0A
	ror	1000	;   76 03 E8
	rora		;   46
	rorb		;   56
	asl	10,x	;   68 0A
	asl	1000	;   78 03 E8
	asla		;   48
	aslb		;   58
	asld		;   05
	asr	10,x	;   67 0A
	asr	1000	;   77 03 E8
	asra		;   47
	asrb		;   57
	lsr	10,x	;   64 0A
	lsr	1000	;   74 03 E8
	lsra		;   44
	lsrb		;   54
	lsrd		;   04
	staa	10	;   97 0A
	staa	10,x	;   A7 0A
	staa	1000	;   B7 03 E8
	stab	10	;   D7 0A
	stab	10,x	;   E7 0A
	stab	1000	;   F7 03 E8
	std	10	;   DD 0A
	std	10,x	;   ED 0A
	std	1000	;   FD 03 E8
	suba	#10	;   80 0A
	suba	10	;   90 0A
	suba	10,x	;   A0 0A
	suba	1000	;   B0 03 E8
	subb	#10	;   C0 0A
	subb	10	;   D0 0A
	subb	10,x	;   E0 0A
	subb	1000	;   F0 03 E8
	subd	#1000	;   83 03 E8
	subd	10	;   93 0A
	subd	10,x	;   A3 0A
	subd	1000	;   B3 03 E8
	sba		;   10
	sbca	#10	;   82 0A
	sbca	10	;   92 0A
	sbca	10,x	;   A2 0A
	sbca	1000	;   B2 03 E8
	sbcb	#10	;   C2 0A
	sbcb	10	;   D2 0A
	sbcb	10,x	;   E2 0A
	sbcb	1000	;   F2 03 E8
	tab		;   16
	tba		;   17
	tst	10,x	;   6D 0A
	tst	1000	;   7D 03 E8
	tsta		;   4D
	tstb		;   5D
	aim	10	;   71 0A
	aim	10,x	;   61 0A
	oim	10	;   72 0A
	oim	10,x	;   62 0A
	eim	10	;   75 0A
	eim	10,x	;   65 0A
	tim	10	;   7B 0A
	tim	10,x	;   6B 0A
	cpx	#1000	;   8C 03 E8
	cpx	10	;   9C 0A
	cpx	10,x	;   AC 0A
	cpx	1000	;   BC 03 E8
	dex		;   09
	des		;   34
	inx		;   08
	ins		;   31
	ldx	#1000	;   CE 03 E8
	ldx	10	;   DE 0A
	ldx	10,x	;   EE 0A
	ldx	1000	;   FE 03 E8
	lds	#1000	;   8E 03 E8
	lds	10	;   9E 0A
	lds	10,x	;   AE 0A
	lds	1000	;   BE 03 E8
	stx	10	;   DF 0A
	stx	10,x	;   EF 0A
	stx	1000	;   FF 03 E8
	sts	10	;   9F 0A
	sts	10,x	;   AF 0A
	sts	1000	;   BF 03 E8
	txs		;   35
	tsx		;   30
	abx		;   3A
	pshx		;   3C
	pulx		;   38
	xgdx		;   18
	bra	.	;   20 FE
	brn	.	;   21 FE
	bcc	.	;   24 FE
	bcs	.	;   25 FE
	beq	.	;   27 FE
	bge	.	;   2C FE
	bgt	.	;   2E FE
	bhi	.	;   22 FE
	ble	.	;   2F FE
	bls	.	;   23 FE
	blt	.	;   2D FE
	bmi	.	;   2B FE
	bne	.	;   26 FE
	bvc	.	;   28 FE
	bvs	.	;   29 FE
	bpl	.	;   2A FE
	bsr	.	;   8D FE
	jmp	10,x	;   6E 0A
	jmp	1000	;   7E 03 E8
	jsr	10	;   9D 0A
	jsr	10,x	;   AD 0A
	jsr	1000	;   BD 03 E8
	nop		;   01
	rti		;   3B
	rts		;   39
	swi		;   3F
	wai		;   3E
	slp		;   1A
	clc		;   0C
	cli		;   0E
	clv		;   0A
	sec		;   0D
	sei		;   0F
	sev		;   0B
	tap		;   06
	tpa		;   07

SHAR_EOF
if test 4346 -ne "`wc -c suite6303.asm`"
then
echo shar: error transmitting suite6303.asm '(should have been 4346 characters)'
fi
echo shar: extracting suite6502.asm '(1645 characters)'
cat << \SHAR_EOF > suite6502.asm

	;   TEST ADDRESSING MODES

	processor   6502

	org	0

	adc	#1
	adc	1
	adc	1,x
	adc	1,y	    ;absolute
	adc	1000
	adc	1000,x
	adc	1000,y
	adc	(1,x)
	adc	(1),y

	and	#1
	and	1
	and	1,x
	and	1,y	    ;absolute
	and	1000
	and	1000,x
	and	1000,y
	and	(1,x)
	and	(1),y

	asl
	asl	1
	asl	1,x
	asl	1000
	asl	1000,x

	bcc	.
	bcs	.
	beq	.
	bit	1
	bit	1000
	bmi	.
	bne	.
	bpl	.
	brk
	bvc	.
	bvs	.
	clc
	cld
	cli
	clv

	cmp	#1
	cmp	1
	cmp	1,x
	cmp	1,y	    ;absolute
	cmp	1000
	cmp	1000,x
	cmp	1000,y
	cmp	(1,x)
	cmp	(1),y

	cpx	#1
	cpx	1
	cpx	1000

	cpy	#1
	cpy	1
	cpy	1000

	dec	1
	dec	1,x
	dec	1000
	dec	1000,x

	dex
	dey

	eor	#1
	eor	1
	eor	1,x
	eor	1,y	    ;absolute
	eor	1000
	eor	1000,x
	eor	1000,y
	eor	(1,x)
	eor	(1),y

	inc	1
	inc	1,x
	inc	1000
	inc	1000,x

	inx
	iny

	jmp	1	    ;absolute
	jmp	1000
	jmp	(1)         ;absolute
	jmp	(1000)

	jsr	1	    ;absolute
	jsr	1000

	lda	#1
	lda	1
	lda	1,x
	lda	1,y	    ;absolute
	lda	1000
	lda	1000,x
	lda	1000,y
	lda	(1,x)
	lda	(1),y

	ldx	#1
	ldx	1
	ldx	1,y
	ldx	1000
	ldx	1000,y

	ldy	#1
	ldy	1
	ldy	1,x
	ldy	1000
	ldy	1000,x

	lsr
	lsr	1
	lsr	1,x
	lsr	1000
	lsr	1000,x

	nop

	ora	#1
	ora	1
	ora	1,x
	ora	1,y	    ;absolute
	ora	1000
	ora	1000,x
	ora	1000,y
	ora	(1,x)
	ora	(1),y

	pha
	php
	pla
	plp

	rol
	rol	1
	rol	1,x
	rol	1000
	rol	1000,x

	ror
	ror	1
	ror	1,x
	ror	1000
	ror	1000,x

	rti
	rts

	sbc	#1
	sbc	1
	sbc	1,x
	sbc	1,y	    ;absolute
	sbc	1000
	sbc	1000,x
	sbc	1000,y
	sbc	(1,x)
	sbc	(1),y

	sec
	sed
	sei

	sta	1
	sta	1,x
	sta	1,y	    ;absolute
	sta	1000
	sta	1000,x
	sta	1000,y
	sta	(1,x)
	sta	(1),y

	stx	1
	stx	1,y
	stx	1000

	sty	1
	sty	1,x
	sty	1000

	tax
	tay
	tsx
	txa
	txs
	tya



SHAR_EOF
if test 1645 -ne "`wc -c suite6502.asm`"
then
echo shar: error transmitting suite6502.asm '(should have been 1645 characters)'
fi
echo shar: extracting suite68705.asm '(1628 characters)'
cat << \SHAR_EOF > suite68705.asm

	processor 68705

	org 0
	adc #10
	adc 10
	adc 1000
	adc ,x
	adc 1,x
	adc 1000,x
	add #10
	add 10
	add 1000
	add ,x
	add 1,x
	add 1000,x

	and #10
	and 10
	and 1000
	and ,x
	and 1,x
	and 1000,x

	asla
	aslx
	asl 10
	asl ,x
	asl 10,x

	asra
	asrx
	asr 10
	asr ,x
	asr 10,x

	bcc .
	bclr	1,23
	bcs .
	beq .
	bhcc .
	bhcs .
	bhi .
	bhs .
	bih .
	bil .

	bit #10
	bit 10
	bit 1000
	bit ,x
	bit 1,x
	bit 1000,x

	blo .
	bls .
	bmc .
	bmi .
	bms .
	bne .
	bpl .
	bra .
	brn .
	brclr	1,10,.
	brset	1,10,.
	bset	1,10
	bsr .

	clc
	cli

	clra
	clrx
	clr 10
	clr ,x
	clr 10,x

	cmp #10
	cmp 10
	cmp 1000
	cmp ,x
	cmp 1,x
	cmp 1000,x

	coma
	comx
	com 10
	com ,x
	com 10,x

	cpx #10
	cpx 10
	cpx 1000
	cpx ,x
	cpx 10,x
	cpx 1000,x

	deca
	decx
	dec 10
	dec ,x
	dec 10,x

	eor #10
	eor 10
	eor 1000
	eor ,x
	eor 10,x
	eor 1000,x

	inca
	incx
	inc 10
	inc ,x
	inc 10,x

	jmp 10
	jmp 1000
	jmp ,x
	jmp 10,x
	jmp 1000,x

	jsr 10
	jsr 1000
	jsr ,x
	jsr 10,x
	jsr 1000,x

	lda #10
	lda 10
	lda 1000
	lda ,x
	lda 10,x
	lda 1000,x

	ldx #10
	ldx 10
	ldx 1000
	ldx ,x
	ldx 10,x
	ldx 1000,x

	lsla
	lslx
	lsl 10
	lsl ,x
	lsl 10,x

	lsra
	lsrx
	lsr 10
	lsr ,x
	lsr 10,x

	nega
	negx
	neg 10
	neg ,x
	neg 10,x

	nop

	ora #10
	ora 10
	ora 1000
	ora ,x
	ora 10,x
	ora 1000,x

	rola
	rolx
	rol 10
	rol ,x
	rol 10,x

	rora
	rorx
	ror 10
	ror ,x
	ror 10,x

	rsp
	rti
	rts

	sbc #10
	sbc 10
	sbc 1000
	sbc ,x
	sbc 10,x
	sbc 1000,x

	sec
	sei

	sta 10
	sta 1000
	sta ,x
	sta 10,x
	sta 1000,x

	stx 10
	stx 1000
	stx ,x
	stx 10,x
	stx 1000,x

	sub #10
	sub 10
	sub 1000
	sub ,x
	sub 10,x
	sub 1000,x

	swi
	tax

	tsta
	tstx
	tst 10
	tst ,x
	tst 10,x

	txa

SHAR_EOF
if test 1628 -ne "`wc -c suite68705.asm`"
then
echo shar: error transmitting suite68705.asm '(should have been 1628 characters)'
fi
echo shar: extracting symbols.c '(3632 characters)'
cat << \SHAR_EOF > symbols.c

/*
 *  SYMBOLS.C
 *
 *  SHash[SHASHSIZE]
 */

#include "asm.h"

extern uword hash1();

static SYMBOL org;
static SYMBOL special;

void
setspecial(value, flags)
{
    special.value = value;
    special.flags = flags;
}

SYMBOL *
findsymbol(str, len)
ubyte *str;
short len;
{
    register uword h1;
    register SYMBOL *sym;
    ubyte buf[64];
    static SYMBOL org;
    short n;

    if (str[0] == '.') {
	if (len == 1) {
	    if (Csegment->flags & SF_RORG) {
		org.flags = Csegment->rflags & SYM_UNKNOWN;
		org.value = Csegment->rorg;
	    } else {
		org.flags = Csegment->flags & SYM_UNKNOWN;
		org.value = Csegment->org;
	    }
	    return(&org);
	}
	if (len == 2 && str[1] == '.')
	    return(&special);
	sprintf(buf, "%ld", Localindex);
	n = strlen(buf);
	bmov(str, buf+n, len);
	len += n;
	str = buf;
    }
    h1 = hash1(str, len);
    for (sym = SHash[h1]; sym; sym = sym->next) {
	if (sym->namelen == len && bcmp(sym->name, str, len))
	    break;
    }
    return(sym);
}

SYMBOL *
createsymbol(str, len)
ubyte *str;
short len;
{
    register SYMBOL *sym;
    register uword h1;
    ubyte buf[64];

    if (str[0] == '.') {
	short n;
	sprintf(buf, "%ld", Localindex);
	n = strlen(buf);
	bmov(str, buf+n, len);
	len += n;
	str = buf;
    }
    sym = (SYMBOL *)allocsymbol();
    sym->name = permalloc(len+1);
    bmov(str, sym->name, len);  /*  permalloc zero's the array for us */
    sym->namelen = len;
    h1 = hash1(str, len);
    sym->next = SHash[h1];
    sym->flags= SYM_UNKNOWN;
    SHash[h1] = sym;
    return(sym);
}

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

    while (len--)
	result = (result << 2) ^ *str++;
    return(result & SHASHAND);
}

/*
 *  Label Support Routines
 */

void
programlabel()
{
    register uword len;
    register SYMBOL *sym;
    register SEGMENT *cseg = Csegment;
    register ubyte *str;
    ubyte   rorg = cseg->flags & SF_RORG;
    ubyte   cflags = (rorg) ? cseg->rflags : cseg->flags;
    ulong   pc = (rorg) ? cseg->rorg : cseg->org;

    Plab = cseg->org;
    Pflags = cseg->flags;
    str = Av[0];
    if (*str == 0)
	return;
    len = strlen(str);
    if (str[len-1] == ':')
	--len;

    /*
     *	Redo:	unknown and referenced
     *		referenced and origin not known
     *		known and phase error	(origin known)
     */

    if (sym = findsymbol(str, len)) {
	if ((sym->flags & (SYM_UNKNOWN|SYM_REF)) == (SYM_UNKNOWN|SYM_REF)) {
	    ++Redo;
	    Redo_why |= 1 << 13;
	    if (Xdebug)
		printf("redo 13: '%s' %04lx %04lx\n", sym->name, sym->flags, cflags);
	} else
	if ((cflags & SYM_UNKNOWN) && (sym->flags & SYM_REF)) {
	    ++Redo;
	    Redo_why |= 1 << 13;
	} else
	if (!(cflags & SYM_UNKNOWN) && !(sym->flags & SYM_UNKNOWN)) {
	    if (pc != sym->value) {
		printf("mismatch %10s %s  pc: %s\n", sym->name, sftos(sym->value, sym->flags), sftos(pc, cflags & 7));
		asmerr(17,0);
		++Redo;
		Redo_why |= 1 << 14;
	    }
	}
    } else {
	sym = createsymbol(str, len);
    }
    sym->value = pc;
    sym->flags = (sym->flags & ~SYM_UNKNOWN) | (cflags & SYM_UNKNOWN);
}

SYMBOL *SymAlloc;

SYMBOL *
allocsymbol()
{
    SYMBOL *sym;

    if (SymAlloc) {
	sym = SymAlloc;
	SymAlloc = SymAlloc->next;
	bzero(sym, sizeof(SYMBOL));
    } else {
	sym = (SYMBOL *)permalloc(sizeof(SYMBOL));
    }
    return(sym);
}

void
freesymbol(sym)
SYMBOL *sym;
{
    sym->next = SymAlloc;
    SymAlloc = sym;
}

void
freesymbollist(sym)
SYMBOL *sym;
{
    register SYMBOL *next;

    while (sym) {
	next = sym->next;
	sym->next = SymAlloc;
	if (sym->flags & SYM_STRING)
	    free(sym->string);
	SymAlloc = sym;
	sym = next;
    }
}

SHAR_EOF
if test 3632 -ne "`wc -c symbols.c`"
then
echo shar: error transmitting symbols.c '(should have been 3632 characters)'
fi
#	End of shell archive
exit 0