[comp.sys.handhelds] Saturn Assembler

jmorriso@fs0.ee.ubc.ca (John Paul Morrison) (06/11/90)

A while ago, I saw a posting for the sass assembler for the HP.
I have the .tar file still here, but I saw some follow ups that
the IBM PC version of the source code was buggy. Someone also 
said that the executable file was on some ftp site. Could some-
one please tell me where I can get the IBM PC version? I think
it is odd that I have seen no other comments about this assembler
It is pretty unique to have an assembler for your calculator!

jp

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

This posting contains a complete development system for
the Saturn processor used on HP-71, HP-28, HP-48 etc.

Hereafter is the README file. Enjoy !

pda@masi.ibp.fr

------------------------------------------------------------------------------
AUTHORS
-------

Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
Janick TAILLANDIER

You are free to use or distribute these programs as long as
you keep this note

These programs are provided as is.  They are in no way
supported by us.


PRESENTATION
------------

These programs provide you with a complete development
system for the Saturn processor (used on the HP-71, HP-28,
HP-48 among others).  It includes an assembler, a linker for
separate assembly, and various utilities to generate message
tables for the HP-71 as well as download programs to the
HP-71 via HP-IL or RS-232.


HISTORY
-------

It was developped for the HP-71 in order for us to produce
more easily the JPC Rom (PPC Paris Rom) for the HP-71.  The
final Rom module was 45 KB (executable) for a total of 1.5
MB source files.

The speed was one of the main design objectives.

These programs were written in C for the HP Integral PC
(under HP-UX) in 1986 and have been adaptated for PC
compatibles (Microsoft C 4.0 in 1987).

It was also used as the final stage of a simple C compiler
for the HP-71.


HP-71 DEPENDENCIES
------------------

This development system is fully compatible with the
assembler described in the HP-71 Internal Design
Specifications (Volumes I or IV).  The opcode syntax is the
one used by HP :  it seems crazy to invent a new one, just
to confuse everyone!

Some macros (LEX, BIN, FORTH, TOKEN...)  are specific to the
HP-71, but you are free not to use them.

You may also want to write specific HP-48 macros to generate
specific objects (it would be nice if HP give us the syntax
they use).

Some opcodes used in newer machines (28, 48...)  are not
present in the HP-71.  Those opcodes (but PC=(A) and RSI)
are not in our opcode table, but could be easily added if
they are known.

The linker preloads a special file (/usr/local/lib/hp71.ep)
containing all HP-71 operating system entry points.  Do not
use any name contained in this file, or remove the loading
of this file.

In summary, HP-71 dependencies should not be a problem.
However if you want to use new opcodes, you will have to add
them.  Please, post your modifications.


CONTENTS
--------

Makefile
	The global Makefile (HP-UX) to generate all programs.

assembler
	Source code for aas (the assembler).  Some files are
	shared between assembler, linker and dump (common.h,
	err.h), some are shared between assembler and linker
	(exp.c, mdep.c).
	Contains a manual page in French.

linker
	Source code for ald (the linker).
	Contains a manual page in French.

dump
	Source code for adp (the file dumper, used for
	debugging).
	Contains a manual page in French.

cpy
	Source code for downloading files from a PC to an
	HP-71 using HP-IL Link card or RS-232.  This should
	now superseded for HP-48 by Kermit.

load
	Source code for acp, utility for copying an
	executable file generated by the linker to a LIF
	disk (to be read by an HP-71 with HP-9114).

equ
	Source for all HP-71 operating system entry points.

jmpdoc
	Some thoughts about adding a new generic branch macro.
	In French. Garbage.

msg
	Source code for amg (HP-71 message table generator).
	Contains a manual page in French.

doc
	Various documentations.


PORTING
-------

If you are using HP-UX, just type make, then make install.

If you are using another flavor of Unix, the Makefile should
work. We think there are no special system dependencies (it was
successfully compiled on Suns 3 and 4 with SunOS 4 and a Vax
under BSD 4.3).

If you are using PC compatibles, we cannot do anything for you.
The Makefiles will probably be difficult to use...

If you are using an Amiga, a Mac or anything else, good work !



Have fun !

Pierre DAVID & Janick TAILLANDIER (July 1st, 1990)

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:32:48 1990
#
# This archive contains:
#	areuh			areuh/cpy		
#	areuh/linker		areuh/dump		
#	areuh/doc		areuh/equ		
#	areuh/load		areuh/msg		
#	areuh/jmpdoc		areuh/assembler		
#	areuh/cpy/a2lex.c	areuh/cpy/a2rs.c	
#	areuh/cpy/copy.h	areuh/linker/mdep.c	
#	areuh/linker/exp.c	areuh/linker/err.h	
#	areuh/linker/common.h	areuh/linker/lutil.c	
#	areuh/linker/lpass.c	areuh/linker/lmain.c	
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo mkdir - areuh
mkdir areuh

chmod 755 areuh

echo mkdir - areuh/cpy
mkdir areuh/cpy

chmod 755 areuh/cpy

echo mkdir - areuh/linker
mkdir areuh/linker

chmod 755 areuh/linker

echo mkdir - areuh/dump
mkdir areuh/dump

chmod 755 areuh/dump

echo mkdir - areuh/doc
mkdir areuh/doc

chmod 755 areuh/doc

echo mkdir - areuh/equ
mkdir areuh/equ

chmod 755 areuh/equ

echo mkdir - areuh/load
mkdir areuh/load

chmod 755 areuh/load

echo mkdir - areuh/msg
mkdir areuh/msg

chmod 755 areuh/msg

echo mkdir - areuh/jmpdoc
mkdir areuh/jmpdoc

chmod 755 areuh/jmpdoc

echo mkdir - areuh/assembler
mkdir areuh/assembler

chmod 755 areuh/assembler

echo x - areuh/cpy/a2lex.c
cat >areuh/cpy/a2lex.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "copy.h"

char outname [100] ;
FILE *fpdev ;

init ()
{
#ifdef unix
    fpdev = stdout ;
#else
    sprintf (outname, "%s.lex", file) ;
    if ((fpdev = fopen (outname, "wb")) == NULL)
        error (ERROPN, outname) ;
#endif
}

output (c)
uchar c ;
{
    putc ((int) c, fpdev) ;
    if (ferror (fpdev)) error (ERRWRT, outname) ;
}

term ()
{
    if (fclose (fpdev))
        error (ERRCLO, outname) ;
}
@EOF
set `wc -lwc <areuh/cpy/a2lex.c`
if test $1$2$3 != 39108641
then
	echo ERROR: wc results of areuh/cpy/a2lex.c are $* should be 39 108 641
fi

chmod 644 areuh/cpy/a2lex.c

echo x - areuh/cpy/a2rs.c
cat >areuh/cpy/a2rs.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "copy.h"
#include <dos.h>

union REGS inregs, outregs ;

init ()
{
    inregs.h.ah = 0 ;
    inregs.h.al = 0xe3 ;
    inregs.x.dx = 0 ;		    /* com1 */
    int86 (0x14, &inregs, &outregs) ;
}

output (c)
char c ;
{
    int ok ;

    ok = 0 ;
    while (!ok)
    {
	inregs.h.ah = 0x03 ;			/* get line status */
	inregs.x.dx = 0x0000 ;
	int86 (0x14, &inregs, &outregs) ;
	ok = (outregs.h.al & 0x30) == 0x30 ;	/* handshake lines */
    }
    inregs.h.ah = 1 ;				/* send char */
    inregs.h.al = c ;
    inregs.x.dx = 0 ;

    int86 (0x14, &inregs, &outregs) ;
}

term ()
{
}
@EOF
set `wc -lwc <areuh/cpy/a2rs.c`
if test $1$2$3 != 47146813
then
	echo ERROR: wc results of areuh/cpy/a2rs.c are $* should be 47 146 813
fi

chmod 644 areuh/cpy/a2rs.c

echo x - areuh/cpy/copy.h
cat >areuh/cpy/copy.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include <stdio.h>

long int con () ;

typedef unsigned char uchar ;

typedef unsigned long int  int32 ;
typedef unsigned short int int16 ;

#define ERRUSA	       1		/* usage */
#define ERROPN	       2		/* cannot open */
#define ERRNAL	       3		/* not a Lex */
#define ERRCLO	       4		/* cannot close */
#define ERRRD	       5		/* error reading */
#define ERRWRT	       6		/* error writing */
#define ERRLEN	       7		/* bad REL(5) FiLeNd field */
#define ERRINT	       8		/* interface error */

uchar	*file ;

uchar	name [10] ;
FILE	*fp ;
int16	ftype ;
int32	lnib, lbyte, lsect ;

uchar	*pgm ;				/* name of current program */

main (argc, argv)
int argc ;
char *argv[] ;
{
    long int magic ;
    int32 l ;
    uchar tab [4] ;
    int i, j, m ;
    int mod ;

    pgm = (uchar *) argv [0] ;		/* program name */

    switch (argc)
    {
	case 1 :
	    file = (uchar *) "lex" ;	/* default name */
	    break ;
	case 2 :
	    file = (uchar *) argv [1] ;
	    break ;
	default :
	    error (ERRUSA, "") ;
	    break ;
    }

    fp = fopen (file, "rb") ;		/* binary file for MS-DOS machines */
    if (fp == NULL)
	error (ERROPN, file) ;

/* get Lex file header */

    fread ((char *) &magic, sizeof (long int), 1 , fp) ;
    if (magic!=0x1b080100)
	error (ERRNAL, file) ;		/* not a Lex file */

    for (i=0; i<8; i++)
	name [i] = (uchar) con (2) ;
    name [8] = name [9] = ' ' ;

    ftype = (int32) con (4) ;		/* file type */

    skip (12) ; 			/* skip date and time */

    lnib = (int32)con (5) - (int32)5 ;	/* get length */
    lsect = (lnib + 511) / 512 ;

    if (ferror (fp))			/* read error */
	error (ERRRD, file) ;

/* initialize output channel */

    init () ;

/* header output */

    for (i=0; i<10; i++)		/* file name */
	output ((uchar) name [i]) ;
    output ((uchar) (ftype / 256)) ;	/* file type */
    output ((uchar) (ftype % 256)) ;
    for (i=1; i<=4; i++)		/* start sector */
	output ((uchar) 0) ;
    l = lsect ;
    for (i=3; i>=0; i--)		/* length in sectors */
    {
	tab [i] = (uchar) l & 0xff ;
	l >>= 8 ;
    }
    for (i=0; i<4; i++)
	output (tab [i]) ;
    for (i=0; i<6; i++)			/* date and time */
	output ((uchar) 0) ;
    output ((uchar) 0x80) ;		/* 80 */
    output ((uchar) 0x01) ;		/* 01 */
    l = lnib ;
    for (i=0; i<4; i++) 		/* length in nibbles */
    {
	output ((uchar) (l & (int32) 0xff)) ;
	l >>= 8 ;
    }

/* data output */

    lbyte = (lnib+1) >> 1 ;
    mod = lbyte % 256 ;
    for (i=1; i<=lsect; i++)
    {
	m = (i == lsect && mod != 0) ? min (256, mod) : 256 ;
	for (j=0; j<m ; j++)
	    output ((uchar) con (2)) ;
    }
    for (j=m; j<256; j++)
	output ((uchar) 0) ;

/* end */

    if (getc (fp) != EOF)		/* bad file len */
	error (ERRLEN, file) ;
    term () ;

    exit (0) ;
}

long int con (n)
int n ;
{
    int i ;
    long int res ;
    uchar buf [1024] ;
    int first ;

    res = 0 ;
    first = 1 ;
    for (i=0; i<n; i++)
    {
	buf [i] = (uchar) getc (fp) ;
	if (first && feof (fp))
	    error (ERRLEN, "") ;
	first = 0 ;
    }
    if (ferror (fp))
	error (ERRRD, file) ;
    for (i=n-1; i>=0; i--)
	res = (res << 4) | hex (buf [i]) ;
    return res ;
}

skip (n)
int n ;
{
    uchar buf [1024] ;

    fread (buf, n, 1, fp) ;
    if (ferror (fp))
	error (ERRRD, file) ;
    if (feof (fp))
	error (ERRLEN, "") ;
}

int min (a, b)
int a, b ;
{
    return a <= b ? a : b ;
}

int hex (c)
uchar c ;
{
    return (c >= 'A' && c <= 'F') ? c - 'A' + 10 : c - '0' ;
}

error (code, str)
int code ;
uchar *str ;
{
    switch (code)
    {
	case ERRUSA :	    /* usage */
	    fprintf (stderr, "usage: %s [file]\n", pgm) ;
	    break ;
	case ERROPN :	    /* cannot open */
	    fprintf (stderr, "%s: cannot open %s\n", pgm, str) ;
	    break ;
	case ERRNAL :	    /* not a Lex */
	    fprintf (stderr, "%s: %s is not a lex file\n", pgm, str) ;
	    break ;
	case ERRCLO :	    /* cannot close */
	    fprintf (stderr, "%s: cannot close %s\n", pgm, str) ;
	    break ;
	case ERRRD  :	    /* error reading */
	    fprintf (stderr, "%s: error reading %s\n", pgm, str) ;
	    break ;
	case ERRWRT :	    /* error writing */
	    fprintf (stderr, "%s: error writing %s\n", pgm, str) ;
	    break ;
	case ERRLEN :	    /* bad REL(5) FiLeNd field */
	    fprintf (stderr, "%s: bad REL(5) FiLeNd field\n", pgm) ;
	    break ;
	case ERRINT :	    /* interface error */
	    fprintf (stderr, "%s: interface error\n", pgm) ;
	    break ;
	default :
	    fprintf (stderr, "%s: internal error\n", pgm) ;
	    break ;
    }
    exit (1) ;
}
@EOF
set `wc -lwc <areuh/cpy/copy.h`
if test $1$2$3 != 2249004719
then
	echo ERROR: wc results of areuh/cpy/copy.h are $* should be 224 900 4719
fi

chmod 644 areuh/cpy/copy.h

echo x - areuh/linker/mdep.c
cat >areuh/linker/mdep.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

      M A C H I N E    D E P E N D E N C I E S

******************************************************************************/

#include "flag.h"

#if ASSEMBLER
#include "aglobal.h"
#else
#include "lglobal.h"
#endif

extern struct symbol *add_label() ;

#if HPUX

void format_time (str)
uchar *str ;
{
    long int l ;

    extern long int time () ;
    extern char *ctime () ;

    l = time (0L) ;
    strcpy (str, ctime (&l)) ;
    str [strlen (str) - 1] = EOL ;
}

char *tab[] = { "",
		"/usr/lib/",
		"/usr/local/lib/",
		"/lib/",
		"/hp71/lib/",
		"/local/lib/",
		0 } ;

void load_file (file)
uchar *file ;
{
    int i = 0 ;
    uchar name [MAXLEN+1] ;
    saddr val ;
    FILE *fp ;

    fp = (FILE *) NULL ;
    while ((tab[i])&&(!fp))
    {
	sprintf (name, "%s%s", tab[i++], file) ;
	fp = fopen (name, "r") ;
    }
    if (!fp) error (ERROPN, file) ;

#if LINKER
    file = 0 ;
#endif
    while (fscanf (fp, "%s\n%X\n", name, &val) != EOF)
    {
#if ASSEMBLER
	add_label (name, val, "", LABS, 1) ;
#else
	add_label (name, val, 1) ;
#endif
    }
    if (ferror (fp)) error (ERRWRT, file) ;
    if (fclose (fp)) error (ERRCLO, file) ;
}

#include <sys/types.h>
#include <sys/stat.h>

/* look for object file (object code or listing file)
 *   if non existent, ok
 *   if exists and not directory, ok
 *   if exists and directory, then append "<dir>/<default>" */

look_obj (fname, dfl)
uchar *fname, *dfl ;
{
    struct stat buf ;

    if (*fname == EOL)		   /* if fname == "" then default it */
	strcpy (fname, dfl) ;

    if (!stat (fname, &buf))	   /* file exists. Is it a directory ? */
    {
	if ((buf.st_mode & S_IFMT) == S_IFDIR)
	    sprintf (fname, "%s/%s", fname, dfl) ;
    }
}

/* build a default file name, based on "source" basename and a given
 * default extension.
 */

dfl_extension (object, source, extension)
uchar *object, *source, *extension ;
{
    uchar *pname ;

    strcpy (object, source) ;
    pname = object ;
    while ((*pname)&&(*pname!='.')) pname++ ;
    if (*pname==EOL) *pname = '.' ;
    strcpy (pname+1, extension) ;
}

#endif	   /* HPUX */


#if ATARI_LATTICE

char skipvar ;

void format_time (str)
uchar *str ;
{
    strcpy (str, "Areuh Tagada Bouzouh bouzouh areuh areuh... et toc !") ;
}

char *optarg ;
int optind = 0, opterr = 0 ;

int getopt (argc, argv, optstr)
int argc ;
char *argv[], *optstr ;
{
    char *o, car ;
    static char *index = 0 ;
    extern char *strchr () ;

    if ((index==(char *)0)||(*(index+1)==0))
    {
	if (++optind>argc-1) return (EOF) ;
	index = argv[optind] ;
	if (*index!='-') return (EOF) ;
    }
    car = *(++index) ;	      /* state 6 */
    if (!(o = strchr (optstr, car))) return ('?') ;
    if (*(o+1)!=':')     return ((int) car) ;
    if (*(index+1)) optarg = index+1 ;
    else
    {
	if (++optind>argc-1) return (EOF) ;
	else optarg = argv[optind] ;
    }
    index = (char *) 0 ;
    return ((int) car) ;
}

uchar *tab[] = { "",
		 "A:",
		 "A:\\TABLE\\",
		 0 } ;

void load_file (file)
uchar *file ;
{
    int i = 0 ;
    uchar name [MAXLEN+1] ;
    saddr val ;
    FILE *fp ;

    fp = (FILE *) NULL ;
    while ((tab[i])&&(!fp))
    {
	sprintf (name, "%s%s", tab[i++], file) ;
	fp = fopen (name, "r") ;
    }
    if (!fp) error (ERROPN, file) ;

#if LINKER
    file = 0 ;
#endif
    while (fscanf (fp, "%s\n%x\n", name, &val) != EOF)
    {
#if ASSEMBLER
	add_label (name, val, "", LABS, 1) ;
#else
	add_label (name, val, 1) ;
#endif
    }
    if (fclose (fp)) error (ERRCLO, file) ;
}

#endif	  /* ATARI_LATTICE */


#if PC_MSC

char skipvar ;

void format_time (str)
uchar *str ;
{
    long int l ;

    extern long int time () ;
    extern char *ctime () ;

    time (&l) ;
    strcpy (str, ctime (&l)) ;
    str [strlen (str) - 1] = EOL ;
}

char *optarg ;
int optind = 0, opterr = 0 ;

int getopt (argc, argv, optstr)
int argc ;
char *argv[], *optstr ;
{
    char *o, car ;
    static char *index = 0 ;
    extern char *strchr () ;

    if ((index==(char *)0)||(*(index+1)==0))
    {
	if (++optind>argc-1) return (EOF) ;
	index = argv[optind] ;
	if (*index!='-') return (EOF) ;
    }
    car = *(++index) ;	      /* state 6 */
    if (!(o = strchr (optstr, car))) return ('?') ;
    if (*(o+1)!=':')     return ((int) car) ;
    if (*(index+1)) optarg = index+1 ;
    else
    {
	if (++optind>argc-1) return (EOF) ;
	else optarg = argv[optind] ;
    }
    index = (char *) 0 ;
    return ((int) car) ;
}

uchar *tab[] = { "",
		 "c:",
		 "c:\\hp71\\",
		 "c:\\lib\\hp71\\",
		 "c:\\lib\\",
		 "c:\\areuh\\lib\\",
		 0 } ;

void load_file (file)
uchar *file ;
{
    int i = 0 ;
    uchar name [MAXLEN+1] ;
    saddr val ;
    FILE *fp ;

    fp = (FILE *) NULL ;
    while ((tab[i])&&(!fp))
    {
	sprintf (name, "%s%s", tab[i++], file) ;
	fp = fopen (name, "r") ;
    }
    if (!fp) error (ERROPN, file) ;

#if LINKER
    file = 0 ;
#endif
    while (fscanf (fp, "%s\n%X\n", name, &val) != EOF)
    {
#if ASSEMBLER
	add_label (name, val, "", LABS, 1) ;
#else
	add_label (name, val, 1) ;
#endif
    }
    if (fclose (fp)) error (ERRCLO, file) ;
}

#include <sys\types.h>
#include <sys\stat.h>

/* look for object file (object code or listing file)
 *   if non existent, ok
 *   if exists and not directory, ok
 *   if exists and directory, then append "<dir>/<default>" */

look_obj (fname, dfl)
uchar *fname, *dfl ;
{
    struct stat buf ;

    if (*fname == EOL)		   /* if fname == "" then default it */
	strcpy (fname, dfl) ;

    if (!stat (fname, &buf))	   /* file exists. Is it a directory ? */
    {
	if ((buf.st_mode & S_IFMT) == S_IFDIR)
	    sprintf (fname, "%s\\%s", fname, dfl) ;
    }
}

/* build a default file name, based on "source" basename and a given
 * default extension.
 */

dfl_extension (object, source, extension)
uchar *object, *source, *extension ;
{
    uchar *pname ;

    strcpy (object, source) ;
    pname = object ;
    while ((*pname)&&(*pname!='.')) pname++ ;
    if (*pname==EOL) *pname = '.' ;
    strcpy (pname+1, extension) ;
}

#endif	  /* PC_MSC */
@EOF
set `wc -lwc <areuh/linker/mdep.c`
if test $1$2$3 != 32610286303
then
	echo ERROR: wc results of areuh/linker/mdep.c are $* should be 326 1028 6303
fi

chmod 644 areuh/linker/mdep.c

echo x - areuh/linker/exp.c
cat >areuh/linker/exp.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                TITAN ASSEMBLER

                             EXPRESSION EVALUATION


calc_expression, reduce_E, reduce_T, reduce_F, reduce_B, reduce_X,
reduce_P, dec_value, hex_value, bin_value, ascii_value, label_value, apply,
trunc, next_char, append_extexp

******************************************************************************/

#include "flag.h"

#if ASSEMBLER
#include "aglobal.h"
#else
#include "lglobal.h"
#endif

uchar extexp [4*MAXLEN] ;
uchar *pexp, *pextexp ;
uchar *xlabel ;
int relabs ;

extern saddr symbol_value() ;

saddr reduce_E(), reduce_T(), reduce_F(), reduce_B(), reduce_X(), reduce_P(),
      dec_value(), hex_value(), bin_value(), ascii_value(), label_value(),
      apply(), trunc() ;
void next_char(), append_extexp() ;


/******************************************************************************

                               CALC_EXPRESSION


synopsis : saddr calc_expression (exp)
           uchar *exp
description : That's the expression evaluator. Productions used are :

    E -> T { {+|-} T }*
    T -> F { {*|/} F }*
    F -> B { {&|!} B }*
    B -> X | -X | `X           (two's and one's complement)
    X -> N { {~|^} N }*
    P -> D | #<hex> | %<bin> | '<ascii>' | \<ascii>\ | <label> | * | (E)

    D -> <dec>                 if expression evaluated by ASSSEMBLER
    D -> <dec> | <dec> r       if expression evaluated by LINKER

    where   E : expression
            T : term
            F : factor
            B : boolean
            X : exponentiation
            P : primary
            D : decimal number
warning : with this grammar, 5--5 is valid (5 minus -5), but 5---5 is not.
          This can be modified by : B -> -B | P . The code is more complex,
          and I'm not sure that it's a real improvement.
note : Algorithm used is recursive descent (Mr Vermeulen would be horrified !)
       like Forth/Assembler rom based assembler, but is quietly different...

******************************************************************************/

saddr calc_expression (exp)
uchar *exp;
{
    saddr val;

    pextexp = extexp ;
    pexp = exp ;
    val = reduce_E() ;
    if (((val>=0L)||(val==EXP_EXT))&&(*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t'))
    {
        error(WRNEXP, "") ;    /* illegal expression */
        val = EXP_ERR ;
    }
    *pextexp = EOL ;
    return (val) ;
}


/******************************************************************************

                                   REDUCE_E


synopsis : saddr reduce_E()
description : This function reduces a given expression starting at pexp.

******************************************************************************/
saddr reduce_E()
{
    saddr val1, val2;
    uchar op, lrelabs;

    val1 = reduce_T () ;

    while ((((op = *pexp)=='+')||(op=='-'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_T () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_T


synopsis : saddr reduce_T ()
description : same as above, for T-production

******************************************************************************/

saddr reduce_T ()
{
    saddr val1, val2 ;
    uchar op, lrelabs ;

    val1 = reduce_F () ;
    while ((((op = *pexp)=='*')||(op=='/'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_F () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_F


synopsis : saddr reduce_F ()
description : same as reduce_E

******************************************************************************/

saddr reduce_F ()
{
    saddr val1, val2;
    uchar op, lrelabs ;

    val1 = reduce_B () ;
    while ((((op = *pexp)=='&')||(op=='!'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_B () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_B


synopsis : saddr reduce_B ()
description : reduces a boolean factor. This must be done by reduction of minus
              sign eventually.

******************************************************************************/

saddr reduce_B ()
{
    saddr val;
    uchar op ;

    op = *pexp ;

    if ((op=='-')||(op=='\`')) next_char () ;
    val = reduce_X () ;
    if (val<0L)
        return(val) ;
    switch (op)
    {
        case '-' :
            return (trunc (-val)) ;
        case '\`' :
            return (trunc (~val)) ;
        default :
            return (val) ;
    }
}


/******************************************************************************

                                   REDUCE_X


synopsis : saddr reduce_X ()
description : same as reduce_E

******************************************************************************/

saddr reduce_X ()
{
    saddr val1, val2;
    uchar op, lrelabs;

    val1 = reduce_P () ;
    while ((((op = *pexp)=='~')||(op=='^'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_P () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_P


synopsis : saddr reduce_P ()
description : these are the terminal rules.
note : rule P -> D is implemented "in line" in this code (not as a separate
  function).

******************************************************************************/

saddr reduce_P ()
{
    saddr val ;
    uchar limit, line[MAXLEN] ;

    switch (*pexp)
    {
        case '#' :
            next_char () ;
            if (((*pexp>='0')&&(*pexp<='9')) ||
               ((*pexp>='A')&&(*pexp<='F')) ||
               ((*pexp>='a')&&(*pexp<='f')))
                val = hex_value () ;
            else
            {
                error (WRNIHX,"");          /* illegal hexadecimal constant */
                val = EXP_ERR ;
            }
            relabs = LABS ;
            break ;
        case '%' :
            next_char () ;
            if ((*pexp=='0')||(*pexp=='1'))
                val = bin_value () ;
            else
            {
                error (WRNIBC, "") ;        /* illegal binary constant */
                val = EXP_ERR ;
            }
            relabs = LABS ;
            break ;
        case '\'' :
        case '\\' :
            limit = *pexp ;
            next_char () ;
            val = ascii_value (limit) ;
            if (*pexp!=limit)
            {
                error (WRNASC,"");                 /* illegal ascii constant */
                val = EXP_ERR ;
            }
            next_char () ;
            relabs = LABS ;
            break ;
        case '*' :
            val = pc ;
            pexp++ ;
            sprintf (line, "%ldr", pc) ;
            relabs = LREL ;
            append_extexp (line) ;
            break ;
        case '(' :
            next_char () ;
            val = reduce_E () ;
            if ((*pexp!=')')&&(val>=0))
            {
                error (WRNPAR, "") ;         /* mismatched parenthesis */
                val = EXP_ERR ;
            }
            next_char () ;
            break ;
        case EOL :
            error (WRNEXP,"") ;              /* illegal expression     */
            val = EXP_ERR ;
            break ;

        default :
            if ((*pexp>='0')&&(*pexp<='9'))
            {
                val = dec_value () ;
                relabs = LABS ;
#if LINKER
                if (*pexp=='r')
                {
                    next_char() ;
                    relabs = LREL ;
                    val += tmodule[file].m_ad ;
                }
#endif
            }
            else val = label_value () ;
            break ;
    }
    return (val) ;
}


/******************************************************************************

                                   DEC_VALUE


synopsis : saddr dec_value ()
descrption : This function returns the decimal value of a constant. The search
             is stopped when a non numeric digit is reached.
             (this can be ),+,-,*,/,&,!).
             Finally, the founded value is returned.
note : this function doesn't check overflow. If there is, numbers are treated
       as 20 bits words, and overflow doesn't propagate on 32 bits of an
       integer (-1 is never reached when calculus).

******************************************************************************/

saddr dec_value ()
{
    saddr val=0L ;

    do
    {
        val = trunc (val * 10L + (saddr) (*pexp-'0') ) ;
        next_char () ;
    }
    while ((*pexp>='0')&&(*pexp<='9')) ;
    return (val);
}


/******************************************************************************

                                   HEX_VALUE


synopsis : saddr hex_value ()
description : same as above for hexadecimal constants

******************************************************************************/

saddr hex_value ()
{
    saddr i, val = 0L ;

    while ( ((*pexp>='0')&&(*pexp<='9')) ||
            ((*pexp>='A')&&(*pexp<='F')) ||
            ((*pexp>='a')&&(*pexp<='f')) )
    {
        if (*pexp<='9') i = (long int) ((*pexp) - '0') ;
        else if (*pexp<='F') i = (long int) ((*pexp) - 'A' + 10) ;
        else i = (long int) ((*pexp) - 'a' + 10) ;
        val = trunc (val*16L +  i) ;
        next_char () ;
    }
    return (val) ;
}


/******************************************************************************

                                   BIN_VALUE


synopsis : saddr bin_value ()
description : same as above for binary constants

******************************************************************************/

saddr bin_value ()
{
    saddr val = 0L ;

    while ((*pexp=='0')||(*pexp=='1'))
    {
        val = trunc (val*2L + ((saddr) ((*pexp) - '0'))) ;
        next_char () ;
    }
    return (val) ;
}


/******************************************************************************

                                  ASCII_VALUE


synopsis : saddr ascii_value ()
description : same as above, but the search is stopped when encoutered a '.
              The pointer *pexp stands on this character.

******************************************************************************/

saddr ascii_value (limit)
uchar limit ;
{
    saddr val = 0 ;

    while ((*pexp!=EOL)&&(*pexp!=limit))
    {
        val = trunc (val*256L + ((saddr) *pexp)) ;
        next_char () ;
    }
    return (val) ;
}


/******************************************************************************

                                  LABEL_VALUE


synopsis : saddr label_value ()
description : parses the symbol, then tries to return the value founded in the
              symbol list.

******************************************************************************/

saddr label_value ()
{
    uchar label[LBLLEN+2], *plabel ;
    int mx, need_par = 0, j = 0 ;
    saddr val ;

    mx = LBLLEN + ((*pexp=='=') ? 1 : 0) ;
    while ((*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t')&&
           (*pexp!=')')&&(*pexp!='\\'))
    {
        if (j<mx) label[j++] = *pexp ;
        pexp++ ;
    }
    label[j] = EOL ;
    plabel = label ;

    if ((val = symbol_value (label)) >= (saddr) 0)
    {                             /* found, copy value */
     
        if (relabs==LREL) sprintf (label, "%ldr", val) ;
        else sprintf (label, "%ld", val) ;
    }
    else if ((val == LBL_UDF) || (val == LBL_IVL))
    {   /* UDF : label not (yet) declared, IVl : invalid label */
        *plabel = EOL ;                /* incoherent value */
        val = EXP_ERR ;
    }
    else if ((val == LBL_EXT) || (val == LBL_XEQ))
    {   /* LBL_EXT: ext. label not known, LBL_XEQ: global defined with ext. */
        val = EXP_EXT ;                        /* keep label name */
    }
    else                       /* (val == LBL_SEQ) */
    {   /* LBL_SEQ : synonym, expandable */
        plabel = xlabel ;              /* get definition of label */
        need_par = 1 ;                 /* enclose label with (...) */
        val = EXP_EXT ;                /* and store it into extep */
    }

    if (need_par) append_extexp ("(") ;
    append_extexp (plabel) ;
    if (need_par) append_extexp (")") ;

    return (val) ;
}


/******************************************************************************

                                     APPLY


synopsis : saddr apply (val1, op, val2, relabs1, relabs2)
           saddr val1, val2
           uchar op, relabs1, relabs2
description : calculate the value of binary operator op applied to operands
              val1 & val2.
note : under overflow condition, numbers are truncated to 20 bits.

******************************************************************************/

saddr apply (val1, op, val2, relabs1, relabs2)
uchar op, relabs1, relabs2 ;
saddr val1, val2 ;
{
    saddr val ;

    if (val2==EXP_ERR)                    return (EXP_ERR) ;
    if ((val1==EXP_EXT)||(val2==EXP_EXT)) return (EXP_EXT) ;

    switch (op)
    {
        case '+' :
            val = trunc (val1 + val2) ;
            break ;
        case '-' :
            val = trunc (val1 - val2 ) ;
            break ;
        case '*' :
            val = trunc (val1 * val2 ) ;
            break ;
        case '/' :
#if ASSEMBLER
            val = (val2 ? val1 / val2 : EXP_ERR ) ;
#else
            val = (val2 ? val1 / val2 : EXP_EXT ) ;
#endif
            if (val2==0L)   error (WRNNUL, "") ;   /* null divisor */
            break ;
        case '&' :
            val = val1 & val2 ;
            break ;
        case '!' :
            val = val1 | val2 ;
            break ;
        case '~' :
            val = trunc (val1*256 + val2) ;
            break ;
        case '^' :
            if ((val1<0)||(val2<0)||((val1==0)&&(val2==0)))
            {
                error (WRNIXP, "") ;           /* Illegal exponentiation */
#if ASSEMLER
                val = EXP_ERR ;
#else
                val = EXP_EXT ;
#endif
            }
            else
            {
                val = 1 ;
                for (;val2>0 ; val2--) val *= val1 ;
                val = trunc (val) ;
            }
            break ;
    }
    if ((relabs1==LUDF)||(relabs2==LUDF))      relabs = LUDF ;
    else if ((relabs1==LREL)||(relabs2==LREL)) relabs = LREL ;
    else                                       relabs = LABS ;
    return (val) ;
}


/******************************************************************************

                                     TRUNC


synopsis : saddr trunc (val)
           saddr val
description : truncates 32 bits integer to 24 bits.

******************************************************************************/

saddr trunc (val)
saddr val ;
{
    return (val & 0xffffff) ;
}


/******************************************************************************

                                   NEXT_CHAR


synopsis : void next_char ()
description : stores the current character in extexp variable, and moves the
              expression pointer (pexp) forward one position.

******************************************************************************/
void next_char ()
{
    *pextexp = *pexp ;
    pextexp++ ;
    pexp++ ;
}


/******************************************************************************

                                 APPEND_EXTEXP


synopsis : void append_extexp (line)
           uchar *line ;
description : append line to extexp string.

******************************************************************************/

void append_extexp (line)
uchar *line ;
{
    while (*line)
    {
        *pextexp = *line ;
        pextexp++ ;
        line++ ;
    }
}
@EOF
set `wc -lwc <areuh/linker/exp.c`
if test $1$2$3 != 634182916414
then
	echo ERROR: wc results of areuh/linker/exp.c are $* should be 634 1829 16414
fi

chmod 644 areuh/linker/exp.c

echo x - areuh/linker/err.h
cat >areuh/linker/err.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                           AREUH ASSEMBLER / LINKER


                          ERROR NUMBERS DECLARATIONS

******************************************************************************/




/* FATAL ERRORS */

#define ERROPN  -1                                       /* A L */
    /* system error opening file */
#define ERRCLO  -2                                       /* A L */
    /* system error closing file */
#define ERRREW  -3                                       /* A */
    /* system error on file at start of pass two */
#define ERRWRT  -4                                       /* A L */
    /* system error writing file */
#define ERRRD   -5                                       /* A L */
    /* system error reading file */
#define ERRMEM  -6                                       /* A L */
    /* not enough memory */

#define ERRLEX  -10                                      /* A */
    /* invalid macro pseudo-op LEX or BIN */
#define ERRPGS  -11                                      /* A */
    /* invalid page size */
#define ERRFLN  -12                                      /* A */
    /* restricted label FiLeNd exists */
#define ERRIFL  -13                                      /* A L */
    /* invalid file name */
#define ERRIMO  -14                                      /* A */
    /* invalid macro-op xx in modular assembling */
#define ERRVMD  -15                                      /* A */
    /* value must be defined for xx */

#define ERRUSA  -20                                      /* A L */
    /* usage: ass [ [-l] source_file ] */
    /* usage: ald ... */

#define ERRNOA  -30                                      /* L */
    /* file not output from aas */
#define ERRICV  -31                                      /* L */
    /* incompatible version */



/* NON FATAL ERRORS */

#define WRNEQU  10                                       /* A */
    /* cannot resolve equate */
#define WRNDUP  11                                       /* A L */
    /* duplicate label */
#define WRNLBL  12                                       /* A */
    /* illegal label */
#define WRNULB  13                                       /* A */
    /* unrecognized label */
#define WRNURF  14                                       /* L */
    /* unresolved reference */
#define WRNURL  15                                       /* L */
    /* unresolved label */

#define WRNEXP  20                                       /* A */
    /* illegal expression */
#define WRNASC  21                                       /* A */
    /* illegal ascii constant */
#define WRNPAR  22                                       /* A */
    /* mismatched parenthesis */
#define WRNIHX  23                                       /* A */
    /* illegal hexadecimal constant */
#define WRNNUL  24                                       /* A */
    /* null divisor */
#define WRNIXP  25                                       /* A */
    /* illegal exponentiation */
#define WRNIBC  26                                       /* A */
    /* illegal binary constant */
#define WRNENA  27                                       /* A */
    /* external references not allowed */

#define WRNYES  30                                       /* A */
    /* GOYES or RTNYES required */
#define WRNIDP  31                                       /* A */
    /* illegal dp arithmetic value */
#define WRNIPP  32                                       /* A */
    /* illegal pointer position */
#define WRNISB  33                                       /* A */
    /* illegal status bit */
#define WRNTFR  34                                       /* A */
    /* illegal transfer value */
#define WRNIWS  35                                       /* A */
    /* illegal word select */
#define WRNLST  36                                       /* A */
    /* invalid LIST argument */
#define WRNJVL  37                                       /* A L */
    /* jump or value too large */
#define WRNMLB  38                                       /* A */
    /* missing label */
#define WRNTST  39                                       /* A */
    /* needs previous test instruction */
#define WRNNHX  40                                       /* A */
    /* non hexadecimal digits present */
#define WRNTMA  41                                       /* A */
    /* too many ascii characters present */
#define WRNTMH  42                                       /* A */
    /* too many hexadecimal digits present */
#define WRNOPC  43                                       /* A */
    /* unknown opcode */

#define WRNIIF  50                                       /* A */
    /* invalid conditional structure */

extern void error() ;
@EOF
set `wc -lwc <areuh/linker/err.h`
if test $1$2$3 != 1275845010
then
	echo ERROR: wc results of areuh/linker/err.h are $* should be 127 584 5010
fi

chmod 644 areuh/linker/err.h

echo x - areuh/linker/common.h
cat >areuh/linker/common.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include <stdio.h>


#define MAXLEN 256
#define EOL    '\0'
#define LBLLEN 12

/******************************************************************************
 TYPE DEFINITIONS
******************************************************************************/

typedef long int saddr ;	      /* Saturne address. At least 32 bits   */
typedef unsigned char uchar ;	      /* unsigned characters, for accents    */
typedef short int sint ;	      /* 16 bits */

/******************************************************************************
 MAGIC NUMBERS
******************************************************************************/

#define  AL_MAGIC 0x1b080100	      /* ... areuh_lex */
#define  AO_MAGIC 0x1b0d0100	      /* ... areuh_output of assembler */
#define ALF_MAGIC 0x1b080100	      /* first version of object file format */
#define AOF_MAGIC 0x1b0d0100	      /* first version of object file format */


/******************************************************************************
 USAGE TYPES IN .ao FILES
******************************************************************************/

#define XABSL 0x10     /* absolute reference */
#define XABSO 0x20     /* absolute reference, with one bias */
#define XRGTO 0x40     /* relative reference, goto type */
#define XRGSB 0x80     /* relative reference, gosub type */


/******************************************************************************
 LABEL VALUES IN .ao FILES
******************************************************************************/

#define LBL_UDF -1L
    /* label not declared (implicit or explicit) <=> only used */
#define LBL_IVL -2L
    /* invalid label (invalid expression for an EQU during pass one) */
#define LBL_EXT -3L
    /* external label not defined here (or yet) */
#define LBL_XEQ -4L
    /* global label which is defined here, with an external reference */
#define LBL_SEQ -5L
    /* local label which is defined with an external reference */


/******************************************************************************
 LABEL TYPES IN .ao FILES
******************************************************************************/

#define LUDF 0
    /* undefined type (external label) */
#define LABS 1
    /* absolute local label (declared explicitly, with constants) */
#define LREL 2
    /* relative local label (declared implicitly, or explicitly with at least
       one relative) */


/******************************************************************************
 VALUES RETURNED BY EXPRESSION EVALUATOR
******************************************************************************/

#define EXP_ERR -1L
#define EXP_EXT -2L

extern int relabs ;
extern uchar extexp[] ;

#include "err.h"
extern void error () ;

#define hex5(str,val) format_hex (str, val, 5) ;
#define hex6(str,val) format_hex (str, val, 6) ;

/******************************************************************************
 MACHINE DEPENDANCIES
******************************************************************************/

#define HPUX		     1
#define ATARI_LATTICE	     0
#define PC_MSC		     0		/* PC (beuark, Microsoft C) */

#if HPUX
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "r"
#define WAO_MODE "w"
#define skip(fp)
#endif

#if ATARI_LATTICE
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "rb"
#define WAO_MODE "wb"
extern char skipvar ;
#define skip(fp) fread(&skipvar,1,1,fp) ;
#endif

#if PC_MSC
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "rb"
#define WAO_MODE "wb"
extern char skipvar ;
#define skip(fp) fread(&skipvar,1,1,fp) ;
#endif
@EOF
set `wc -lwc <areuh/linker/common.h`
if test $1$2$3 != 1244243878
then
	echo ERROR: wc results of areuh/linker/common.h are $* should be 124 424 3878
fi

chmod 644 areuh/linker/common.h

echo x - areuh/linker/lutil.c
cat >areuh/linker/lutil.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "lglobal.h"

extern char *malloc () ;
extern saddr calc_expression () ;
uchar *memoire () ;

/******************************************************************************

				  FIND_LABEL

synopsis : struct symbol *find_label (label)
	   char *label
description : find address of label, return address of structure describing it.

******************************************************************************/

struct symbol *find_label (label)
char *label ;
{
    struct symbol *p ;
    int test ;

    p = h_label [label[1]]->s_next ;
    while (p)
    {
	test = strcmp (label, p->s_name) ;
	if (test==0)  break ;
	p = p->s_next ;
	if (test<0) p = (struct symbol *) NULL ;
    }
    return (p) ;
}


/******************************************************************************

				   ADD_LABEL


synopsis : void add_label (label, val, os)
	   uchar *label
	   saddr val
	   int os
description : add a label in label table and, if already defined, add it to
  multiply defined lists.

******************************************************************************/

void add_label (label, val, os)
uchar *label ;
saddr val ;
int os ;
{
    uchar error_text [MAXLEN+1] ;
    struct symbol *p, *s ;
    int b = 1 ;

    p = find_label (label) ;
    if (p)
    {
	sprintf (error_text, "%s in files %s and %s", label,
			     fname[p->s_file],
			     fname[file]) ;
	error (WRNDUP, error_text) ;	       /* duplicate label */
    }
    else
    {
	s = p = h_label [label[1]] ;
	while ((b)&&(s))
	{
	    if (strcmp (label, s->s_name)<0) b = 0 ;
	    else
	    {
		p = s ;  s = s->s_next ;
	    }
	}
	s = (struct symbol *) memoire (sizeof (struct symbol)) ;
	s->s_next = p->s_next ;
	p->s_next = s ;
	strcpy (s->s_name, label) ;
	s->s_xref = (struct xtable *) NULL ;
	p = s ;
    }
    p->s_value = val ;
    p->s_file = (uchar) file ;
    p->s_os = os ;
}


/******************************************************************************

				ADD_UNRES


synopsis : void add_unres (label, def)
	   char *label, *def
	   int file
description : during first part of pass one, if a label is undefined, add it
  to a special list. During second part, if this list is scaned. If value
  is then defined, the label will be removed. At the end of first pass, this
  queue will be the undefined labels queue, which should be empty...

******************************************************************************/

void add_unres (label, def)
uchar *label, *def ;
{
    struct unres *x ;

    x = (struct unres *) memoire (sizeof (struct unres)) ;
    strcpy (x->u_label, label) ;
    x->u_file = (uchar) file ;
    x->u_def = memoire (strlen (def) + 1) ;
    strcpy (x->u_def, def) ;
    x->u_next = head_unres ;
    head_unres = x ;
}


/******************************************************************************

				  READ_USAGE


synopsis : void read_usage (characteristic, def, fp)
	   long int *characteristic
	   char *def
	   FILE *fp
description : read an entry in third part of object file fp.

******************************************************************************/

void read_usage (characteristic, def, fp)
long int *characteristic ;
char *def ;
FILE *fp ;
{
    int i ;

    fread (characteristic, sizeof (long int), 1, fp) ;
    fread (&pc, sizeof (saddr), 1, fp) ;
    i = 0 ;
    while ((def [i] = (uchar) fgetc (fp)) != '\n') i++ ;
    def [i] = EOL ;
    if (ferror (fp)) error (ERRRD, fname [file]) ;
}


int lrange (offset, nibs)
saddr *offset ;
int nibs ;
{
    saddr Sixtine, Fiftine ;
    int r ;

    Sixtine = ((saddr) 1) << (nibs*4) ;
    Fiftine = Sixtine >> 1 ;
    r = ((*offset>=-Fiftine)&&(*offset<Fiftine)) ;
    if (*offset<0) *offset += Sixtine ;
    return (r) ;
}


/******************************************************************************

			      RESOLVE_USAGE


synopsis : void resolve_usage (characteristic, def, file, fp, code)
	   long int characteristic
	   char *def, *code
	   FILE *fp
	   int file
description : make all the work which is to be made by a linker. Resolve
  all usages.

******************************************************************************/

void resolve_usage (characteristic, def, fp, code)
saddr characteristic ;
uchar *def, *code ;
FILE *fp ;
{
    uchar hexa [MAXLEN+1] ;
    saddr type, source, dest, offset ;
    int i, j ;

    type = characteristic & (XABSL | XABSO | XRGTO | XRGSB) ;
    characteristic &= ~type ;
    dest = calc_expression (def) ;
    if (dest < (saddr) 0)
    {
	error (WRNURF, def) ;	  /* unresolved reference */
	dest = (saddr) 0 ;
    }
    switch ((int) type)
    {
	case XABSL :
	    source = 0 ;
	    break ;
	case XABSO :
	    source = 1 ;
	    break ;
	case XRGTO :
	    source = tmodule [file].m_ad + pc  ;
	    break ;
	case XRGSB :
	    source = tmodule [file].m_ad + pc  + characteristic ;
	    break ;
    }
    offset = dest - source ;
    if ((type==XRGTO)||(type==XRGSB))
    {
	if (!lrange (&offset, characteristic))
	{
	    offset = (saddr) 0 ;
	    error (WRNJVL, def) ;    /* Jump or value too large */
	}
    }
    hex6 (hexa, offset) ;
    for (i=0, j=5; i<characteristic; i++, j--)
    {
	code [pc+i] = hexa[j] ;
    }
}


/******************************************************************************

				SYMBOL_VALUE


synopsis : saddr symbol_value (label)
	   uchar *label
description : fetch a label, and return its value.

******************************************************************************/

saddr symbol_value (label)
uchar *label ;
{
    struct symbol *ad ;
    struct xtable *x, *y, *z ;

    ad = find_label (label) ;

    if ((ad)&&(passnb==2)&&xref)
    {
	x = (struct xtable *) memoire (sizeof (struct xtable)) ;
	x->x_pc = pc ;
	x->x_file = file ;
	z = y = ad->s_xref ;
	while ((y)&&(y->x_file<file))
	{
	    z = y ;
	    y = y->x_next ;
	}
	if (y==z) ad->s_xref = x ;	/* insert at begining of the list */
	else z->x_next = x ;		/* insert in middle of list */
	x->x_next = y ;
	ad->s_os = 0 ;
    }
    return ((ad) ? ad->s_value : EXP_EXT) ;
}


/******************************************************************************

				  MEMOIRE


synopsis : uchar *memoire (size)
	   int size
description : get memory from heap using malloc. It is just a layer above
	      malloc, including a test.

******************************************************************************/

uchar *memoire (size)
int size ;
{
    uchar *x ;

    if ((x = (uchar *) malloc (size)) == NULL)
	error (ERRMEM, "") ;
    return (x) ;
}


/******************************************************************************

				 FORMAT_HEX


synopsis : void format_hex (str, val, dig)
	   uchar *str
	   saddr val
	   int dig
description : stores into str the hexadecimal string representing the dig
	      low order hex digits of val.

******************************************************************************/

format_hex (str, val, dig)
uchar *str ;
saddr val ;
int dig ;
{
    register int i, h ;

    for (i=dig-1; i>=0; i--)
    {
	h = (int) (val & ((saddr) 0xf)) ;
	str [i] = h + ((h < 10) ? '0' : 'A' - 10) ;
	val >>= 4 ;
    }
    str [dig] = EOL ;
}
@EOF
set `wc -lwc <areuh/linker/lutil.c`
if test $1$2$3 != 32910407349
then
	echo ERROR: wc results of areuh/linker/lutil.c are $* should be 329 1040 7349
fi

chmod 644 areuh/linker/lutil.c

echo x - areuh/linker/lpass.c
cat >areuh/linker/lpass.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "lglobal.h"


extern void add_label (), add_unres () ;
extern long int calc_expression () ;
extern uchar *memoire () ;


/******************************************************************************

				   PASS1


synopsis : pass1 ()
description : processes the first pass on the object files. Open each file,
  read part one (code) and two (public label definitions), and close it.

******************************************************************************/

pass1 ()
{
    tmodule [1].m_ad = (saddr) 0 ;
    for (file=1; file<=nfile; file++)	ps_part12 () ;
	    /* still undefined labels ? */
    file = nfile + 1 ;
    add_label ("=FiLeNd", tmodule[file].m_ad, 0) ;
    if (head_unres)    pass1_bis () ;	    /* yes, try to resolve */
}


/******************************************************************************

				  PS_PART12


synopsis : ps_part12 ()
description : in first pass, process parts one and two of an object file, and
  store all necessary informations in tmodule array.
  name is the file name, i is the entry in tmodule array.

******************************************************************************/

ps_part12 ()
{
    FILE *fp ;
    uchar label [LBLLEN+2], def [MAXLEN+1], type ;
    saddr size, val ;
    long int part2, nl, magic ;
    int j, k ;

    if (!(fp = fopen (fname[file], RAO_MODE)))
	error (ERROPN, fname[file]) ;	  /* error opening file */
    fgetl (magic, fp) ;
    if ((magic<AOF_MAGIC)||(magic>AO_MAGIC))
	error (ERRNOA, fname[file]) ;	  /* not output of aas */
    if (magic!=AO_MAGIC)
	error (ERRICV, fname[file]) ;	  /* incompatible version */

    fgetl (part2, fp) ;
    fgetl (size, fp) ;			   /* length of code */
    tmodule[file+1].m_ad = tmodule[file].m_ad + size ;

    fseek (fp, part2, 0) ;
    fgetl (tmodule[file].m_part3, fp) ;
    fgetl (nl, fp) ;

    if (ferror (fp)) error (ERRRD, fname [file]) ;

    for (j=1; j<=nl; j++)
    {
	k = 0 ;
	while ((label [k] = (uchar) fgetc (fp)) != '\n') k++ ;
	label [k] = EOL ;
	fgetl (val, fp) ;
	if (ferror (fp)) error (ERRRD, fname [file]) ;
	if (val<0L)
	{
	    k = 0 ;
	    while ((def [k] = (uchar) fgetc (fp)) != '\n') k++ ;
	    def [k] = EOL ;
	    val = calc_expression (def) ;
	}
	else
	{
	    type = (uchar) getc (fp) ;
	    switch (type)
	    {
		case LABS :
		    break ;
		case LREL :
		    val += tmodule[file].m_ad ;
		    break ;
		case LUDF :
		default :
		    fprintf (stderr, "Internal error. Aie aie aie. LUDF\n") ;
		    exit (1) ;
	    }
	}
	if (val>=0L) add_label (label, val, 0) ;
	else add_unres (label, def) ;
    }
    if (fclose (fp)) error (ERRCLO, fname[file]) ;   /* error closing file */
}


/******************************************************************************

				PASS1_BIS


synopsis : pass1_bis ()
description : at the end of first pass, if still undefined labels, try to
  resolve all definitions. If not succesful, exit on error.

******************************************************************************/

pass1_bis ()
{
    struct unres *xdef ;
    saddr val ;

    passbis = 1 ;     /* signal to error message driver */

    while (head_unres)
    {
	file = head_unres->u_file ;
	val = calc_expression (head_unres->u_def) ;

	if (val<0) error (WRNURL, head_unres->u_label) ; /* unresolved label */
	else add_label (head_unres->u_label, val, 0) ;

	xdef = head_unres ;
	head_unres = head_unres->u_next ;
        free ((char *) xdef->u_def) ;
	free ((char *) xdef) ;
    }

    passbis = 0 ;
}


/******************************************************************************

				PASS2


synopsis : void pass2 ()
description : during pass two, we open each file, we read the code into a
  string variable properly dimensioned. Then, for each external reference
  usage, we store the proper value into the proper place (we hope so !).
  At last, we append the code to the final lex file. That's grehate.

******************************************************************************/

void pass2 ()
{
    FILE *fp ;
    uchar def [MAXLEN+1], *code ;
    int j ;
    long int size, bidon, nu, characteristic ;

    for (file=1; file<=nfile; file++)
    {
	fp = fopen (fname[file], RAO_MODE) ;
	if (!fp) error (ERROPN, fname[file]) ;
	fgetl (bidon, fp) ;
	fgetl (bidon, fp) ;
	fgetl (size, fp) ;
	code = memoire (size) ;
	fread ((char *) code, (int) size, 1, fp) ;

	fseek (fp, tmodule[file].m_part3, 0) ;
	fgetl (nu, fp) ;

	if (ferror (fp)) error (ERRRD, fname [file]) ;

	for (j=1; j<=nu; j++)
	{
	    read_usage (&characteristic, def, fp) ;
	    resolve_usage (characteristic, def, fp, code) ;
	}

	fwrite (code, (int) size, 1, fplex) ;
	free ((char *) code) ;
	if (ferror (fplex)) error (ERRWRT, flex) ;
	if (fclose (fp)) error (ERRCLO, fname[file]) ;
    }
}
@EOF
set `wc -lwc <areuh/linker/lpass.c`
if test $1$2$3 != 1997114979
then
	echo ERROR: wc results of areuh/linker/lpass.c are $* should be 199 711 4979
fi

chmod 644 areuh/linker/lpass.c

echo x - areuh/linker/lmain.c
cat >areuh/linker/lmain.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "lglobal.h"

saddr pc ;
int nfile, file ;
uchar flex [MAXLEN+1], flisting [MAXLEN+1] ;
FILE *fplex ;
struct module tmodule[MAXMOD] ;
struct unres *head_unres ;
struct symbol *h_label[256] ;
uchar *code ;
uchar *fname[MAXMOD+2] ;
int page_size, cntlist, xref, passnb, errnb ;
int passbis = 0 ;

void prompt (), read_line (), make_name () ;
extern uchar *memoire () ;

main (argc, argv)
int argc ;
uchar *argv[] ;
{
    int r = 0, c, i ;
    int errflg = 0 ;

    extern char *optarg ;
    extern int optind, opterr ;

    opterr = 0 ;

    xref = 0 ;
    page_size = 0 ;
    strcpy (flex, "") ;
    strcpy (flisting, "") ;

    fname[0] = memoire (sizeof(HP71EP)+1) ;
    strcpy (fname[0], HP71EP) ;
    nfile = 0 ;

    while ((c = getopt (argc, argv, "xa:Apl:o:")) != EOF)
        switch (c)
        {
            case 'x' :
                xref = 1 ;
                break ;
            case 'a' :
                strcpy (flisting, optarg) ;
                cntlist = 2 ;
                break ;
            case 'A' :
                cntlist = 1 ;
                break ;
            case 'p' :
                r++ ;
                break ;
            case 'l' :
                sscanf (optarg, "%d", &page_size) ;
                break ;
            case 'o' :
                strcpy (flex, optarg) ;
                break ;
            case '?' :
                errflg++ ;
                break ;
        }
        
    if ((r)||(argc==1)) prompt () ;
    if (errflg || ((optind==argc)&&(nfile==0)))
        error (ERRUSA, "") ;
    for (i=optind; i<argc; i++)
        make_name (nfile+i-optind+1, argv [i]) ;
    nfile += argc - optind ;

    if (*flex==EOL) strcpy (flex, "lex") ;

    if (page_size==0) page_size = 72 ;

    fname [nfile + 1] = memoire (sizeof("eof.ep")+1) ;
    strcpy (fname[nfile + 1], "eof.ep") ;

    init () ;
    pass1 () ;
    between () ;
    pass2 () ;
    term () ;
    exit (errnb) ;
}


/******************************************************************************

                                    PROMPT


synopsis : void prompt ()
description : if "-p" option is used, or if no parameters are passed to "ald",
  asks the user for missing arguments.

******************************************************************************/

void prompt ()
{
    uchar line [MAXLEN+1] ;

    do
    {
        printf ("Input module : ") ;
        read_line (stdin, line) ;
        if (*line) make_name (++nfile, line) ;
    } while (*line) ;
    if (*flex==EOL)
    {
        printf ("Object file : ") ;
        read_line (stdin, flex) ;
    }
    if (cntlist==0)
    {
        printf ("Listing file : ") ;
        read_line (stdin, flisting) ;
        if (*flisting)
        {
            cntlist = 2 ;
            xref = 1 ;
        }
        else cntlist = 0 ;
    }
    if (cntlist)
    {
        if (page_size==0)
        {
            printf ("Page length : ") ;
            read_line (stdin, line) ;
            sscanf (line, "%d", &page_size) ;
        }
    }
}

void read_line (fp, line)
FILE *fp ;
uchar *line ;
{
    int c, i = -1 ;

    do
    {
        c = getc (fp) ;
        if (i<MAXLEN) line[++i] = c ;
    } while ((c!=EOF)&&(c!='\n')) ; 
    line[i] = EOL ;
    if (ferror (fp)) error (ERRRD, "stdin") ; /* il se trouve que c'est stdin */
}


/******************************************************************************

                                   MAKE_NAME


synopsis : void make_name (i, file)
           int i
           uchar *file
description : parse file name, and store file name with proper extension in
  fname table.

******************************************************************************/

void make_name (i, file)
int i ;
uchar *file ;
{
    uchar *pfile ;

    pfile = file ;
    while ((*pfile)&&(*pfile!='.')) pfile++ ;
    fname [i] = memoire (strlen(file) + ((*pfile) ? 1 : 4) ) ;
    strcpy (fname[i], file) ;
    if (!(*pfile)) strcat (fname[i], ".ao") ;
}
@EOF
set `wc -lwc <areuh/linker/lmain.c`
if test $1$2$3 != 1885714190
then
	echo ERROR: wc results of areuh/linker/lmain.c are $* should be 188 571 4190
fi

chmod 644 areuh/linker/lmain.c

exit 0

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:32:51 1990
#
# This archive contains:
#	areuh/linker/llist.c	areuh/linker/linit.c	
#	areuh/linker/lglobal.h	areuh/linker/lerror.c	
#	areuh/linker/flag.h	areuh/linker/ald.1	
#	areuh/linker/Makefile	areuh/dump/adp.c	
#	areuh/dump/common.h	areuh/dump/err.h	
#	areuh/dump/adp.1	areuh/dump/Makefile	
#	areuh/doc/areuh.doc	
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - areuh/linker/llist.c
cat >areuh/linker/llist.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "lglobal.h"

FILE *fd_l ;
int l_line = 0, l_page = 1 ;

void l_files (), l_xref () ;



void l_init ()
{
    uchar dfl [MAXLEN+1] ;

    switch (cntlist)
    {
        case 0 :
            break ;
        case 1 :
            fd_l = stdout ;
            strcpy (flisting, "stdout") ;
            break ;
        case 2 :
            dfl_extension (dfl, "list", "al") ;
            look_obj (flisting, dfl) ;
            if (!(fd_l = fopen (flisting, "w")))
                error (ERROPN, flisting) ;
            break ;
    }
}


void l_new_page (flag)
int flag ;
{
    if (!cntlist) return ;
    for (; l_line<page_size; l_line++) fprintf (fd_l, "\n") ;
    if (flag)
    {
        fprintf (fd_l,"AREUH LINKER V2.2 - Page %03d - File: %s\n",
                      ++l_page, flex) ;
        fprintf (fd_l,"\n") ;
        l_line = 2 ;
    }
    if (ferror (fd_l)) error (ERRWRT, flisting) ;
}


void l_flush ()
{
    if (!cntlist) return ;
    l_new_page (0) ;
    if (cntlist==2)
        if (fclose (fd_l)) error (ERRCLO, flisting) ;
}


void l_print (line)
uchar *line ;
{
    if (!cntlist)
    {
        printf ("%s\n", line) ;
        return ;
    }

    if (l_line==page_size-6) l_new_page (1) ;
    fprintf (fd_l, "%s\n", line) ;
    l_line++ ;
    if (ferror (fd_l)) error (ERRWRT, flisting) ;
}


void report ()
{
    if (cntlist && errnb) l_new_page (1) ;
    if (xref) l_xref () ;
    if (cntlist && xref) l_new_page (1) ;
    if (cntlist) l_files () ;
    else if (xref && errnb)
    {
        printf ("Areuh linker : %03d errors", errnb) ;
        if (ferror (fd_l)) error (ERRWRT, flisting) ;
    }
}


void l_files ()
{
    uchar line[MAXLEN+1], start[MAXLEN+1], end[MAXLEN+1], length[MAXLEN+1] ;
    int i ;
    saddr val ;

    sprintf (line, "Output module : %s", flex) ;
    l_print (line) ;
    l_print ("") ;
    for (file=1; file<=nfile; file++)
    {
        sprintf (line, "Source module : %s", fname [file]) ;
        l_print (line) ;
        hex5 (start, tmodule[file].m_ad) ;
        val = (tmodule[file].m_ad==tmodule[file+1].m_ad) ? 0 : 1 ;
        hex5 (end, tmodule[file+1].m_ad - val) ;
        hex5 (length, tmodule[file+1].m_ad - tmodule[file].m_ad) ;
        sprintf (line, "%10sStart = %s, End = %s, Length = %s", 
                       "", start, end, length) ;
        l_print (line) ;
        l_print ("") ;
    }
    for (i=0; i<4; i++) l_print ("") ;
    strcpy (line, "Date : ") ;
    format_time (line+7) ;
    l_print (line) ;
    l_print ("") ;
    sprintf (line, "Errors : %03d", errnb) ;
    l_print (line) ;
    l_print ("") ;
    l_print ("") ;
    l_print ("Areuh Assembler/Linker V2.2, (c) P. David & J. Taillandier 1986  Paris, France") ;
    l_new_page (0) ;
}


void l_xref ()
{
    uchar line [MAXLEN+1], tmp [MAXLEN+1], rel [MAXLEN+1] ;
    uchar format [MAXLEN+1], xformat [MAXLEN+1] ;
    struct symbol *t ;
    struct xtable *x ;
    int i ;

    sprintf (format, "%%-%ds = %%s  File : %%s", LBLLEN+1) ;
    sprintf (xformat, "%%%ds+ %%s   (Rel %%s in %%s)", LBLLEN+11) ;
    for (i=0; i<=255; i++)
    {
        t = h_label [i]->s_next ;
        while (t)
        {
            if (!t->s_os)
            {
                hex5 (tmp, t->s_value) ;
                sprintf (line, format, t->s_name, tmp, fname[t->s_file]) ;
                l_print (line) ;
                x = t->s_xref ;
                while (x)
                {
                    hex5 (tmp, tmodule[x->x_file].m_ad + x->x_pc) ;
                    hex5 (rel, x->x_pc) ;
                    sprintf (line, xformat, "", tmp, rel, fname[x->x_file]) ;
                    l_print (line) ;
                    x = x->x_next ;
                }
            } /* du if */
            t = t->s_next ;
        } /* du while */
    } /* du for */
}
@EOF
set `wc -lwc <areuh/linker/llist.c`
if test $1$2$3 != 1675564008
then
	echo ERROR: wc results of areuh/linker/llist.c are $* should be 167 556 4008
fi

chmod 644 areuh/linker/llist.c

echo x - areuh/linker/linit.c
cat >areuh/linker/linit.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "lglobal.h"

extern void l_init () ;
extern uchar *memoire () ;

void free_mem () ;


init()
{
    struct symbol *s ;
    int i ;

    head_unres = (struct unres *) NULL ;

    s = (struct symbol *) memoire (256*sizeof(struct symbol)) ;
    for (i=0; i<256; i++)
    {
        strcpy (s->s_name, "") ;
        s->s_value = 0L ;
        s->s_file = 0 ;
        s->s_os = 1 ;
        s->s_xref = (struct xtable *) NULL ;
        s->s_next = (struct symbol *) NULL ;
        h_label [i] = s++ ;
    }
    l_init () ;
    file = errnb = passbis = 0 ;
    load_file (HP71EP) ;
    passnb = 1 ;
}

between ()
{
    long int magic = AL_MAGIC ;
    uchar dfl [MAXLEN+1] ;

    strcpy (dfl, "lex") ;
    look_obj (flex, dfl) ;
    if (!(fplex = fopen (flex, "w")))
        error (ERROPN, flex) ;
    fwrite (&magic, sizeof (long int), 1, fplex) ;
    if (ferror (fplex)) error (flex) ;
    passnb = 2 ;
}

term ()
{
    if (fclose (fplex))
        error (ERRCLO, flex) ;
    if (cntlist || xref) report () ;
    l_flush () ;

    free_mem () ;
}


void free_mem ()
{
    struct symbol *s1, *s2 ;
    struct xtable *x1, *x2 ;
    int i ;

    for (i=0; i<=255; i++)
    {
        s1 = h_label[i]->s_next ;
        while (s1)
        {
            if (xref)
            {
                x1 = s1->s_xref ;
                while (x1)
                {
                    x2 = x1->x_next ;
                    free ((char *) x1) ;
                    x1 = x2 ;
                }
            }
            s2 = s1->s_next ;
            free ((char *) s1) ;
            s1 = s2 ;
        }
    }
    free ((char *) h_label [0]) ;

    for (i=0; i<=nfile+1; i++)
        free ((char *) fname [i]) ;
}
@EOF
set `wc -lwc <areuh/linker/linit.c`
if test $1$2$3 != 993011925
then
	echo ERROR: wc results of areuh/linker/linit.c are $* should be 99 301 1925
fi

chmod 644 areuh/linker/linit.c

echo x - areuh/linker/lglobal.h
cat >areuh/linker/lglobal.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "common.h"

#define fgetl(lg,fp) fread(&(lg),sizeof(long int),1,fp)

/******************************************************************************
  MODULE TABLE
******************************************************************************/

#define MAXMOD 80                      /* maximum number of modules */

struct module                          /* module descriptor */
{
    long int m_part3 ;                 /* address of utilisations part */
    saddr m_ad ;                       /* Saturn address of start of code */
} ;

extern struct module tmodule [] ;      /* module descriptors table */


/******************************************************************************
  UNRESOLVED LABELS LIST
******************************************************************************/

struct unres                           /* unresolved label element */
{
    uchar u_label [LBLLEN+2] ;         /* label name (with leading '=') */
    uchar u_file ;                     /* file where declared */
    uchar *u_def ;                     /* definition address */
    struct unres *u_next ;             /* next element */
} ;

extern struct unres *head_unres ;      /* unresolved label list */


/******************************************************************************
  CROSS-REFERENCE LIST
******************************************************************************/

struct xtable
{
    saddr x_pc ;                       /* relative addr. where symb. is used */
    uchar x_file ;                     /* file where symbol is used */
    struct xtable *x_next ;            /* link */
} ;


/******************************************************************************
  LABEL TABLE
******************************************************************************/

struct symbol
{
    uchar s_name [LBLLEN+2] ;          /* label name */
    saddr s_value ;                    /* label value */
    uchar s_file ;                     /* last file where label is declared */
    uchar s_os ;                       /* 1 is O.S. entry point not used */
    struct xtable *s_xref ;            /* head of xref list */
    struct symbol *s_next ;            /* next label */
} ;

extern struct symbol *h_label [] ;     /* pseudo-hash table */


/******************************************************************************
  CODE
******************************************************************************/

extern uchar *code ;

extern uchar *fname[] ;

extern uchar flex [], flisting [] ;
extern FILE *fplex ;
extern saddr pc ;
extern nfile, file ;
extern int cntlist, page_size, xref, passnb, errnb, passbis ;

extern uchar hp71ep [] ;
@EOF
set `wc -lwc <areuh/linker/lglobal.h`
if test $1$2$3 != 893152897
then
	echo ERROR: wc results of areuh/linker/lglobal.h are $* should be 89 315 2897
fi

chmod 644 areuh/linker/lglobal.h

echo x - areuh/linker/lerror.c
cat >areuh/linker/lerror.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                 AREUH LINKER


                               ERROR PROCESSING


error

******************************************************************************/

#include "lglobal.h"


/******************************************************************************

                                     ERROR


synopsis : void error (errno, msg)
           int errno
           char *msg
descritpion : reports an error message on listing file, if any, else on
              standard output.

******************************************************************************/

void error (errno, msg)
int errno ;
uchar *msg ;
{
    uchar txt[MAXLEN+1], tmp[MAXLEN+1];

    switch (errno)
    {
        case ERROPN :
            sprintf (txt, "system error opening file %s", msg) ;
            break ;
        case ERRCLO :
            sprintf (txt, "system error closing file %s", msg) ;
            break ;
        case ERRWRT :
            sprintf (txt, "system error writing file %s", msg) ;
            break ;
        case ERRRD  :
            sprintf (txt, "system error reading file %s", msg) ;
            break ;
        case ERRMEM :
            strcpy (txt, "not enough memory");
            break ;
        case ERRUSA :
            strcpy (txt, "usage: ald [-p] [-l n] [-A] [-a file]") ;
            strcat (txt, " [-o object_file] file1 file2..filen") ;
            break ;
        case ERRICV :
            sprintf (txt, "incompatible version of file %s", fname[file]) ;
            break ;
        case ERRNOA :
            sprintf (txt, "file %s not an output from aas", fname[file]) ;
            break ;

        case WRNDUP :
            sprintf (txt, "duplicate label %s", msg) ;
            break ;
        case WRNURF :
            hex5 (tmp, pc) ;
            sprintf (txt, "unresolved reference at %s in file %s : %s",
                          tmp, fname[file], msg) ;
            break ;
        case WRNURL :
            sprintf (txt, "unresolved label %s in file %s", msg, fname[file]) ;
            break ;
        case WRNEXP :
            strcpy (txt, "illegal expression");
            break ;
        case WRNASC :
            strcpy (txt, "illegal ascii constant");
            break ;
        case WRNPAR :
            strcpy (txt, "mismatched parenthesis");
            break ;
        case WRNIHX :
            strcpy (txt, "illegal hexadecimal constant");
            break ;
        case WRNNUL :
            strcpy (txt, "null divisor");
            break ;
        case WRNIXP :
            strcpy (txt, "illegal exponentiation") ;
            break ;
        case WRNIBC :
            strcpy (txt, "illegal binary constant") ;
            break ;
        case WRNJVL :
            hex5 (tmp, pc) ;
            sprintf (txt, "jump or value too large at %s in file %s : %s",
                          tmp, fname[file], msg) ;
            break ;
    }
    if (errno<0)
    {
        fprintf (stderr, "ald: %s\n", txt) ;
        exit (errno) ;
    }
    else
    {
        errnb++ ;
        if (! ((passnb==1)&&(!passbis)&&(errno==WRNURL)) )
          l_print (txt) ;
    }
}       /* end of "error()"      */
@EOF
set `wc -lwc <areuh/linker/lerror.c`
if test $1$2$3 != 1233933481
then
	echo ERROR: wc results of areuh/linker/lerror.c are $* should be 123 393 3481
fi

chmod 644 areuh/linker/lerror.c

echo x - areuh/linker/flag.h
cat >areuh/linker/flag.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/****************************************************************************/
/* !!! CONTENTS OF THIS FILE MUST BE DIFFERENT FOR ASSEMBLER AND LINKER !!! */
/****************************************************************************/
#define ASSEMBLER 0
#define LINKER    1
@EOF
set `wc -lwc <areuh/linker/flag.h`
if test $1$2$3 != 1663507
then
	echo ERROR: wc results of areuh/linker/flag.h are $* should be 16 63 507
fi

chmod 644 areuh/linker/flag.h

echo x - areuh/linker/ald.1
cat >areuh/linker/ald.1 <<'@EOF'
.TH ALD 1L
.SH NAME
ald \- areuh link editor
.SH SYNOPSIS
.B ald
[
.B -p
] [
.B -l
.I page length
] [
.B -A
] [
.B -a
.I listing file
] [
.B -x
] [
.B -o
.I object file
] [ file1 ... filen ]
.SH DESCRIPTION
.I Ald
est le cross-link-editor pour le HP-71, qui prend un ou des
fichiers intermediaires, les fusionne et place dans le fichier objet
un fichier pret a etre transmis au HP-71 (voir
.IR cp71 (1L)).
.PP
Les options sont :
.TP 17
.B -p
Utilisation interactive : demande les noms des fichiers
au clavier. Option par defaut lorsqu'il n'y a aucun parametre.
.TP
.BI -l " page length"
La longueur des pages du
.I listing file
est fixee a
.I page length
lignes (72 par defaut).
.TP
.B -A
Genere un listing d'edition avec table des symboles.
Le listing est envoye sur la sortie standard.
.TP
.BI -a " listing file"
Genere un listing d'edition dans le fichier
.IR "listing file" .
.TP
.I -x
Genere dans le
.I listing file
une table des references croisees, indiquant pour chaque
symbole sa valeur et les offsets dans les fichiers des
instructions y faisant reference.
.TP
.BI -o " object file"
Place le code objet dans le fichier specifie
.RB ( lex
par defaut)
.SH AUTHORS
Pierre David
Janick Taillandier
.SH SEE ALSO
aas(1L),
adp(1L),
amg(1L),
cp71(1L).
.br
.I "IDS vol I"
for HP-71.
@EOF
set `wc -lwc <areuh/linker/ald.1`
if test $1$2$3 != 712461284
then
	echo ERROR: wc results of areuh/linker/ald.1 are $* should be 71 246 1284
fi

chmod 644 areuh/linker/ald.1

echo x - areuh/linker/Makefile
cat >areuh/linker/Makefile <<'@EOF'
#
# Makefile genere automatiquement par mkmf (le masque par defaut a ete adapte)
#

CFLAGS	      = -O
LDFLAGS	      =
LIBS	      =
SYSLIBS	      =
BINDEST	      = /usr/local/bin

#
# S'il y a plus d'un programme, il faut aussi remplacer la cible
# $(PROGRAM) par autant de cibles que necessaire.
#

PROGRAM       = ald

SRCS	      = exp.c \
		lerror.c \
		linit.c \
		llist.c \
		lmain.c \
		lpass.c \
		lutil.c \
		mdep.c

HDRS	      = common.h \
		err.h \
		flag.h \
		lglobal.h

EXTHDRS	      = /usr/include/stdio.h \
		/usr/include/sys/stat.h \
		/usr/include/sys/types.h

OBJS	      = exp.o \
		lerror.o \
		linit.o \
		llist.o \
		lmain.o \
		lpass.o \
		lutil.o \
		mdep.o

MANDEST	      = /usr/local/man/man1.Z

MANPAGES      = ald.1

#
# Les cibles :
#	all : compiler tout
#	clean : effacer les .o et les core
#	clobber : effacer tout ce qui peut etre regenere
#	depend : recalculer toutes les dependances et les inserer ici
#	install : installe le programme dans l'aborescence
#	tags : cree les tags
#

all:		$(PROGRAM)

$(PROGRAM):     $(OBJS) $(LIBS)
		cc $(LDFLAGS) $(OBJS) $(LIBS) $(SYSLIBS) -o $(PROGRAM)

clean:;		rm -f $(OBJS) core

clobber:;	rm -f $(OBJS) $(PROGRAM) core tags

depend:;	mkmf ROOT=$(ROOT)

install:	$(PROGRAM)
		-strip $(PROGRAM)
		if [ $(BINDEST) != . ] ; \
		then \
		    (cd $(BINDEST) ; rm -f $(PROGRAM)) ; \
		    cp $(PROGRAM) $(BINDEST) ; \
		    if [ "$(MANPAGES)" != none ] ; \
		    then \
			(cd $(MANDEST) ; rm -f $(MANPAGES)) ; \
			for i in $(MANPAGES) ; \
			do \
			    compress < $$i > $(MANDEST)/$$i ; \
			done ; \
		    fi ; \
		fi

tags:           $(HDRS) $(SRCS)
		ctags $(HDRS) $(SRCS)

#
# Dependances calculees automatiquement par mkmf.
# Ne rien changer apres cette ligne !
#
###
exp.o: flag.h lglobal.h common.h /usr/include/stdio.h err.h
lerror.o: lglobal.h common.h /usr/include/stdio.h err.h
linit.o: lglobal.h common.h /usr/include/stdio.h err.h
llist.o: lglobal.h common.h /usr/include/stdio.h err.h
lmain.o: lglobal.h common.h /usr/include/stdio.h err.h
lpass.o: lglobal.h common.h /usr/include/stdio.h err.h
lutil.o: lglobal.h common.h /usr/include/stdio.h err.h
mdep.o: flag.h lglobal.h common.h /usr/include/stdio.h err.h \
	/usr/include/sys/types.h /usr/include/sys/stat.h
@EOF
set `wc -lwc <areuh/linker/Makefile`
if test $1$2$3 != 1023262244
then
	echo ERROR: wc results of areuh/linker/Makefile are $* should be 102 326 2244
fi

chmod 644 areuh/linker/Makefile

echo x - areuh/dump/adp.c
cat >areuh/dump/adp.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "common.h"

#define fgetl(lg,fp)  fread(&(lg),sizeof(long int),1,fp)

main (argc, argv)
int argc ;
char *argv[] ;
{
    FILE *fp ;
    uchar line [MAXLEN + 1], hexvar[MAXLEN+1], type ;
    saddr magic, pc, p2, p3, nu, nl, i, j, characteristic, value ;

    if (argc!=2)
    {
	fprintf (stderr, "usage: adp file\n") ;
	exit (1) ;
    }

    fp = fopen (argv[1], RAO_MODE) ;
    if (fp==NULL)
    {
	fprintf (stderr, "adp: error opening %s\n", argv[1]) ;
	exit (1) ;
    }

    printf ("file %s : ", argv[1]) ;
    fgetl (magic, fp) ;
    if ((magic<AOF_MAGIC)||(magic>AO_MAGIC))
    {
	fprintf (stderr, "adp: %s is not an Areuh object file\n", argv [1]) ;
	exit (1) ;
    }
    printf ("version %d\n", magic - AOF_MAGIC) ;
    if (magic!=AO_MAGIC)
    {
	fprintf (stderr, "Wrong version\n") ;
	exit (1) ;
    }
    fgetl (p2, fp) ;
    fgetl (pc, fp) ;

    printf ("code: length (in nibbles) = %ld\n", pc) ;

    fseek (fp, p2, 0) ;
    fgetl (p3, fp) ;
    fgetl (nl, fp) ;

    printf ("public definitions : number = %ld\n", nl) ;
    for (i=1; i<=nl; i++)
    {
	printf ("%4d:", i) ;
	j = 0 ;
	while ((line [j] = (uchar) getc (fp)) != '\n') j++ ;
	line [j]= EOL ;
	printf (" %-13s, val = ", line) ;     /* LBLLEN + 1 */
	fgetl (value, fp) ;
	if (value >= (saddr) 0)
	{
	    hex5 (hexvar, value) ;
	    printf ("%s, ", hexvar) ;
	    type = getc (fp) ;
	    switch (type)
	    {
		case LABS : printf ("Abs") ; break ;
		case LREL : printf ("Rel") ; break ;
		case LUDF : printf ("Udf") ; break ;
		default : printf ("Type aie aie aie") ; break ;
	    }
	}
	else if (value == LBL_UDF)
	{
	    printf ("-UDF-") ;
	}
	else if (value == LBL_IVL)
	{
	    printf ("-IVL-") ;
	}
	else if (value == LBL_EXT)
	{
	    printf ("-EXT-") ;
	}
	else if (value == LBL_XEQ)
	{
	    printf ("-XEQ-") ;
	    fscanf (fp, "%s\n", line) ;
	    printf (", definition = %s", line) ;
	}
	else		    /* (value == LBL_SEQ) */
	{
	    printf ("-SEQ-") ;
	}
	printf ("\n") ;
    }

    fgetl (nu, fp) ;
    printf ("references not resolved: number = %d\n", nu) ;
    for (i=1; i<=nu; i++)
    {
	fgetl (characteristic, fp) ;
	fgetl (pc, fp) ;
	fscanf (fp, "%s\n", line) ;
	printf ("%4d:", i) ;
	hex5 (hexvar, pc) ;
	printf (" pc = %s", hexvar) ;
	printf (", type = ") ;
	switch ((int) (characteristic & 0xf0))
	{
	    case XABSL : printf ("XABSL") ; break ;
	    case XABSO : printf ("XABSO") ; break ;
	    case XRGTO : printf ("XRGTO") ; break ;
	    case XRGSB : printf ("XRGSB") ; break ;
	}
	printf (", length = %1d", characteristic & 0xf) ;
	printf (", val = %s\n", line) ;
    }
}


/* function called indirectly, via hex5 */

format_hex (str, val, dig)
uchar *str ;
saddr val ;
int dig ;
{
    register int i, h ;

    for (i=dig-1; i>=0; i--)
    {
	h = (int) (val & ((saddr) 0xf)) ;
	str [i] = h + ((h < 10) ? '0' : 'A' - 10) ;
	val >>= 4 ;
    }
    str [dig] = EOL ;
}
@EOF
set `wc -lwc <areuh/dump/adp.c`
if test $1$2$3 != 1465473093
then
	echo ERROR: wc results of areuh/dump/adp.c are $* should be 146 547 3093
fi

chmod 644 areuh/dump/adp.c

echo x - areuh/dump/common.h
cat >areuh/dump/common.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include <stdio.h>


#define MAXLEN 256
#define EOL    '\0'
#define LBLLEN 12

/******************************************************************************
 TYPE DEFINITIONS
******************************************************************************/

typedef long int saddr ;	      /* Saturne address. At least 32 bits   */
typedef unsigned char uchar ;	      /* unsigned characters, for accents    */
typedef short int sint ;	      /* 16 bits */

/******************************************************************************
 MAGIC NUMBERS
******************************************************************************/

#define  AL_MAGIC 0x1b080100	      /* ... areuh_lex */
#define  AO_MAGIC 0x1b0d0100	      /* ... areuh_output of assembler */
#define ALF_MAGIC 0x1b080100	      /* first version of object file format */
#define AOF_MAGIC 0x1b0d0100	      /* first version of object file format */


/******************************************************************************
 USAGE TYPES IN .ao FILES
******************************************************************************/

#define XABSL 0x10     /* absolute reference */
#define XABSO 0x20     /* absolute reference, with one bias */
#define XRGTO 0x40     /* relative reference, goto type */
#define XRGSB 0x80     /* relative reference, gosub type */


/******************************************************************************
 LABEL VALUES IN .ao FILES
******************************************************************************/

#define LBL_UDF -1L
    /* label not declared (implicit or explicit) <=> only used */
#define LBL_IVL -2L
    /* invalid label (invalid expression for an EQU during pass one) */
#define LBL_EXT -3L
    /* external label not defined here (or yet) */
#define LBL_XEQ -4L
    /* global label which is defined here, with an external reference */
#define LBL_SEQ -5L
    /* local label which is defined with an external reference */


/******************************************************************************
 LABEL TYPES IN .ao FILES
******************************************************************************/

#define LUDF 0
    /* undefined type (external label) */
#define LABS 1
    /* absolute local label (declared explicitly, with constants) */
#define LREL 2
    /* relative local label (declared implicitly, or explicitly with at least
       one relative) */


/******************************************************************************
 VALUES RETURNED BY EXPRESSION EVALUATOR
******************************************************************************/

#define EXP_ERR -1L
#define EXP_EXT -2L

extern int relabs ;
extern uchar extexp[] ;

#include "err.h"
extern void error () ;

#define hex5(str,val) format_hex (str, val, 5) ;
#define hex6(str,val) format_hex (str, val, 6) ;

/******************************************************************************
 MACHINE DEPENDANCIES
******************************************************************************/

#define HPUX		     1
#define ATARI_LATTICE	     0
#define PC_MSC		     0		/* PC (beuark, Microsoft C) */

#if HPUX
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "r"
#define WAO_MODE "w"
#define skip(fp)
#endif

#if ATARI_LATTICE
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "rb"
#define WAO_MODE "wb"
extern char skipvar ;
#define skip(fp) fread(&skipvar,1,1,fp) ;
#endif

#if PC_MSC
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "rb"
#define WAO_MODE "wb"
extern char skipvar ;
#define skip(fp) fread(&skipvar,1,1,fp) ;
#endif
@EOF
set `wc -lwc <areuh/dump/common.h`
if test $1$2$3 != 1244243878
then
	echo ERROR: wc results of areuh/dump/common.h are $* should be 124 424 3878
fi

chmod 644 areuh/dump/common.h

echo x - areuh/dump/err.h
cat >areuh/dump/err.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                           AREUH ASSEMBLER / LINKER


                          ERROR NUMBERS DECLARATIONS

******************************************************************************/




/* FATAL ERRORS */

#define ERROPN  -1                                       /* A L */
    /* system error opening file */
#define ERRCLO  -2                                       /* A L */
    /* system error closing file */
#define ERRREW  -3                                       /* A */
    /* system error on file at start of pass two */
#define ERRWRT  -4                                       /* A L */
    /* system error writing file */
#define ERRRD   -5                                       /* A L */
    /* system error reading file */
#define ERRMEM  -6                                       /* A L */
    /* not enough memory */

#define ERRLEX  -10                                      /* A */
    /* invalid macro pseudo-op LEX or BIN */
#define ERRPGS  -11                                      /* A */
    /* invalid page size */
#define ERRFLN  -12                                      /* A */
    /* restricted label FiLeNd exists */
#define ERRIFL  -13                                      /* A L */
    /* invalid file name */
#define ERRIMO  -14                                      /* A */
    /* invalid macro-op xx in modular assembling */
#define ERRVMD  -15                                      /* A */
    /* value must be defined for xx */

#define ERRUSA  -20                                      /* A L */
    /* usage: ass [ [-l] source_file ] */
    /* usage: ald ... */

#define ERRNOA  -30                                      /* L */
    /* file not output from aas */
#define ERRICV  -31                                      /* L */
    /* incompatible version */



/* NON FATAL ERRORS */

#define WRNEQU  10                                       /* A */
    /* cannot resolve equate */
#define WRNDUP  11                                       /* A L */
    /* duplicate label */
#define WRNLBL  12                                       /* A */
    /* illegal label */
#define WRNULB  13                                       /* A */
    /* unrecognized label */
#define WRNURF  14                                       /* L */
    /* unresolved reference */
#define WRNURL  15                                       /* L */
    /* unresolved label */

#define WRNEXP  20                                       /* A */
    /* illegal expression */
#define WRNASC  21                                       /* A */
    /* illegal ascii constant */
#define WRNPAR  22                                       /* A */
    /* mismatched parenthesis */
#define WRNIHX  23                                       /* A */
    /* illegal hexadecimal constant */
#define WRNNUL  24                                       /* A */
    /* null divisor */
#define WRNIXP  25                                       /* A */
    /* illegal exponentiation */
#define WRNIBC  26                                       /* A */
    /* illegal binary constant */
#define WRNENA  27                                       /* A */
    /* external references not allowed */

#define WRNYES  30                                       /* A */
    /* GOYES or RTNYES required */
#define WRNIDP  31                                       /* A */
    /* illegal dp arithmetic value */
#define WRNIPP  32                                       /* A */
    /* illegal pointer position */
#define WRNISB  33                                       /* A */
    /* illegal status bit */
#define WRNTFR  34                                       /* A */
    /* illegal transfer value */
#define WRNIWS  35                                       /* A */
    /* illegal word select */
#define WRNLST  36                                       /* A */
    /* invalid LIST argument */
#define WRNJVL  37                                       /* A L */
    /* jump or value too large */
#define WRNMLB  38                                       /* A */
    /* missing label */
#define WRNTST  39                                       /* A */
    /* needs previous test instruction */
#define WRNNHX  40                                       /* A */
    /* non hexadecimal digits present */
#define WRNTMA  41                                       /* A */
    /* too many ascii characters present */
#define WRNTMH  42                                       /* A */
    /* too many hexadecimal digits present */
#define WRNOPC  43                                       /* A */
    /* unknown opcode */

#define WRNIIF  50                                       /* A */
    /* invalid conditional structure */

extern void error() ;
@EOF
set `wc -lwc <areuh/dump/err.h`
if test $1$2$3 != 1275845010
then
	echo ERROR: wc results of areuh/dump/err.h are $* should be 127 584 5010
fi

chmod 644 areuh/dump/err.h

echo x - areuh/dump/adp.1
cat >areuh/dump/adp.1 <<'@EOF'
.TH ADP 1L
.SH NAME
adp \- areuh intermediate file dump
.SH SYNOPSIS
.B adp
file
.SH DESCRIPTION
.I Adp
affiche des informations sur le fichier intermediaire
specifie.
En particulier,
.B adp
affiche la taille du code,
les symboles externes definis dans ce fichier, ainsi que
les expressions n'ayant pas pu etre resolues a l'assemblage.
.PP
.B Adp
a ete developpe pour des besoins internes et ne doit normalement pas etre
utilise.
.SH AUTHORS
Pierre David
Janick Taillandier
.SH SEE ALSO
aas(1L),
ald(1L),
amg(1L),
cp71(1L).
.br
.I "IDS vol I"
for HP-71.
@EOF
set `wc -lwc <areuh/dump/adp.1`
if test $1$2$3 != 3092554
then
	echo ERROR: wc results of areuh/dump/adp.1 are $* should be 30 92 554
fi

chmod 644 areuh/dump/adp.1

echo x - areuh/dump/Makefile
cat >areuh/dump/Makefile <<'@EOF'
#
# Makefile genere automatiquement par mkmf (le masque par defaut a ete adapte)
#

CFLAGS	      = -O
LDFLAGS	      =
LIBS	      =
SYSLIBS	      =
BINDEST	      = /usr/local/bin

#
# S'il y a plus d'un programme, il faut aussi remplacer la cible
# $(PROGRAM) par autant de cibles que necessaire.
#

PROGRAM       = adp

SRCS	      = adp.c

HDRS	      = common.h \
		err.h

EXTHDRS	      = /usr/include/stdio.h

OBJS	      = adp.o

MANDEST	      = /usr/local/man/man1.Z

MANPAGES      = adp.1

#
# Les cibles :
#	all : compiler tout
#	clean : effacer les .o et les core
#	clobber : effacer tout ce qui peut etre regenere
#	depend : recalculer toutes les dependances et les inserer ici
#	install : installe le programme dans l'aborescence
#	tags : cree les tags
#

all:		$(PROGRAM)

$(PROGRAM):     $(OBJS) $(LIBS)
		cc $(LDFLAGS) $(OBJS) $(LIBS) $(SYSLIBS) -o $(PROGRAM)

clean:;		rm -f $(OBJS) core

clobber:;	rm -f $(OBJS) $(PROGRAM) core tags

depend:;	mkmf ROOT=$(ROOT)

install:	$(PROGRAM)
		-strip $(PROGRAM)
		if [ $(BINDEST) != . ] ; \
		then \
		    (cd $(BINDEST) ; rm -f $(PROGRAM)) ; \
		    cp $(PROGRAM) $(BINDEST) ; \
		    if [ "$(MANPAGES)" != none ] ; \
		    then \
			(cd $(MANDEST) ; rm -f $(MANPAGES)) ; \
			for i in $(MANPAGES) ; \
			do \
			    compress < $$i > $(MANDEST)/$$i ; \
			done ; \
		    fi ; \
		fi

tags:           $(HDRS) $(SRCS)
		ctags $(HDRS) $(SRCS)

#
# Dependances calculees automatiquement par mkmf.
# Ne rien changer apres cette ligne !
#
###
adp.o: common.h /usr/include/stdio.h err.h
@EOF
set `wc -lwc <areuh/dump/Makefile`
if test $1$2$3 != 762491533
then
	echo ERROR: wc results of areuh/dump/Makefile are $* should be 76 249 1533
fi

chmod 644 areuh/dump/Makefile

echo x - areuh/doc/areuh.doc
sed 's/^@//' >areuh/doc/areuh.doc <<'@EOF'

          ASSEMBLEUR / EDITEUR DE LIENS
                   POUR LE HP71



I - PRINCIPE


A: Presentation

Le  systeme  de  developpement  pour HP71 que nous
presentons ici est base sur un  assembleur  et  un
editeur de liens ecrits en Langage C.

Ce  systeme  fonctionne a l'heure actuelle sur des
ordinateurs differents :

- Les ordinateurs fonctionnant sous systeme  HP-UX
en particulier, et sous systeme Unix en general.

-  les  ordinateurs  Atari  520  et  1040  ST sous
systeme d'exploitation TOS.

- une adaptation est en cours pour l'ordinateur HP
Vectra et autres IBM PC sous systeme MS-DOS.

Tous  nos efforts se sont portes vers la reduction
des   temps   d'assemblage.    Voir   les    temps
d'execution   donnes   en  exemple  pour  plus  de
details.


B: Introduction a l'assembleur

L'assembleur a deux modes de fonctionnement :

Le mode "assemblage complet", qui  permet  d'avoir
la compatibilite avec le "machin" (l'assembleur du
module  Forth).   En   particulier,   toutes   les
macro-operations  de generation de fichiers lex ou
bin sont supportees.

Le  mode  "assemblage   separe"   permet   de   se
rapprocher  des  conditions de travail de l'equipe
de  developpement  du  HP71  aux  laboratoires  de
Corvallis (OR 97330) en autorisant l'assemblage de
modules separes, et leur reunion en  seul  fichier
par l'intermediaire de l'editeur de liens.


C: Avantages et inconvenients

Parmi   les  nombreux  avantages  que  procure  ce
systeme, nous pouvons citer :

Utilisation des points d'entree HP  sans  avoir  a
les  declarer  explicitement  par une operation du
type EQU.

Edition  d'une  table  des   references   croisees
donnant  pour chaque symbole le nom, la valeur, la
ligne ou il est declare et les lignes  ou  il  est
utilise.

Introduction   de  nouveaux  operateurs  dans  les
expressions,  et  possibilite   d'introduire   des
valeurs en binaire.

Les  noms des labels sont maintenant significatifs
sur 12 caracteres.

Quant   aux   inconvenients,   il    manque    les
pseudo-operations  FORTH,  WORD et WORDI. Et, bien
sur, il faut un "gros" ordinateur.


D: Principe de l'assemblage separe

L'assemblage d'un fichier en  modules  separes  se
fait en deux phases.

IL   faut  d'abord  assembler  tous  les  fichiers
(modules) constituant le source. Ensuite, il  faut
proceder  a  l'edition de liens, qui rassemble ces
modules en un seul fichier.

Si il s'avere necessaire de modifier une partie du
texte  source, il suffit seulement de re-assembler
le  module  contenant  ce  texte,  et  de  refaire
l'edition de liens. Le gain de temps est enorme.

Cette   gestion   modulaire  permet  egalement  un
traitement plus efficace des  labels.   Un  module
peut  appeler  une  routine  ecrite  dans un autre
module a partir du moment ou le label est  precede
d'un  signe '=' dans les modules concernes. Ceci a
pour role de declarer le label  externe  (dans  le
module  appelant)  ou public (dans le module ou le
label est declare) et accessible a tous.  Ce  sont
les labels globaux.

A   cette  categorie  s'ajoute  celle  des  labels
locaux. Ils ne comportent pas de signe '=', et des
modules  peuvent  avoir des labels portant le meme
nom.  Ceci permet d'avoir, par exemple,  plusieurs
labels  "argerr" dans des modules differents, sans
causer le moindre conflit.

C'est le meme systeme que celui employe par HP, et
decrit  dans  les  IDS  Vol.  I  (ch. 16). Seul ce
systeme  permet   le   developpement   de   grands
programmes en assembleur.



II - DIFFERENCES AVEC LE "MACHIN"


A: Selection du mode

La  selection  du  mode  d'assemblage  (complet ou
separe) est faite par la presence de la macro  LEX
ou BIN en premiere ligne du fichier source.

B: Majuscules / Minuscules

Mis a part les labels, tous les op-codes et toutes
les  expressions  sont  compris  aussi   bien   en
majuscules qu'en minuscules.

C: Macro-operation interdites

En  assemblage  separe,  les  pseudo-operations de
generation de fichiers LEX ou BIN sont interdites.
Ainsi,  LEX,  ID,  MSG,  POLL, ENTRY, CHAR, TOKEN,
KEY, ENDTXT, BIN et  CHAIN  sont  interdites  hors
d'un  assemblage  complet.   On  exerce  ainsi  un
controle plus precis sur la generation du code.

Par ailleurs, les macro FORTH, WORD et WORDI  sont
interdites.

Seule  la  premiere utilisation de TITLE est prise
en compte.

D: Macro-operations ajoutees

En  premier  lieu,  il  y a RDSYMB (ReaD SYMBols).
Elle permet de charger un  fichier  contenant  des
points d'entree sans avoir a attendre l'edition de
liens. Par exemple, en  assemblage  complet,  ceci
permet  d'avoir  les points d'entree supportes par
HP (fichier "hp71.ep"). La syntaxe est :

       RDSYMB <fichier>


Ensuite,  nous  avons  l'assemblage  conditionnel.
Par exemple, si nous avons :

AREUH  EQU    1

       IF     AREUH
       P=P+1
       RTN
       ELSE
       ASRB
       C+P+1
       ENDIF

Seul le code P=P+1 et RTN sera assemble.

Inversement,  si  AREUH avait ete declare avec une
valeur nulle, le code ASRB  et  C+P+1  aurait  ete
assemble.  Ceci  permet  de  gerer  simplement des
versions differents d'un meme programme  (versions
de  mise  au point).  Attention cependant :  il ne
peut y avoir  imbrication  d'une  telle  structure
conditionnelle.

E: Opcodes ajoutes

D0=HEX  et  D1=HEX  (presents, mais non documentes
dans le "machin") fonctionnent a merveille.

LC(6) et CON(6) (utilises par HP) sont presents.

F: Valeurs numeriques

Les   valeurs   numeriques   calculees   dans  les
expressions,   ou   renvoyees   par   des   labels
comportent  six  chiffres hexadecimaux et non cinq
comme dans le "machin". Comme dans les IDS.

En revanche, les valeurs affichees dans les tables
de  symboles  le sont sur cinq chiffres seulement.
Cette limitation ne concerne  que  l'affichage  et
non  le  stockage  interne.  Ceci  est  conforme a
l'affichage fourni par l'assembleur des IDS, et  a
ete  conserve en raison de l'habitude acquise a la
lecture des adresses du HP71.

G: Les Expressions

Les  expressions  peuvent  contenir des labels, la
valeur du compteur ordinal (PC), des constantes et
des  operateurs.   Il  n'y  a pas de limitation du
niveau d'imbrication des parentheses.

Maintenant,  les  labels sont significatifs sur 12
caracteres.

Le   symbole  '*'  (en  position  d'operande)  est
considere comme la  valeur  du  compteur  ordinal.
Dans  le  cas  d'une  compilation  separee,  cette
valeur est la valeur reelle, tenant compte  de  la
position du module dans le fichier complet.

Les constantes de valeur superieure a six chiffres
hexadecimaux sont tronquees.

Les constantes Ascii sont delimitees soit par  des
apostrophes ('), soit par des anti-slash (\).

Un  nouveau  type  de  constante est ajoutee : les
constantes binaires. Elles doivent etre  precedees
d'un signe '%', comme dans :  %01110001

Les   operateurs  :   nous  en  donnons  la  liste
complete, par ordre de priorite decroissante.  Les
operateurs de meme priorite sont evalues de gauche
a droite.

@~ (*256+)               ^  (puissance)
- (moins  unaire)       ` (complement  a  1)
& (et logique)          ! (ou logique)
* (multiplication)      / (division  entiere)
+ (addition)            - (soustraction)


H: FiLeNd

Le  label  FiLeNd est ajoute systematiquement a la
fin de chaque fichier ou module assemble.

En outre, le label  global  "=FiLeNd"  est  ajoute
automatiquement   en   fin   de  fichier  lors  de
l'edition de liens pour l'assemblage separe.



III - MODE D'EMPLOI DES PROGRAMMES


Les  deux  programmes "aas" et "ald" admettent les
memes options.

-o

Specifie  le   nom   du   fichier   resultant   de
l'assemblage ou de l'edition de liens.

-a <fichier>

Demande  l'impression d'un listing d'assemblage ou
d'edition de liens. Le listing est envoye dans  le
fichier specifie.

-A

Demande  l'impression d'un listing d'assemblage ou
d'edition de  liens.   Le  listing  est  envoye  a
l'affichage (ou stdout sur les systemes Unix).

-l <longueur de page>

Specifie la longueur physique des pages, en nombre
de lignes.  La longueur du texte  sera  inferieure
de 6 lignes.

-x

Demande  l'impression  d'une  table des references
croisees.

-p

Active la saisie interactive des options  decrites
precedemment.    Notons   que   ne   donner  aucun
parametre active implicitement cette option.


Pour aas,  il  faut  ensuite  fournir  le  nom  du
fichier source.

Pour  ald,  il  faut  fournir les noms de tous les
modules.


Par defaut, le fichier genere a  pour  nom  "lex".
Les   fichiers  source  ont  ".as"  comme  suffixe
(extension), et les fichiers intermediaires (entre
l'assembleur  et  l'editeur  de  liens)  ont ".ao"
comme  suffixe.   En   general,   il   n'est   pas
necessaire d'indiquer ces extensions.



IV - EXEMPLES


Assembler  le  fichier f1.as (qui commence par une
macro LEX), et fichier assemble dans "lex" :

aas f1

Assembler   le   fichier   f1.as   avec   listing,
references  croisees  dans  le  fichier "list", et
fichier resultat dans "lex" :

aas -xalist f1

aas -x -a list f1

Meme exemple que precedemment avec une longueur de
page de 66 lignes (papier 11") :

aas -xalist -l66 f1

Assembler  le  fichier  f1.as,  avec resultat dans
"toto", avec parametrage interactif :

aas
  puis entrer "f1"
  puis entrer "toto"
  puis entrer [RETURN]




Les fichiers f1.as, f2.as et f3.as continennent le
source d'un fichier lex.

Assemblage des trois fichiers :

aas f1

aas f2

aas f3

Edition de liens des fichiers f1, f2 et f3  (fi.ao
pour  i=1..3),  avec demande d'un listing et d'une
table des  references  croisees  dans  le  fichier
"list", et fichier assemble nomme "totolex".

ald -xalist -ototolex f1 f2 f3



        Pierre David (PC37, SIG1, CHHU616)
    Janick Taillandier (PC246, SIG6, CHHU178)
@EOF
set `wc -lwc <areuh/doc/areuh.doc`
if test $1$2$3 != 36314359707
then
	echo ERROR: wc results of areuh/doc/areuh.doc are $* should be 363 1435 9707
fi

chmod 644 areuh/doc/areuh.doc

exit 0

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:32:54 1990
#
# This archive contains:
#	areuh/doc/readme.dos	areuh/doc/compc.doc	
#	areuh/doc/areuh110.doc	
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - areuh/doc/readme.dos
cat >areuh/doc/readme.dos <<'@EOF'
			  HP-71 DEVELOPMENT SYSTEM





NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR
MMERCIAL DISTRIBUTION - NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR COMMERCIA
ISTRIBUTION - NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR COMMERCIAL DISTRIBU




Notice :  this is a public  domain  software.  You are	encouraged  to make
copies of it.  Feel free to distribute it.  The only restriction is that it
cannot be distributed on a commercial basis.




INTRODUCTION
------------


This disk contains the AREUH development system.  It is intended to produce
LEX or BIN files for the HP-71B, using a PC or	compatible  computer.  This
system	includes an  assembler, a linker, a message  table  generator,	and
miscellaneous useful tools.

It is a sophisticated  set of programs.  They have been optimized for speed
without compromising capabilities.  The assembler is able to process source
files  either  compatible  with  Forth /  Assembler  Rom or HP	development
system.  It should be able to  understand  all	source	file  formats.	The
linker is a  convenient  tool to develop  large  projects  as well as small
ones.  The table message  generator (like other tools) is very easy to use,
and greatly simplify the creation of such tables.

It was written by Pierre David and Janick  Taillandier, from PPC-Paris.  We
are happy to thank Stephane  Barizien for its efficient help for all MS-DOS
problems.

As described above, you are welcome to copy and distribute it free. We hope
it will help HP-71 software development. It is our common interest.

It was used by the authors to develop :

- JPCROM (19+ KB Lex file, 461 KB source files, assembled in 2.20 minutes)
  JPCROM is the PPC-Paris LEX file, including 100 various keywords.

- GRAPHIC (9 KB Lex file, 290 KB source files, assembled in 1.15 minutes)
  GRAPHIC is a commercial product, providing graphic  capabilities  similar
  to HP-85,  HP-41,  HP-200  graphic  languages on a ThinkJet  (MOVE, DRAW,
  LABEL...).


I - HISTORY
-----------


The AREUH  development	system (AREUH stands for  Assembleur  Relogeable En
Utilisation  Heuristique) was developed from April to August 1986 on a UNIX
machine :  the HP Integral Personal  Computer.	Unfortunately,	many people
are now using PC or compatible.  So, in July 1987, we have decided to adapt
AREUH to these so called computers.

The process was rather hard for us :  we had to find a PC, a C compiler, an
HPIL card, etc.  We also had a lot of  difficulties  with the  surprising C
compiler  implementation,  as well as with the numerous but powerless  text
editors...

We have no personal interest in this MS-DOS version.  It was a tough job to
get it work, and we get no profit from it.

This was done to allow all HP-71  developers  to benefit  from our tool and
stop using  archaic ones, and we hope to see more HP-71  software.  We wish
this could help.

We hope the time we have spent on this	project will not be a wasted  time.
We would appreciate receiving feed-back from you.  It would also be nice to
mention that your software has been developed with this assembler.


II - WHY A LINKER ?
-------------------


If you take a look at the IDS Vol.  III, or HPIL IDS, you may  notice  that
HP used a linker.  Other  large  projects,  such as JPCROM or GRAPHIC  have
been using a linker.

Using a linker	allows	splitting a large  problem  into small,  manageable
units :  you have only small  files to edit and  assemble.  You divide your
problem  into  functional  units,  with clear  interfaces.  You work on one
module at a time, you don't have to take care of the others.

Incidentally,  you spare time because you have only one module to assemble,
and you have small convenient  facilities,  such as local labels known only
inside the module, and global ones known everywhere.


III - PRINCIPLE
---------------


A : THE TWO MODES
-----------------

The assembler has two operating modes :

- compatibility mode
- modular mode

The first one is  intended to assemble	all source  files  written  for the
Assembler  Rom.  All  macro-operations	such  as  LEX,	BIN,  CHAIN...	are
supported.  No linkage step is needed.

The second one is similar to the description  given in IDS Vol.  I, chapter
16.  In  fact, it has more  features  than  this  one.	This  mode  needs a
linkage  step, and  supports  local and global	labels.  A global  label is
preceded by an "=" character.

To use the compatibility  mode, the first line of the file must be a LEX or
BIN macro-operation.  Any other first line activates modular mode.

If you wish to use system entry points in  compatibility  mode, you can use
the RDSYMB  macro-operation.  It will read the	specified  file to load all
supported entry points.  You don't need any more to write long lists of EQU
to use system entry points.

In  modular  mode,   everything  is  automatic.  The  system  entry  points
addresses are loaded at link time.

In both  modes, you cannot use FORTH, WORD and WORDI  macro-operations.  In
modular  mode, you cannot use LEX, ID, MSG, POLL, ENTRY, CHAR,	TOKEN, KEY,
ENDTXT, BIN and CHAIN.


B : LISTINGS
------------

You can  output  assembler  or	linker	listings,  with  optional  complete
cross-reference  section.  For an  example,  see  FINPUT  listing  in JPC43
(April 1987).


C : ADDED FEATURES
------------------

Compared with the Assembler  Rom, or HP's one, the following  features have
been added :

- label  names	may have up to 12  significant	characters  (13 if they are
preceded by an "=" symbol).

- all  opcodes and  modifiers  are not case  sensitive.  You can mix freely
lower and upper case characters.  Label names are always case sensitive.

- conditional assembly is allowed, with macro-operation IF. The syntax is :
       IF     <expression>
	<assembled if expression # 0>
       ELSE
	<assembled if expression = 0>
       ENDIF

The ELSE part is optional.

- the  macro-operation	RDSYMB (ReaD SYMBol) was implemented to load a file
containing entry points.  The syntax is :
       RDSYMB <filename>
In this MS-DOS version,  <filename> can be an absolute file reference (such
as  a:\lib\hp71.ep),  or a  relative  one.  In the last  case,	the file is
looked for in specific locations.

- D0=HEX and D1=HEX,  undocumented  and bugged opcodes in the Assembler Rom
are present and unbugged !

- numerical values are processed on 6 hexadecimal  digits  (nibbles), as in
HP's assembler.  This allows providing LC(6) and CON(6) instructions.

-  litteral  constants	may  be  delimited  either  by '  (quote)  or  by \
(backslash) symbols.

- there is no limit on parenthesis level.

- a new constant type is supported :  binary constants.  They are used with
a % symbol :  for example :  %01110001 = #71 = 113.

- new operators have been added. They are
   ~   -> *256+
   ^   -> power
   `   -> one's complement
All operators are listed below, in descending order or precedence.
   ~   (*256+)			     ^	 (power)
   -   (unary minus)		     `	 (one's complement)
   &   (logical and)		     !	 (logical or)
   *   (multiplication) 	     /	 (integer division)
   +   (addition)		     -	 (binary subtraction)

- FiLeNd label is automatically  added at the end of each assembled file or
module.  In modular  mode, a global label  =FiLeNd is  automatically  added
after the last module during link step.


IV - USING THE PROGRAMS
-----------------------


A : File naming conventions :
-----------------------------

- source files have the ".as" (Areuh Source) extension,
- object file resulting from assembly in modular mode have the ".ao" (Areuh
  Object) extension,
- list files have the ".al" (Areuh List) extension,
- message description files have the ".am" (Areuh Message) extension,
- entry points files have the ".ep" (Entry Point) extension,
- complete lex files (result of aas in compatibility mode or ald) are named
  "lex".

These  are  suggested  names.  You can	override  them	using  full  names.
However, using them is easier.


B : Assembler (aas) and Linker (ald)
------------------------------------

Both programs share the same options.

-o <file>
specifies  the name of output file.  If the specified  name is a directory,
the output file is written in this directory, using default name.

-a <file>
produces  a listing  in the  specified	file.  If the  specified  name is a
directory,  the listing file is written in this  directory,  using  default
name.

-A
produces a listing on standard output.

-l <page length>
specifies  the physical page length in number of lines	(default is 72, for
12" paper).  Text length is (page length - 6).

-x
asks  for a  cross-reference  table.  Should  be used  only  when  -a or -A
options are specified.

-p
enables  interactive options input.  If no option or file name is specified
after aas or ald, you automatically enter interactive prompt mode.

After aas, you have to supply the source  file names (wild card  characters
allowed).  File names order is irrelevant.

After  ald, you have to supply	the  intermediate  file  names	(wild  card
characters allowed).  File names order is very important, it corresponds to
the link order.


The  linker is	limited  to 80 files.  As far as MS-DOS  command  lines are
limited to a small  numbers of	characters,  you may have  difficulties  to
specify  a full  ald  command.	In  this  case,  you  can  use	interactive
prompting :
  ald  <answer
where "answer" is a text file containing the answers to all questions.


C : Message table generator (amg)
---------------------------------

Amg reads on  standard	input a message  table	description,  and writes on
standard output an HP-71 message table, ready to be assembled.

The message table  description	contains  several lines with the  following
structure :

<message label>:<message text>

For example :
=eDIRFL:Directory Full

If you	want to use  building  blocks,	the  building  block  text  must be
enclosed within square brackets, for example :
=eUNEXP:Unexpected [Message ]
[Message ] (with a  white  space)  is a local  building  block.  It will be
created in the message table.

Amg recognizes automatically mainframe building blocks. For example :
=eBADMD:[Invalid ]Mode
[Invalid ] (with a white space) is a mainframe building block.	The message
table will reference it without creating it.

Messages  are  numbered  from 0.  If an  argument  is  given,  it must be a
number, and messages will be numbered from it.

Amg checks  that there is a message  whose total  length is multiple  of 16
nibbles, as requested by the HP-71  Operating  System.	Otherwise, an error
is written in the generated file.


D : Downloading to HP-71 :
--------------------------

Two  utilities are provided to download the  assembled	files to the HP-71.
You can use either the RS232 interface or the HP82973 HPIL interface.


RS232 : (program a2rs)
----------------------

The syntax is : a2rs [ <file> ]
If no file name is specified, the default is "lex".

For the connection, we have used the following cable :

       PC	       HP82164A RS232/HPIL

	2 ----\ /----  2
	       x
	3 ----/ \----  3

	4 ----\ /----  4
	       x
	5 ----/ \----  5

	6 ----\ /----  6
	       x
       20 ----/ \---- 20

	7 -----------  7


The HP82164A must be configured from the HP-71 by :
  REMOTE @ OUTPUT :RS232;"LI5;C0" @ LOCAL
before running a2rs, you have to enter on your HP-71 :
  COPY :RS232


HPIL : (program a2lex)
----------------------

Prior to transfer  your  assembled  file, you must use a2lex to convert the
file to the format needed by HPILLINK.

The syntax is : a2lex [ <file> ]
If no file name is specified,  the default is "lex".  The ".lex"  extension
is automatically appended to the converted file.

Then, you can download using HPILLINK.


CUSTOMIZING YOUR DOWNLOADING PROGRAM : (program a2?)
----------------------------------------------------

The syntax will be : a2? [ <file> ]
If no file name is specified, the default is "lex".

In order to allow you to use any device you may wish to download  your LEX,
we give you the source code for a2lex (file a2lex.c) as an example.

You have to write only three functions in C :
  init () :
    initializes your interface
  output (char c) :
    outputs the character c to your interface
  term () :
    terminates the process.

These functions can be empty.  They are only responsible for the interface,
and not for the conversion process.


V - EXAMPLES
------------


To assemble "compat.as" (compatibility mode), you must type :
  aas compat
The output will be in "lex" file.


To assemble  "compat.as" with listing and cross-reference  section, sent to
file "list", type :
  aas -xalist -l66 compat	 or
  aas -x -a list -l 66 compat.as


To assemble the same file with interactive options input, simply type :
  aas
    then enter "compat"
    then press [RETURN] 	 (output is default, "lex")
    then enter "list"            (for listing file)
    then enter "yes"             (for cross reference)
    then enter "66"              (for page length)


To assemble files "x1.as", "x2.as", "x3.as" (modular mode), you must type :
  aas x*.as			 or
  aas x1 x2 x3

To link these files, with a listing and cross-reference in file "list", and
a lex file in "totolex", you must type :
  ald -xalist -ototolex x1 x2 x3
Warning : the order of object modules if important.


To create a message table from "jpc.am", you must type :
  amg <jpc.am >mes.as

If you wish to number these messages starting from 27, you must type :
  amg 27 <jpc.am >mes.as


VI - ENTRY POINTS FILES
-----------------------


AREUH is provided with two files :

  hp71.ep :	   mainframe supported entry points and symbols
  hpil.ep :	   hpil supported entry points

These files are looked for in the following directories :
  current directory
  c:\hp71\
  c:\lib\hp71\
  c:\lib\
  c:\areuh\lib\
or at the location specifed by RDSYMB.

You can add entry  points to these files, or use other files.  Only hp71.ep
is  automatically  loaded at link time.  If you want to use hpil.ep or your
own file, you must load them explicitly at assembly time with RDSYMB.

The  supplied  files are  sorted in reverse  order.  This is only for speed
considerations.  Each label has its name, followed by its hexadecimal value
on the next line.

If you find any error in these files, please inform us.


VII - IN CASE OF PROBLEMS
-------------------------

If you have a  problem,  before  reporting  it to us,  please  check if the
problem is not in your source code or computer system.

We will try to answer your  questions or solve your  problems (NOT hardware
or  connection	problems).  Send us on a 3.5" LIF (or MS-DOS)  format  your
source code, with a complete  description and localization of your problem.
This is not a programming aid service...

Write to :
  Pierre David		 or	    Janick Taillandier
  33 Bd St Martin		    335 rue Lecourbe
  75003 Paris			    75015 Paris
  FRANCE			    FRANCE


APPENDIX 1 : DISTRIBUTION DISK
------------------------------


This disks contains the following files :

aas.exe 	Areuh ASsembler
ald.exe 	Areuh LoaDer (Loader = Linker under UNIX)
amg.exe 	Areuh Message table Generator
a2lex.exe	Areuh To HPILLINK LEX format
a2rs.exe	Areuh To RS232
adp.exe 	Areuh DumP (utility to dump intermediate files)

readme		This file

xmp\compat.as	Example for compatibility mode
xmp\x1.as	Example for modular mode (file header)
xmp\x2.as	Example for modular mode (execution routine)
xmp\x3.as	Example for modular mode (decomparse routines)
xmp\jpc.am	Example of message table description (from JPCROM)

src\copy.h	body of a2lex program
src\a2lex.c	dedicated I/O routines

lib\hp71.ep	HP-71 supported entry points and symbols
lib\hpil.ep	HP-IL supported entry points


APPENDIX 2 : MS-DOS NOTE
------------------------

These programs have been successfully  tested on an HP 150, MS-DOS 2.11 and
on an AT compatible MS-DOS 3.20.

We have used Microsoft C 4.0 to compile all programs.



Enjoy !

Pierre David & Janick Taillandier
@EOF
set `wc -lwc <areuh/doc/readme.dos`
if test $1$2$3 != 501253715946
then
	echo ERROR: wc results of areuh/doc/readme.dos are $* should be 501 2537 15946
fi

chmod 644 areuh/doc/readme.dos

echo x - areuh/doc/compc.doc
cat >areuh/doc/compc.doc <<'@EOF'
			COMMUNICATION HP-71 <=> PC

		      Michael Markov (PPC Paris 301)


This file documments three HP-71 programs I use to upload and download files to
and from my HP110. They can also be used to do the same with IBM PC or
compatible machines equipped with an HP82973 HPIL Interface.

Why do I need special programs to do this, when HPILLINK provides the ability
to upload and download files from the PC keyboard? Because I only want to
exchange files with the PC, not use a remote keyboard for my HP-71. The editor
I have on the PC or the HP110 (Ed Gilbert's Editor, NOT memomaker) is much
faster than any text editors I have on the HP-71, they handle long text files
without slowing down to the speed of cold molasses, and have features HP-71
users only dream of. Editing BASIC programs is usually faster without the delays
introduced by the remote keyboard. Finally - HPILLINK set-up with the remote
keyboard does a number of unfriendly things, such as mess-up my STARTUP, my key
assignments, or even FREEPORT memory I do not want FREEPORTED, if I do not have
KEYBOARD LEX in my machine.

Still, it is nice to have mass storage and printers at work, by way of HPILLINK
and the IBM XT in my department. Being able to share data stored in my HP-71
using the HPILLINK /C option helps keep my bosses happy with my HP-71. Hence,
the routines below.

NOTE: LINK 1.02 (Southern Software) provides similar capabilities. I hear there
soon will be a new version called LINK PLUS, with many interesting features.
I use LINK 1.02 rather than HPILLINK if I want to use the PC as a printer or
as a video interface for my HP-71. 
   
The first program is intended to upload or download a single file at a time,
from the HP-71 keyboard. Before using this program, you must run the
HPILLINK.EXE program on the PC, and connect the HP-71 to the PC HP-IL port.

When you download a file, you must provide the full file name, such as:
JUNK.TEX

When you upload a file, the program will automatically supply the correct file
extension if you have the FTYPE$ keyword available. See source code below.
If not, the extension will be left blank, and you will have to RENAME the file
from the PC keyboard if you want the correct extension.

The file transfer takes little or no time. Once done, disconnect the HP-71,
exit HPILLINK with the F8 key, and do whatever you desire with either the PC or
the HP-71. Enjoy! 


0010 ! PC71EX - Transfer HP71 files between a PC and an HP71 with HPILLINK
0020 ! Copyright Michael Markov 1988
0030 ! 
0040 ! Uses FTYPE$ keyword from DATACOM ROM - See FLTYPELXS for source
0050 ! This is required if you want to provide the proper file extension
0060 ! when uploading files to an IBM PC via HPILLINK /HP82973 Interface card
0070 ! or to an HP110 running HPILLINK.
0080 ! 
0090 ! If you do not have the FTYPE$ keyword, comment-out the line 300 :
0100 ! 300 T$=FTYPE$(F$)
0110 ! 
0120 ! The advantage of this program is that it allows file transfers without
0130 ! messing-up your favorite STARTUP, your key assignments, or FREEPORTing
0140 ! stuff you may not want free-ported. This was developed when I started
0150 ! to make heavy use of my HP110 to edit HP71 source code files, which I
0160 ! then assembled using the AREUH (PPC-Paris) assembler-linker before 
0170 ! downloading the resulting LEX for testing in the HP71. I had no need for
0180 ! an external keyboard since the EDITOR I use on my HP110 is considerably
0190 ! faster than EDTEXT, and provides more flexibility.
0200 ! 
0210 LOCAL @ DISP 'Up or Download?(U/D)'
0220 A$=UPRC$(KEYWAIT$) @ IF A$='D' THEN 240
0230 IF A$='U' THEN 280 ELSE 210
0240 LOCAL @ INPUT 'DOWNLOAD FILE? ';F$ @ IF F$='' THEN END 
0250 P=DEVADDR(':PC')
0260 SEND UNT TALK P DDT 0 UNT MTA LISTEN P DATA F$ EOL 
0270 COPY :P @ GOTO 240
0280 INPUT 'Upload file? ';F$ @ IF F$='' THEN END 
0290 P=DEVADDR(':PC') @ T$=''
0300 T$=FTYPE$(F$)[1,3] ! comment out if FTYPES keyword not available
0310 SEND UNL LISTEN P MTA DDL 0 DATA F$,'.',T$,10 
0320 COPY F$ TO :P @ GOTO 280

The second program is a minor variant of the PC71EX program given above. It
allows you to upload or download ROM images just as if the PC was an HPIL disk
drive. There is one interesting difference: the file stored on the DOS disk will
take less space than on HPIL mass storage. Apparently, HPILLINK and ROMCOPY
version RCPY:E were designed to work together better than the mass storage
option! Here, we see the advantages of an intelligent mass storage device.

0010 ! PCROM - Transfer HP71 ROM images between a PC and an HP71 with HPILLINK
0011 ! and ROMCOPY LEX.
0020 ! Copyright Michael Markov 1988
0030 ! 
0040 ! This program is a slightly modified version of PC71EX, elsewhere on this
0041 ! swapdisk. See PCCOMM for documentation.
0042 ! 
0210 LOCAL @ DISP 'Up or Download?(U/D)'
0220 A$=UPRC$(KEYWAIT$) @ IF A$='D' THEN 240
0230 IF A$='U' THEN 280 ELSE 210
0240 LOCAL @ INPUT 'DOWNLOAD FILE? ';F$ @ IF F$='' THEN END 
0241 INPUT 'To :PORT(#)? ','5';N
0250 P=DEVADDR(':PC') @ IF NOT POS(F$,'.ROM') THEN F$=F$&'.ROM'
0260 SEND UNT TALK P DDT 0 UNT MTA LISTEN P DATA F$ EOL 
0261 X=POS(UPRC$(F$),'.ROM') @ F$=F$[1,X-1]&':'&STR$(P)
0270 ROMCOPY F$ TO ':PORT('&STR$(N)&')' @ GOTO 240
0280 INPUT 'Upload file? ';F$ @ IF F$='' THEN END 
0281 INPUT 'From :PORT(#)? ','5';N
0290 P=DEVADDR(':PC') @ X=POS(UPRC$(F$),'.ROM') @ IF X THEN F$=F$[1,X-1]
0310 SEND UNL LISTEN P MTA DDL 0 DATA F$,'.ROM',10 
0320 ROMCOPY ':PORT('&STR$(N)&')' TO :P @ GOTO 280

The last program allows you to upload many files to the PC, under the control
of an HP-71 program. I have used it to transfer entire swapdisks to my HP110,
for friends that have HP-71 machines and PC's, but not HP9114 drives. They then
read the disks as best they can. I understand that there is a new package from
Personalized Software called READHP, that allows IBM machines to read 3.5" disks
formatted by HP machines.

It should be possible to download files from the PC with a PCTODISK program,
just as easily as you can upload entire disks. The easiest approach would be
to start things going by creating a TEXT file with all the desired filenames
and extensions with the DIR A: >DIR.TEX. Then use PC71EX to download the file,
and let your HP-71 control the download to an HPIL mass storage device. I have
not needed to do this, since I am not (as of this date) getting any
contributions on DOS disks. However, if HP abandons HPIL, this may be the only
way to have peripherals for our HP41/HP75/HP71 computers, may they last many
years. (Have you purchased a spare HP-71 yet? NO? Why?).

NOTE: PCTODISK does not yet exist, except as an idea. It is one of my many
'to do sometime' projects.

Anyways, easy PC<==>HP71 communications will greatly ease the transition to the
world of DOS/OS2 machines, where instead of HP BASIC you will be forced to learn
PASCAL, C, MEGA BASIC or QUICK BASIC if you want to do any serious programming.
   
Obvioulsy, the PC must be running HPILLINK, and the default drive to which 
HPILLINK writes the files should be as empty as possible. Load HPILLINK with
A:HPILLINK, then replace the disk in the default drive (usually A:) with a
newly formated disk. On the HP71, run DISKTOPC. When the program stops, replace
the disk in the default drive, and run DISKTOPC on the HP71 to continue the
upload.

NOTE: Do NOT purge the temporary directory file (default DIRFL), except at the
start of the upload, before the first file is transfered. This allows the PDIR
keyword (JPCROM) to create a new file that contains all the information you need
to upload the disk. The HP-71 automatically deletes file entries as the upload
goes on. Any time the DISKTOPC program stops, you can LIST DIRFL to find out
how many files still ave to be uploaded.

Note that the program polls the PC to determine whether the remote load failed
for any reason, such as no space remaining available on the PC. This program is
intended to be used in conjunction with a video interface on the HPIL loop.

The program uses JPCROM to create a directory listing of the disk to be
uploaded to the PC. This is by far the most convenient way. Among other things,
JPCROM implements a poll handler that allows your HP-71 to identify HP-41,
HP-75 and other non-HP71-standard file types. This allows you to tag the file
names to help identify the contents of the file. HPILLINK does not recognize
HP-41 or HP-75 file types. In fact, it does not recognize all HP-71 file types,
atleast, not the version I have (Maybe revision E does better, but I do not have
that yet. 

It should be obvious that minor changes to line 240 allow uploading only HP-71
files, or only HP41 files, etc, should you so desire.

0010 ! DISKTOPC - UPLOAD FILES TO PC WITH HPILLINK
0020 ! This program is available, at least in concept, in the HPILLINK
0030 ! documentation. It implements the task in a way that helps minimizes
0040 ! user intervention. It was written to facilitate uploading Swapdisks
0050 ! to an IBM PC equipped with an HPIL interface card.
0060 ! 
0070 ! Since the HP71 is the controller, you can have a disk drive on the loop,
0080 ! and copy each file from the drive to the IBM PC, using a minimum of
0090 ! HP-71 memory.
0100 ! JPCROM REQUIRED. IF NOT AVAILABLE, CREATE DISK DIRECTORY LISTING WITH
0110 ! SOME BASIC ROUTINE SUCH AS DIR71
0120 CONTROL ON @ RESET HPIL @ RESTORE IO @ DISPLAY IS :DISPLAY
0130 INPUT "Which drive? ";D
0140 P=DEVADDR('%16('&STR$(D)&')')
0150 INPUT 'temp. file? ','DIRFL';F$
0155 ON ERROR GOTO 161
0160 PDIR :P TO F$ @ GOTO 169
0161 OFF ERROR @ DISP ERRM$;'Purge? (Y/N)'
0162 A$=UPRC$(KEYWAIT$) @ IF A$='Y' THEN PURGE F$ @ GOTO 155
0169 OFF ERROR @ ASSIGN #1 TO F$ @ RESTORE #1
0180 DIM A$[60] @ D=DEVADDR(':PC') @ STANDBY ON @ REMOTE 
0190 FOR I=0 TO FILESZR(F$)-1 @ READ #1;A$ @ DISP I;A$
0200 IF SPOLL(D)#5 THEN 270
0210 F$=TRIM$(A$[1,10])
0220 T$=TRIM$(A$[14,19])[1,3]
0230 IF T$='41:' OR T$='75:' THEN G$=F$&T$[1,2] @ T$='UNK' ELSE G$=F$
0240 SEND UNL LISTEN D MTA DDL 0 DATA G$,'.',T$,10 
0250 COPY F$&':'&STR$(P) TO :D
0260 NEXT I
0270 LOCAL @ DISP 'HP110 Drive A full-delete last file copied'
0280 READ #1,I-2;A$ @ DISP 'last file copied: ';I-2;A$
0281 FOR J=I-2 TO 0 STEP -1 @ DELETE #1,J @ NEXT J
0290 STANDBY OFF @ CONTROL OFF @ END 

       LEX    'FTYPELEX'  LEX file name
       TITLE  FTYPELEX, File type LEX,  Samuel H Chau [242]
*
       ID     #F6         compatible with DCLEX in DATACOMM ROM
       MSG    0           no message table
       POLL   0           no poll handler
*
       ENTRY  FTYPE
       CHAR   #F          string function
*
       KEY    'FTYPE$'    Syntax: FTYPE$('file specifier') or
*                                 FTYPE$(assign channel #)
*                         Returns file type as a 5-char string
*                         Null string returned if file not found
*                         Example:  FTYPE$('FORTHRAM') returns FORTH
       TOKEN  1
       ENDTXT             end of text table
************************
*      **** EQUate Table ****
*
AVE=D1 EQU #18BB8 update AVMEME from D1 or C
BSERR  EQU #0939A BASIC system error
D0=AVS EQU #09B2C set D0 to address in AVMEMS
D1MSTK EQU #1954E set D1 at MTMSTK (AVMEME)
FDCH#  EQU #114AC find channel # in assign table
FFIB#  EQU #122EF find file number in FIB
FILXQ$ EQU #09B95 filename execute for a string expression
FINDF  EQU #09F77 find a file
FLTDH  EQU #1B223 convert 12-digit flt to HEX integer
FNRTN  EQU #0F23C function return
FTYPDC EQU #06902 file type decompile
FUNCR0 EQU #2F89B function scratch RAM start
POLL   EQU #12337 poll LEX files with process #
POPMTH EQU #1B3DB skip past item on MATH stack
RSTK<R EQU #014A8 restore RSTK level(s) from RSTKBF buffer
R<RSTK EQU #014DD save RSTK level(s) into RSTKBF buffer
STRHED EQU #14C2E generate string head on stack
pFINDF EQU #00017 poll to find a file
pFSPCx EQU #00005 poll to execute file specifier
eFSPEC EQU #0003A invalid filespec error
*
************************
*
       NIBHEX C11    one string or numeric parameter
FTYPE  CD0EX
       RSTK=C        save D0 (PC) on return stack
       GOSBVL R<RSTK save RSTK level(s)  [P=0]
       A=DAT1 W      get top of MATH stack in A
       LCHEX  A      load C:0 for parameter type check
       ?C>A   P      integer parameter?
       GOYES  FTYP03 yes: interpret as channel #
       A=A+1  P
       ?A#0   B      not string parameter?
       GOYES  FTYP01 yes: parameter is invalid
       GOTO   FTYP09 no: interpret string as file specifier
FTYP01 LC(4)  eFSPEC load Invalid filespec error
FTYP02 GOVLNG BSERR  BASIC error exit
FTYP03 D1=D1+ 16     pop integer argument off MATH stack
       GOSUB  ave=d1 update stack top pointer
       GOSBVL FLTDH  convert 12 form channel # to HEX integer
       B=A    B      put HEX form in B for FDCH#
       GOSBVL FDCH#  find channel # in assign table
       GONC   FTYP08 not found: ready for exit
       ?A=0   B      channel closed? no: A(B)=FIB#
       GOYES  FTYP08 yes: punt!
       GOSBVL FFIB#  find file # in FIB
       GOC    FTYP08 not found? yes: punt! no: D1 @ file # in FIB
       D1=D1+ 5      advance to file type entry in FIB
FTYP04 GOSBVL D0=AVS set D0 to AVMEMS
       C=0    W      preclear C
       DAT0=C W      blank out word at AVMEMS
       D0=D0+ 2      point past one null
       GOSBVL FTYPDC get file type (5 chars), D0 points past it
       GOSUB  d1mstk set D1 to AVMEME
       GOSBVL D0=AVS set D0 to AVMEMS
       C=DAT0 W      get file type in C
       ?C=0   B      not at file type string?
       GOYES  FTYP06 yes: move pointer down
FTYP05 ?C=0   B      end of file type string?
       GOYES  FTYP07 yes: ready for string return
       D1=D1- 2      point D1 down 1 char
       DAT1=C B      push one ASCII char onto stack
FTYP06 CSR    W
       CSR    W      shift to next char in file type string
       GOTO   FTYP05 continue building string on stack
FTYP07 GOSBVL STRHED generate string header on stack
       GOSBVL RSTK<R restore RSTK level(s)
       C=RSTK
       CD0EX         restore D0 (PC) from RSTK
       GOVLNG FNRTN  function return
FTYP08 GOSUB  d1mstk set D1 to AVMEME
       GOTO   FTYP07 return with string
FTYP09 GOSUB  ave=d1 update stack top pointer
       C=DAT1 W      read string header into C
       CSR    W
       CSR    W      shift to string length field
       ?C=0   A      null string?
       GOYES  FTYP08 yes: ready for return
       GOSBVL FILXQ$ execute tokenized file specifier
       P=     0
       LCASC  '  '   load C with 2 ASCII spaces
       R0=C          save in R0
       GOC    FTYP16 file specifier is mainframe recognizable
       GOSBVL POLL   illegal: issue file spec execution poll
       CON(2) pFSPCx file specifier execute poll
       GOC    FTYP13 error return from poll: error exit
       ?XM=0         pFSPCx poll handled? 
       GOYES  FTYP10 yes: continue
       GOTO   FTYP01 no: Invalid filespec error
FTYP10 C=R0          last 2 chars of filename into C
       R1=C          save in R1
       R0=A          filename (blank filled) into R0
       GOSUB  d1mstk set D1 to stack top
       GOSBVL POPMTH skip past current item on stack
       GOSUB  ave=d1 update stack top pointer
       GOSBVL POLL   issue poll to find file
       CON(2) pFINDF file finder poll
       GONC   FTYP11 no error: continue
       A=C    A      save C in A
       LCHEX  16     load C with HPIL File not found error #
       ?A=C   B      file not found on HPIL mass storage?
       GOYES  FTYP12 yes: ready for return
       C=A    A      restore C from A
       GONC   FTYP13 B.E.T.
FTYP11 ?XM=0         pFINDF poll handled?
       GOYES  FTYP14 yes: continue
FTYP12 GOTO   FTYP08 no: ready for return
FTYP13 GOTO   FTYP02 load BASIC error returned from LEX file
FTYP14 D1=(5) FUNCR0 set D1 to function scratch RAM
       C=R0
       DAT1=C W      put file attributes into function scratch RAM
       D1=D1+ 11     advance to file type field
FTYP15 GOTO   FTYP04 go find file type
FTYP16 GOSUB  ave=d1 update stack top pointer
       GOSBVL FINDF  find the file
       GOC    FTYP12 not found: ready for return
       D1=D1+ 16     move to file type field in file header
       GONC   FTYP15 B.E.T.
ave=d1 GOVLNG AVE=D1
d1mstk GOVLNG D1MSTK
       END
@EOF
set `wc -lwc <areuh/doc/compc.doc`
if test $1$2$3 != 339269816177
then
	echo ERROR: wc results of areuh/doc/compc.doc are $* should be 339 2698 16177
fi

chmod 644 areuh/doc/compc.doc

echo x - areuh/doc/areuh110.doc
cat >areuh/doc/areuh110.doc <<'@EOF'
			 USING AREUH WITH A HP110

		      Michael Markov (PPC Paris 301)


Using AREUH with an HP110 presents a variety of problems, most of which are 
related to the fact that AREUH requires about 200+K of memory to run. This leaves
you with 70K of EDISC for your source code, intermediate files, listing files,
and anything else you may feel you absolutely have to have, such as ED110, in
case you need to edit the source file, or HPILLINK to upload and download LEX
files.... Keep in mind that listing files are roughly twice the size of source
files, and that the object file takes some room. Needless to say, this means
that you cannot keep the 150K byte AAS.EXE program in the A: drive.

Therefore, HP100 owners who still want to use AREUH for serious work must resign
themselves to loading AAS.EXE from disk each time they wish to assemble a LEX
file. Worse, unless they are working with source files of 20K or less, they must
also resign themselves to either sending the listing file to a disk file, or to
a printer. Either approach means that execution time is much slower than you
would expect from the AREUH documentation. Still, my HP110 and AREUH allow me to assemble a 42K source code files about 4 minutes, while my
HP71 requires over half an hour to do the same job, in spite of a 1.9 times
speed-up. (Yes, I am considering the purchase of a 512K base Portable Plus with
a 1 or 2 Meg RAM card, but considering the cost, maybe I would be better off
with a full-size desk top machine.)

Let me hasten to say that 20K source files are quite sufficient for individual
keywords. Assembling such small files is unbelievably fast, and very convenient
for debugging sessions. You will have few problems assembling such files using
either the compatibility mode or the modular mode. However, source code files
show a definite tendency to grow: TXTSORTS, once less than 13K, is now 42K. TKS,
the source for DISASMLX, grew to 77K from similar beginnings. The following
material describes the work-arounds I developed to allow me to assemble such
source files more or less painlessly.

Since the major space and memory waster is saving the listing file, you must ask
yourself whether you need a listing file. In the compatibility mode, you can use
the LIST OFF and LIST ON keywords to suppress the listing file for portions of
the files that you have already assembled successfully in previous sessions.
For example, with the LIST OFF suppressing most of the TKS listing, DISASMLX
can be assembled in about two minutes. This is definitely worth taking advantage
of -- just list the portion of the source that includes any new keyword you add
to the file you are building. This will let you know if any jumps are out of
range, which is the most common problem when adding a new keyword to a file, 
assuming you have already tested and assembled the keyword separately. However,
there always comes the time when you need a complete listing for code-packing/
code review purposes. When this happens, I use the following procedure:

1)  If your source code file is more than 20K bytes long, prepare a work disk
    that contains ONLY HPILLINK, the source code and any symbol files you use,
    to include the entry point files found in the AREUH disk \LIB subdirectory.
    You should first format this disk, then copy the symbol files from AREUH to
    the work disk with   COPY C:\LIB\*.EP D: (If you have only one drive, first
    copy the files to the A: drive, then to the work disk. Next, copy any
    special Symbol files  to be loaded with RDSYMB. Finally, copy the source
    code file to the work disk. This may sound complicated, but if you use AREUH
    frequently, you will prepare several work disks in a single session, so that
    all you have to do in this step is add the source code. You can reuse such
    work disks at any time by simply deleting old source and listing files. Do
    not forget to add any special symbol files. When your souce file grows
    beyond the size that can be edited with MEMOMAKER, you may want to add your
    favorite EDitor software. While this limits the space remaining free for the
    source and listing files, it is very convenient.
    
    You should seriously consider breaking-up your larger source code files into
    smaller files (20K or less) that can be assembled from the A: drive, as
    execution time suffers badly when assembling the source from mass storage.
    The AREUH loader-linker will allow you to combine the resulting intermediate
    files into a single large LEX file. See WRITHEAD.BAS and WRITHEAD.DOC on the
    disk. These files help a lot when using the modular mode.

    If you do NOT use supported entry points, you can assemble source files of
    up to about 60K from the A: drive, since you do not need to have the entry
    point files in either the A: drive (current directory) or the C: drive...
 
2)  Format a blank 3.5" disk in drive C:
3)  Backup your HP110 with COPY *.* C:    (from MS-DOS)
4)  Delete all files except the source code file to be assembled, and PACK.COM.
    If the file is in excess of 30K or 60K (see step 1 above), delete everything
    except PACK.COM since you have to assemble the source from the work disk
    prepared in step 1 above.
NOTE: If you use AREUH frequently, you will already have back-up disks, and you
    need only back-up current work in progress.
5)  PACK the A: drive (Type PACK [Return]).
6)  You may now delete PACK.COM if you are real short of memory.
7)  EXIT MS-DOS, and press the f6 key (System Configuration).
8)  Increase the Memory allocation to 200+ Kbytes.
9)  Exit the configuration menu, and return to MS-DOS.
10) Replace the disk in your C: drive with the AREUH disk.
11) Copy any entry point files required from the C:\LIB subdirectory to the A:
    drive (unless these files are available on your work disk).
11) Load AAS.EXE with C:AAS - The interactive mode is a must if you have only
    one drive. Otherwise, you can use toggles documented in the README file to
    more or less duplicate what follows.
12) Once the interactive menu comes up, replace the AREUH disk with your work
    disk. This may be the work disk prepared in step 1, or the back-up disk
    created in step 2 and 3. This disk will be used to save the listing file.
13) Now, you are ready to respond to the prompts in the interactive menu:

                   Source in drive A:      Source in drive C:
    Source file :  TXTSORTS.TEX            C:TXTSORTS.TEX
    Object file :  TSORT                   TSORT             output to A: drive
    Listing File : C:LIST                  C:LIST            listing to disk
    Cross Reference: Y                     Y                 Yes, nice to have
    Page length :  88                      88                I use 8 lines per
             						     inch to save paper

While assembling version 7 of the above LEX, I got an object file of 3066 bytes
and a listing file of 74K bytes. The LEX itself, after conversion to HPILLINK
format with the AREUH A2LEX.EXE program and downloading to the HP71 was 1513
bytes long (TSORTLX7).

You can read the source from one external drive, direct the object file to the
same disk, while having the AREUH disk in a second drive, and send the listing
file to a third drive, assuming you can borrow one (I used a cassette drive to
check this.)  This flexibility should allows HP110 users to assemble LEX files
of up to 32K. 

14) I actually work with two disk drives, which simplifies things. I keep the
    AREUH disk in drive C: and the work disk in drive D:, so that I respond to
    the Listing file : prompt with  D:LIST. Minor difference that makes life
    somewhat easier.

15) Now, I look at the listing file using Ed Gilbert's Editor, which I keep on
    the work disk:  D:ED D:LIST     (EDit file LIST on drive D:). If you have
    only one drive, you may do the same using drive C:

16) If there are errors, edit the source file and go back to step 1. Otherwise,
    put the AREUH disk in drive C: and  execute the A2LEX program:

    C:A2LEX  TSORT    This creates a new file in HPILLINK format with the LEX
                      extension.

17) Finally, you are ready to download the LEX file to your HP71 using HPILLINK:
        
    D:HPILLINK (or, if you have only one drive, replace the AREUH disk with your
               work disk, and use C:HPILLINK)

18) See the PCCOMM file elsewhere on this disk to findout how to transfer files
    between your HP-17 and your HP110 with a minimum of effort.

NOTE: The HP-71 MAY REMAIN ON THE LOOP WHILE ALL OF THE ABOVE IS GOING ON,
PROVIDED THAT YOU FIRST EXECUTE  "CONTROL OFF".

WARNING: The HP110 may tell you that your drive has a bad unit if you try any
mass storage operation after the HP-71 has been the controller. This is because
the HP110 usually works with 512 byte mass storage sectors, while the HP71
normally uses 256 byte sectors. Reply Ignore to the problem prompt. Thereafter,
you should no longer have problems.           
@EOF
set `wc -lwc <areuh/doc/areuh110.doc`
if test $1$2$3 != 14815489013
then
	echo ERROR: wc results of areuh/doc/areuh110.doc are $* should be 148 1548 9013
fi

chmod 644 areuh/doc/areuh110.doc

exit 0

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:32:56 1990
#
# This archive contains:
#	areuh/equ/sasm.ep	areuh/equ/hp71.ep	
#	areuh/equ/hpil.ep	areuh/equ/Makefile	
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - areuh/equ/sasm.ep
cat >areuh/equ/sasm.ep <<'@EOF'
=xromFF	00095
=xZERO	0001C
=xVARS	0005B
=xROUND	0004C
=xPOS	00042
=xPCRD	0003E
=xNEG	0003D
=xNEAR	0003C
=xMATH	00036
=xINTO	0002E
=xFLOW	00029
=xEXTND	00026
=xCLOCK	00015
=xANGLE	00006
=uTEST	0D435
=uSTRPT	000D0
=uRND>P	0C9CF
=uRESXT	0C9C1
=uRESTP	000F1
=uRESNX	0C9BD
=uRESD1	0E1EE
=uRES12	0C994
=uOPNWM	000E0
=uOPNNM	000D8
=uOPNM-	000DF
=uNUMNs	000F9
=uNUMNn	000F8
=uNUMFs	000FB
=uNUMFn	000FA
=uNUMEs	000FD
=uNUMEn	000FC
=uMULT	000D1
=uMODES	0BDB1
=uLOOPS	000D3
=uLOOPP	000EF
=uLOOPB	000D2
=uJMP{}	000D9
=uJMPst	000DA
=uJMPdl	000DB
=uIMsta	000DE
=uIMend	000F0
=uIMbck	000DC
=uIMXCH	000D4
=uHKB^	000F6
=uDELIM	000F4
=uCPLXC	000EE
=uALit	000F7
=t^	00080
=tZERO	C01EF
=tZ	0005A
=tXWORD	000EF
=tXFN	000B3
=tWAIT	000D8
=tVARS	B01EF
=tVAL	000A5
=tUSING	000FD
=tUSER	000E2
=tUPRC$	000AB
=tUNF	000B0
=tTRACE	000EA
=tTO	000F3
=tTIMER	000E4
=tTIME$	00095
=tTIME	0007B
=tTHEN	000F4
=tTAN	00098
=tTAB	000F7
=tSVAR	0002D
=tSUB	000C1
=tSTR$	000A6
=tSTOP	000D9
=tSTEP	000F6
=tSTAT	000CE
=tSQR	00092
=tSMALL	00011
=tSIN	00096
=tSHORT	000CB
=tSGN	000A1
=tSFLAG	000FB
=tSEMIC	000F2
=tSDEV	0009E
=tRUN	000FE
=tROUND	C01EF
=tRND	000A0
=tRMD	0006D
=tRFILE	000DE
=tRETRN	000DB
=tRESTR	000DE
=tRES	0007F
=tREM	000E6
=tRELOP	0008A
=tREAL	000BC
=tREAD	000C7
=tRDIAN	000D4
=tRAD	0006E
=tPURGE	000EB
=tPRMST	000F3
=tPRMEN	000F8
=tPRINT	000CD
=tPREDV	0009F
=tPOS	201B3
=tPORT	000D1
=tPI	00079
=tPCRD	E01EF
=tPAUSE	000D7
=tOVF	000AF
=tOR	0008D
=tOPT'N	000ED
=tON	000E0
=tOFF	000E1
=tNUM	000A3
=tNOT	00081
=tNEXT	000C4
=tNEG	D01EF
=tNEAR	C01EF
=tNAME	000BD
=tMOD	00074
=tMIN	000AC
=tMEAN	0009D
=tMAXRL	0006C
=tMAX	000AD
=tMATH	601EF
=tMAIN	000D2
=tLR	000B6
=tLPRP	000AA
=tLOG10	00093
=tLOG	00090
=tLN	00091
=tLITRL	000C4
=tLIST	000BB
=tLINPT	000BF
=tLINE#	0000F
=tLET	000C0
=tLEN	000A9
=tLBLST	000F6
=tLBLRF	0000E
=tKEYS	000CF
=tKEY$	00073
=tKEY	000E5
=tIVL	000AE
=tISUB$	000A7
=tIS	000E7
=tIP	0006A
=tINX	000B2
=tINTR	015FF
=tINTO	E01EF
=tINTEG	000CA
=tINT9	00005
=tINT8	00006
=tINT7	00007
=tINT6	00008
=tINT5	00009
=tINT4	0000A
=tINT3	0000B
=tINT2	0000C
=tINT12	00002
=tINT11	00003
=tINT10	00004
=tINT	0009C
=tINPUT	000C9
=tINF	00070
=tIN	000F2
=tIMAGE	000FF
=tIF	000DF
=tGOTO	000DD
=tGOSUB	000DC
=tFP	0006B
=tFOR	000C3
=tFN	0007C
=tFLT9	00015
=tFLT8	00016
=tFLT7	00017
=tFLT6	00018
=tFLT5	00019
=tFLT4	0001A
=tFLT3	0001B
=tFLT2	0001C
=tFLT12	00012
=tFLT11	00013
=tFLT10	00014
=tFLT1	0001D
=tFLOW	901EF
=tFFN	000B4
=tFETCH	000C8
=tFACT	000A8
=tEXTND	601EF
=tEXTIF	000F4
=tEXP	00094
=tEXOR	0008C
=tERROR	000E3
=tERRN	00076
=tERRL	00075
=tEPS	00071
=tEOL	000F0
=tENTER	4FFEF
=tENDSB	000C2
=tENDDF	000BA
=tEND	000DA
=tELSE	000F5
=tEDIT	000B8
=tDVZ	000B1
=tDSTRY	000BE
=tDMYAR	0007E
=tDIV	00086
=tDISP	000C5
=tDIM	000CC
=tDELET	000B7
=tDELAY	000D6
=tDEGRE	000D3
=tDEG	0006F
=tDEF	000B9
=tDATE$	00078
=tDATE	00077
=tDATA	000C6
=tCVAL	000E1
=tCOS	00097
=tCOPY	000B5
=tCOMMA	000F1
=tCOLON	000E2
=tCMPLX	0007A
=tCLOCK	501EF
=tCHR$	000A4
=tCFLAG	000FA
=tCEIL	00072
=tCAT	000EC
=tCARD	000D0
=tCALL	000F9
=tBIG	00010
=tBEEP	000E8
=tBASE	000E9
=tAUTO	000EE
=tATAN	0009B
=tASIN	00099
=tARRAY	0007D
=tANGLE	601B3
=tAND	0008B
=tALL	000F8
=tADIG9	00069
=tADIG8	00068
=tADIG7	00067
=tADIG6	00066
=tADIG5	00065
=tADIG4	00064
=tADIG3	00063
=tADIG2	00062
=tADIG1	00061
=tADIG0	00060
=tADD	000D5
=tACOS	0009A
=tABS	000A2
=t@	000F4
=t/	00084
=t-	00082
=t+	00087
=t*	00083
=t&	00089
=t%	00085
=t!	000FC
=sXWORD	00009
=sXQT	00000
=sXCPT	00004
=sUNDEF	00001
=sSpecl	00006
=sSTOP	00005
=sSTAT	00006
=sSSTdc	00001
=sSST	00002
=sSIGN	00009
=sRUNDC	00007
=sRUNBn	00004
=sRFILE	00008
=sRETRN	00000
=sRESTR	0000A
=sRENUM	00008
=sRENAM	00006
=sREADI	00004
=sRDX	0000B
=sRAD	00009
=sPRGCF	0000B
=sPCRD	00008
=sONTMR	00006
=sONERR	00004
=sNoChn	00002
=sNEGRD	0000B
=sMULT	00008
=sMAINc	00005
=sKEYS	00005
=sInit	00003
=sIX	00007
=sIRAM	00002
=sINX	00005
=sINFRD	0000A
=sI/OBF	0000A
=sGOSUB	00003
=sFOUND	0000A
=sEXTGS	00005
=sEXTDV	00000
=sERROR	00000
=sEOF	00007
=sENDx	00001
=sDEST	00003
=sCplxP	00007
=sCntg	00002
=sCURUP	00002
=sCURUD	00004
=sCURBT	00003
=sCONTK	00009
=sCONT	0000A
=sCHAIN	0000B
=sCARDC	00008
=sCARD	00002
=sC/P	00001
=sBYEx	00000
=sARITH	00007
=pZERPG	000F7
=pWTKY	0001C
=pWRCBF	0001A
=pWCRD8	00024
=pWCRD	00035
=pWARN	000F3
=pVER$	00000
=pTRFMx	0003C
=pTRANS	000EF
=pTIMR#	0003B
=pTEST	000F0
=pSysFn	00044
=pSREQ	000F9
=pSREC#	00028
=pRUNnB	00031
=pRUNft	00030
=pRTNTp	0003A
=pRNAME	00011
=pREN	00039
=pREAD#	00027
=pRDNBF	00019
=pRDCBF	00018
=pRCRD	00034
=pPWROF	000FC
=pPURGE	00010
=pPRTIS	0000F
=pPRTCL	0000E
=pPRIN#	00026
=pPRGPR	00032
=pPARSE	000F4
=pMRGE2	0002F
=pMNLP	000FA
=pMERGE	0000D
=pMEM	000F1
=pLIST2	0002E
=pLIST	0000C
=pKYDF	0001B
=pIMcpw	00022
=pIMcpi	00021
=pIMbck	00020
=pIMXQT	0001D
=pIMXCH	0001F
=pIMCHR	0001E
=pFTYPE	0002D
=pFSPCx	00005
=pFSPCp	00004
=pFPROT	0000B
=pFNOUT	0003E
=pFNIN	0003D
=pFINDF	00017
=pFILXQ	00003
=pFILDC	00002
=pFASCH	0002C
=pExcpt	000F8
=pERROR	000F2
=pEOFIL	00025
=pENTER	00012
=pEDIT	0002B
=pDSWNK	000FE
=pDSWKY	000FD
=pDIDST	0000A
=pDEVCp	00001
=pDATLN	0002A
=pCURSR	00029
=pCRT=8	00023
=pCREAT	00009
=pCRDAB	00033
=pCOPYx	00008
=pCONFG	000FB
=pCMPLX	00038
=pCLDST	000FF
=pCAT$	00007
=pCAT	00006
=pCALSV	00037
=pCALRS	00036
=pBSCex	000F6
=pBSCen	000F5
=oTXsod	00005
=oTIMEh	00016
=oSUBLn	00025
=oSPDn2	0000E
=oSPDTB	00111
=oSHLNb	00013
=oRTN3p	00014
=oRTN2p	0000F
=oRTN1p	0000A
=oRLENb	00034
=oRECLb	00024
=oREC#b	00020
=oPROTb	00009
=oPOL#p	0000A
=oMSGPT	00009
=oMAINT	0005D
=oLXsod	00005
=oKYsod	00005
=oIMPLh	00025
=oFTYPh	00010
=oFTYPb	00005
=oFT-FL	00010
=oFSIZb	00039
=oFNAMh	00000
=oFLSTr	00031
=oFLENh	00020
=oFLAGh	00014
=oFIL#b	00000
=oFBF#b	00002
=oFBEGb	0000D
=oDp	0002E
=oDLENb	0002E
=oDEVCb	0000C
=oDBEGb	00015
=oDAsod	0000D
=oDATEh	0001A
=oD1p	0001E
=oD0p	00019
=oCPOSb	00028
=oCOPYb	0000A
=oBSsod	00011
=oBPOSp	00005
=oBNsod	00011
=oAp	0003E
=oACCSb	0000B
=o41sod	00005
=lTIMEh	00004
=lTEXTp	00004
=lSPDn2	00001
=lSPDn	00001
=lSPDTB	0004E
=lSHLNb	00002
=lRTN3p	00005
=lRTN2p	00005
=lRTN1p	00005
=lRLENb	00005
=lRECLb	00004
=lREC#b	00004
=lPROTb	00001
=lPOLra	00006
=lPOLSV	0003E
=lPOLLp	00005
=lPOL#p	00005
=lMSGp	00004
=lLXTKR	00004
=lLXID	00002
=lLXFAD	00005
=lLXENT	0000B
=lLXADR	00005
=lFTYPh	00004
=lFTYPb	00004
=lFSIZb	00006
=lFNAMh	00010
=lFNAM8	00010
=lFNAM+	00004
=lFLENh	00005
=lFLAGh	00002
=lFILSV	00032
=lFILBF	00100
=lFIL#b	00002
=lFIB	0003F
=lFBF#b	00003
=lFBEGb	00006
=lEOL	00002
=lDp	00010
=lDLENb	00006
=lDEVCb	00001
=lDEVC	00005
=lDBEGb	0000B
=lDATEh	00006
=lD1p	00005
=lD0p	00005
=lCPOSb	00006
=lCOPYb	00001
=lBPOSp	00005
=lAp	00010
=lACCSb	00001
=kcVIEW	0000B
=kcUSEX	0000C
=kcUSER	00003
=kcUP	00012
=kcTOP	00014
=kcSST	00011
=kcRUN	0000F
=kcRT	00009
=kcOFF	00018
=kcLFT	00008
=kcLERR	0001A
=kcLC	00001
=kcLAST	00019
=kcI/R	00002
=kcGON	00016
=kcFRT	00006
=kcFLFT	00005
=kcEOL	0000D
=kcDOWN	00013
=kcCTRL	0000A
=kcCONT	00010
=kcCALC	00017
=kcBOT	00015
=kcBKSP	00007
=kcATTN	0000E
=kc-LIN	00004
=kc-CHR	00000
=k#VIEW	0006E
=k#USEX	000A5
=k#USER	0006D
=k#UP	00032
=k#TOP	000A2
=k#SST	00066
=k#RUN	0002E
=k#RT	00030
=k#OFF	00063
=k#LFT	0002F
=k#LERR	000A1
=k#LC	0006A
=k#LAST	000A4
=k#I/R	00069
=k#GON	0009B
=k#FRT	000A0
=k#FLFT	0009F
=k#EOL	00026
=k#DOWN	00033
=k#CTRL	0009E
=k#CONT	00070
=k#CALC	0006F
=k#BOT	000A3
=k#BKSP	00067
=k#ATTN	0002B
=k#3	00029
=k#2	00028
=k#1	00027
=k#-LIN	0006B
=k#-CHR	00068
=flVIEW	FFFCC
=flUSRX	FFFC6
=flUSER	FFFF7
=flUNF	FFFFB
=flTNOF	FFFCD
=flSUSP	FFFC1
=flSCEN	FFFF2
=flRTN	FFFD4
=flRPTD	FFFC5
=flRAD	FFFF6
=flQIET	FFFFF
=flPWDN	FFFCF
=flPRGM	FFFC2
=flPDWN	FFFEB
=flOVF	FFFFA
=flNZ8	FFFC8
=flNZ7	FFFC9
=flNZ6	FFFCA
=flNZ5	FFFCB
=flNZ4	FFFE8
=flNOPR	FFFE6
=flNOFN	FFFD6
=flNEGR	FFFF4
=flMKOF	FFFCE
=flLC	FFFF1
=flIVL	FFFF8
=flINX	FFFFC
=flINFR	FFFF5
=flFXEN	FFFF3
=flEXTD	FFFEA
=flEXAC	FFFD2
=flEOT	FFFE9
=flDVZ	FFFF9
=flDORM	FFFD5
=flDG3	FFFEC
=flDG2	FFFED
=flDG1	FFFEE
=flDG0	FFFEF
=flCTRL	FFFD0
=flCTON	FFFFD
=flCMDS	FFFD1
=flCLOC	FFFD3
=flCALC	FFFC0
=flBPLD	FFFE7
=flBEEP	FFFFE
=flBAT	FFFC3
=flBASE	FFFF0
=flALRM	FFFC4
=flAC	FFFC7
=fTEXT	00001
=fSOS	000CF
=fSDATA	0E0D0
=fROM	0E21C
=fMOS	0007F
=fLIF1	00001
=fLEX	0E208
=fKEY	0E20C
=fEOS	0006F
=fEOR	000EF
=fEOF	000FF
=fDATA	0E0F0
=fBIN	0E204
=fBASIC	0E214
=fASCII	00001
=fAOS	000DF
=ew/o	000EB
=enull	00000
=eZRO/0	00007
=eZRDIV	00008
=eXWORD	00023
=eXFNNF	00022
=eWRGNM	00049
=eWALGN	0005B
=eVFYER	00044
=eVARTY	00032
=eVALGN	0005C
=eUNORC	00014
=eUNKCD	00045
=eUNFLW	00001
=eUALGN	0005F
=eTUSLO	00048
=eTUFAS	00047
=eTRKOF	000E5
=eTRKDN	00061
=eTOOMI	00027
=eTOOFI	00028
=eTOO	000EF
=eTNINF	00004
=eTFWRN	00058
=eTFM	000F1
=eTFFLD	00038
=eSYSER	00017
=eSYNTX	0004B
=eSUBSC	0001C
=eSTROV	00025
=eSTMNF	0001E
=eSQR-	0000A
=eSPGNF	00031
=eSIGOP	00013
=eRwoGS	0002C
=eRWERR	00046
=eRECOR	0001D
=eRALGN	0005D
=eR1WRN	00057
=eR0WRN	00056
=eQUOEX	0004D
=ePULL	000F6
=ePRTCT	000F8
=ePROTD	00042
=ePRNEX	0004C
=ePRMIS	00024
=ePRCER	00054
=ePLLC#	00059
=ePLLC	0005A
=ePALGN	0005E
=eOVFLW	00002
=eOVFL*	000F5
=eNXwoF	0002B
=eNVSTA	00033
=eNUMIN	00026
=eNSVAR	00033
=eNOTIN	00043
=eNODAT	00020
=eNFOUN	000E8
=eNEG^X	00009
=eMSPAR	00052
=eMPI	00019
=eMMCOR	00017
=eMEM	00018
=eLOG-	0000D
=eLOBAT	00016
=eLN0	0000C
=eL2LNG	00041
=eIVTAB	00030
=eIVSTA	00034
=eIVSOP	00035
=eIVSAR	00033
=eIVARG	0000B
=eINX	00015
=eINVUS	0002E
=eINVST	000ED
=eINVLD	000EC
=eINVIM	0002D
=eINPUT	000F4
=eINF^0	00012
=eINF	000F3
=eIMGOV	0002F
=eILVAR	00053
=eILTFM	00037
=eILPAR	00051
=eILLEG	000E6
=eILKEY	00055
=eILEXP	00050
=eILCNT	0004F
=eIF/IF	0000E
=eIF-IF	0000F
=eIF*ZR	00010
=eFwoNX	0002A
=eFnFND	00039
=eFTYPE	0003F
=eFSPEC	0003A
=eFPROT	0003D
=eFOPEN	0003E
=eFNNtF	00021
=eFILE	000EA
=eFEXST	0003B
=eFACCS	0003C
=eF2BIG	0004A
=eEXPCT	000E7
=eEXP0	00003
=eEXCHR	0004E
=eEOFIL	00036
=eDVCNF	00040
=eDATTY	0001F
=eCHNL#	00029
=eCALGN	00060
=eALGN	000F0
=eAF	0001B
=e2MROM	0001A
=e1^INF	00011
=e0^NEG	00005
=e0^0	00006
=e#of#	000F7
=dPORT	00001
=dPCRD	00007
=dMAIN	00000
=dIRAM	00001
=dCARD	00007
=cRCL	00067
=cR->C	00069
=cC->C	00068
=bSTMXQ	00811
=bSTMT	00801
=bSTAT	00806
=bSTART	00808
=bSCRTC	00E00
=bROMTB	00BFE
=bPILSV	0080F
=bPILAI	00810
=bLEX	00BFC
=bIEXKY	00802
=bFLIO5	0080E
=bFLIO4	0080D
=bFLIO3	0080C
=bFLIO2	0080B
=bFLIO1	0080A
=bFILE	00805
=bFIB	00803
=bFBF#S	00BA0
=bFBF#E	00BCF
=bECOMD	00809
=bCHARS	00BFB
=bCARD	00807
=bASSGN	00804
=bALTCH	00BFB
=a9	00039
=a8	00038
=a7	00037
=a6	00036
=a5	00035
=a4	00034
=a3	00033
=a2	00032
=a1	00031
=a0	00030
=a.	0002E
=a'	00027
=a$	00024
=a"	00022
=a!	00021
=ZERBUF	18B20
=YX2-15	0D27A
=YX2-12	0D274
=YMDHMS	130DB
=YMDH01	130E5
=YMDDAY	13304
=XYEX	0C697
=XXHEAD	1A44E
=XROM01	00001
=XMTADR	08133
=XDelay	00009
=WSTRFX	138B5
=WRTSTR	1396F
=WRTNUM	139C4
=WRTFIB	11CEE
=WRITNB	1752B
=WRDSCN	02C2A
=WRDSC+	02C26
=WIPOUT	1B0AF
=WINDST	2F471
=WINDLN	2F473
=WFTMDT	085DD
=ValSub	0000A
=VRIABL	04BC4
=VIEWD1	15147
=VECTOR	2F43C
=VARP	0350E
=VARNBR	0E289
=VARNB-	0E28D
=VARDC	0537C
=VALCHK	1AE61
=VAL00	1AD8F
=USst05	1BBD4
=USst03	1BBCE
=USnm05	1BD12
=USloop	1C14B
=USINGp	03628
=USING	1B446
=USGrst	1BC63
=USGch-	1BC0B
=USGch+	1BC15
=USG*10	1B508
=UPDPC	07B58
=UPDANN	13571
=UPD2ST	2F674
=UPD2EN	2F6A6
=UPD1ST	2F55D
=UPD1EN	2F599
=UPCPOS	13C67
=UNP	00001
=UNFNIB	2F6FA
=TstEnd	1C0FF
=Trace	0000F
=TWO*	0DB38
=TST15	0D47A
=TST12A	0D476
=TRTO+	0FE7B
=TRTO*	0FEA9
=TRSFMu	16B84
=TRPREG	2F6F9
=TRMNTR	0F1DD
=TRKDON	1CFAC
=TRFROM	0FE59
=TRFMBF	2F8C5
=TRFLCK	0FE18
=TRC90	0DA11
=TRACEM	2F7B0
=TONE	0EBEB
=TODT	13229
=TMRIN3	2F6B6
=TMRIN2	2F6AE
=TMRIN1	2F6A6
=TMRAD3	2F6A1
=TMRAD2	2F69C
=TMRAD1	2F697
=TKSCN7	08A99
=TKSCN+	08A6B
=TIMOFS	2F763
=TIMLST	2F76F
=TIMLAF	2F77B
=TIMER3	2E1F8
=TIMER2	2E2F8
=TIMER1	2E3F8
=TIMAF	2F787
=TGSBS	2F5A3
=TFORN	2F59E
=TFHDLR	1702F
=TERCHR	2F97D
=TBMSG$	099AB
=TBLJMP	0242A
=TASTK	2F599
=TAN15	0D733
=TAN12	0D72F
=SetAVM	1B9FA
=SavLvl	00005
=SYSFLG	2F6D9
=SYSEN	2F58A
=SYNTXe	02E2B
=SWPBYT	17A24
=SVTRC	0FA35
=SVINFO	0845A
=SVINF+	08457
=SUBONE	0C327
=STUFF	1B0B2
=STSCR	0E92C
=STSAVE	2F6BE
=STRTST	1B1C7
=STRNGP	0379D
=STRHED	14C2E
=STRHDR	0F09A
=STRGCK	036BA
=STREQL	1B1EF
=STRASN	0F6B3
=STR$SB	18149
=STR$00	1815C
=STORE3	0F62F
=STORE	0F5F8
=STMTR1	2F881
=STMTR0	2F871
=STMTD1	2F896
=STMTD0	2F891
=STMBUF	090DF
=STMBCL	090E7
=STKVCT	1470C
=STKCMD	155ED
=STKCHR	18504
=STCD2	0D427
=STATSV	1732F
=STATRS	172F3
=STATAR	2F7AD
=STAB2	0D400
=STAB1	0D3D9
=SRLEAS	015EC
=SQRSAV	0D629
=SQR70	0C5C3
=SQR17	0C553
=SQR15	0C534
=SPLTAX	0E62B
=SPLTAC	0C934
=SPLITC	0C940
=SPLITA	0C6BF
=SPACE	0AD9D
=SNDWD+	17E1F
=SNAPSV	015A7
=SNAPRS	01571
=SNAPR*	01578
=SNAPBF	2F7F0
=SLEEP	006C2
=SKIPDC	057F6
=SIN15	0D71A
=SIN12	0D716
=SIGTST	0E636
=SIGCHK	0BD98
=SHRT	0F96C
=SHFRBD	0DB5F
=SHFRAC	0DB51
=SHFLAC	0DB46
=SHF10	0C486
=SFLAGT	13608
=SFLAGS	135FA
=SFLAGC	13601
=SFLAG?	1364C
=SETTMO	13158
=SETSB	0D641
=SETFMT	0F01F
=SETALR	12917
=SETALM	1290D
=SENDWD	17E15
=SENDIT	17DE3
=SENDEL	17DC1
=SEND20	17DFA
=SECHMS	13252
=SE1-10	04468
=SCRTCH	2F901
=SCRST0	2F901
=SCRPTR	2F966
=SCROLT	2F946
=SCRLLR	0212E
=SCREX3	2F971
=SCREX2	2F961
=SCREX1	2F951
=SCREX0	2F941
=SCOPCK	0915B
=SCNRT	022B9
=SCAN	04C40
=SB15S	0E19A
=SAVSTK	2F59E
=SAVGSB	0D64E
=SAVEXM	0D663
=SAVESB	0D66E
=SAVED0	1149A
=SAVD0	1C587
=SALLOC	0153B
=S-R1-3	2F890
=S-R1-2	2F88B
=S-R1-1	2F886
=S-R1-0	2F881
=S-R0-3	2F880
=S-R0-2	2F87B
=S-R0-1	2F876
=S-R0-0	2F871
=ResetC	00008
=RUNRTN	074EA
=RUNRT1	074E7
=RSTST	0F5C5
=RSTKBp	2F81F
=RSTKBF	2F820
=RSTK<R	014A8
=RSTD0	06832
=RST2<R	014A6
=RPTKY	152BA
=RPLSBH	1799B
=RPLLIN	013F7
=ROWDVR	2E350
=ROMFND	1102F
=ROMCID	00BFE
=RNSEED	2F6FE
=RNDNRM	0CAB1
=RNDAHX	136CB
=RND12+	0C9D5
=RND-12	1B01F
=RMD15	0C77E
=RJUST	12AE2
=RFUPD+	0A66E
=RFNBFR	2F57B
=RFAD-I	0A659
=RFAD--	0A652
=RFAD+I	0A702
=RFAD++	0A6FB
=REWIND	11365
=REVPOP	0BD31
=REV$	1B38E
=REST*	03035
=RESREG	2F7C2
=RESPTR	03172
=RESERV	2F986
=RESCAN	04A4C
=REPROM	18A1E
=RENSUB	1A753
=REM15	0C7D3
=RELJMP	05047
=REDUCE	15977
=RECALL	0F281
=RECADR	0F4B7
=READP5	0323B
=READNB	17518
=READIN	0F484
=RDTEXT	17489
=RDLNAS	13A1F
=RDINFO	0846B
=RDHDR1	076FD
=RDCHDR	076F0
=RDCHD+	076EE
=RDBAS	173FF
=RDATTY	17CC6
=RCVOFS	1C050
=RCSCR	0E954
=RCLW3	0E9C4
=RCLW2	0E9BE
=RCLW1	0E981
=RCL*	0E983
=RCCD2	0D41C
=RCCD1	0D3F5
=RAWBFR	2F580
=RANGE	1B07C
=RAMROM	0A5F7
=RAMEND	2F5B2
=R<RSTK	014DD
=R<RST2	014DB
=R4REV	1DBA8
=R3REV	153AB
=R3=D10	03526
=R2REV	0AA83
=R1REV	00785
=QUOTCK	0623D
=QUOEXe	02E8B
=PgmRun	0000D
=PWROFF	00526
=PWIDTH	2F958
=PUTRES	18115
=PURGDC	05745
=PUGFIB	12198
=PSHUPD	08F0D
=PSHSTL	08C85
=PSHSTK	08C7F
=PSHMCR	08F0B
=PSHGSB	08F13
=PRT#DC	06841
=PRSscn	1BA88
=PRSsc+	1BA84
=PRSC00	07B93
=PRPSND	06B17
=PRNTDC	05450
=PRNEXe	02E95
=PRMPTR	2F5B7
=PRMCNT	2F94B
=PRINTt	00001
=PRINT*	17F37
=PRGMST	2F562
=PRGMEN	2F567
=PRGFMF	0A146
=PRESCN	04A49
=PREP	0ADAF
=PPOS	2F956
=POPUPD	08F3E
=POPSTR	1B405
=POPSTK	08F55
=POPMTH	1B3DB
=POPBUF	010EE
=POP2N+	0BD58
=POP2N	0BC8C
=POP1S	0BD38
=POP1R	0E8FD
=POP1N+	0BD91
=POP1N	0BD1C
=POLLD+	1232D
=POLL	12337
=PNDALM	2F761
=PI/4	0DAA1
=PI/2D	0DB7A
=PI/2	0DB77
=PFNDZL	078E2
=PFINDL	078DF
=PEDITD	0FF62
=PEDIT	0FF5F
=PDEV	09E9E
=PCADDR	2F679
=PART3	18097
=PARERR	02F08
=P1-10	041C1
=OVP	00002
=OVFNIB	2F6FB
=OVFL	0CA73
=OUTVAR	0373E
=OUTRES	0BC84
=OUTNIB	02D28
=OUTNBS	05426
=OUTNBC	05423
=OUTLIT	036F3
=OUTLI1	03709
=OUTELA	05303
=OUTEL1	05300
=OUTC15	05421
=OUTBYT	02CE8
=OUTBY+	02CE5
=OUTBS	2F58F
=OUT3TK	02D15
=OUT3TC	02D12
=OUT2TK	02CFF
=OUT2TC	02CFD
=OUT1TK	02CEB
=OUT1T+	02CDF
=ORXM	0D633
=ORSB	0D63C
=ORGSB	0D65B
=OPENF	11B06
=ONTIMR	08008
=ONP40	02B7B
=ONINTR	2F68D
=ONDC20	05501
=OKP	00000
=OFFFLG	2F442
=OBEDIT	17687
=OBCOLL	01435
=OAGNXT	03060
=NwOFFS	1C02D
=NoCont	0000E
=NXTVAR	13E4C
=NXTVA-	13E58
=NXTSTM	08A48
=NXTP	03455
=NXTLIN	10031
=NXTIRQ	2F70D
=NXTEXP	1C2F7
=NXTELM	148AC
=NXTADR	147E8
=NUMSCN	04D18
=NUMCK	0369D
=NUMC+O	03696
=NUMC++	03690
=NULLP	07999
=NTOKNL	048E6
=NTOKEN	0493B
=NOSCRL	14C8A
=NORDIM	0AE2D
=NEEDSC	2F94A
=MVMEM+	0133C
=MULTF	0C446
=MTHSTK	2F599
=MTADR+	081A1
=MTADDR	08195
=MSPARe	02E5C
=MSN15	0D557
=MSN12	0D553
=MPY	0ECBB
=MPOP2N	0BD54
=MPOP1N	0BD8D
=MP2-15	0C43A
=MP2-12	0C432
=MP15S	0C440
=MP1-12	0C436
=MOVEUM	1B15C
=MOVEUA	1B168
=MOVEU4	1B174
=MOVEU3	1B177
=MOVEU2	1B172
=MOVEU1	1B16F
=MOVEU0	1B162
=MOVEDM	1B0EE
=MOVEDD	1B106
=MOVEDA	1B0FA
=MOVED3	1B109
=MOVED2	1B104
=MOVED1	1B101
=MOVED0	1B0F4
=MOVE*M	01308
=MOD15	0C796
=MLFFLG	2F870
=MGOSUB	1AF01
=MFWRQ8	093C3
=MFWRNQ	093C5
=MFWRN	093BC
=MFLG=0	13DA1
=MFERRS	0939E
=MFERR*	093F1
=MFERR	09393
=MFER42	0962C
=MESSG	0CC17
=MEMERX	0944F
=MEMERR	0944D
=MEMER*	0945B
=MEMCKL	012A5
=MEMBER	1B098
=MBOX^	2F7A9
=MAXCMD	2F976
=MAKEBF	01751
=MAKE1	0DACE
=MAINST	2F558
=MAINLP	002FD
=MAINEN	2F571
=MAIN30	0037E
=MAIN05	00338
=LXTXTT	1EE9F
=LXFND	0979D
=LSTLEN	06C27
=LSLEEP	006CD
=LOOPST	2F7AC
=LOCKWD	2F7B2
=LOCFIL	1721D
=LOCADR	0A611
=LNSKP-	089FF
=LNPEXT	02617
=LNEP66	027EA
=LN30	0CD9C
=LN15	0CD81
=LN12	0CD7D
=LN1+XF	0CD51
=LN1+15	0CD44
=LISTDC	05839
=LINP	02A07
=LINEP+	02626
=LINEP	02620
=LIN#DC	05115
=LIN#D+	05112
=LIN#AU	05122
=LIMITS	0AC3E
=LGT15	0D1AE
=LEXPTR	2F6CF
=LEXBF+	10DDF
=LEEWAY	000D4
=LEAVE	04C01
=LDSST2	04F9E
=LDSST1	04F72
=LDCSPC	2F6C1
=LDCSET	05060
=LDCOMP	04F69
=LDCM10	04F6F
=LDCEXT	04F5E
=LCDINI	00665
=LBLNIF	02A0D
=LBLNAM	077E7
=LBLINP	02A04
=LBLIN#	2F871
=LASTFN	000B4
=LABLDC	05702
=LABELP	03E9F
=KYDN?	00774
=KEYSCN	00D4D
=KEYSAV	2F462
=KEYRD	14E11
=KEYPTR	2F443
=KEYNAM	1AC04
=KEYMRG	08B8F
=KEYFND	08CB8
=KEYDEL	08D2C
=KEYCOD	1FD22
=KEYBUF	2F444
=KEY$	1ACA8
=KCOLD	2F462
=KCOLC	2F463
=KCOLB	2F464
=KCOLA	2F465
=KCOL9	2F466
=KCOL8	2F467
=KCOL7	2F468
=KCOL6	2F469
=KCOL5	2F46A
=KCOL4	2F46B
=KCOL3	2F46C
=KCOL2	2F46D
=KCOL1	2F46E
=KCOL0	2F46F
=Insert	00007
=InhEOL	00004
=IVVARe	02E66
=IVPARe	02E3F
=IVP	00004
=IVLNIB	2F6FD
=IVEXPe	02E35
=IVARG	0D749
=IVAERR	0E920
=ISRAM?	10192
=IS-TBL	2F78D
=IS-PRT	2F794
=IS-PLT	2F7A2
=IS-INP	2F79B
=IS-DSP	2F78D
=IOFSCR	1188E
=IOFND0	118C1
=IOBFST	2F571
=IOBFEN	2F576
=INXNIB	2F6F9
=INVNaN	0C65F
=INTRPT	0000F
=INTR50	000DB
=INTR4	2F400
=INTR28	000B9
=INTM	2F430
=INTGR	0F99B
=INTB	2F420
=INTA	2F410
=INPOFF	18B49
=INFR15	0C73D
=INF*0	0C607
=INBS	2F6C6
=INADDR	2F6D4
=IMxq27	1BB9C
=IMoffs	1BA58
=IMinit	1B88F
=IMerr	1B989
=IMentr	1B535
=IMGxq1	1BAAB
=IMD0-2	1BA21
=IMD0+2	1BA2D
=ILCNTe	02E70
=IF12A	0C739
=IDIVA	0EC6E
=IDIV	0EC7B
=I/ORES	118FF
=I/OFND	118BA
=I/OEXP	11A11
=I/OEX2	11A0F
=I/ODAL	11A41
=I/OCON	11920
=I/OCOL	11979
=I/OALL	1197D
=I/OAL+	1197B
=HXDCW	0ECB4
=HXDASC	05FF4
=HUGE	0B75D
=HTRAP	0CB2F
=HPSCRH	2F97F
=HNDLFL	0CBC9
=HMSSEC	13274
=HEXDEC	0ECAF
=HEXASC	17148
=HDFLT	1B31B
=HASH2	1B0A3
=HASH1	1B0A1
=GetEXP	1C086
=GTXT++	05192
=GTPTRX	14670
=GTPTRS	14636
=GTKYCD	08D92
=GTKYC+	08D9B
=GTFLAG	1365E
=GTEXT1	051A5
=GTEXT+	05199
=GTEXT	05079
=GSBSTK	2F5A3
=GOTOp	029F6
=GOTODC	0552E
=GOTO+	07A06
=GOTO	079FA
=GOSUBp	029F6
=GOSUB	079E9
=GNXTCR	03064
=GETVAL	0DAB2
=GETSTC	07726
=GETST-	07728
=GETST*	07716
=GETSA	0E551
=GETPRO	06BEE
=GETPR1	06BFB
=GETNAM	1A085
=GETMSK	01BBA
=GETDIM	0AD6B
=GETCON	0DAA3
=GETCH#	11427
=GETAVM	1864D
=GDISP$	1C3C7
=FUNCR1	2F8AB
=FUNCR0	2F89B
=FUNCD1	2F8C0
=FUNCD0	2F8BB
=FTYPF#	11059
=FTYPDC	06902
=FTBSCH	11093
=FSPECx	09F2D
=FSPECp	03CC5
=FSPECe	02F02
=FRange	0B46A
=FPOLL	1250A
=FORUPD	0A6AE
=FORSTK	2F59E
=FNRTN4	0F238
=FNRTN3	0F235
=FNRTN2	0F219
=FNRTN1	0F216
=FNPWDS	0D3C0
=FNDFCN	1A0A1
=FNDCLR	1DAEF
=FLTYPp	03E71
=FLTDH	1B223
=FLOAT	1B322
=FLIP8	0DB8D
=FLIP11	0DBAB
=FLIP10	0DB9C
=FLGREG	2F6E9
=FLDEVX	01154
=FLADDR	0126B
=FIXP	02A6E
=FIRSTC	2F47C
=FINLIN	18A3A
=FINITC	0CD0F
=FINITA	0CD03
=FINDLB	07786
=FINDL	0FFE4
=FINDF+	09F63
=FINDF	09F77
=FINDD0	023E0
=FINDA	023E3
=FIND	0F563
=FILXQ^	09B76
=FILXQ$	09B95
=FILSK+	06F1D
=FILFIL	011CE
=FILEP1	03EFC
=FILEP-	03F00
=FILEP+	03F07
=FILEP!	03F0F
=FILEP	03E9C
=FILEF	09FB0
=FILDC*	05759
=FILCRD	1C879
=FIBOFF	12132
=FIBADR	11457
=FIBAD-	11478
=FGTBL	00C9B
=FCSTRT	0E757
=FCHLBL	0782C
=FASCFD	110C3
=F-R1-3	2F8BA
=F-R1-2	2F8B5
=F-R1-1	2F8B0
=F-R1-0	2F8AB
=F-R0-3	2F8AA
=F-R0-2	2F8A5
=F-R0-1	2F8A0
=F-R0-0	2F89B
=Except	0000C
=EndNum	000E6
=EXPSKP	1A9AC
=EXPRDC	05922
=EXPR	0F23C
=EXPPLS	03FDC
=EXPPAR	03FD9
=EXPP10	03FE3
=EXPEXC	0F186
=EXPEX-	0F178
=EXPEX+	0F182
=EXP15	0CF5A
=EXF	0D5DF
=EXDCLP	0592E
=EXCPAR	187E8
=EXCHRe	02E81
=EXCAD+	08631
=EXACT	128B0
=EXAB2	0D40E
=EXAB1	0D3E7
=EX15S	0D5CE
=EX15M	0D5CA
=EX12	0D5C6
=EX-115	0CF48
=ESCSTA	2F47B
=ESCSEQ	023C1
=ERRSUB	2F683
=ERRRTN	074ED
=ERRM$f	09806
=ERRLCH	2F97C
=ERRL#	2F7EC
=ERRADR	2F688
=ERR#	2F7E4
=EOLXCK	05405
=EOLXC*	052EC
=EOLSTR	2F95B
=EOLSCN	08AA7
=EOLLEN	2F95A
=EOLDC	05402
=EOLCKR	02A7A
=EOLCK	02A7E
=ENDSUB	195A8
=ENDIMG	1C040
=ENDBIN	0764B
=ENDALL	0769A
=EFIELD	00000
=EDITWF	0A533
=EDIT80	0A5A5
=DZP	00003
=DXP100	0CF7F
=DWIDTH	2F94F
=DVZNIB	2F6FC
=DV2-15	0C4AC
=DV2-12	0C4A8
=DV15S	0C4B2
=DV15M	0C4AC
=DUSP30	035B1
=DUSP10	03655
=DSTRY*	0B0C9
=DSTRDC	05280
=DSPUPD	01ADA
=DSPSTA	2F475
=DSPSET	2F7B1
=DSPRST	02443
=DSPMSK	2F540
=DSPLIN	10127
=DSPLI+	1010F
=DSPFMT	2F6DC
=DSPDGT	2F6DD
=DSPCNO	09716
=DSPCNB	0971F
=DSPCNA	09721
=DSPCL?	020B6
=DSPCHX	2F674
=DSPCHC	01C3C
=DSPCHA	01C3E
=DSPBUF	09723
=DSPBFS	2F480
=DSPBFE	2F540
=DSP$00	185DB
=DSLEEP	0056D
=DROPDC	05470
=DRANGE	1B076
=DPVCTR	0AC50
=DPOS	2F94D
=DPART3	17EF8
=DPART2	17EA3
=DONNA	09656
=DMNSN	0AE39
=DIVF	0C4B8
=DISPt	00000
=DISPP	035A4
=DISPDC	05450
=DISINT	2F470
=DEST	0F7B0
=DELAYp	02AC6
=DELAYT	2F948
=DEFADR	2F967
=DECP	0328F
=DECHEX	1B2D2
=DEBNCE	00CF7
=DD3ST	2E104
=DD3END	2E160
=DD3CTL	2E1FF
=DD2ST	2E200
=DD2END	2E260
=DD2CTL	2E2FF
=DD1ST	2E300
=DD1END	2E34C
=DD1CTL	2E3FF
=DCRMNT	1C177
=DCPLIN	10108
=DCONTR	2E3FE
=DCHXW	0ECDC
=DCHXF	1B223
=DCHX=C	1B2D0
=DBLSUB	0DADD
=DBLPI4	0DAFC
=DAYYMD	13335
=DAY2JD	13407
=DATPTR	2F692
=DATLEN	0B584
=D=WORD	04C0E
=D=AVMS	1A460
=D=AVME	1A476
=D1MSTK	1954E
=D1MST+	13E21
=D1FSTK	1955D
=D1C=R3	03047
=D1=AVE	18651
=D12R0A	1BA3C
=D0ASCI	09833
=D0ASC+	0982C
=D0=PCA	09B37
=D0=FIB	13AC5
=D0=AVS	09B2C
=D0+2RD	13A32
=CurOff	00006
=Clear	00005
=CkLpNC	1B66D
=CkLoop	1B669
=CVUCW	03FBC
=CURTOP	10063
=CURSRU	1009A
=CURSRT	096C1
=CURSRD	100A4
=CURSOR	2F47E
=CURSFR	151D7
=CURSFL	151DF
=CURRST	2F55D
=CURRL	2F7E8
=CURREN	2F56C
=CURDVC	0A60B
=CURBOT	10059
=CSRC9	1B42F
=CSRC8	1B42C
=CSRC7	1B415
=CSRC6	1B418
=CSRC5	1B41B
=CSRC4	1B41E
=CSRC3	1B421
=CSRC2	1B424
=CSRC15	1B441
=CSRC14	1B43E
=CSRC13	1B43B
=CSRC12	1B438
=CSRC11	1B435
=CSRC10	1B432
=CSRC1	1B427
=CSPEED	2F977
=CSLC9	1B415
=CSLC8	1B42C
=CSLC7	1B42F
=CSLC6	1B432
=CSLC5	1B435
=CSLC4	1B438
=CSLC3	1B43B
=CSLC2	1B43E
=CSLC15	1B427
=CSLC14	1B424
=CSLC13	1B421
=CSLC12	1B41E
=CSLC11	1B41B
=CSLC10	1B418
=CSLC1	1B441
=CSL9R0	1BA0D
=CRTF	116C1
=CRLFSD	022A2
=CRLFOF	02296
=CRLFND	0229E
=CRFSB-	11664
=CRETF+	084C4
=CREATE	115A7
=CRDFIL	1D21D
=CR	2C000
=CPL#10	07887
=COUNTC	1C346
=COS15	0D725
=COS12	0D721
=CORUPT	09083
=COPYu	08269
=CONVUC	152AA
=CONFST	2F9E6
=CONF	10212
=CONCOM	0467E
=COMCK+	032AE
=COMCK	036CD
=COLLAP	091FB
=COLDST	00000
=CNVWUC	03FB8
=CNVUCR	152A7
=CNTADR	2F67E
=CNFLCT	0BD15
=CNFFND	109AC
=CMPT	125B2
=CMOSTW	2F438
=CMOSTV	0168F
=CMDS20	01672
=CMDPTR	2F6D4
=CMDPR"	01627
=CMDINI	016D1
=CMDFND	01693
=CMD1ST	01654
=CLRPRM	04827
=CLRFRC	0C6F4
=CLOSEF	12087
=CLOSEA	120E4
=CLCSTK	2F585
=CLCBFR	2F576
=CLASSA	0D590
=CKSUM4	1DBA6
=CKSUM3	153A9
=CKSUM2	0AA81
=CKSREQ	00721
=CKINFO	18542
=CKINF-	18534
=CK"ON"	076AD
=CHNLST	2F5BE
=CHNHED	0F579
=CHN#SV	2F96F
=CHKmem	012C7
=CHKSPC	012AE
=CHKEOL	13D6D
=CHIRP	0EC5A
=CHEDIT	14C99
=CHAIN-	07C1C
=CHAIN+	07C12
=CATEDT	06435
=CATCHR	03F70
=CATCH+	03F69
=CATC++	03F66
=CAT$20	06746
=CALSTK	2F5AD
=CALLP	0389C
=CALL	18DAE
=CALBIN	18D8C
=C+A2D1	1C053
=BldIMG	1BA68
=BldIMA	1BA66
=BldIM+	1BA6A
=BitsOK	00001
=BYTscA	1BA4A
=BSERR	0939A
=BSCEXT	075CF
=BSCEXC	07437
=BSCEX2	0743A
=BRTF	0DC15
=BRT30	0DBE3
=BP+C	0EB40
=BOPNM-	1B864
=BLNKCK	051C1
=BLDLCD	0189C
=BLDDSP	01898
=BLDCON	16279
=BLDBIT	019BC
=BIG	0B747
=BIASC+	0D540
=BIASA+	0D52D
=BF2STK	18663
=BF2DSP	01C0E
=BEEP	0EA6E
=BASICs	000B5
=BASE	0F953
=BASCHK	0773E
=BASCHA	07741
=BACK3B	13B08
=BACK2B	13B0A
=BACK1B	13B0C
=BACK	1BA4F
=AVS2DS	09708
=AVMEMS	2F594
=AVMEME	2F599
=AVE=D1	18BB8
=AVE=C	18BBB
=AUTINC	2F6CB
=ATNFLG	2F442
=ATNDIS	2F441
=ATNCLR	00510
=ATAN15	0DBBE
=ASRW5	0ED0A
=ASRW4	0ED0D
=ASRW3	0ED10
=ASNMNT	0F5E0
=ASLW5	0ED1B
=ASLW4	0ED1E
=ASLW3	0ED21
=ASIN15	0DBCC
=ASIN12	0DBC8
=ASCII	0079B
=ASCICK	0514E
=ARYSIZ	0B61B
=ARYELM	0B5A7
=ARYDC	05178
=ARRYCK	0366A
=ARITH	061E0
=ARGSTA	0E90C
=ARGST-	0E910
=ARGPRP	0E8EF
=ARGPR+	0E8EB
=ARGF	0D6A4
=ARGERR	0BF19
=ARG15	0D67F
=ARG12	0D67B
=ANNAD4	2E34E
=ANNAD3	2E34C
=ANNAD2	2E102
=ANNAD1	2E100
=ANN1.5	2E101
=ALRM6	2F755
=ALRM5	2F749
=ALRM4	2F73D
=ALRM3	2F731
=ALRM2	2F725
=ALRM1	2F719
=ALMSRV	1257D
=ALLDUN	04BEF
=ADRSUB	0F4CF
=ADRS80	0F567
=ADRS50	0F551
=ADRS40	0F52B
=ADJN	12825
=ADJA	1289A
=ADHEAD	181B7
=ADDRSS	0F527
=ADDP	03A03
=ADDONE	0C330
=ADDF	0C372
=AD2-15	0C363
=AD2-12	0C35F
=AD15s	0C369
=AD15S	0E19D
=AD15M	0C366
=ACTIVE	2F5A8
=ACOS15	0DBD7
=ACOS12	0DBD3
=ACCEPT	0450F
=A-MULT	1B349
=?PRFIL	1737E
=?PRFI+	17380
=1/X15	0C33E
=-LINE	15275
=#CK	03356
@EOF
set `wc -lwc <areuh/equ/sasm.ep`
if test $1$2$3 != 1817363424571
then
	echo ERROR: wc results of areuh/equ/sasm.ep are $* should be 1817 3634 24571
fi

chmod 644 areuh/equ/sasm.ep

echo x - areuh/equ/hp71.ep
cat >areuh/equ/hp71.ep <<'@EOF'
=xZERO
0001C
=xVARS
0005B
=xROUND
0004C
=xPOS
00042
=xPCRD
0003E
=xNEG
0003D
=xNEAR
0003C
=xMATH
00036
=xINTO
0002E
=xFLOW
00029
=xEXTND
00026
=xCLOCK
00015
=xANGLE
00006
=uTEST
0D435
=uSTRPT
000D0
=uRND>P
0C9CF
=uRESXT
0C9C1
=uRESTP
000F1
=uRESNX
0C9BD
=uRESD1
0E1EE
=uRES12
0C994
=uOPNWM
000E0
=uOPNNM
000D8
=uOPNM-
000DF
=uNUMNs
000F9
=uNUMNn
000F8
=uNUMFs
000FB
=uNUMFn
000FA
=uNUMEs
000FD
=uNUMEn
000FC
=uMULT
000D1
=uMODES
0BDB1
=uLOOPS
000D3
=uLOOPP
000EF
=uLOOPB
000D2
=uJMP{}
000D9
=uJMPst
000DA
=uJMPdl
000DB
=uIMsta
000DE
=uIMend
000F0
=uIMbck
000DC
=uIMXCH
000D4
=uHKB^
000F6
=uDELIM
000F4
=uCPLXC
000EE
=uALit
000F7
=t^
00080
=tZERO
C01EF
=tZ
0005A
=tXWORD
000EF
=tXFN
000B3
=tWAIT
000D8
=tVARS
B01EF
=tVAL
000A5
=tUSING
000FD
=tUSER
000E2
=tUPRC$
000AB
=tUNF
000B0
=tTRACE
000EA
=tTO
000F3
=tTIMER
000E4
=tTIME$
00095
=tTIME
0007B
=tTHEN
000F4
=tTAN
00098
=tTAB
000F7
=tSVAR
0002D
=tSUB
000C1
=tSTR$
000A6
=tSTOP
000D9
=tSTEP
000F6
=tSTAT
000CE
=tSQR
00092
=tSMALL
00011
=tSIN
00096
=tSHORT
000CB
=tSGN
000A1
=tSFLAG
000FB
=tSEMIC
000F2
=tSDEV
0009E
=tRUN
000FE
=tROUND
C01EF
=tRND
000A0
=tRMD
0006D
=tRFILE
000DE
=tRETRN
000DB
=tRESTR
000DE
=tRES
0007F
=tREM
000E6
=tRELOP
0008A
=tREAL
000BC
=tREAD
000C7
=tRDIAN
000D4
=tRAD
0006E
=tPURGE
000EB
=tPRMST
000F3
=tPRMEN
000F8
=tPRINT
000CD
=tPREDV
0009F
=tPOS
201B3
=tPORT
000D1
=tPI
00079
=tPCRD
E01EF
=tPAUSE
000D7
=tOVF
000AF
=tOR
0008D
=tOPT'N
000ED
=tON
000E0
=tOFF
000E1
=tNUM
000A3
=tNOT
00081
=tNEXT
000C4
=tNEG
D01EF
=tNEAR
C01EF
=tNAME
000BD
=tMOD
00074
=tMIN
000AC
=tMEAN
0009D
=tMAXRL
0006C
=tMAX
000AD
=tMATH
601EF
=tMAIN
000D2
=tLR
000B6
=tLPRP
000AA
=tLOG10
00093
=tLOG
00090
=tLN
00091
=tLITRL
000C4
=tLIST
000BB
=tLINPT
000BF
=tLINE#
0000F
=tLET
000C0
=tLEN
000A9
=tLBLST
000F6
=tLBLRF
0000E
=tKEYS
000CF
=tKEY$
00073
=tKEY
000E5
=tIVL
000AE
=tISUB$
000A7
=tIS
000E7
=tIP
0006A
=tINX
000B2
=tINTR
015FF
=tINTO
E01EF
=tINTEG
000CA
=tINT9
00005
=tINT8
00006
=tINT7
00007
=tINT6
00008
=tINT5
00009
=tINT4
0000A
=tINT3
0000B
=tINT2
0000C
=tINT12
00002
=tINT11
00003
=tINT10
00004
=tINT
0009C
=tINPUT
000C9
=tINF
00070
=tIN
000F2
=tIMAGE
000FF
=tIF
000DF
=tGOTO
000DD
=tGOSUB
000DC
=tFP
0006B
=tFOR
000C3
=tFN
0007C
=tFLT9
00015
=tFLT8
00016
=tFLT7
00017
=tFLT6
00018
=tFLT5
00019
=tFLT4
0001A
=tFLT3
0001B
=tFLT2
0001C
=tFLT12
00012
=tFLT11
00013
=tFLT10
00014
=tFLT1
0001D
=tFLOW
901EF
=tFFN
000B4
=tFETCH
000C8
=tFACT
000A8
=tEXTND
601EF
=tEXTIF
000F4
=tEXP
00094
=tEXOR
0008C
=tERROR
000E3
=tERRN
00076
=tERRL
00075
=tEPS
00071
=tEOL
000F0
=tENTER
4FFEF
=tENDSB
000C2
=tENDDF
000BA
=tEND
000DA
=tELSE
000F5
=tEDIT
000B8
=tDVZ
000B1
=tDSTRY
000BE
=tDMYAR
0007E
=tDIV
00086
=tDISP
000C5
=tDIM
000CC
=tDELET
000B7
=tDELAY
000D6
=tDEGRE
000D3
=tDEG
0006F
=tDEF
000B9
=tDATE$
00078
=tDATE
00077
=tDATA
000C6
=tCVAL
000E1
=tCOS
00097
=tCOPY
000B5
=tCOMMA
000F1
=tCOLON
000E2
=tCMPLX
0007A
=tCLOCK
501EF
=tCHR$
000A4
=tCFLAG
000FA
=tCEIL
00072
=tCAT
000EC
=tCARD
000D0
=tCALL
000F9
=tBIG
00010
=tBEEP
000E8
=tBASE
000E9
=tAUTO
000EE
=tATAN
0009B
=tASIN
00099
=tARRAY
0007D
=tANGLE
601B3
=tAND
0008B
=tALL
000F8
=tADIG9
00069
=tADIG8
00068
=tADIG7
00067
=tADIG6
00066
=tADIG5
00065
=tADIG4
00064
=tADIG3
00063
=tADIG2
00062
=tADIG1
00061
=tADIG0
00060
=tADD
000D5
=tACOS
0009A
=tABS
000A2
=t@
000F4
=t/
00084
=t-
00082
=t+
00087
=t*
00083
=t&
00089
=t%
00085
=t!
000FC
=sXWORD
00009
=sXQT
00000
=sXCPT
00004
=sUNDEF
00001
=sSpecl
00006
=sSTOP
00005
=sSTAT
00006
=sSSTdc
00001
=sSST
00002
=sSIGN
00009
=sRUNDC
00007
=sRUNBn
00004
=sRFILE
00008
=sRETRN
00000
=sRESTR
0000A
=sRENUM
00008
=sRENAM
00006
=sREADI
00004
=sRDX
0000B
=sRAD
00009
=sPRGCF
0000B
=sPCRD
00008
=sONTMR
00006
=sONERR
00004
=sNoChn
00002
=sNEGRD
0000B
=sMULT
00008
=sMAINc
00005
=sKEYS
00005
=sInit
00003
=sIX
00007
=sIRAM
00002
=sINX
00005
=sINFRD
0000A
=sI/OBF
0000A
=sGOSUB
00003
=sFOUND
0000A
=sEXTGS
00005
=sEXTDV
00000
=sERROR
00000
=sEOF
00007
=sENDx
00001
=sDEST
00003
=sCplxP
00007
=sCntg
00002
=sCURUP
00002
=sCURUD
00004
=sCURBT
00003
=sCONTK
00009
=sCONT
0000A
=sCHAIN
0000B
=sCARDC
00008
=sCARD
00002
=sC/P
00001
=sBYEx
00000
=sARITH
00007
=pZERPG
000F7
=pWTKY
0001C
=pWRCBF
0001A
=pWCRD8
00024
=pWCRD
00035
=pWARN
000F3
=pVER$
00000
=pTRFMx
0003C
=pTRANS
000EF
=pTIMR#
0003B
=pTEST
000F0
=pSREQ
000F9
=pSREC#
00028
=pRUNnB
00031
=pRUNft
00030
=pRTNTp
0003A
=pRNAME
00011
=pREN
00039
=pREAD#
00027
=pRDNBF
00019
=pRDCBF
00018
=pRCRD
00034
=pPWROF
000FC
=pPURGE
00010
=pPRTIS
0000F
=pPRTCL
0000E
=pPRIN#
00026
=pPRGPR
00032
=pPARSE
000F4
=pMRGE2
0002F
=pMNLP
000FA
=pMERGE
0000D
=pMEM
000F1
=pLIST2
0002E
=pLIST
0000C
=pKYDF
0001B
=pIMcpw
00022
=pIMcpi
00021
=pIMbck
00020
=pIMXQT
0001D
=pIMXCH
0001F
=pIMCHR
0001E
=pFTYPE
0002D
=pFSPCx
00005
=pFSPCp
00004
=pFPROT
0000B
=pFNOUT
0003E
=pFNIN
0003D
=pFINDF
00017
=pFILXQ
00003
=pFILDC
00002
=pFASCH
0002C
=pExcpt
000F8
=pERROR
000F2
=pEOFIL
00025
=pENTER
00012
=pEDIT
0002B
=pDSWNK
000FE
=pDSWKY
000FD
=pDIDST
0000A
=pDEVCp
00001
=pDATLN
0002A
=pCURSR
00029
=pCRT=8
00023
=pCREAT
00009
=pCRDAB
00033
=pCOPYx
00008
=pCONFG
000FB
=pCMPLX
00038
=pCLDST
000FF
=pCAT$
00007
=pCAT
00006
=pCALSV
00037
=pCALRS
00036
=pBSCex
000F6
=pBSCen
000F5
=oTXsod
00005
=oTIMEh
00016
=oSUBLn
00025
=oSPDn2
0000E
=oSPDTB
00111
=oSHLNb
00013
=oRTN3p
00014
=oRTN2p
0000F
=oRTN1p
0000A
=oRLENb
00034
=oRECLb
00024
=oREC#b
00020
=oPROTb
00009
=oPOL#p
0000A
=oMSGPT
00009
=oMAINT
0005D
=oLXsod
00005
=oKYsod
00005
=oIMPLh
00025
=oFTYPh
00010
=oFTYPb
00005
=oFT-FL
00010
=oFSIZb
00039
=oFNAMh
00000
=oFLSTr
00031
=oFLENh
00020
=oFLAGh
00014
=oFIL#b
00000
=oFBF#b
00002
=oFBEGb
0000D
=oDp
0002E
=oDLENb
0002E
=oDEVCb
0000C
=oDBEGb
00015
=oDAsod
0000D
=oDATEh
0001A
=oD1p
0001E
=oD0p
00019
=oCPOSb
00028
=oCOPYb
0000A
=oBSsod
00011
=oBPOSp
00005
=oBNsod
00011
=oAp
0003E
=oACCSb
0000B
=o41sod
00005
=lTIMEh
00004
=lTEXTp
00004
=lSPDn2
00001
=lSPDn
00001
=lSPDTB
0004E
=lSHLNb
00002
=lRTN3p
00005
=lRTN2p
00005
=lRTN1p
00005
=lRLENb
00005
=lRECLb
00004
=lREC#b
00004
=lPROTb
00001
=lPOLra
00006
=lPOLSV
0003E
=lPOLLp
00005
=lPOL#p
00005
=lMSGp
00004
=lLXTKR
00004
=lLXID
00002
=lLXFAD
00005
=lLXENT
0000B
=lLXADR
00005
=lFTYPh
00004
=lFTYPb
00004
=lFSIZb
00006
=lFNAMh
00010
=lFNAM8
00010
=lFNAM+
00004
=lFLENh
00005
=lFLAGh
00002
=lFILSV
00032
=lFIL#b
00002
=lFIB
0003F
=lFBF#b
00003
=lFBEGb
00006
=lEOL
00002
=lDp
00010
=lDLENb
00006
=lDEVCb
00001
=lDEVC
00005
=lDBEGb
0000B
=lDATEh
00006
=lD1p
00005
=lD0p
00005
=lCPOSb
00006
=lCOPYb
00001
=lBPOSp
00005
=lAp
00010
=lACCSb
00001
=kcVIEW
0000B
=kcUSEX
0000C
=kcUSER
00003
=kcUP
00012
=kcTOP
00014
=kcSST
00011
=kcRUN
0000F
=kcRT
00009
=kcOFF
00018
=kcLFT
00008
=kcLERR
0001A
=kcLC
00001
=kcLAST
00019
=kcI/R
00002
=kcGON
00016
=kcFRT
00006
=kcFLFT
00005
=kcEOL
0000D
=kcDOWN
00013
=kcCTRL
0000A
=kcCONT
00010
=kcCALC
00017
=kcBOT
00015
=kcBKSP
00007
=kcATTN
0000E
=kc-LIN
00004
=kc-CHR
00000
=k#VIEW
0006E
=k#USEX
000A5
=k#USER
0006D
=k#UP
00032
=k#TOP
000A2
=k#SST
00066
=k#RUN
0002E
=k#RT
00030
=k#OFF
00063
=k#LFT
0002F
=k#LERR
000A1
=k#LC
0006A
=k#LAST
000A4
=k#I/R
00069
=k#GON
0009B
=k#FRT
000A0
=k#FLFT
0009F
=k#EOL
00026
=k#DOWN
00033
=k#CTRL
0009E
=k#CONT
00070
=k#CALC
0006F
=k#BOT
000A3
=k#BKSP
00067
=k#ATTN
0002B
=k#3
00029
=k#2
00028
=k#1
00027
=k#-LIN
0006B
=k#-CHR
00068
=flVIEW
FFFCC
=flUSRX
FFFC6
=flUSER
FFFF7
=flUNF
FFFFB
=flTNOF
FFFCD
=flSUSP
FFFC1
=flSCEN
FFFF2
=flRTN
FFFD4
=flRPTD
FFFC5
=flRAD
FFFF6
=flQIET
FFFFF
=flPWDN
FFFCF
=flPRGM
FFFC2
=flPDWN
FFFEB
=flOVF
FFFFA
=flNZ8
FFFC8
=flNZ7
FFFC9
=flNZ6
FFFCA
=flNZ5
FFFCB
=flNZ4
FFFE8
=flNOPR
FFFE6
=flNOFN
FFFD6
=flNEGR
FFFF4
=flMKOF
FFFCE
=flLC
FFFF1
=flIVL
FFFF8
=flINX
FFFFC
=flINFR
FFFF5
=flFXEN
FFFF3
=flEXTD
FFFEA
=flEXAC
FFFD2
=flEOT
FFFE9
=flDVZ
FFFF9
=flDORM
FFFD5
=flDG3
FFFEC
=flDG2
FFFED
=flDG1
FFFEE
=flDG0
FFFEF
=flCTRL
FFFD0
=flCTON
FFFFD
=flCMDS
FFFD1
=flCLOC
FFFD3
=flCALC
FFFC0
=flBPLD
FFFE7
=flBEEP
FFFFE
=flBAT
FFFC3
=flBASE
FFFF0
=flALRM
FFFC4
=flAC
FFFC7
=fTEXT
00001
=fSOS
000CF
=fSDATA
0E0D0
=fROM
0E21C
=fMOS
0007F
=fLIF1
00001
=fLEX
0E208
=fKEY
0E20C
=fEOS
0006F
=fEOR
000EF
=fEOF
000FF
=fDATA
0E0F0
=fBIN
0E204
=fBASIC
0E214
=fASCII
00001
=fAOS
000DF
=ew/o
000EB
=enull
00000
=eZRO/0
00007
=eZRDIV
00008
=eXWORD
00023
=eXFNNF
00022
=eWRGNM
00049
=eWALGN
0005B
=eVFYER
00044
=eVARTY
00032
=eVALGN
0005C
=eUNORC
00014
=eUNKCD
00045
=eUNFLW
00001
=eUALGN
0005F
=eTUSLO
00048
=eTUFAS
00047
=eTRKOF
000E5
=eTRKDN
00061
=eTOOMI
00027
=eTOOFI
00028
=eTOO
000EF
=eTNINF
00004
=eTFWRN
00058
=eTFM
000F1
=eTFFLD
00038
=eSYSER
00017
=eSYNTX
0004B
=eSUBSC
0001C
=eSTROV
00025
=eSTMNF
0001E
=eSQR-
0000A
=eSPGNF
00031
=eSIGOP
00013
=eRwoGS
0002C
=eRWERR
00046
=eRECOR
0001D
=eRALGN
0005D
=eR1WRN
00057
=eR0WRN
00056
=eQUOEX
0004D
=ePULL
000F6
=ePRTCT
000F8
=ePROTD
00042
=ePRNEX
0004C
=ePRMIS
00024
=ePRCER
00054
=ePLLC#
00059
=ePLLC
0005A
=ePALGN
0005E
=eOVFLW
00002
=eOVFL*
000F5
=eNXwoF
0002B
=eNVSTA
00033
=eNUMIN
00026
=eNSVAR
00033
=eNOTIN
00043
=eNODAT
00020
=eNFOUN
000E8
=eNEG^X
00009
=eMSPAR
00052
=eMPI
00019
=eMMCOR
00017
=eMEM
00018
=eLOG-
0000D
=eLOBAT
00016
=eLN0
0000C
=eL2LNG
00041
=eIVTAB
00030
=eIVSTA
00034
=eIVSOP
00035
=eIVSAR
00033
=eIVARG
0000B
=eINX
00015
=eINVUS
0002E
=eINVST
000ED
=eINVLD
000EC
=eINVIM
0002D
=eINPUT
000F4
=eINF^0
00012
=eINF
000F3
=eIMGOV
0002F
=eILVAR
00053
=eILTFM
00037
=eILPAR
00051
=eILLEG
000E6
=eILKEY
00055
=eILEXP
00050
=eILCNT
0004F
=eIF/IF
0000E
=eIF-IF
0000F
=eIF*ZR
00010
=eFwoNX
0002A
=eFnFND
00039
=eFTYPE
0003F
=eFSPEC
0003A
=eFPROT
0003D
=eFOPEN
0003E
=eFNNtF
00021
=eFILE
000EA
=eFEXST
0003B
=eFACCS
0003C
=eF2BIG
0004A
=eEXPCT
000E7
=eEXP0
00003
=eEXCHR
0004E
=eEOFIL
00036
=eDVCNF
00040
=eDATTY
0001F
=eCHNL#
00029
=eCALGN
00060
=eALGN
000F0
=eAF
0001B
=e2MROM
0001A
=e1^INF
00011
=e0^NEG
00005
=e0^0
00006
=e#of#
000F7
=dPORT
00001
=dPCRD
00007
=dMAIN
00000
=dIRAM
00001
=dCARD
00007
=cRCL
00067
=cR->C
00069
=cC->C
00068
=bSTMXQ
00811
=bSTMT
00801
=bSTAT
00806
=bSTART
00808
=bSCRTC
00E00
=bROMTB
00BFE
=bPILSV
0080F
=bPILAI
00810
=bLEX
00BFC
=bIEXKY
00802
=bFILE
00805
=bFIB
00803
=bECOMD
00809
=bCHARS
00BFB
=bCARD
00807
=bASSGN
00804
=bALTCH
00BFB
=a9
00039
=a8
00038
=a7
00037
=a6
00036
=a5
00035
=a4
00034
=a3
00033
=a2
00032
=a1
00031
=a0
00030
=a.
0002E
=a'
00027
=a$
00024
=a"
00022
=a!
00021
=ZERBUF
18B20
=YX2-15
0D27A
=YX2-12
0D274
=YMDHMS
130DB
=YMDH01
130E5
=YMDDAY
13304
=XYEX
0C697
=XXHEAD
1A44E
=XROM01
00001
=XMTADR
08133
=XDelay
00009
=WSTRFX
138B5
=WRTSTR
1396F
=WRTNUM
139C4
=WRTFIB
11CEE
=WRITNB
1752B
=WRDSCN
02C2A
=WRDSC+
02C26
=WRBYTC
13A73
=WIPOUT
1B0AF
=WINDST
2F471
=WINDLN
2F473
=WFTMDT
085DD
=ValSub
0000A
=VRIABL
04BC4
=VIEWD1
15147
=VECTOR
2F43C
=VARP
0350E
=VARNBR
0E289
=VARNB-
0E28D
=VARDC
0537C
=VALCHK
1AE61
=VAL00
1AD8F
=USst05
1BBD4
=USst03
1BBCE
=USnm05
1BD12
=USloop
1C14B
=USINGp
03628
=USING
1B446
=USGrst
1BC63
=USGch-
1BC0B
=USGch+
1BC15
=USG*10
1B508
=UPDPCC
07B65
=UPDANN
13571
=UPD2ST
2F674
=UPD2EN
2F6A6
=UPD1ST
2F55D
=UPD1EN
2F599
=UPCPOS
13C67
=UNP
00001
=UNFNIB
2F6FA
=TstEnd
1C0FF
=Trace
0000F
=TWO*
0DB38
=TST15
0D47A
=TST12A
0D476
=TRTO+
0FE7B
=TRSFMu
16B84
=TRPREG
2F6F9
=TRMNTR
0F1DD
=TRKDON
1CFAC
=TRFROM
0FE59
=TRFMBF
2F8C5
=TRC90
0DA11
=TRACEM
2F7B0
=TRACDC
052FC
=TONE
0EBEB
=TODT
13229
=TMRIN3
2F6B6
=TMRIN2
2F6AE
=TMRIN1
2F6A6
=TMRAD3
2F6A1
=TMRAD2
2F69C
=TMRAD1
2F697
=TKSCN7
08A99
=TKSCN+
08A6B
=TIMOFS
2F763
=TIMLST
2F76F
=TIMLAF
2F77B
=TIMER3
2E1F8
=TIMER2
2E2F8
=TIMER1
2E3F8
=TIMAF
2F787
=TGSBS
2F5A3
=TFORN
2F59E
=TFHDLR
1702F
=TERCHR
2F97D
=TBMSG$
099AB
=TBLJMP
0242A
=TBLJMC
02426
=TBLJM2
0243D
=TASTK
2F599
=TAN15
0D733
=TAN12
0D72F
=SetAVM
1B9FA
=SavLvl
00005
=SYSFLG
2F6D9
=SYSEN
2F58A
=SYNTXe
02E2B
=SWPBYT
17A24
=SVTRC
0FA35
=SVINFO
0845A
=SVINF+
08457
=SUBONE
0C327


=STUFF
1B0B2
=STSCR
0E92C
=STSAVE
2F6BE
=STRTST
1B1C7
=STRNGP
0379D
=STRHED
14C2E
=STRHDR
0F09A
=STRGCK
036BA
=STREQL
1B1EF
=STRASN
0F6B3
=STRALL
1AF5D
=STR$SB
18149
=STR$00
1815C
=STORE
0F5F8
=STMTR1
2F881
=STMTR0
2F871
=STMTD1
2F896
=STMTD0
2F891
=STMBUF
090DF
=STMBCL
090E7
=STKVCT
1470C
=STKCMD
155ED
=STKCHR
18504
=STCD2
0D427
=STATSV
1732F
=STATRS
172F3
=STATAR
2F7AD
=STAB2
0D400
=STAB1
0D3D9
=SRLEAS
015EC
=SQRSAV
0D629
=SQR70
0C5C3
=SQR17
0C553
=SQR15
0C534
=SPLTAX
0E62B
=SPLTAC
0C934
=SPLITC
0C940
=SPLITA
0C6BF
=SPACE
0AD9D
=SNDWD+
17E1F
=SNAPSV
015A7
=SNAPRS
01571
=SNAPR*
01578
=SNAPBF
2F7F0
=SLEEP
006C2
=SKIPDC
057F6
=SIN15
0D71A
=SIN12
0D716
=SIGTST
0E636
=SIGCHK
0BD98
=SHUTDN
005E2
=SHRT
0F96C
=SHFRBD
0DB5F
=SHFRAC
0DB51
=SHFLAC
0DB46
=SHF10
0C486
=SFLAGT
13608
=SFLAGS
135FA
=SFLAGC
13601
=SFLAG?
1364C
=SETTMO
13158
=SETSB
0D641
=SETFMT
0F01F
=SETALR
12917
=SETALM
1290D
=SENDWD
17E15
=SENDIT
17DE3
=SENDEL
17DC1
=SEND20
17DFA
=SECHMS
13252
=SE1-10
04468
=SCRTCH
2F901
=SCRST0
2F901
=SCRPTR
2F966
=SCROLT
2F946
=SCRLLR
0212E
=SCREX3
2F971
=SCREX2
2F961
=SCREX1
2F951
=SCREX0
2F941
=SCOPCK
0915B
=SCNRT
022B9
=SCAN
04C40
=SB15S
0E19A
=SAVSTK
2F59E
=SAVGSB
0D64E
=SAVEXM
0D663
=SAVESB
0D66E
=SAVD1
1C578
=SAVD0
1C587
=SALLOC
0153B
=S-R1-3
2F890
=S-R1-2
2F88B
=S-R1-1
2F886
=S-R1-0
2F881
=S-R0-3
2F880
=S-R0-2
2F87B
=S-R0-1
2F876
=S-R0-0
2F871
=ResetC
00008
=RUNRTN
074EA
=RUNRT1
074E7
=RTNX10
08FF2
=RSTST
0F5C5
=RSTKBp
2F81F
=RSTKBF
2F820
=RSTK<R
014A8
=RSTD1
1C596
=RSTD0
06832
=RST2<R
014A6
=RPTKY
152BA
=RPLSBH
1799B
=RPLLIN
013F7
=ROWDVR
2E350
=ROMFND
1102F
=ROMCK5
10FE4
=ROMCID
00BFE
=ROMCHK
10FDE
=RNSEED
2F6FE
=RNDNRM
0CAB1
=RNDAHX
136CB
=RND12+
0C9D5
=RND-12
1B01F
=RJUST
12AE2
=RFUPD+
0A66E
=RFNBFR
2F57B
=RFAD-I
0A659
=RFAD--
0A652
=RFAD+I
0A702
=RFAD++
0A6FB
=REWIND
11365
=REVPOP
0BD31
=REV$
1B38E
=REST*
03035
=RESREG
2F7C2
=RESPTR
03172
=RESERV
2F986
=RESCAN
04A4C
=REPROM
18A1E
=RENSUB
1A753
=RELJMP
05047
=REDUCE
15977
=RECALL
0F281
=RECADR
0F4B7
=READP5
0323B
=READNB
17518
=READIN
0F484
=RDTEXT
17489
=RDLNAS
13A1F
=RDINFO
0846B
=RDHDR1
076FD
=RDCHDR
076F0
=RDCHD+
076EE
=RDBYTA
13A2F
=RDBAS
173FF
=RDATTY
17CC6
=RCVOFS
1C050
=RCURON
14C80
=RCSCR
0E954
=RCLW3
0E9C4
=RCLW2
0E9BE
=RCLW1
0E981
=RCLALL
1AFBF
=RCL*
0E983
=RCCD2
0D41C
=RCCD1
0D3F5
=RAWBFR
2F580
=RANGE
1B07C
=RAMROM
0A5F7
=RAMEND
2F5B2
=R<RSTK
014DD
=R<RST2
014DB
=R4REV
1DBA8
=R3REV
153AB
=R3=D10
03526
=R2REV
0AA83
=R1REV
00785
=QUOTCK
0623D
=QUOEXe
02E8B
=PgmRun
0000D
=PWROFF
00526
=PWIDTH
2F958
=PUTRES
18115
=PURGEF
17359
=PURGDC
05745
=PUGFIB
12198
=PSHUPD
08F0D
=PSHSTL
08C85
=PSHSTK
08C7F
=PSHMCR
08F0B
=PSHGSB
08F13
=PRT#DC
06841
=PRSscn
1BA88
=PRSsc+
1BA84
=PRSC00
07B93
=PRPSND
06B17
=PRNTDC
05450
=PRNEXe
02E95
=PRMPTR
2F5B7
=PRMCNT
2F94B
=PRMCHN
0B375
=PRINTt
00001
=PRINT*
17F37
=PRGMST
2F562
=PRGMEN
2F567
=PRGFMF
0A146
=PRESCN
04A49
=PREP
0ADAF
=PPOS
2F956
=POPUPD
08F3E
=POPSTR
1B405
=POPSTK
08F55
=POPMTH
1B3DB
=POPBUF
010EE
=POP2N+
0BD58
=POP2N
0BC8C
=POP1S
0BD38
=POP1R
0E8FD
=POP1N+
0BD91
=POP1N
0BD1C
=POLLD+
1232D
=POLL
12337
=PNDALM
2F761
=PI/4
0DAA1
=PI/2D
0DB7A
=PI/2
0DB77
=PFNDZL
078E2
=PFINDL
078DF
=PEDITM
0FF70
=PEDITD
0FF62
=PEDIT
0FF5F
=PDEV
09E9E
=PCEXPR
06828
=PCADDR
2F679
=PART3
18097
=PARERR
02F08
=P1-10
041C1
=OVP
00002
=OVFNIB
2F6FB
=OVFL
0CA73
=OUTVAR
0373E
=OUTRES
0BC84
=OUTNIB
02D28
=OUTNBS
05426
=OUTNBC
05423
=OUTLIT
036F3
=OUTLI1
03709
=OUTELA
05303
=OUTEL1
05300
=OUTC15
05421
=OUTBYT
02CE8
=OUTBY+
02CE5
=OUTBS
2F58F
=OUT3TK
02D15
=OUT3TC
02D12
=OUT2TK
02CFF
=OUT2TC
02CFD
=OUT1TK
02CEB
=OUT1T+
02CDF
=ORXM
0D633
=ORSB
0D63C
=ORGSB
0D65B
=OPENF
11B06
=ONTIMR
08008
=ONP40
02B7B
=ONINTR
2F68D
=ONDC20
05501
=OKP
00000
=OFFFLG
2F442
=OBEDIT
17687
=OBCOLL
01435
=OAGNXT
03060
=NwOFFS
1C02D
=NoCont
0000E
=NXTVA-
13E58
=NXTSTM
08A48
=NXTP
03455
=NXTLIN
10031
=NXTIRQ
2F70D
=NXTEXP
1C2F7
=NXTELM
148AC
=NXTADR
147E8
=NXPRMP
0B3A5
=NXPR10
0B3B0
=NUMSCN
04D18
=NUMCK
0369D
=NUMC+O
03696
=NUMC++
03690
=NULLP
07999
=NTOKNL
048E6
=NTOKEN
0493B
=NRMCON
161AF
=NOSCRL
14C8A
=NORDIM
0AE2D
=NEEDSC
2F94A
=MVMEM+
0133C
=MULTF
0C446
=MTHSTK
2F599
=MTADR+
081A1
=MTADDR
08195
=MSPARe
02E5C
=MSN15
0D557
=MSN12
0D553
=MSIZE+
1040A
=MSIZE
10407
=MPY
0ECBB
=MPOP2N
0BD54
=MPOP1N
0BD8D
=MP2-15
0C43A
=MP2-12
0C432
=MP15S
0C440
=MP1-12
0C436
=MOVEUM
1B15C
=MOVEUA
1B168
=MOVEU4
1B174
=MOVEU3
1B177
=MOVEU2
1B172
=MOVEU1
1B16F
=MOVEU0
1B162
=MOVEDM
1B0EE
=MOVEDD
1B106
=MOVEDA
1B0FA
=MOVED3
1B109
=MOVED2
1B104
=MOVED1
1B101
=MOVED0
1B0F4
=MOVE*M
01308
=MOD15
0C796
=MLFFLG
2F870
=MGOSUB
1AF01
=MFWRQ8
093C3
=MFWRNQ
093C5
=MFWRN
093BC
=MFLG=0
13DA1
=MFERsp
0940D
=MFERRS
0939E
=MFERR*
093F1
=MFERR
09393
=MFER42
0962C
=MESSG
0CC17
=MEMERX
0944F
=MEMERR
0944D
=MEMER*
0945B
=MEMCKL
012A5
=MEMBER
1B098
=MBOX^
2F7A9
=MAXCMD
2F976
=MANSTK
196D3
=MAKEBF
01751
=MAKE1
0DACE
=MAINST
2F558
=MAINLP
002FD
=MAINEN
2F571
=MAIN30
0037E
=MAIN05
00338
=LXTXTT
1EE9F
=LXFND
0979D
=LSTLEN
06C27
=LSLEEP
006CD
=LOOPST
2F7AC
=LOCKWD
2F7B2
=LOCFIL
1721D
=LOCADR
0A611
=LNSKP-
089FF
=LNPEXT
02617
=LNEP66
027EA
=LN30
0CD9C
=LN15
0CD81
=LN12
0CD7D
=LN1+XF
0CD51
=LN1+15
0CD44
=LISTDC
05839
=LINSKP
08A05
=LINP
02A07
=LINEP+
02626
=LINEP*
02634
=LINEP
02620
=LIN#DC
05115
=LIN#D+
05112
=LIN#AU
05122
=LIMITS
0AC3E
=LGT15
0D1AE
=LEXPTR
2F6CF
=LEXBF+
10DDF
=LEEWAY
000D4
=LEAVE
04C01
=LDSST2
04F9E
=LDSST1
04F72
=LDCSPC
2F6C1
=LDCSET
05060
=LDCOMP
04F69
=LDCM10
04F6F
=LDCEXT
04F5E
=LCDINI
00665
=LBLNIF
02A0D
=LBLNAM
077E7
=LBLINP
02A04
=LBLIN#
2F871
=LASTFN
000B4
=LABLDC
05702
=LABELP
03E9F
=KYDN?
00774
=KEYSCN
00D4D
=KEYSAV
2F462
=KEYRD
14E11
=KEYPTR
2F443
=KEYNAM
1AC04
=KEYMRG
08B8F
=KEYFND
08CB8
=KEYDEL
08D2C
=KEYCOD
1FD22
=KEYBUF
2F444
=KEY$
1ACA8
=KCOLD
2F462
=KCOLC
2F463
=KCOLB
2F464
=KCOLA
2F465
=KCOL9
2F466
=KCOL8
2F467
=KCOL7
2F468
=KCOL6
2F469
=KCOL5
2F46A
=KCOL4
2F46B
=KCOL3
2F46C
=KCOL2
2F46D
=KCOL1
2F46E
=KCOL0
2F46F
=Insert
00007
=InhEOL
00004
=IVVARe
02E66
=IVPARe
02E3F
=IVP
00004
=IVLNIB
2F6FD
=IVEXPe
02E35
=IVARG
0D749
=IVAERR
0E920
=ISRAM?
10192
=IS-TBL
2F78D
=IS-PRT
2F794
=IS-PLT
2F7A2
=IS-INP
2F79B
=IS-DSP
2F78D
=IOFSCR
1188E
=IOFND0
118C1
=IOBFST
2F571
=IOBFEN
2F576
=INXNIB
2F6F9
=INVNaN
0C65F
=INTRPT
0000F
=INTR50
000DB
=INTR4
2F400
=INTM
2F430
=INTGR
0F99B
=INTB
2F420
=INTA
2F410
=INPOFF
18B49
=INFR15
0C73D
=INF*0
0C607
=INBS
2F6C6
=INADDR
2F6D4
=IN/REP
15255
=IMxq27
1BB9C
=IMoffs
1BA58
=IMinit
1B88F
=IMerr
1B989
=IMentr
1B535
=IMGxq1
1BAAB
=IMD0-2
1BA21
=IMD0+2
1BA2D
=ILCNTe
02E70
=IF12A
0C739
=IDIVA
0EC6E
=IDIV
0EC7B
=I/ORES
118FF
=I/OFND
118BA
=I/OEXP
11A11
=I/OEX2
11A0F
=I/ODAL
11A41
=I/OCON
11920
=I/OCOL
11979
=I/OALL
1197D
=I/OAL+
1197B
=HXDCW
0ECB4
=HXDASC
05FF4
=HUGE
0B75D
=HTRAP
0CB2F
=HPSCRH
2F97F
=HNDLFL
0CBC9
=HMSSEC
13274
=HEXDEC
0ECAF
=HEXASC
17148
=HDFLT
1B31B
=HASH2
1B0A3
=HASH1
1B0A1
=GetEXP
1C086
=GTXT++
05192
=GTPTRX
14670
=GTPTRS
14636
=GTKYCD
08D92
=GTKYC+
08D9B
=GTKY54
08E9A
=GTFLAG
1365E
=GTEXT1
051A5
=GTEXT+
05199
=GTEXT
05079
=GSBSTK
2F5A3
=GOTOp
029F6
=GOTODC
0552E
=GOTO
079FA
=GOSUBp
029F6
=GOSUB
079E9
=GNXTCR
03064
=GETVAL
0DAB2
=GETSTC
07726
=GETST-
07728
=GETST*
07716
=GETSA
0E551
=GETPRO
06BEE
=GETPR1
06BFB
=GETPR+
06BF5
=GETNAM
1A085
=GETMSK
01BBA
=GETDIM
0AD6B
=GETCON
0DAA3
=GETCNT
1A076
=GETCH#
11427
=GETAVM
1864D
=GDISP$
1C3C7
=FUNCR1
2F8AB
=FUNCR0
2F89B
=FUNCD1
2F8C0
=FUNCD0
2F8BB
=FTYPF#
11059
=FTYPDC
06902
=FTBSCH
11093
=FSPECx
09F2D
=FSPECp
03CC5
=FSPECe
02F02
=FRange
0B46A
=FRAC15
0C70E
=FPOLL
1250A
=FORUPD
0A6AE
=FORSTK
2F59E
=FNRTN4
0F238
=FNRTN3
0F235
=FNRTN2
0F219
=FNRTN1
0F216
=FNPWDS
0D3C0
=FNDFCN
1A0A1
=FNDCLR
1DAEF
=FLTYPp
03E71
=FLTDH
1B223
=FLOAT
1B322
=FLIP8
0DB8D
=FLIP11
0DBAB
=FLIP10
0DB9C
=FLGREG
2F6E9
=FLDEVX
01154
=FLADDR
0126B
=FIXP
02A6E
=FIXDC
05493
=FIRSTC
2F47C
=FINLIN
18A3A
=FINITC
0CD0F
=FINITA
0CD03
=FINDLR
0FFDE
=FINDLB
07786
=FINDL0
0FFFD
=FINDL
0FFE4
=FINDF+
09F63
=FINDF
09F77
=FINDD0
023E0
=FINDA
023E3
=FIND
0F563
=FILXQ^
09B76
=FILXQ$
09B95
=FILSK+
06F1D
=FILFIL
011CE
=FILEP1
03EFC
=FILEP-
03F00
=FILEP+
03F07
=FILEP!
03F0F
=FILEP
03E9C
=FILEF
09FB0
=FILDC*
05759
=FILCRD
1C879
=FIBOFF
12132
=FIBADR
11457
=FIBAD-
11478
=FGTBL
00C9B
=FCSTRT
0E757
=FCHLBL
0782C
=FASCFD
110C3
=FAC15S
0E72B
=F-R1-3
2F8BA
=F-R1-2
2F8B5
=F-R1-1
2F8B0
=F-R1-0
2F8AB
=F-R0-3
2F8AA
=F-R0-2
2F8A5
=F-R0-1
2F8A0
=F-R0-0
2F89B
=Except
0000C
=EndNum
000E6
=EXPSKP
1A9AC
=EXPRDC
05922
=EXPR
0F23C
=EXPPLS
03FDC
=EXPPAR
03FD9
=EXPP10
03FE3
=EXPEXC
0F186
=EXPEX-
0F178
=EXPEX+
0F182
=EXP15
0CF5A
=EXF
0D5DF
=EXDCLP
0592E
=EXCPAR
187E8
=EXCHRe
02E81
=EXCAD+
08631
=EXACT
128B0
=EXAB2
0D40E
=EXAB1
0D3E7
=EX15S
0D5CE
=EX15M
0D5CA
=EX12
0D5C6
=EX-115
0CF48
=ESCSTA
2F47B
=ESCSEQ
023C1
=ERRSUB
2F683
=ERRRTN
074ED
=ERRM$f
09806
=ERRL#
2F7EC
=ERRADR
2F688
=ERR#
2F7E4
=EOLXCK
05405
=EOLXC*
052EC
=EOLSTR
2F95B
=EOLSN5
08AB1
=EOLSCN
08AA7
=EOLLEN
2F95A
=EOLDC
05402
=EOLCKR
02A7A
=EOLCK8
02A92
=EOLCK
02A7E
=ENDSUB
195A8
=ENDIMG
1C040
=ENDBIN
0764B
=ENDALL
0769A
=EFIELD
00000
=EDITWF
0A533
=EDIT80
0A5A5
=DZP
00003
=DXP100
0CF7F
=DWIDTH
2F94F
=DVZNIB
2F6FC
=DV2-15
0C4AC
=DV2-12
0C4A8
=DV15S
0C4B2
=DV15M
0C4AC
=DSTRDC
05280
=DSPUPD
01ADA
=DSPSTA
2F475
=DSPSET
2F7B1
=DSPRST
02443
=DSPMSK
2F540
=DSPLIN
10127
=DSPLI+
1010F
=DSPFMT
2F6DC
=DSPDGT
2F6DD
=DSPCNO
09716
=DSPCNB
0971F
=DSPCNA
09721
=DSPCL?
020B6
=DSPCHX
2F674
=DSPCHC
01C3C
=DSPCHA
01C3E
=DSPBUF
09723
=DSPBFS
2F480
=DSPBFE
2F540
=DSP$00
185DB
=DSLEEP
0056D
=DROPDC
05470
=DRANGE
1B076
=DPVCTR
0AC50
=DPOS
2F94D
=DPART3
17EF8
=DPART2
17EA3
=DONNA
09656
=DMNSN
0AE39
=DIVF
0C4B8
=DISPt
00000
=DISPP
035A4
=DISPDC
05450
=DISINT
2F470
=DEST
0F7B0
=DELAYp
02AC6
=DELAYT
2F948
=DEFADR
2F967
=DEFADC
052FC
=DECP
0328F
=DECHEX
1B2D2
=DEBNCE
00CF7
=DD3ST
2E104
=DD3END
2E160
=DD3CTL
2E1FF
=DD2ST
2E200
=DD2END
2E260
=DD2CTL
2E2FF
=DD1ST
2E300
=DD1END
2E34C
=DD1CTL
2E3FF
=DCRMNT
1C177
=DCPLIN
10108
=DCONTR
2E3FE
=DCHXW
0ECDC
=DCHXF
1B223
=DCHX=C
1B2D0
=DBLSUB
0DADD
=DBLPI4
0DAFC
=DAYYMD
13335
=DAY2JD
13407
=DATPTR
2F692
=DATLEN
0B584
=D=WORD
04C0E
=D=AVMS
1A460
=D=AVME
1A476
=D1MSTK
1954E
=D1MST+
13E21
=D1FSTK
1955D
=D1C=R3
03047
=D1@AVS
01299
=D1=AVE
18651
=D12R0A
1BA3C
=D0ASCI
09833
=D0ASC+
0982C
=D0=PCA
09B37
=D0=OBS
05067
=D0=FIB
13AC5
=D0=AVS
09B2C
=D0+2RD
13A32
=CurOff
00006
=Clear
00005
=CkLpNC
1B66D
=CkLoop
1B669
=CVUCW
03FBC
=CURTOP
10063
=CURSRU
1009A
=CURSRT
096C1
=CURSRR
151C7
=CURSRL
151CF
=CURSRD
100A4
=CURSOR
2F47E
=CURSFR
151D7
=CURSFL
151DF
=CURRST
2F55D
=CURRL
2F7E8
=CURREN
2F56C
=CURDVC
0A60B
=CURBOT
10059
=CSRW5
0ED2C
=CSRW4
0ED2F
=CSRW3
0ED32
=CSRC9
1B42F
=CSRC8
1B42C
=CSRC7
1B415
=CSRC6
1B418
=CSRC5
1B41B
=CSRC4
1B41E
=CSRC3
1B421
=CSRC2
1B424
=CSRC15
1B441
=CSRC14
1B43E
=CSRC13
1B43B
=CSRC12
1B438
=CSRC11
1B435
=CSRC10
1B432
=CSRC1
1B427
=CSPEED
2F977
=CSLW5
0ED3D
=CSLW4
0ED40
=CSLW3
0ED43
=CSLC9
1B415
=CSLC8
1B42C
=CSLC7
1B42F
=CSLC6
1B432
=CSLC5
1B435
=CSLC4
1B438
=CSLC3
1B43B
=CSLC2
1B43E
=CSLC15
1B427
=CSLC14
1B424
=CSLC13
1B421
=CSLC12
1B41E
=CSLC11
1B41B
=CSLC10
1B418
=CSLC1
1B441
=CSL9R0
1BA0D
=CRTF
116C1
=CRLFSD
022A2
=CRLFOF
02296
=CRLFND
0229E
=CRFSB-
11664
=CRETF+
084C4
=CREATE
115A7
=CRDFIL
1D21D
=CR
2C000
=CPL#10
07887
=COUNTC
1C346
=COS15
0D725
=COS12
0D721
=CORUPT
09083
=COPYu
08269
=CONVUC
152AA
=CONFST
2F9E6
=CONF
10212
=CONCOM
0467E
=COMPL#
07870
=COMCKO
032AA
=COMCK+
032AE
=COMCK
036CD
=COLLAP
091FB
=COLDST
00000
=CNVWUC
03FB8
=CNVUCR
152A7
=CNTADR
2F67E
=CNFLCT
0BD15
=CNFFND
109AC
=CMPT
125B2
=CMOSTW
2F438
=CMOSTV
0168F
=CMDS20
01672
=CMDPTR
2F6D4
=CMDPR"
01627
=CMDINI
016D1
=CMDFND
01693
=CMD1ST
01654
=CLRPRM
04827
=CLRFRC
0C6F4
=CLOSEF
12087
=CLOSEA
120E4
=CLLINK
1A72C
=CLCSTK
2F585
=CLCBFR
2F576
=CLASSA
0D590
=CKSUM4
1DBA6
=CKSUM3
153A9
=CKSUM2
0AA81
=CKSREQ
00721
=CKINFO
18542
=CKINF-
18534
=CK"ON"
076AD
=CHNLST
2F5BE
=CHNHED
0F579
=CHN#SV
2F96F
=CHKmem
012C7
=CHKSUM
1CDEE
=CHKEOL
13D6D
=CHIRP
0EC5A
=CHEDIT
14C99
=CHAIN-
07C1C
=CHAIN+
07C12
=CATEDT
06435
=CATCHR
03F70
=CATCH+
03F69
=CATC++
03F66
=CAT$90
068D7
=CAT$83
068D4
=CAT$20
06746
=CALSTK
2F5AD
=CALLP
0389C
=CALL
18DAE
=CALBIN
18D8C
=C+A2D1
1C053
=BldIMG
1BA68
=BldIMA
1BA66
=BldIM+
1BA6A
=BitsOK
00001
=BSERR
0939A
=BSCEXT
075CF
=BSCEXC
07437
=BSCEX2
0743A
=BRTF
0DC15
=BRT30
0DBE3
=BP+C
0EB40
=BOPNM-
1B864
=BLNKCK
051C1
=BLNC+
07810
=BLDLCD
0189C
=BLDDSP
01898
=BLDCON
16279
=BLDBIT
019BC
=BLANKC
07818
=BIG
0B747
=BIASC+
0D540
=BIASA+
0D52D
=BF2STK
18663
=BF2DSP
01C0E
=BF2DS+
01C08
=BEEP
0EA6E
=BCKSPC
151E7
=BASICs
000B5
=BASE
0F953
=BASCHK
0773E
=BASCHA
07741
=BACK3B
13B08
=BACK2B
13B0A
=BACK1B
13B0C
=BACK
1BA4F
=AVS=D0
01494
=AVS2DS
09708
=AVMEMS
2F594
=AVMEME
2F599
=AVM2DS
01C01
=AVE=D1
18BB8
=AVE=C
18BBB
=AUTINC
2F6CB
=ATNFLG
2F442
=ATNDIS
2F441
=ATNCLR
00510
=ATAN15
0DBBE
=ASRW5
0ED0A
=ASRW4
0ED0D
=ASRW3
0ED10
=ASNMNT
0F5E0
=ASLW5
0ED1B
=ASLW4
0ED1E
=ASLW3
0ED21
=ASIN15
0DBCC
=ASIN12
0DBC8
=ASCII
0079B
=ASCICK
0514E
=ARYSIZ
0B61B
=ARYELM
0B5A7
=ARYDC
05178
=ARRYCK
0366A
=ARITH
061E0
=ARGSTA
0E90C
=ARGST-
0E910
=ARGPRP
0E8EF
=ARGPR+
0E8EB
=ARGF
0D6A4
=ARGERR
0BF19
=ARG15
0D67F
=ARG12
0D67B
=ANNAD4
2E34E
=ANNAD3
2E34C
=ANNAD2
2E102
=ANNAD1
2E100
=ANN1.5
2E101
=ALRM6
2F755
=ALRM5
2F749
=ALRM4
2F73D
=ALRM3
2F731
=ALRM2
2F725
=ALRM1
2F719
=ALMSRV
1257D
=ALLDUN
04BEF
=ALINFO
01531
=ADRSUB
0F4CF
=ADRS80
0F567
=ADRS50
0F551
=ADRS40
0F52B
=ADJN
12825
=ADJA
1289A
=ADHEAD
181B7
=ADDRSS
0F527
=ADDRCK
1C5A5
=ADDP
03A03
=ADDONE
0C330
=ADDF
0C372
=AD2-15
0C363
=AD2-12
0C35F
=AD15s
0C369
=AD15S
0E19D
=AD15M
0C366
=ACTIVE
2F5A8
=ACOS15
0DBD7
=ACOS12
0DBD3
=ACCEPT
0450F
=A-MULT
1B349
=?PRFIL
1737E
=?PRFI+
17380
=1/X15
0C33E
=-LINE
15275
=-CHAR
1527D
=#CK
03356
@EOF
set `wc -lwc <areuh/equ/hp71.ep`
if test $1$2$3 != 3714371225112
then
	echo ERROR: wc results of areuh/equ/hp71.ep are $* should be 3714 3712 25112
fi

chmod 644 areuh/equ/hp71.ep

echo x - areuh/equ/hpil.ep
cat >areuh/equ/hpil.ep <<'@EOF'
=YTML
00C9B
=WRITIT
0691A
=WRITE#
0453F
=UTLEND
007CC
=ULYL
00C55
=TSTATA
04205
=TSTAT
041FE
=START-
007F1
=START+
007EE
=START
007E8
=SKP-LF
02248
=SETUP
03D33
=SETLP
03B7D
=SENDIT
0698F
=SENDI+
06989
=SEEKRD
062D8
=SEEKB
04239
=SEEKA
04232
=SAVEIT
03DB6
=ROMTYP
040D2
=RESTRT
02FF8
=RESTOR
03E5C
=REDCHR
02262
=REDC00
02252
=RED-LF
0224F
=READSU
0663D
=READRG
06805
=READIT
06649
=READ#
044FF
=RDST01
0226C
=PUTX
06A02
=PUTGF-
00BE9
=PUTGF+
00BED
=PUTGF
00BF1
=PUTEX
06AC8
=PUTEN
06AF1
=PUTE
06AC0
=PUTDX
00E55
=PUTD
06AAE
=PUTCN
06AEC
=PUTC+N
06AE8
=PUTC+
06B18
=PUTC
06B1C
=PUTARL
00E25
=PUTALR
00E3D
=PROCST
06EBB
=PROCLT
071CE
=PROCDW
07180
=PRNTSp
07468
=PRNTSd
07B3E
=PRMSGA
00CB9
=PREND
01022
=PRASCI
00FEA
=PACKd
07B4A
=NXTENT
04A1E
=NEWFIL
04A65
=NEWFI+
04A49
=NAMEpb
07994
=NAMEp
07998
=MTYLL
00C8A
=MTYL
00C83
=MOVEFL
04571
=LSTENT
04A34
=LOOP#p
076A7
=LOOP#d
07CAA
=LISTEN
00C5C
=INITFL
068E4
=GTYPST
06FF3
=GTYPRM
03F6E
=GTYPR+
03F6C
=GTYPE
00BFF
=GLOOP#
02D5A
=GHEXBT
03F7D
=GHEXB+
03F81
=GFTYPE
02D96
=GETX
066B0
=GETST-
0679E
=GETST
06787
=GETPIL
06E0B
=GETPI+
06E14
=GETNE
0673B
=GETMBX
03B62
=GETLPs
01D15
=GETID+
067FA
=GETID
0680E
=GETHSS
0313A
=GETERR
06791
=GETEND
067E5
=GETDev
00B5B
=GETDVW
07133
=GETDR+
047F9
=GETDR#
047E0
=GETDR"
047DE
=GETDIX
06DA2
=GETDIR
04820
=GETDID
06D84
=GETDI!
047D7
=GETD
067C8
=GET
06751
=GDIRST
04843
=GADRST
07064
=GADRRM
03FAB
=GADRR+
03FBA
=GADDR
008FF
=FXQPIL
0734F
=FRASPp
07CC9
=FRASPp
076D4
=FRAMEE
06B43
=FRAME-
0073B
=FRAME+
0072D
=FORMAT
04291
=FNDMBX
03BE0
=FNDMBD
03BCA
=FNDMB-
03BAB
=FNDMB+
03BA7
=FNDCHK
00B86
=FNDCH-
00B7B
=FINDFx
04732
=FINDFL
0469F
=FINDF+
046A6
=ENDTAP
044D9
=ENDFN
007C0
=DVCSPp
07925
=DSPCAT
06571
=DEVPR$
01C36
=DEVPAR
01BF0
=DDT
06B34
=DDL
06B25
=CHKSTS
00B8F
=CHKST+
03160
=CHKSET
03149
=CHKMAS
0425C
=CHKASN
03C57
=CHKAIO
04086
=BLDCAT
06300
=BDISPJ
035A2
@EOF
set `wc -lwc <areuh/equ/hpil.ep`
if test $1$2$3 != 2722721854
then
	echo ERROR: wc results of areuh/equ/hpil.ep are $* should be 272 272 1854
fi

chmod 644 areuh/equ/hpil.ep

echo x - areuh/equ/Makefile
cat >areuh/equ/Makefile <<'@EOF'
#
# Ce Makefile fait un minimum de choses
#

LIBDEST	      = /usr/local/lib

EP	      = hp71.ep hpil.ep

#
# Les cibles :
#	all : rien (ne fait que signaler l'absence eventuelle de hp71.ep)
#	install : installe le programme dans l'aborescence
#	clean : rien (compatibilite avec le Makefile general)
#	clobber : rien (compatibilite avec le Makefile general)
#	tags : rien (compatibilite avec le Makefile general)
#

all:		$(EP)

depend:;	mkmf ROOT=$(ROOT)

install:	$(EP)
		if [ "$(LIBDEST)" != . ] ; \
		then \
		    (cd $(LIBDEST) ; rm -f $(EP)) ; \
		    cp $(EP) $(LIBDEST) ;\
		fi ;

clean: ;

clobber: ;

tags: ;
@EOF
set `wc -lwc <areuh/equ/Makefile`
if test $1$2$3 != 33107618
then
	echo ERROR: wc results of areuh/equ/Makefile are $* should be 33 107 618
fi

chmod 644 areuh/equ/Makefile

exit 0

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:32:59 1990
#
# This archive contains:
#	areuh/load/acp.c		areuh/msg/amg.c			
#	areuh/msg/amg.1			areuh/msg/Makefile		
#	areuh/jmpdoc/A			areuh/jmpdoc/sauts		
#	areuh/jmpdoc/algo		areuh/jmpdoc/jmpparam		
#	areuh/jmpdoc/jmp.c		areuh/Makefile			
#	areuh/assembler/aerror.c	areuh/assembler/agen.h		
#	areuh/assembler/aglobal.h	
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - areuh/load/acp.c
cat >areuh/load/acp.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include <stdio.h>
#include <time.h>

typedef unsigned short uint16 ;
typedef unsigned long uint32 ;

struct disc_hdr
{
    uint16  mlfi ;			/* Lif Id (0x8000) */
    char   l_label [6] ;		/* volume label */
    uint32 l_dstart ;			/* directory start record (usually 2) */
    uint16 l_sys3000 ;			/* system 3000 (0x1000) */
    uint16 l_spare1 ;			/* 0x0000 */
    uint32 l_dirlen ;			/* directory length */
    uint16 l_version ;			/* 0x0001 */
    uint16 l_spare2 ;			/* 0x0000 */
    uint32 trkpersurf ;			/* tracks per surface */
    uint32 surfpermed ;			/* number of surfaces */
    uint32 sectpertrk ;			/* records per track */
    char   l_date [6] ;			/* date & time */
    char   l_spare [213] ;		/* padding */
} ;

struct lif_filent
{
    char    l_filnam [10] ;		/* file name */
    uint16  l_filtyp ;			/* file type */
    uint32  l_startsec ;		/* start record */
    uint32  l_fillen ;			/* file length */
    char    l_create_time [6] ;		/* date & time created */
    uint16  l_flagwd ;			/* volume flag/number 0x8001 */
    uint32  l_startexec ;		/* implementation */
} ;

FILE *fp, *fplif, *fpw ;
char filename[10] ;
int type ;
long int dir_sec, data_sec ;
struct lif_filent dir_entry, areuh_dir ;
struct disc_hdr header ;
long int a = 0, b = 0, eod = 0 ;

#define DISK "/dev/dsk/floppy"

main (argc, argv)
int argc ;
char *argv[] ;
{
    long int magic ;

    if (argc!=2)
    {
        fprintf (stderr, "usage: acp file\n") ;
        exit (1) ;
    }

    if (!(fp=fopen (argv[1], "r")))
    {
        fprintf (stderr, "acp: cannot open file %s\n", argv[1]) ;
        exit (1) ;
    }
    fread (&magic, sizeof (long int), 1 , fp) ;
    if (magic!=0x1b080100)
    {
        fprintf (stderr, "acp: %s not a lex file\n", argv[1]) ;
        exit (1) ;
    }
    if (!(fplif=fopen (DISK, "r")))
    {
        fprintf (stderr, "acp: cannot open %s for read\n", DISK) ;
        exit (1) ;
    }
    if (!read_lif ())
    {
        fprintf (stderr, "acp: not a LIF disk\n") ;
        exit (1) ;
    }
    read_file_infos () ;
    search_dir () ;
    if (!(fpw=fopen (DISK, "w")))
    {
        fprintf (stderr, "acp: cannot open %s for write\n", DISK) ;
        exit (1) ;
    }
    write_data () ;
    write_dir () ;
    if (fclose (fplif))
    {
        fprintf (stderr, "acp: cannot close %s opened for read\n", DISK) ;
        exit (1) ;
    }
    if (fclose (fpw))
    {
        fprintf (stderr, "acp: cannot close %s opened for write\n", DISK) ;
        exit (1) ;
    }
    if (fclose (fp))
    {
        fprintf (stderr, "acp: cannot close file %s\n", argv[1]) ;
        exit (1) ;
    }
    exit (0) ;
}

skip (n)
int n ;
{
    char c ;
    int i ;

    for (i=1; i<=n; i++) fread (&c, 1, 1, fp) ;
}

con (pvar, n)
unsigned int *pvar ;
int n ;
{
    int i ;
    unsigned char areuh [256] ;

    fread (areuh, n, 1, fp) ;
    *pvar = 0 ;
    for (i=n-1; i>=0; i--)
    {
        *pvar = (*pvar * 16) + hex(areuh[i]) ;
    }
}

read_file_infos ()
{
    int i ;
    unsigned int c ;
    int length, length_sect ;

    for (i=0; i<8; i++)
    {
        con (&c, 2) ;
        dir_entry.l_filnam[i] = (unsigned char) c ;
    }
    dir_entry.l_filnam[8] = ' ' ;
    dir_entry.l_filnam[9] = ' ' ;
    con (&c, 4) ;
    dir_entry.l_filtyp = (unsigned short) c ;
    skip (12) ;
    con (&length, 5) ;
    length_sect = (length -= 5 ) ;

    read_date (dir_entry.l_create_time) ;

    dir_entry.l_startexec = 0 ;
    for (i=0; i<4; i++)
    {  
        c = length&0xff ;
        dir_entry.l_startexec = (((unsigned int) dir_entry.l_startexec)*0x100)
            + c ;
        length /= 256 ;
    }
 
    dir_entry.l_fillen = length_sect / 512 + ((length_sect%512) ? 1 : 0) ;
    dir_entry.l_flagwd = (unsigned short int) 0x8001 ;
}

read_date (str)
char *str ;
{
    int i ;
    long clock ;
    struct tm *ptm ;

    clock = time ((long *) 0) ;
    ptm = localtime (&clock) ;
    str [0] = bcd (ptm->tm_year) ;
    str [1] = bcd (ptm->tm_mon + 1) ;
    str [2] = bcd (ptm->tm_mday) ;
    str [3] = bcd (ptm->tm_hour) ;
    str [4] = bcd (ptm->tm_min) ;
    str [5] = '\0' ;
}

int bcd (n)
int n ;
{
    return (((n / 10) * 16) + (n % 10)) ;
}

int read_lif ()
{
    fread (&header, sizeof (header), 1, fplif) ;
    if (((unsigned short)header.mlfi)!=0x8000) return (0) ;
    return (1) ;
}

search_dir()
{
    struct lif_filent cur_dir_entry ;
    long int compteur = 1, sod, sodn, limite ;

    sod = header.l_dstart  + header.l_dirlen ;
    limite = ((unsigned) header.l_dirlen)*8 ;
    fseek (fplif, header.l_dstart*0x100, 0) ;
    fread (&cur_dir_entry, sizeof(cur_dir_entry), 1, fplif) ;
    while ((cur_dir_entry.l_filtyp != 0xffff)&&(compteur<=limite))
    {
        if ((cur_dir_entry.l_filtyp == 0) &&
            (cur_dir_entry.l_fillen >= dir_entry.l_fillen) && !a ) 
        {
            a = ftell (fplif) - 32 ;
            sodn = cur_dir_entry.l_startsec ;
        }
        else if (strncmp (cur_dir_entry.l_filnam, dir_entry.l_filnam, 10) == 0)
        {
            b = ftell (fplif) - 32 ;
            memcpy ((char *) &areuh_dir, (char *) &cur_dir_entry, 32) ;
        }
        sod = cur_dir_entry.l_startsec + cur_dir_entry.l_fillen ;
        fread (&cur_dir_entry, sizeof(cur_dir_entry), 1, fplif) ;
        compteur++ ;
    }
    if ((b) && (areuh_dir.l_fillen >= dir_entry.l_fillen))
    {
        a = b ;
        b = 0 ;
        sodn = areuh_dir.l_startsec ;
    }
    else if (!a)
    {
        if (compteur <= limite)
        {
            eod = ftell (fplif) ;
            a = eod - 32 ;
            sodn = sod ;
            if (sodn+((unsigned) dir_entry.l_fillen)>=
                                          ((unsigned) header.trkpersurf) *
                                          ((unsigned) header.surfpermed) *
                                          ((unsigned) header.sectpertrk))
            {
                fprintf (stderr, "acp: no room in data area\n") ;
                exit (1) ;
            }
        }
        else
        {
            fprintf (stderr, "acp: no room in directory area\n") ;
            exit (1) ;
        }
    }
    dir_entry.l_startsec = sodn ;
}

write_data ()
{
    int c = 0, d ;

    fseek (fpw, ((unsigned long) dir_entry.l_startsec)*0x100, 0) ;
    while ((d=getc (fp))!=EOF)
    {
        if (c)
        {
            fputc (hex(d)*16+hex(c), fpw) ;
            c = 0 ;
        }
        else c = d ;
    }
    if (c) fputc (hex(c), fpw) ;
}

int hex (c)
int c ;
{
    return (((c>='A')&&(c<='F'))?c-'A'+10:c-'0') ;
}

write_dir ()
{
    long int *plong, i ;

    update (a, &dir_entry) ;
    if (b)
    {
        areuh_dir.l_filtyp = 0 ;
        update (b, &areuh_dir) ;
    }
    if (eod)
    {
        plong = (long int *) &areuh_dir ;
        for (i=1; i<=8; i++)
        {
            *plong = -1 ;
            plong++ ;
        }
        update (eod, &areuh_dir) ;
    }
}

update (x, pdir)
long int x ;
struct lif_filent *pdir ;
{
    struct lif_filent sector[8] ;

/*
fclose(fpw) ; fpw = fopen (DISK, "w") ;
fclose(fplif) ; fplif = fopen (DISK, "r") ;
    fseek (fplif, x, 0) ;
    fread (sector, sizeof (sector), 1, fplif) ;
    write (sector, sizeof (sector), 1, fpw) ;
    memcpy (&sector[(x/32) % 8], pdir, 32) ;
    fseek (fpw, x, 0) ;
    fwrite (sector, sizeof (sector), 1, fpw) ;
*/

    fseek (fpw, x, 0) ;
    fwrite (pdir, sizeof *pdir, 1, fpw) ;
}
@EOF
set `wc -lwc <areuh/load/acp.c`
if test $1$2$3 != 32511297588
then
	echo ERROR: wc results of areuh/load/acp.c are $* should be 325 1129 7588
fi

chmod 644 areuh/load/acp.c

echo x - areuh/msg/amg.c
cat >areuh/msg/amg.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include <stdio.h>		    /* Pour emmerder J.T. */

#define EOL '\0'		    /* End Of Line */
#define NSTR ""			    /* null string */
#define SPEC_CHAR '\\'		    /* special character */
#define MAXLEN 500		    /* input line max length */
#define MSGLEN 48		    /* message max length */
#define LBLMAX 7		    /* length of a sasm label */

#define BBMAX	64		    /* max number of building blocks */
#define MGMAX	255		    /* max number of messages	     */

#define ERRUSA	1		    /* usage: msg in_file out_file [n] */
#define ERRINP	2		    /* invalid input line */
#define ERRIVL	3		    /* invalid building block */
#define ERRTMB	4		    /* too many blocks */
#define ERRTMM	5		    /* too many messages */
#define ERRNSB	6		    /* no sufficient space for blocks */
#define ERRFST	7		    /* no valid first message */


#define VALUE(p) ((p)&((token)0xff))/* value of a token */
#define MFBB (token) 0x100	    /* MainFrame Building Block */
#define LLBB (token) 0x200	    /* LocaL Building Block */
#define ASCH (token) 0x400	    /* AScii CHaracter */
#define INST (token) 0x800	    /* INSerTion mark */

typedef short int token ;	    /* token = (type, value)  */

/* ascii representations of messages / building blocks */

char mftab[17][MSGLEN+1] ;	    /* mainframe building blocks */
char bbtab[BBMAX][MSGLEN+1] ;	    /* local building blocks table */
char mgtab[MGMAX][MSGLEN+1] ;	    /* message table */

/* tokenised representations for local messages / building blocks */
token bbtok[BBMAX][MSGLEN+1] ;	    /* local building blocks */
token mgtok[MGMAX][MSGLEN+1] ;	    /* messages */

/* length of local messages / building blocks */
short int bblen[BBMAX] ;
short int mglen[MGMAX] ;

/* symbolic labels for messages */
char lbltab[MGMAX][LBLMAX+1] ;

int mbase = 0 ;	  /* base for message numerotation */
int bbase ;	  /* base for building block numerotation */

int mdep ;	  /* relative message number (relative to mbase) */
int bdep ;	  /* idem for building blocks */

char line [MAXLEN+1] ;		    /* input line */
char *pline ;

int ln = 0 ;			    /* line number */

int ind16 ;			    /* msg # whose length is 16, 32, 48... */
#define INMG 0x100		    /* msg in mgtab */
#define INBB 0x200		    /* msg in bbtab */

token read_block () ;


/******************************************************************************
				     MAIN

purpose : main program. see called procedures for information.
******************************************************************************/
main (argc, argv)
int argc ;
char *argv[] ;
{
    if (argc>2) erreur(ERRUSA) ;
    else if (argc==2) mbase = atoi(argv[1]) ;

    init () ;
    pass1 () ;
    between () ;
    pass2 () ;
    exit (0) ;
}


/******************************************************************************
				     INIT

purpose : initializes "mainframe building blocks" list.
******************************************************************************/
init ()
{
    strcpy (mftab [0], "Illegal ") ;
    strcpy (mftab [1], " Expected") ;
    strcpy (mftab [2], " Not Found") ;
    strcpy (mftab [3], "Context") ;
    strcpy (mftab [4], "File") ;
    strcpy (mftab [5], " w/o ") ;
    strcpy (mftab [6], "Invalid ") ;
    strcpy (mftab [7], "Stat") ;
    strcpy (mftab [8], "Too ") ;
    strcpy (mftab [9], ": Align then ENDLN") ;
    strcpy (mftab[10], "Transform") ;
    strcpy (mftab[11], "Inf") ;
    strcpy (mftab[12], " Input") ;
    strcpy (mftab[13], " Ovfl") ;
    strcpy (mftab[14], "Pull") ;
    strcpy (mftab[15], "") ;		 /* insert message : ### of ### */
    strcpy (mftab[16], " Protect") ;
}


/******************************************************************************
				READ_LINE

synopsis : int read_line ()
description : reads a line from stdin
note : returns -1 if EOF reached, 0 otherwise
******************************************************************************/
int read_line ()
{
    int c, i = -1 ;

    ln++ ;		    /* new line to be read */
    do
    {
	c = getchar () ;
	if (i<MAXLEN) line[++i] = (char) c ;
    }
    while ((c!=EOF)&&(c!='\n')) ;
    line [i] = EOL ;
    return ( (c==EOF) ? -1 : 0) ;
}


/******************************************************************************
				 BUILD_LABEL

purpose : scans the line, isolate the label if exits, otherwise generates it.
******************************************************************************/
build_label ()
{
    int i = 0 ;

    while ((*pline!=':')&&(*pline!=EOL))
    {
	if (i<LBLMAX) lbltab [mdep][i++] = *pline ;
	pline++ ;
    }
    if (*pline==EOL) erreur (ERRINP) ;
    pline++ ;
    if (i) lbltab [mdep][i] = EOL ;
    else sprintf (lbltab[mdep], "MSG%d", mbase + mdep) ;
}


/******************************************************************************
			     GET_CODE

synopsis : get_code ()
purpose : parses a number if possible (three digits < 256), and modify input
  line and its pointer (line/pline). If not possible, returns pline unchanged.
******************************************************************************/
void get_code ()
{
    register char *pp ;
    register int code ;

    pp = pline ;
    code = (*(pp++)-'0') * 100 ;
    if ((*pp<'0') || (*pp>'9')) return ;
    code += (*(pp++)-'0') * 10 ;
    if ((*pp<'0') || (*pp>'9')) return ;
    code += (*pp)-'0' ;
    if (code>255) return ;
    pline = pp ;
    *pline = (char)code ;
    return ;
}


/******************************************************************************
			       PASS1

synopsis : pass1 ()
purpose : reads stdin and, for each line, parses it, creates local building
  blocks if any, and tokenises the message.
******************************************************************************/
pass1 ()
{
    int itok, ncar, iascii ;
    token bb ;

    mdep = 0 ;
    bdep = 0 ;
    while (read_line () == 0)
    {
	pline = line ;
	build_label () ;
	mglen [mdep] = 4 + 1 ;	 /* 4 for (blk len, msg #), 1 for blk term. */
	itok = 0 ;
	ncar = 0 ;
	iascii = 0 ;
	while (*pline)
	{
	    switch (*pline)
	    {
		case '^' :		/* insert text cell */
		    if (*(pline+1)==' ')
		    {
			pline++ ;	   /* trailing space */
			mgtok [mdep][itok++] = INST + 0xf3 ;
		    }
		    else
			mgtok [mdep][itok++] = INST + 0xf2 ;
		    mgtab [mdep][iascii++] = '^' ;
		    mglen [mdep] += 2 ;
		    ncar = 0 ;
		    break ;
		case '[' :
		    pline++ ;
		    bb = read_block () ;     /* bb  is a full token */
		    mgtok [mdep][itok++] = bb ;
		    mgtab [mdep][iascii] = EOL ;
		    strcat (mgtab[mdep], (bb&MFBB) ? mftab [VALUE(bb)-230]
						   : bbtab [VALUE(bb)] ) ;
		    iascii = strlen (mgtab[mdep]) ;
		    mglen [mdep] += 3 ;
		    ncar = 0 ;
		    break ;
		case SPEC_CHAR :
		    pline++ ;
		    if (*pline==EOL) break ;
		    if ((*pline=='0')||(*pline=='1')||(*pline=='2'))
			get_code () ;
		default :
		    if (ncar == 0 ) mglen[mdep] ++ ;
		    ncar++ ;
		    mgtab [mdep][iascii++] = *pline ;
		    mgtok [mdep][itok++] = ASCH + (unsigned char) *pline ;
		    mglen [mdep] += 2 ;
		    if (ncar == 12) mglen [mdep] ++ ; /* cell > 11 char */
		    else if (ncar == 17)
		    {
			ncar = 1 ;
			mglen [mdep] ++ ;
		    }
		    break ;
	    }
	    pline++ ;
	}
	mgtab[mdep][iascii] = EOL ;
	mdep++ ;
	if (mdep>MGMAX) erreur (ERRTMM) ;
    }
}


/******************************************************************************
			      READ_BLOCK

synopsis : token read_block ()
purpose : reads a block in input line, finds it if already defined. Otherwise
  stores it in block tables. Returns a complete token.
******************************************************************************/
token read_block ()
{
    int iascii = 0 ;
    int ncar = 0 ;
    int x, itok = 0 ;

    bblen [bdep] = 5 ;
    while ((*pline)&&(*pline!=']'))
    {
	if (*pline==SPEC_CHAR)
	{
	    pline++ ;
	    if (*pline==EOL) break ;
	    if ((*pline=='0')||(*pline=='1')||(*pline=='2'))
		get_code () ;
	}
	if (*pline==EOL) erreur (ERRIVL) ;
	if (ncar==0) bblen [bdep] ++ ;
	ncar++ ;
	bbtab [bdep][iascii++] = *pline ;
	bbtok [bdep][itok++] = ASCH + (unsigned char) *pline ;
	bblen [bdep] += 2 ;
	if (ncar == 12) bblen [bdep]++ ;
	else if (ncar == 17)
	{
	    ncar = 1 ;
	    bblen [bdep]++ ;
	}
	pline++ ;
    }
    if (*pline==EOL) erreur (ERRIVL) ;
    bbtab [bdep][iascii] = EOL ;
    bbtok [bdep][itok] = (token) 0 ;
    x = find_block (bbtab[bdep], mftab, 16) ;
    if (x>=0) return ((token)(MFBB + x + 230)) ;
    x = find_block (bbtab[bdep], bbtab, bdep-1) ;
    if (x>=0) return ((token)(LLBB + x)) ;
    if (bdep>=BBMAX) erreur (ERRTMB) ;
    return ((token)(LLBB + bdep++)) ;
}


/******************************************************************************
				 FIND_BLOCK

synopsis : int find_block (areuh, tab, imax)
	   char *areuh ;
	   char tab [][MSGLEN+1] ;
	   int imax ;
purpose : searches in table tab (mainframe / local building blocks) for 
  areuh building block. If found, return its index, otherwise -1.
******************************************************************************/
int find_block (areuh, tab, imax)
char *areuh ;
char tab[][MSGLEN+1] ;
int imax ;
{
    int i ;

    for (i=0; i<=imax; i++)
	if (strcmp (tab[i], areuh)==0) return (i) ;
    return (-1) ;
}


/******************************************************************************
				   FIND_16

synopsis : int find_16 (xxlen, dep)
	   short int xxlen[] ;
	   int dep ;
description : returns the index of a message whose length is a multiple of 16,
  otherwise -1.
******************************************************************************/
int find_16 (xxlen, dep)
short int xxlen[] ;
int dep ;
{
    int i = 0 ;

    while (i<dep)
	if (xxlen[i] % 16) i++ ;
	else break ;
    return ((i==dep) ? -1 : i) ;
}


/******************************************************************************
				   BETWEEN

synopsis : between ()
purpose : find a message length multiple of 16. If no one, then disp an error
  message and build a comment.
  Caclulate base for building blocks.
******************************************************************************/
between ()
{
    ind16 = find_16 (mglen, mdep) ;
    if (ind16>=0)
	ind16 += INMG ;
    else
    {
	ind16 = find_16 (bblen, bdep) ;
	if (ind16>=0)
	    ind16 += INBB ;
	else
	{
	    ind16 = 0 ;
	    printf ("**************************\n") ;
	    printf ("* E R R O R        ! ! ! *\n") ;
	    printf ("*                        *\n") ;
	    printf ("* no valid first message *\n") ;
	    printf ("**************************\n") ;
	}
    }
    if (mbase + mdep + bdep - 1 <= 255)
	bbase = mbase + mdep ;
    else
    {
	if (bdep < mbase)
	    bbase = 0 ;
	else erreur (ERRNSB) ; /* no sufficient space for blocks */
    }
}


/******************************************************************************
				     PASS2

synopsis : pass2 ()
purpose : sends output to stdout.
******************************************************************************/
pass2 ()
{
    int index ;

    header () ;

    index = ind16 & ~(INMG | INBB) ;
    switch (ind16 & (INMG | INBB))
    {
	case INMG :
	    print_msg (mgtab, mgtok, mglen, index) ;
	    break ;
	case INBB :
	    print_msg (bbtab, bbtok, bblen, index) ;
	    break ;
/*	default :    there is no valid first message */
    }

    if (ind16 & INMG)
    {
	build (mgtab, mgtok, mglen, 0, index - 1) ;
	build (mgtab, mgtok, mglen, index + 1, mdep - 1) ;
    }
    else build (mgtab, mgtok, mglen, 0, mdep - 1) ;

    if (ind16 & INBB)
    {
	build (bbtab, bbtok, bblen, 0, index - 1) ;
	build (bbtab, bbtok, bblen, index + 1, bdep - 1) ;
    }
    else build (bbtab, bbtok, bblen, 0, bdep - 1) ;

    terminator () ;
}


/******************************************************************************
				   PRINT_MSG

synopsis : print_msg (tab, tok, len, ind)
	   char tab [][MSGLEN+1] ;
	   token tok [][MSGLEN+1] ;
	   short int len [] ;
	   int ind ;
purpose : outputs message ind in table (tab, tok, len).
******************************************************************************/
print_msg (tab, tok, len, ind)
char tab [][MSGLEN+1] ;
token tok [][MSGLEN+1] ;
short int len [] ;
int ind ;
{
    token c ;
    int msg, j, k ;
    char areuh [MAXLEN] ;

    msg = ((tab==mgtab) ? 1 : 0) ;
    printf ("\n") ;
    printf ("* %s\n", tab[ind]) ;	/* message text */
    printf ("%8sCON(2) %d\n", NSTR, len[ind]) ;	      /* length */

    printf ("%8sCON(2) ", NSTR) ;
    if (msg) printf ("%-7s", lbltab [ind]) ;
    else printf ("BB%-3d  ", bbase + ind ) ;
    printf ("  Message # %d\n", ((msg) ? mbase : bbase) + ind) ;

    j = 0 ;
    while (tok[ind][j])
    {
	switch ((tok[ind][j]) & (MFBB | LLBB | ASCH | INST) )
	{
	    case (int)MFBB :
		printf ("%8sCON(1) 14\n", NSTR) ;
		printf ("%8sCON(2) %d\n", NSTR, VALUE(tok[ind][j])) ;
		j++ ;
		break ;
	    case (int)LLBB :
		printf ("%8sCON(1) 13\n", NSTR) ;
		printf ("%8sCON(2) BB%d\n", NSTR, bbase + VALUE(tok[ind][j])) ;
		j++ ;
		break ;
	    case (int)INST :
		printf ("%8sNIBHEX %2x\n", NSTR, VALUE(tok[ind][j])) ;
		j++ ;
		break ;
	    case (int)ASCH :
		k = 0 ;
		while (((c=tok[ind][j+k])&ASCH) && (k<16))
		    areuh [k++] = VALUE (c) ;
		areuh [k] = EOL ;
		if (k<=8)
		{
		    printf ("%8sCON(1) %d\n", NSTR, k-1) ;
		    output_ascii (areuh, k) ;
		}
		else if (k<=11)
		{
		    printf ("%8sCON(1) %d\n", NSTR, k-1) ;
		    output_ascii (areuh, 8) ;
		    output_ascii (areuh+8, k-8) ;
		}
		else
		{
		    printf ("%8sCON(1) 11\n", NSTR) ;
		    printf ("%8sCON(1) %d\n", NSTR, k-1) ;
		    output_ascii (areuh, 8) ;
		    output_ascii (areuh+8, k-8) ;
		}
		j += k ;
	}
    }
    printf ("%8sCON(1) 12\n", NSTR) ;
}


/******************************************************************************
				  OUTPUT_ASCII

synopsis : output_ascii (str, len)
	   char *str ;
	   int len ;
purpose : outputs a string in sasm format (NIBASC / CON()), depending on the
  ascii value of characters.
******************************************************************************/
output_ascii (str, len)
unsigned char *str ;
int len ;
{
    char buf[MAXLEN] ;
    char *pbuf ;

    pbuf = buf ;
    while (len--)
    {
	if ((*str >= 0x20) && (*str <= 0x7e) && (*str != '\''))
	{
	    *pbuf = *str ;
	    pbuf++ ;
	}
	else
	{
	    if (pbuf != buf)
	    {
		*pbuf = EOL ;
		printf ("%8sNIBASC '%s'\n", NSTR, buf) ;
		pbuf = buf ;
	    }
	    printf ("%8sCON(2) %d\n", NSTR, *str) ;
	}
	str++ ;
    }
    if (pbuf != buf)
    {
	*pbuf = EOL ;
	printf ("%8sNIBASC '%s'\n", NSTR, buf) ;
    }
}


/******************************************************************************
				    BUILD

synospis : build (tab, tok, len, n1, n2)
	   char tab [][MSGLEN+1] ;
	   token tok [][MSGLEN+1] ;
	   short int len [] ;
	   int n1, n2 ;
purpose : build a list of messages.
******************************************************************************/
build (tab, tok, len, n1, n2)
char tab [][MSGLEN+1] ;
token tok [][MSGLEN+1] ;
short int len [] ;
int n1, n2 ;
{
    int i ;
 
    for (i=n1; i<=n2; i++)
	print_msg (tab, tok, len, i) ;
}


/******************************************************************************
			       HEADER

synopsis : header ()
purpose : print table header, cad EQU table, lowest and highest msg #.
******************************************************************************/
header ()
{
    int i ;

    printf ("MBASE   EQU    %d\n", mbase) ;
    for (i=0; i<mdep; i++)
	printf ("%-7s EQU    (MBASE)+%-3d  %s\n", lbltab[i], i, mgtab[i]) ;

    if (bdep)
    {
	printf ("\n") ;
	for (i=0; i<bdep; i++)
	    printf ("BB%-3d   EQU    %-11d  %s\n",
		bbase + i, bbase + i, mgtab[i]) ;
    }

    printf ("\n") ;
    printf ("=MSGTBL\n") ;
    printf ("%8sCON(2) (MBASE)+0    Lowest message #\n", NSTR) ;
    printf ("%8sCON(2) (MBASE)+%-3d  Highest message #\n", NSTR, mdep-1) ;
}


/******************************************************************************
			       TERMINATOR

synospsis : terminator ()
purpose : print "NIBHEX FF"
******************************************************************************/
terminator ()
{
    printf ("\n") ;
    printf ("%8sNIBHEX FF       Table terminator\n", NSTR);
    if (ind16==0) erreur (ERRFST) ;
}


/******************************************************************************
				ERREUR

synopsis : erreur (errn)
purpose : declenche une erreur de numero errn
******************************************************************************/
erreur (errn)
{
    fprintf (stderr, "amg: error in line %d, ", ln) ;
    switch (errn)
    {
	case ERRUSA :
	    fprintf (stderr, "usage: amg [n]\n") ;
	    break ;
	case ERRINP :
	    fprintf (stderr, "invalid source line\n") ;
	    break ;
	case ERRIVL :
	    fprintf (stderr, "invalid building block\n") ;
	    break ;
	case ERRTMB :
	    fprintf (stderr, "too many blocks\n") ;
	    break ;
	case ERRTMM :
	    fprintf (stderr, "too many messages\n") ;
	    break ;
	case ERRNSB :
	    fprintf (stderr, "not enough space for blocks\n") ;
	    break ;
	case ERRFST :
	    fprintf (stderr, "no valid first message\n") ;
	    break ;
    }
    exit(2) ;
}
@EOF
set `wc -lwc <areuh/msg/amg.c`
if test $1$2$3 != 667243217247
then
	echo ERROR: wc results of areuh/msg/amg.c are $* should be 667 2432 17247
fi

chmod 644 areuh/msg/amg.c

echo x - areuh/msg/amg.1
cat >areuh/msg/amg.1 <<'@EOF'
.TH AMG 1L
.SH NAME
amg \- areuh message generator
.SH SYNOPSIS
.B amg
[
.I first message
]
.SH DESCRIPTION
.I Amg
est un generateur de table de messages pour le HP-71.
Il admet sur l'entree standard une suite de messages, un
par ligne et place sur la sortie standard un texte source
(a assembler avec
.BR aas (1L))
constituant ainsi une table de messages a inserer dans
un source de fichier Lex.
.PP
Un message est specifie suivant le format suivant :
.RS 5n
.nf
	label:message
.fi
.RE
ou
.I label
est une etiquette symbolique utilisee par l'assembleur et
.I message
est le message. Attention aux espaces superflus.
.PP
Les messages sont des suites de caracteres. Certains caracteres ont
une signification speciale. Il s'agit de :
.TP 15
.B \[
Introduit un
.I building block. Si c'est un building block du systeme,
.B amg
y fait reference, sinon un nouveau building block est genere.
Le caractere
.B \]
marque la fin du building block.
.TP
.B ^
Indique une insertion dans le message. Voir les IDS I pour plus
de details.
.TP
<backslash>
Neutralise la signification speciale du caractere suivant, ou
introduit un caractere non imprimable par son code octal.
.PP
Le systeme d'exploitation du HP-71 contient 17 buildings-blocks
integres.
.B Amg
les reconnait automatiquement, il s'agit de :
.RS 5n
.nf
 0	"Illegal "
 1	" Expected"
 2	" Not Found"
 3	"Context"
 4	"File"
 5	" w/o "
 6	"Invalid "
 7	"Stat"
 8	"Too "
 9	": Align then ENDLN"
10	"Transform"
11	"Inf"
12	" Input"
13	" Ovfl"
14	"Pull"
15	/* insert message : ### of ### */
16	" Protect"
.fi
.RE
.PP
.B Amg
definit le symbole
.B =MSGTBL
destine a etre reference dans l'en-tete du fichier Lex. Les symboles
definis par l'utilisateur sont aussi definis, mais ils sont exportes
seulement si l'utilisateur a place un signe
.B =
au debut de l'etiquette.
.PP
L'exemple suivant est la table des messages de JPC Rom :
.RS 5n
.nf
=eHEAD:JPC 
=eDRIVE:Driver Lex File
=eNSTRG:Not Found
=eSTRUC:Structure Mismatch
=eIPRMP:[Invalid ]Prompt
=eIFMT:[Invalid ]Format
=eIDIM:#Dims
=eINOVR:Var[ Not Found]
=eSUN:Sun[day]
=eMON:Mon[day]
=eTUE:Tues[day]
=eWED:Wednes[day]
=eTHU:Thurs[day]
=eFRI:Fri[day]
=eSAT:Satur[day]
=eFNINT:Function Interrupted
=eOBSOL:Removed Keyword
=eCPYRG:(c) 1986, 1987, 1988 PPC-Paris
.fi
.RE
.SH DIAGNOSTICS
.PP
.B Amg
signale une erreur lorsqu'aucun message ne respecte la regle du
premier message (longueur multiple de 4), mais genere un source
quand meme.
.SH AUTHORS
Pierre David
Janick Taillandier
.SH SEE ALSO
aas(1L),
ald(1L),
adp(1L),
cp71(1L).
.br
.I "IDS vol I"
for HP-71.
@EOF
set `wc -lwc <areuh/msg/amg.1`
if test $1$2$3 != 1254192549
then
	echo ERROR: wc results of areuh/msg/amg.1 are $* should be 125 419 2549
fi

chmod 644 areuh/msg/amg.1

echo x - areuh/msg/Makefile
cat >areuh/msg/Makefile <<'@EOF'
#
# Makefile genere automatiquement par mkmf (le masque par defaut a ete adapte)
#

CFLAGS	      = -O
LDFLAGS	      =
LIBS	      =
SYSLIBS	      =
BINDEST	      = /usr/local/bin

#
# S'il y a plus d'un programme, il faut aussi remplacer la cible
# $(PROGRAM) par autant de cibles que necessaire.
#

PROGRAM       = amg

SRCS	      = amg.c

HDRS	      =

EXTHDRS	      = /usr/include/stdio.h

OBJS	      = amg.o

MANDEST	      = /usr/local/man/man1.Z

MANPAGES      = amg.1

#
# Les cibles :
#	all : compiler tout
#	clean : effacer les .o et les core
#	clobber : effacer tout ce qui peut etre regenere
#	depend : recalculer toutes les dependances et les inserer ici
#	install : installe le programme dans l'aborescence
#	tags : cree les tags
#

all:		$(PROGRAM)

$(PROGRAM):     $(OBJS) $(LIBS)
		cc $(LDFLAGS) $(OBJS) $(LIBS) $(SYSLIBS) -o $(PROGRAM)

clean:;		rm -f $(OBJS) core

clobber:;	rm -f $(OBJS) $(PROGRAM) core tags

depend:;	mkmf ROOT=$(ROOT)

install:	$(PROGRAM)
		-strip $(PROGRAM)
		if [ $(BINDEST) != . ] ; \
		then \
		    (cd $(BINDEST) ; rm -f $(PROGRAM)) ; \
		    cp $(PROGRAM) $(BINDEST) ; \
		    if [ "$(MANPAGES)" != none ] ; \
		    then \
			(cd $(MANDEST) ; rm -f $(MANPAGES)) ; \
			for i in $(MANPAGES) ; \
			do \
			    compress < $$i > $(MANDEST)/$$i ; \
			done ; \
		    fi ; \
		fi

tags:           $(HDRS) $(SRCS)
		ctags $(HDRS) $(SRCS)

#
# Dependances calculees automatiquement par mkmf.
# Ne rien changer apres cette ligne !
#
###
amg.o: /usr/include/stdio.h
@EOF
set `wc -lwc <areuh/msg/Makefile`
if test $1$2$3 != 752441499
then
	echo ERROR: wc results of areuh/msg/Makefile are $* should be 75 244 1499
fi

chmod 644 areuh/msg/Makefile

echo x - areuh/jmpdoc/A
cat >areuh/jmpdoc/A <<'@EOF'
/* 000 */	{1, "?A>B",	 3, 3, "800",	2, 0},
/* 010 */	{4, "GOYES",	41, 2, "00",	1, 2},
/* 010 */	{4, "GOSBVL",	53, 7, "8F000",	3, 5},
/* 012 */	{4, "GONC",	33, 3, "500",	2, 2},
/* 014 */	{1, "?C>A",	 3, 3, "802",	2, 0},
/* 015 */	{1, "?A>=C",	 3, 3, "80E",	2, 0},
/* 017 */	{1, "?B#C",	 7, 3, "805",	1, 0},
/* 018 */	{1, "?A<=B",	 7, 3, "80C",	2, 0},
/* 020 */	{5, "RTNC",	 5, 3, "400",	0, 0},
/* 028 */	{7, "RTNYES",	13, 2, "00",	0, 0},
/* 030 */	{1, "?B#A",	 7, 3, "804",	1, 0},
/* 031 */	{5, "RTNNC",	 1, 3, "500",	0, 0},
/* 035 */	{8, "?P#",	39, 3, "880",	0, 0},
/* 038 */	{6, "?MP=0",	 3, 3, "838",	0, 0},
/* 043 */	{1, "?D#0",	 7, 3, "80F",	1, 0},
/* 052 */	{1, "?B<=A",	 3, 3, "808",	2, 0},
/* 060 */	{1, "?C=A",	 3, 3, "802",	1, 0},
/* 061 */	{1, "?A=0",	 7, 3, "808",	1, 0},
/* 071 */	{0, "JSRC",	 0, 0, "",	0, 0},
/* 076 */	{5, "RTNSXM",	 5, 2, "00",	0, 0},
/* 080 */	{4, "GOTO",	33, 4, "6000",	2, 3},
/* 081 */	{0, "JSRYES",	 0, 0, "",	0, 0},
/* 082 */	{0, "JSRNC",	 0, 0, "",	0, 0},
/* 083 */	{1, "?C>=A",	 7, 3, "80A",	2, 0},
/* 085 */	{9, "?ST=0",	35, 3, "860",	0, 0},
/* 093 */	{1, "?A<B",	 7, 3, "804",	2, 0},
/* 094 */	{9, "?ST#0",	35, 3, "870",	0, 0},
/* 100 */	{1, "?A<=C",	 7, 3, "80A",	2, 0},
/* 100 */	{1, "?C<A",	 3, 3, "806",	2, 0},
/* 111 */	{1, "?D>C",	 7, 3, "803",	2, 0},
/* 118 */	{1, "?A#B",	 7, 3, "804",	1, 0},
/* 119 */	{1, "?B>=C",	 3, 3, "809",	2, 0},
/* 126 */	{1, "?C#A",	 3, 3, "806",	1, 0},
/* 127 */	{1, "?A#0",	 7, 3, "80C",	1, 0},
/* 130 */	{6, "?XM=0",	 3, 3, "831",	0, 0},
/* 143 */	{1, "?C<=A",	 7, 3, "80E",	2, 0},
/* 144 */	{1, "?C>=B",	 3, 3, "80D",	2, 0},
/* 145 */	{1, "?D=C",	 7, 3, "803",	1, 0},
/* 147 */	{9, "?ST=1",	35, 3, "870",	0, 0},
/* 150 */	{6, "?SB=0",	 3, 3, "832",	0, 0},
/* 151 */	{6, "?SR=0",	 7, 3, "834",	0, 0},
/* 152 */	{0, "JMP",	 0, 0, "0",	0, 0},
/* 155 */	{9, "?ST#1",	35, 3, "860",	0, 0},
/* 156 */	{1, "?B=0",	 7, 3, "809",	1, 0},
/* 175 */	{4, "GOLONG",	33, 6, "8C000",	3, 4},
/* 177 */	{1, "?D<C",	 7, 3, "807",	2, 0},
/* 183 */	{1, "?B<=C",	 7, 3, "80D",	2, 0},
/* 186 */	{1, "?A>C",	 7, 3, "806",	2, 0},
/* 189 */	{1, "?C>D",	 3, 3, "807",	2, 0},
/* 196 */	{1, "?C>B",	 7, 3, "805",	2, 0},
/* 201 */	{1, "?C<=B",	 7, 3, "809",	2, 0},
/* 204 */	{1, "?D#C",	 3, 3, "807",	1, 0},
/* 210 */	{1, "?B#0",	 7, 3, "80D",	1, 0},
/* 213 */	{1, "?A=C",	 7, 3, "802",	1, 0},
/* 214 */	{5, "RTNCC",	 1, 2, "03",	0, 0},
/* 215 */	{5, "RTNSC",	 5, 2, "02",	0, 0},
/* 218 */	{1, "?C=D",	 3, 3, "803",	1, 0},
/* 225 */	{0, "JMPNO",	 0, 0, "",	0, 0},
/* 229 */	{1, "?C=B",	 7, 3, "801",	1, 0},
/* 232 */	{1, "?C=0",	 7, 3, "80A",	1, 0},
/* 241 */	{4, "GOSUB",	101, 4, "7000",	2, 3},
/* 246 */	{0, "JSR",	 0, 0, "",	0, 0},
/* 248 */	{1, "?A<C",	 7, 3, "802",	2, 0},
/* 249 */	{1, "?C<D",	 3, 3, "803",	2, 0},
/* 258 */	{1, "?C<B",	 7, 3, "801",	2, 0},
/* 265 */	{1, "?C>=D",	 7, 3, "80F",	2, 0},
/* 270 */	{4, "GOSUBL",	97, 6, "8E000",	3, 4},
/* 274 */	{1, "?B>C",	 7, 3, "801",	2, 0},
/* 278 */	{1, "?A#C",	 7, 3, "806",	1, 0},
/* 282 */	{1, "?C#D",	 7, 3, "807",	1, 0},
/* 283 */	{1, "?B>A",	 3, 3, "804",	2, 0},
/* 290 */	{4, "GOVLNG",	53, 7, "8D000",	3, 5},
/* 295 */	{1, "?C#B",	 7, 3, "805",	1, 0},
/* 296 */	{1, "?D>=C",	 3, 3, "80B",	2, 0},
/* 298 */	{1, "?C#0",	 7, 3, "80E",	1, 0},
/* 308 */	{0, "JMPC",	 0, 0, "",	0, 0},
/* 309 */	{4, "GOC",	37, 3, "400",	2, 2},
/* 311 */	{1, "?B=C",	 3, 3, "801",	1, 0},
/* 313 */	{1, "?A>=B",	 7, 3, "808",	2, 0},
/* 317 */	{0, "JMPYES",	 0, 0, "",	0, 0},
/* 318 */	{0, "JMPNC",	 0, 0, "",	0, 0},
/* 319 */	{8, "?P=",	35, 3, "890",	0, 0},
/* 321 */	{1, "?B=A",	 7, 3, "800",	1, 0},
/* 326 */	{1, "?D=0",	 7, 3, "80B",	1, 0},
/* 334 */	{0, "JSRNO",	 0, 0, "",	0, 0},
/* 339 */	{1, "?B>=A",	 7, 3, "80C",	2, 0},
/* 340 */	{1, "?C<=D",	 3, 3, "80B",	2, 0},
/* 347 */	{1, "?B<C",	 7, 3, "805",	2, 0},
/* 351 */	{1, "?B<A",	 7, 3, "800",	2, 0},
/* 360 */	{1, "?D<=C",	 7, 3, "80F",	2, 0},
/* 362 */	{5, "SREQ?",	 5, 3, "80E",	0, 0},
@EOF
set `wc -lwc <areuh/jmpdoc/A`
if test $1$2$3 != 919103935
then
	echo ERROR: wc results of areuh/jmpdoc/A are $* should be 91 910 3935
fi

chmod 644 areuh/jmpdoc/A

echo x - areuh/jmpdoc/sauts
cat >areuh/jmpdoc/sauts <<'@EOF'
BETC	(0)
		GOC				3

		GOTO				4

		GOLONG				6

-------------------------------------------------------------------------------

BETNC	(1)
		GONC				3

		GOTO				4

		GOLONG				6

-------------------------------------------------------------------------------

JMP	(2)
		GOTO				4

		GOLONG				6

-------------------------------------------------------------------------------

JMPC	(3)
		GOC				3

		GONC	xx			7
		GOTO
	xx

		GONC	xx			9
		GOLONG
	xx

-------------------------------------------------------------------------------

JMPNC	(4)
		GONC				3

		GOC	xx			7
		GOTO
	xx

		GOC	xx			9
		GOLONG
	xx

-------------------------------------------------------------------------------

JMPYES	(5)
		<test>				2
		GOYES

		!<test>				6
		GOYES	xx
		GOTO
	xx

		!<test>				8
		GOYES	xx
		GOLONG
	xx

		<test>				9
		GOYES	xx
		GONC	yy
	xx	GOTO
	yy

		<test>				11
		GOYES	xx
		GONC	yy
	xx	GOLONG
	yy

-------------------------------------------------------------------------------

JSR	(6)
		GOSUB				4

		GOSUBL				6
@EOF
set `wc -lwc <areuh/jmpdoc/sauts`
if test $1$2$3 != 83971021
then
	echo ERROR: wc results of areuh/jmpdoc/sauts are $* should be 83 97 1021
fi

chmod 644 areuh/jmpdoc/sauts

echo x - areuh/jmpdoc/algo
cat >areuh/jmpdoc/algo <<'@EOF'
Traitement de la classe des JMP

    passe 1
	ajouter un nouveau descriptif de JMP
	memoriser origine
	memoriser destination
	memoriser type (JMP, JMPC, BETNC, etc.)
	si l'instruction precedente etait un test reversible
	    alors memoriser ce fait
	fin si
	si destination # erreur
	    alors chercher le type de saut de taille minimum
	    sinon type de saut = taille max
	fin si
	memoriser le type de saut trouve
	renvoyer sa taille
    passe 2
	renvoyer la taille du saut, telle que calculee par ps_jmp a la fin pass1
    passe 3
	si listing
	    alors imprimer la ligne courante
	fin si
	traiter les instructions correspondant au type calcule par ps_jmp

Procedure ps_jmp, appelee a la fin de la passe 1

    pour tous les descriptifs de JMP faire
	pour toutes les combinaisons de saut de taille < taille de la passe 1
	    si |origine - destination| < taille adressable par cette combinaison
		alors
		    delta := taille de la passe 1 - taille de cette combinaison
		    org := origine de ce saut
		    pour tous les descriptifs de JMP apres celui-ci faire
			origine -= delta
			si destination > org
			    alors destination -= delta
			fin si
		    fin pour
		    pour tous les descriptifs de JMP avant celui-ci faire
			si destination > org
			    alors destination -= delta
			fin si
		    fin pour
		    memoriser la combinaison et l'inversion eventuelle du test
		    sortir de la boucle et passer au descriptif de JMP suivant
	    fin si
	fin pour
    fin pour

regtest, ptrtest, stattest

    si origine du JMP suivant = pc + 2
	et JMP suivant doit avoir inversion du test
    alors inverser le test
    fin si
@EOF
set `wc -lwc <areuh/jmpdoc/algo`
if test $1$2$3 != 552601625
then
	echo ERROR: wc results of areuh/jmpdoc/algo are $* should be 55 260 1625
fi

chmod 644 areuh/jmpdoc/algo

echo x - areuh/jmpdoc/jmpparam
cat >areuh/jmpdoc/jmpparam <<'@EOF'
 		Lg	Avant	Apres	Invers.
-------------------------------------------------------------------------------

BETC
 GOC    %s	3	-127	+128	Non

 GOTO   %s	4	-2047	+2048	Non

 GOLONG %s	6	-32766	+32769	Non
-------------------------------------------------------------------------------

BETNC
 GONC   %s	3	-127	+128	Non

 GOTO   %s	4	-2047	+2048	Non

 GOLONG %s	6	-32766	+32769	Non
-------------------------------------------------------------------------------

JMP
 GOTO   %s	4	-2047	+2048	Non

 GOLONG %s	6	-32766	+32769	Non
-------------------------------------------------------------------------------

JMPC
 GOC    %s	3	-127	+128	Non

 GONC   *+7	7	-2044	+2051	Non
 GOTO   %s

 GONC   *+9	9	-32763	+32772	Non
 GOLONG %s
-------------------------------------------------------------------------------

JMPNC
 GONC   %s	3	-127	+128	Non

 GOC    *+7	7	-2044	+2051	Non
 GOTO   %s

 GOC    *+9	9	-32763	+32772	Non
 GOLONG %s
-------------------------------------------------------------------------------

JMPYES
 <test>
 GOYES  %s	2	-128	+127	Non

 !<test>
 GOYES  *+6	6	-2045	+2050	Oui
 GOTO   %s

 !<test>
 GOYES  *+8	8	-32764	+32771	Oui
 GOLONG %s

 <test>
 GOYES  *+5	9	-2042	+2053	Non
 GONC   *+6
 GOTO   %s

 <test>
 GOYES  *+5	11	-32759	+32776	Non
 GONC   *+8
 GOLONG %s
-------------------------------------------------------------------------------

JSR
 GOSUB  %s	4	-2044	+2051	Non

 GOSUBL %s	6	-32762	+32773	Non
-------------------------------------------------------------------------------
@EOF
set `wc -lwc <areuh/jmpdoc/jmpparam`
if test $1$2$3 != 731701502
then
	echo ERROR: wc results of areuh/jmpdoc/jmpparam are $* should be 73 170 1502
fi

chmod 644 areuh/jmpdoc/jmpparam

echo x - areuh/jmpdoc/jmp.c
cat >areuh/jmpdoc/jmp.c <<'@EOF'
#define OUI 1
#define NON 0
#define JMPVIDE {0,0,0,0,0,0,0,0}

struct jmpcode
{
    char *jc_text [4] ;		/* les 4 lignes au max. d'un goto */
    int jc_long ;		/* longueur en quartets */
    saddr jc_min, jc_max ;
    int jc_invert ;		/* OUI s'il faut inverser le test, NON sinon */
} ;

struct jmpcode jmptable [7][6] =
{

/* BETC */
    {   {"GOC %s", 0, 0, 0, 3, -127, 128, NON},
	{"GOTO %s", 0, 0, 0, 4, -2047, 2048, NON},
	{"GOLONG %s", 0, 0, 0, 6, -32766, 32768, NON},
	JMPVIDE,
	JMPVIDE,
	JMPVIDE},

/* BETNC */
    {	{"GONC %s", 0, 0, 0, 3, -127, 128, NON},
	{"GOTO %s", 0, 0, 0, 4, -2047, 2048, NON},
	{"GOLONG %s", 0, 0, 0, 6, -32766, 32768, NON},
	JMPVIDE,
	JMPVIDE,
	JMPVIDE},

/* JMP */
    {	{"GOTO %s", 0, 0, 0,  4, -2047, 2048, NON},
	{"GOLONG %s", 0, 0, 0, 6, -32766, 32768, NON},
	JMPVIDE,
	JMPVIDE,
	JMPVIDE,
	JMPVIDE},

/* JMPC */
    {	{"GOC %s", 0, 0, 0, 3, -127, 128, NON},
	{"GONC *+7", "GOTO %s", 0, 0, 7, -2044, 2051, NON},
	{"GONC *+9", "GOLONG %s", 0, 0, 9, -32763, 32772, NON},
	JMPVIDE,
	JMPVIDE,
	JMPVIDE},

/* JMPNC */
    {	{"GONC %s", 0, 0, 0, 3, -127, 128, NON},
	{"GOC *+7", "GOTO %s", 0, 0, 7, -2044, 2051, NON},
	{"GOC *+9", "GOLONG %s", 0, 0, 9, -32763, 32772, NON},
	JMPVIDE,
	JMPVIDE,
	JMPVIDE},

/* JMPOUI */
    {	{"GOYES %s", 0, 0, 0, 2, -128, 127, NON},
    	{"GOYES *+6", "GOTO %s", 0, 0, 6, -2045, 2050, OUI},
	{"GOYES *+8", "GOLONG %s", 0, 0, 8, -32764, 32771, OUI},
	{"GOYES *+5", "GONC *+6", "GOTO %s", 0, 9, -2042, 2053, NON},
	{"GOYES *+5", "GONC *+8", "GOLONG %s", 0, 11, -32759, 32776, NON},
	JMPVIDE},

/* JSR */
    {	{"GOSUB %s", 0, 0, 0, 4, -2044, 2051, NON},
    	{"GOSUBL %s", 0, 0, 0, 6, -32762, 32773, NON},
	JMPVIDE,
	JMPVIDE,
	JMPVIDE,
	JMPVIDE},
} ;
@EOF
set `wc -lwc <areuh/jmpdoc/jmp.c`
if test $1$2$3 != 713081716
then
	echo ERROR: wc results of areuh/jmpdoc/jmp.c are $* should be 71 308 1716
fi

chmod 644 areuh/jmpdoc/jmp.c

echo x - areuh/Makefile
cat >areuh/Makefile <<'@EOF'
#
# Makefile general pour areuh
#
# A pour seule fonction d'appeler et d'enchainer les differents Makefiles
#

SUBDIR	      = assembler linker msg dump equ
BINDEST       = /usr/local/bin
LIBDEST       = /usr/local/lib
MANDEST       = /usr/local/man/man1.Z
SHELL	      = /bin/sh

#
# Les cibles :
#	all : compiler tout
#	clean : effacer les .o et les core
#	clobber : effacer tout ce qui peut etre regenere
#	depend : recalculer toutes les dependances et les inserer ici
#	install : installe le programme dans l'aborescence
#	tags : cree les tags
#

all:
	@for i in $(SUBDIR);\
	do (\
	    echo Making $$i ...;\
	    cd $$i;\
	    $(MAKE) ROOT=$(ROOT)\
	); done

clean:
	@for i in $(SUBDIR);\
	do (\
	    echo Cleaning $$i ...;\
	    cd $$i;\
	    $(MAKE) clean\
	); done

clobber:
	@for i in $(SUBDIR);\
	do (\
	    echo Clobbering $$i ...;\
	    cd $$i;\
	    $(MAKE) clobber\
	); done

depend:
	@for i in $(SUBDIR);\
	do (\
	    echo Creating dependencies for $$i ...;\
	    cd $$i;\
	    $(MAKE) ROOT=$(ROOT) depend\
	); done

install:
	@for i in $(SUBDIR);\
	do (\
	    echo Installing $$i ...;\
	    cd $$i;\
	    $(MAKE) BINDEST=$(BINDEST) LIBDEST=$(LIBDEST) MANDEST=$(MANDEST) install\
	); done
@EOF
set `wc -lwc <areuh/Makefile`
if test $1$2$3 != 611841202
then
	echo ERROR: wc results of areuh/Makefile are $* should be 61 184 1202
fi

chmod 644 areuh/Makefile

echo x - areuh/assembler/aerror.c
cat >areuh/assembler/aerror.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                TITAN ASSEMBLER


                               ERROR  PROCESSING


error

******************************************************************************/

#include "aglobal.h"

extern void l_print() ;


/******************************************************************************

                                     ERROR


synopsis : void error (errnb, msg)
           int errnb
           char *msg
descritpion : reports an error message on listing file, if any, else on
              standard output.

******************************************************************************/

void error (errnb, msg)
int errnb ;
uchar *msg ;
{
    uchar txt[MAXLEN+1], tmp[MAXLEN+1];

    if ((errnb<0)||(passnb==2))
    {
        switch (errnb)
        {
            case ERROPN :
                sprintf (txt, "system error opening file %s",msg) ;
                break ;
            case ERRCLO :
                sprintf (txt, "system error closing file %s",msg) ;
                break ;
            case ERRREW :
                sprintf (txt,"system error on file %s at start of pass 2",msg);
                break ;
            case ERRWRT :
                sprintf (txt, "system error writing file %s", msg) ;
                break ;
            case ERRRD :
                sprintf (txt, "system error reading file %s", msg) ;
                break ;
            case ERRMEM :
                strcpy (txt, "not enough memory");
                break ;
            case ERRLEX :
                strcpy (txt, "invalid pseudo-op LEX or BIN");
                break ;
            case ERRPGS :
                strcpy (txt, "invalid page size");
                break ;
            case ERRFLN :
                strcpy (txt, "restricted label FiLeNd exists");
                break ;
            case ERRIFL :
                strcpy (txt, "invalid file name") ;
                break ;
            case ERRIMO :
                sprintf (txt,"invalid macro-op %s in modular assembling",msg);
                break ;
            case ERRVMD :
                sprintf (txt,"value must be defined for %s",msg);
                break ;
            case ERRUSA :
                strcpy (txt, "usage: aas [-p] [-l n] [-A] [-a file]") ;
                strcat (txt, " [-o object_file]  [file1 ... filen]") ;
                break ;

            case WRNEQU :
                strcpy (txt, "cannot resolve equate");
                break ;
            case WRNDUP :
                strcpy (txt, "duplicate label");
                break ;
            case WRNLBL :
                strcpy (txt, "illegal label");
                break ;
            case WRNULB :
                strcpy (txt, "unrecognized label");
                break ;
            case WRNEXP :
                strcpy (txt, "illegal expression");
                break ;
            case WRNASC :
                strcpy (txt, "illegal ascii constant");
                break ;
            case WRNPAR :
                strcpy (txt, "mismatched parenthesis");
                break ;
            case WRNIHX :
                strcpy (txt, "illegal hexadecimal constant");
                break ;
            case WRNNUL :
                strcpy (txt, "null divisor");
                break ;
            case WRNIXP :
                strcpy (txt, "illegal exponentiation") ;
                break ;
            case WRNIBC :
                strcpy (txt, "illegal binary constant") ;
                break ;
            case WRNENA :
                strcpy (txt, "external references not allowed") ;
                break ;
            case WRNYES :
                strcpy (txt, "GOYES or RTNYES required");
                break ;
            case WRNIDP :
                strcpy (txt, "illegal dp arithmetic value");
                break ;
            case WRNIPP :
                strcpy (txt, "illegal pointer position");
                break ;
            case WRNISB :
                strcpy (txt, "illegal status bit");
                break ;
            case WRNTFR :
                strcpy (txt, "illegal transfer value");
                break ;
            case WRNIWS :
                strcpy (txt, "illegal word select");
                break ;
            case WRNLST :
                strcpy (txt, "invalid LIST argument");
                break ;
            case WRNJVL :
                strcpy (txt, "jump or value too large");
                break ;
            case WRNMLB :
                strcpy (txt, "missing label");
                break ;
            case WRNTST :
                strcpy (txt, "needs previous test instruction");
                break ;
            case WRNNHX :
                strcpy (txt, "non hexadecimal digits present");
                break ;
            case WRNTMA :
                strcpy (txt, "too much ascii characters present");
                break ;
            case WRNTMH :
                strcpy (txt, "too much hexadecimal digits present");
                break ;
            case WRNOPC :
                strcpy (txt, "unknown opcode");
                break ;
            case WRNIIF :
                strcpy (txt, "invalid conditional structure") ;
                break ;
        }
        if (errnb<0)                              /* fatal error */
        {
            fprintf(stderr, "aas: %s\n", txt) ;
            exit (errnb) ;
        }
        else
        {
            if (cntlist)
            {
                sprintf (tmp, "* %s", txt) ;
                if (error_this_line++) l_print ((saddr)0, "", "", F_TL) ;
                l_print ((saddr)0, "", tmp, F_TL) ;
            }
            else printf ("Line %d : %s\n", linenb, txt);
            errcnt++ ;           /* we are in the second pass case */
        }
    }   /* end of "if" statement */
}       /* end of "error()"      */
@EOF
set `wc -lwc <areuh/assembler/aerror.c`
if test $1$2$3 != 1926266180
then
	echo ERROR: wc results of areuh/assembler/aerror.c are $* should be 192 626 6180
fi

chmod 644 areuh/assembler/aerror.c

echo x - areuh/assembler/agen.h
cat >areuh/assembler/agen.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

			       AREUH ASSEMBLER

		   GLOBAL DECLARATIONS FOR CODE GENERATION


******************************************************************************/

#define F_LSET 0x01
#define F_RETY 0x02
#define F_TREE 0x04
#define F_GOYS 0x08
#define F_ABSL 0x10
#define F_EXPR 0x20
#define F_GSUB 0x40
#define F_PART 0x80

#define fs_A 9
#define fs_B 7

#define ar_C 1
#define ar_D 2
#define ar_E 3
#define ar_F 4

extern uchar hex () ;
extern int dec () ;
@EOF
set `wc -lwc <areuh/assembler/agen.h`
if test $1$2$3 != 39101761
then
	echo ERROR: wc results of areuh/assembler/agen.h are $* should be 39 101 761
fi

chmod 644 areuh/assembler/agen.h

echo x - areuh/assembler/aglobal.h
cat >areuh/assembler/aglobal.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "common.h"                       /* common to assembler & linker */

/* flag for listing output */

#define F_PC 0x1                          /* print pc */
#define F_LN 0x2                          /* print line number */
#define F_GC 0x4                          /* print generated code */
#define F_TL 0x8                          /* print text line */


/******************************************************************************
  CROSS REFERENCE LIST
******************************************************************************/

struct xtable
{
    sint x_line ;                         /* line where symbol is used */
    struct xtable *x_next, *x_prev ;      /* link */
} ;


/******************************************************************************
  SYMBOL TABLE
******************************************************************************/

struct symbol                             /* one symbol */
{
    uchar s_name[LBLLEN+2] ;              /* symbol name */
    saddr s_value ;                       /* symbol value */
    uchar s_type ;                        /* type (LABS, LREL or LUDF) */
    uchar s_os ;                          /* 1 if O.S. entry point not used */
    uchar *s_def ;                        /* external definition if any */
    sint s_decl ;                         /* line where declared */
    struct xtable *s_xref ;               /* head of xref list */
    struct symbol *s_next ;               /* next symbol */
} ;

extern struct symbol *h_label[] ;         /* speed table for fast access */


/******************************************************************************
  OPCODE TABLE
******************************************************************************/

struct mnemo_desc                         /* one table element */
{
    uchar m_class ;                       /* opcode class (0..43) */
    char *m_text ;                        /* mnemonic */
    uchar m_flag ;                        /* flags */
    uchar m_len ;                         /* generated code length */
    char *m_code ;                        /* generated code */
    uchar m_a ;                           /* variable a */
    uchar m_b ;                           /* variable b */
} ;

extern struct mnemo_desc mnemo_table[] ;  /* the opcode table */

extern int h_opcode[] ;                   /* hash table for opcodes */


/******************************************************************************
  EXTERNAL REFERENCES NOT RESOLVED
******************************************************************************/

struct xused
{
    uchar u_characteristic ;              /* type and number of nibs */
    saddr u_pc ;                          /* relative address  */
    uchar *u_expression ;                 /* expression representation */
    struct xused *u_next ;                /* next element in the xused queue */
} ;

extern struct xused *headxu ;             /* head of previous queue */


/******************************************************************************
  GLOBAL VARIABLES
******************************************************************************/

/* files */

extern uchar fsource[], flisting[], fobject[] ; /* file names */
extern FILE *fd_s, *fd_l, *fd_o ;         /* and associated streams */

/* listing management */

extern int cntlist, cntlist_ref ;         /* type of output (no/stdout/file) */
extern int page_size ;                    /* size of listing page */
extern uchar l_title[], l_stitle[] ;      /* var. used by (S)TITLE opcodes */
extern int errcnt, error_this_line ;      /* error management */
extern int print_this_line ;              /* 0 if line must not be printed */
extern int xref ;                         /* 1 if cross reference table */
extern int running ;                      /* 0 if END opcode reached */
extern int passnb ;                       /* current pass number */
extern int linenb ;                       /* current line number */
           

/* code management */

extern saddr pc ;                         /* current program counter */
extern int gen_len ;                      /* current opcode code length */
extern uchar gen_code[] ;                 /* current opcode code */
extern int prev_test ;                    /* previous opcode was a test */
extern int exec, in_if, in_else ;         /* conditionnal assembly */


/* informations to linker */

extern uchar *xlabel ;                    /* label synonym */
extern uchar extexp[] ;                   /* external expression */
extern int modular ;                      /* 0 if LEX encoutered */
@EOF
set `wc -lwc <areuh/assembler/aglobal.h`
if test $1$2$3 != 1225624828
then
	echo ERROR: wc results of areuh/assembler/aglobal.h are $* should be 122 562 4828
fi

chmod 644 areuh/assembler/aglobal.h

exit 0

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:33:03 1990
#
# This archive contains:
#	areuh/assembler/ainput.c	areuh/assembler/alabel.c	
#	areuh/assembler/alist.c		areuh/assembler/amain.c		
#	areuh/assembler/amnemo.c	areuh/assembler/aobj.c		
#	areuh/assembler/aopc1.c		
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - areuh/assembler/ainput.c
cat >areuh/assembler/ainput.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                TITAN ASSEMBLER

                        INPUT STREAM READING & PARSING



read_line, parse_line, next_token, stcp

******************************************************************************/

#include "aglobal.h"



/******************************************************************************

                                   READ_LINE


synopsis : int read_line (fd, line)
           FILE *fd
           uchar *line
description : read_line reads a line from the source file, or stdin.
note : read_line returns -1 if EOF reached, 0 otherwise.

******************************************************************************/

int read_line (fd, line)
FILE *fd ;
uchar line[] ;
{
    int c, i = -1 ;

    do
    {
        c = getc (fd) ;
        if (i<MAXLEN)
            line[++i] = (uchar) c ;
    }
    while ((c!=EOF)&&(c!='\n')) ;
    line[i] = EOL ;
    if (c==EOF)
    {
        if (ferror (fd))  error (ERRRD, fsource) ;    /* stdin doesn't fail */
    }
    else c = 0 ;

    linenb++ ;
    return (c) ;
}


/******************************************************************************

                                  PARSE_LINE


synopsis : void parse_line (line, label, mnemo, modif)
           uchar *line, *label, *mnemo, *modif
description : parse_line breaks the line read from the source file in three
              components :
                - label : max LBLLEN or LBLLEN+1 characters
                - mnemonic : max 6 characters
                - modifier : not limited (in fact, MAXLEN characters)
note : parse_line doesn't return a result, the line is always valid.

******************************************************************************/

void parse_line(line, label, mnemo, modif)
uchar *line, *label, *mnemo, *modif ;
{
    int i=0, j ;

    *label = EOL ;
    *mnemo = EOL ;
    *modif = EOL ;

/* label parse */


/*               no label      comment       null line     tab *
 *               |             |             |             |   *
 *               v             v             v             v   */

    if ((*line!=' ')&&(*line!='*')&&(*line!=EOL)&&(*line!='\t'))
        i = stcp (label, line, 0, (*line=='=') ? LBLLEN+1 : LBLLEN) ;
    else if ((*line!='\t')&&(*line!='*')&&(*line!=EOL)&&
             (line[1]!=' ')&&(line[1]!='*')&&(line[1]!=EOL)&&(line[1]!='\t'))
        i = stcp (label, line, 1, (line[1]=='=') ? LBLLEN+1 : LBLLEN) ;
        

/* mnemonic parse */

    i = next_token (line, i) ;
    if (i<0) return ;
    if (line[i]=='*') return ;
    i = stcp (mnemo, line, i, 6) ;
    for (j=0; j<6; j++) mnemo[j] -= ((mnemo[j]<'a')||(mnemo[j]>'z')) ? 0 : 32 ;

/* modifier parse */

    i = next_token (line, i) ;
    if (i<0) return ;
    strcpy (modif, line+i) ;
}


/******************************************************************************

                                  NEXT_TOKEN


synopsis : int next_token (line, i)
           uchar *line
           int i
descrption : next_token looks the line, from the i-th position, for the next
             non-blank character or end of line. If end-of-line is reached,
             a negative value (-1) is returned to caller. Otherwise, the
             position of character is returned, which permits to reassign
             the line index (i=next_token(line, i)).

******************************************************************************/

int next_token (line, i)
uchar *line ;
int i ;
{
    while ((line[i]!=EOL)&&((line[i]==' ')||(line[i]=='\t'))) i++ ;
    return ((line[i]) ? i : -1);
}


/******************************************************************************

                                     STCP


synopsis : int stcp (str1, str2, i, lmax)
           uchar *str1, *str2
           int i, lmax
description : stcp is an alternate name for "string_copy". In fact, stcp copies
              str2 (from i-th position) into str1 (from 0-th position) until a
              blank character of end-of-line is reached. If lmax (max length of
              str1) is is reached, the rest of the field is ignored.
              The returned value is the new line index value.
note : we assume that stcp works well. No error value is returned.

replace with "strncpy" in C library for future releases

******************************************************************************/

int stcp (str1, str2, i, lmax)
uchar *str1, *str2;
int i, lmax;
{
    int j=0;
    do
    {
        if (j<lmax) str1[j++] = str2[i];
    }
    while ((str2[++i]!=' ')&&(str2[i]!='\t')&&(str2[i]!=EOL));
    str1[j] = EOL;
    return (i);
}
@EOF
set `wc -lwc <areuh/assembler/ainput.c`
if test $1$2$3 != 1775724915
then
	echo ERROR: wc results of areuh/assembler/ainput.c are $* should be 177 572 4915
fi

chmod 644 areuh/assembler/ainput.c

echo x - areuh/assembler/alabel.c
cat >areuh/assembler/alabel.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                TITAN ASSEMBLER

                               LABEL  PROCESSING


ps_label, find_label, add_label, label_value, s_init

******************************************************************************/

#include "aglobal.h"


extern saddr calc_expression() ;
extern uchar *memoire() ;

struct symbol *find_label(), *add_label() ;


/******************************************************************************

                                   PS_LABEL


synopsis : void ps_label (label, mnemo, modif)
           uchar *label, *mnemo, *modif
description : "pass" function call "ps_label" when a label is encoutered.
              Thus, in function of pass number, we must process the label.

              If pass one, the label is declared and its value is assigned (if
              possible, else -1), only if it is not yet declared.

              If pass two, the label is declared.
              We calculate the value of the label. If it had a value, we
              compare both. If not, the value is assigned.

******************************************************************************/

void ps_label (label, mnemo, modif)
uchar *label, *mnemo, *modif;
{
    struct symbol *ad;
    saddr val ;

/* la ligne ci-dessous teste si la partie "utile" du label est "FiLeNd" */
    if (strcmp(label + (*label=='='), "FiLeNd")==0) error (ERRFLN, "") ;

    ad = find_label (label) ;
        /* during pass two, label must be found. Otherwise, 
           the assembler is bug-full !!!                         */
    if (strcmp (mnemo, "EQU"))
    {                                  /* implicit declaration */
        switch (passnb)
        {
            case 1 :
                if (ad==NULL) add_label (label, pc, "", LREL, 0) ;
                else if ((ad->s_value==LBL_UDF)||(ad->s_value==LBL_EXT))
                {
                     ad->s_value = pc ;
                     ad->s_type = LREL ;
                }
                break ;
            case 2 :
                if ((ad->s_value!=pc)||(ad->s_type!=LREL))
                    error (WRNDUP, ""); /* duplicate label */
                break ;
        }
    }
    else                               /* explicit declaration (EQU) */
    {
        val = calc_expression (modif) ;
        switch (passnb)
        {
            case 1:
                if (ad==NULL)
                {
                    if (val >= 0L)
                    {
                        add_label (label, val, "", relabs, 0) ;
                    }
                    else if (val == EXP_ERR)
                    {
                        add_label (label, LBL_IVL, "", LUDF, 0) ;
                    }
                    else                             /* (val == EXP_EXT) */
                    {
                        if (*label=='=')
                            add_label (label, LBL_XEQ, extexp, LUDF, 0) ;
                        else add_label (label, LBL_SEQ, extexp, LUDF, 0) ;
                    }
                }
                else if ((ad->s_value==LBL_UDF)||(ad->s_value==LBL_EXT))
                {
                    if (val >= 0L)
                    {
                        ad->s_value = val ;
                        ad->s_type = relabs ;
                    }
                    else if (val == EXP_ERR)
                    {
                        ad->s_value = LBL_IVL ;
                        ad->s_type = LUDF ;
                    } 
                    else            /* (val == EXP_EXT) */
                    {
                        ad->s_value = (*label=='=') ? LBL_XEQ : LBL_SEQ ;
                        ad->s_def = memoire (strlen (extexp) + 1) ;
                        strcpy (ad->s_def, extexp) ;
                        ad->s_type = LUDF ;
                    }
                }
                break;                 /* du 'case pass one' */
            case 2:
                if (ad->s_value >= 0L) /* first value of label in first pass */
                    if (val!=ad->s_value) error (WRNDUP, "") ;
                else if (ad->s_value == LBL_IVL)
                {
                    if (val >= 0L)
                    {
                        ad->s_value = val ;
                        ad->s_type = relabs ;
                    }
                    else if (val == EXP_ERR)
                    {
                        ad->s_value = 0L ;
                        ad->s_type = LABS ;
                    }
                    else        /* EXP_EXT */
                    {
                        ad->s_def = memoire (strlen(extexp)+1);
                        if (ad->s_def == (uchar *) NULL)
                            error (ERRMEM, "") ;
                        strcpy (ad->s_def, extexp) ;
                        ad->s_value = (*label=='=')? LBL_XEQ :LBL_SEQ ;
                        ad->s_type = LUDF ;
                    }
                }
                else if ((ad->s_value == LBL_XEQ) || (ad->s_value == LBL_SEQ))
                {
                    if (val == EXP_EXT)
                    {
                        if (strcmp(ad->s_def, extexp))
                            error (WRNDUP, "") ; /* duplicate label */
                    }
                    else
                    {
                        ad->s_value = val ;
                        ad->s_type = relabs ;
                    }
                }
                break;                 /* end of 'case pass 2' */
        }
    }
}


/******************************************************************************

                                  FIND_LABEL


synopsis : struct symbol *find_label (label)
           uchar *label
description : find_label searches the symbol list for a given label.
              If the search is succesful, find_label returns a pointer to the
              structure. If not, NULL is returned.

******************************************************************************/

struct symbol *find_label (label)
uchar *label ;
{
    struct symbol *p ;
    int test ;

    if ((!modular)&&(*label=='=')) label++ ;
    p = h_label[(int) ((*label=='=') ? label[1] : label[0])]->s_next ;
    while (p)
    {
        test = strcmp (label, p->s_name) ;
        if (test==0)    break ;
        p = p->s_next ;
        if (test<0) p = NULL ;         /* label < p->s_name : not found */
    }
    return (p) ;
}


/******************************************************************************

                                  ADD_LABEL


synopsis : struct symbol *add_label (label, val, exp, type, os)
           uchar *label, *exp
           saddr val
           uchar type, os
description : add_label inserts the label (name and value) in the symbol list.
note : the symbol list is always sorted by label name.

******************************************************************************/

struct symbol *add_label (label, val, exp, type, os)
uchar *label, *exp ;
saddr val ;
uchar type, os ;
{
    struct symbol *p, *s ;
    int b=1 ;

    if ((!modular)&&(*label=='=')) label++ ;
    p = h_label[(int) ((*label=='=') ? label[1] : label[0]) ] ;
    s = p ;
    while ((b) && (s))
    {
        if (strcmp(label, s->s_name)<0)   b = 0 ;
        else
        {
            p = s ; s = s->s_next ;
        }
    }
    s = (struct symbol *) memoire (sizeof(struct symbol)) ;
    if (s)
    {
        s->s_next = p->s_next ;
        p->s_next = s ;
        strcpy (s->s_name, label) ;
        s->s_decl = (sint) linenb ;
        s->s_xref = (struct xtable *) NULL ;
        s->s_value = val ;
        s->s_type = type ;
        s->s_os = os ;
        if ((val==LBL_XEQ)||(val==LBL_SEQ))
        {
            s->s_def = memoire (strlen (exp) + 1) ;
            strcpy (s->s_def, exp) ;
        }
        else s->s_def = (uchar *) NULL ;
    }
    else  error (ERRMEM, "") ;

    return (s) ;
}


/******************************************************************************

                                 SYMBOL_VALUE


synopsis : saddr symbol_value (label)
           uchar *label
description : label_value returns the value of the label, knowing its name.
              If it doesn't exist, and this occurs during the second pass, an
              error message is generated.
note : if symbol not found in the symbol list, -1 is returned. It's to the
       caller (label_value) to report the error "unrecognized label".

******************************************************************************/

saddr symbol_value (label)
uchar *label ;
{
    struct symbol *ad;
    struct xtable *x ;
    saddr val ;

    ad = find_label (label) ;
    if (ad) val = ad->s_value ;
    else
    {
        val = ((*label=='=')&&(modular)) ? LBL_EXT : LBL_UDF ;
        ad = add_label (label, val, "", LUDF, 0) ;
    }
    if (passnb==2)
    {                      /* label must be found in pass two */
        if (xref)          /* need to store it in cross-ref. table */
        {
            x = (struct xtable *) memoire (sizeof(struct xtable)) ;
            if (x)
            {
                x->x_next = ad->s_xref ;
                if (ad->s_xref) ad->s_xref->x_prev = x ;
                ad->s_xref = x ;
                x->x_prev = (struct xtable *) NULL ;
                x->x_line = (sint) linenb ;
            }
            else error (ERRMEM, "") ;
        }
        if (val==LBL_UDF)
            error (WRNULB, "") ;   /* undefined label */
    }

    if (val==LBL_SEQ) xlabel = ad->s_def ;
    ad->s_os = 0 ;                 /* (O.S.) label is used */
    relabs = ad->s_type ;
    return (val) ;
}


/******************************************************************************

                                    S_INIT


synopsis : void s_init ()
description : initializes the symbol list. It is structured as follow :
              - a table (0..255) which points to a list of labels beginning
                with the character (index in this table is the first char.)
              - a chained list of labels,
              - a doubly linked list of references on this label. This is not
                initialized here.

******************************************************************************/

void s_init ()
{
    struct symbol *s ;
    int i ;

    s = (struct symbol *) memoire (256*sizeof(struct symbol)) ;
    if (!(s)) error (ERRMEM, "") ;

    for (i=0; i<256; i++)
    {
        strcpy (s->s_name, "") ;
        s->s_value = (saddr) 0 ;
        s->s_type = LUDF ;
        s->s_decl = (sint) 0 ;
        s->s_xref = (struct xtable *) NULL ;
        s->s_next = (struct symbol *) NULL ;
        h_label[i] = s++ ;
    }
}
@EOF
set `wc -lwc <areuh/assembler/alabel.c`
if test $1$2$3 != 346120010937
then
	echo ERROR: wc results of areuh/assembler/alabel.c are $* should be 346 1200 10937
fi

chmod 644 areuh/assembler/alabel.c

echo x - areuh/assembler/alist.c
cat >areuh/assembler/alist.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

				AREUH ASSEMBLER

			    LISTING FILE PROCESSING


l_init, l_flush, l_print, l_new_page, l_line, l_page

******************************************************************************/

#include "aglobal.h"

int l_line, l_page ;
void l_new_page (), l_page_header () ;

uchar fstdout [] = "stdout" ;


/******************************************************************************

				    L_INIT


synopsis : l_init()
description : initiates the listing mechanism, if necessary.

******************************************************************************/

void l_init()
{
    uchar tmp [MAXLEN+1] ;

    switch (cntlist)
    {
	case 0 :
	    break ;
	case 1 :
	    fd_l = stdout ;
	    break ;
	case 2 :
	    dfl_extension (tmp, fsource, "al") ;
	    look_obj (flisting, tmp) ;
	    if ((fd_l = fopen (flisting, "w")) == NULL)
		error (ERROPN, flisting) ;
	    break ;
    }
    l_page = 0 ;
    if (cntlist) l_page_header () ;
}


/******************************************************************************

				    L_FLUSH


synospsis : void l_flush ()
description : forces a new page, then closes the listing file if necessary.

******************************************************************************/

void l_flush()
{
    if (cntlist==0)	return ;
    l_new_page(0) ;
    if (cntlist == 2)
    {
	if (fclose (fd_l))  error (ERRCLO, flisting) ;
    }
}


/******************************************************************************

				    L_PRINT



synopsis : void l_print (pc, code, msg, flags)
	   saddr pc
	   uchar *code, *msg
	   int flags
description : prints a line on the listing file.
	      The line may contain  - program counter value	F_PC
				    - line number		F_LN
				    - generated code		F_GC
				    - text line 		F_TL
	      according the "flags" variable.
	      E.g. : to print pc and generated code, call
		     l_print(pc, gen_code, "", F_PC + F_GC)

******************************************************************************/

void l_print (address, code, msg, flags)
saddr address ;
uchar *code, *msg ;
int flags ;
{
    uchar line[MAXLEN+1], tmp[MAXLEN+1] ;

    if (!(cntlist))	return ;

    if (flags==F_TL)
    {
	sprintf (line, "%.79s", msg) ;
    }
    else
    {
	if (flags & F_LN) sprintf (line, "%04d ", linenb) ;     /* 5 chars */
	else strcpy (line, "     ") ;

	if (flags & F_PC)					/* 6 chars */
	{
	    hex5 (tmp, address) ;
	    strcat (line, tmp) ;
	    strcat (line, " ") ;
	}
	else strcat (line, "      ") ;

	if (flags & F_GC)					/* 9 chars */
	{
	    sprintf (tmp, "%-9.8s", code) ;
	    strcat (line, tmp) ;
	}
	else strcat (line, "         ") ;

	if (flags & F_TL)				       /* 60 chars */
	{
	    sprintf (tmp, "%.60s", msg) ;
	    strcat (line, tmp) ;
	}
    }

    if (l_line==(page_size-6))	 l_new_page (1) ;

    fprintf (fd_l, "%s\n", line) ;
    if (ferror (fd_l))
	error (ERRWRT, (cntlist == 1) ? fstdout : flisting) ;
    l_line++ ;

    if (strlen(code)>8)
	l_print (address+8, code+8, "", F_PC + F_GC) ;
}



/******************************************************************************

				  L_NEW_PAGE


synopsis : void l_new_page (flag)
	   int flag
description : forces a new page on listing file, and if flag # 0, prints a
	      header composed by page number, l_stitle and l_title.

******************************************************************************/

void l_new_page (flag)
int flag ;
{
    if (!(cntlist)) return ;

    for (; l_line<page_size; l_line++)	 fprintf (fd_l, "\n") ;
    if (ferror (fd_l))
	error (ERRWRT, (cntlist == 1) ? fstdout : flisting) ;

    if (flag) l_page_header () ;
}


void l_page_header ()
{
    fprintf (fd_l, "Page %03d           %.60s\n", ++l_page, l_title) ;
    fprintf (fd_l, "AREUH ASS. V2.4    %.60s\n", l_stitle) ;
    fprintf (fd_l, "\n") ;
    l_line = 3 ;
    if (ferror (fd_l))
	error (ERRWRT, (cntlist == 1) ? fstdout : flisting) ;
}
@EOF
set `wc -lwc <areuh/assembler/alist.c`
if test $1$2$3 != 1925374204
then
	echo ERROR: wc results of areuh/assembler/alist.c are $* should be 192 537 4204
fi

chmod 644 areuh/assembler/alist.c

echo x - areuh/assembler/amain.c
cat >areuh/assembler/amain.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                TITAN ASSEMBLER

                                 MAIN FONCTION


main, prompt

******************************************************************************/

#include "aglobal.h"

struct symbol *h_label[256] ;

struct xused *headxu ;

uchar fsource [MAXLEN+1], flisting [MAXLEN+1], fobject [MAXLEN+1] ;
FILE *fd_s, *fd_l, *fd_o ;

int cntlist, cntlist_ref ;
int page_size ;
uchar l_title[MAXLEN+1], l_stitle[MAXLEN+1];
int errcnt, error_this_line ;
int print_this_line ;
int xref ;
int running ;
int passnb ;
int linenb ;

saddr pc ;
int gen_len ;
uchar gen_code[19] ;
int prev_test ;
int exec, in_if, in_else ;

int modular, linker ;


extern void init(), between(), term(), pass() ;
extern int read_line() ;


/******************************************************************************

                                     MAIN




synopsis : aas  [-p]  [-l n] [-A] [-a afile] [-o objfile]  [file1 [... filen]]

description : Aas is a cross assembler which runs on UNIX based machines.
              Aas assembles the named file, or the standard input if no file
              is specified. The optional arguments -a or -A may be used to
              obtain an assembly listing. If -A is used, listing goes to
              standard output. If -a is used, the listing goes to afile.
              -l option specifies page length.
              The output of assembly is left in the filoe objfile; if that is
              omitted, then the output is left in a file "lex".

******************************************************************************/

main (argc, argv)
int argc ;
char *argv[] ;
{
    int  r = 0, c, i ;
    int errflg = 0 ;
    int errrep = 0 ;
    char saveo [MAXLEN+1], savel [MAXLEN+1] ;

    extern char *optarg ;
    extern int optind, opterr ;


    opterr = 0 ;

/* par defaut, on a : */
    xref = 0 ;                      /* pas de cross ref */
    page_size = 0 ;                 /* taille de page non fournie */
    cntlist_ref = 0 ;               /* pas de listing */
    strcpy (fobject, "") ;          /* fichier objet := "" */
    strcpy (fsource, "") ;          /* fichier source := "" */
    strcpy (flisting, "") ;         /* fichier listing := "" */

/* analyse des options */
    while ((c = getopt(argc, argv, "xa:Apl:o:")) != EOF)
        switch (c)
        {
            case 'x' :                               /* cross-ref */
                xref = 1 ;
                break ;
            case 'a' :                               /* listing sur fichier */
                strcpy (flisting, optarg) ;
                cntlist_ref = 2 ;
                break ;
            case 'A' :                               /* listing sur stdout */
                cntlist_ref = 1 ;
                break ;
            case 'p' :                               /* prompt */
                r++ ;                                /* r := 1 */
                break ;
            case 'l' :                               /* page length */
                sscanf (optarg, "%d", &page_size) ;  /* page_size := -l <n> */
                break ;
            case 'o' :                               /* object file */
                strcpy (fobject, optarg) ;
                break ;
            case '?' :                               /* non reconnu */
                errflg++ ;
                break ;
        }
/* si on a demande "-p", ou si pas d'argument : interface interactive */
    if ((r)||(argc==1)) prompt () ;
/* si option non reconnue ou si pas de nom de source, alors erreur */
    if (errflg || ((optind==argc)&&(fsource[0]==EOL)))
        error (ERRUSA, "") ;

/* page_size = 72 par defaut */
    if (page_size==0)         page_size = 72 ;

    if (*fsource)               /* got source file name with prompt() */
    {
        init() ;
        pass() ;
        between() ;
        pass() ;
        term() ;
        errrep = errcnt ;
    }
    else
    {
        for (i=optind; i<argc; i++)
        {
            strcpy (saveo, fobject) ;
            strcpy (savel, flisting) ;
            strcpy (fsource, argv [i]) ;
            if (optind != argc-1)  printf ("%s:\n", fsource) ;
            init() ;
            pass() ;
            between() ;
            pass() ;
            term() ;
            strcpy (fobject, saveo) ;
            strcpy (flisting, savel) ;
            errrep += errcnt ;
        }
    }
    exit (errrep) ;                  /* permet de signaler les erreurs */
}


/******************************************************************************

                                    PROMPT


synopsis : prompt()
description : if "-p" option is used, prompts the user for files to be used.

******************************************************************************/

prompt ()
{
    uchar line[MAXLEN+1] ;

    while (fsource[0]==EOL)
    {
        printf ("Source  file : ") ;
        read_line (stdin, fsource) ;
    }
    if (fobject[0]==EOL)
    {
        printf ("Object  file : ") ;
        read_line (stdin, fobject) ;
    }
    if (cntlist_ref==0)
    {
        printf ("Listing file : ") ;
        read_line (stdin, flisting) ;
        cntlist_ref = (flisting[0]) ? 2 : 0 ;
    }
    if (cntlist_ref)
    {
        if (xref==0)
        {
            printf ("Cross reference (y/n) : ") ;
            read_line (stdin, line) ;
            if ((*line=='y')||(*line=='Y')||(*line=='o')||(*line=='O'))
                xref = 1 ;
        }
        if (page_size==0)
        {
            printf ("Page length : ") ;
            read_line (stdin, line) ;
            sscanf (line, "%d", &page_size) ;
        }
    }
}
@EOF
set `wc -lwc <areuh/assembler/amain.c`
if test $1$2$3 != 2117355948
then
	echo ERROR: wc results of areuh/assembler/amain.c are $* should be 211 735 5948
fi

chmod 644 areuh/assembler/amain.c

echo x - areuh/assembler/amnemo.c
cat >areuh/assembler/amnemo.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                AREUH ASSEMBLER

                              MNEMONIC PROCESSING


ps_mnemo, find_mnemo, hex, dec

******************************************************************************/

#include "aglobal.h"

extern void regtest(), regarith(), reglogic(), branches(), rtnyes(), ptrtest(),
            stattest(), setptr(), setstat(), dparith(), datatrans(), nibhex(),
            lchex(), dxhex(), nibasc(), lcasc(),

            bss(), eject(), endx(), list(), title(), stitle(), lex(), id(),
            msg(), poll(), entryx(), charx(), key(), token(), bin(), chain(),
            endtxt(), endifx(), absx(), rdsymb(), elsex(), ifx() ;


/******************************************************************************

                                 PROCESS_MNEMO


synopsis : ps_mnemo (line, modif, ad)
           uchar *line, *modif
           struct mnemo_desc *ad 
description : pass control to the appropriate routine, to process the opcode.

******************************************************************************/

ps_mnemo (line, modif, ad)
uchar *line, *modif ;
struct mnemo_desc *ad ;
{
    switch (ad->m_class)
    {
        case 1 :
            regtest(ad, modif) ;
            break ;
        case 2 :
            regarith(ad, modif) ;
            break ;
        case 3 :
            reglogic(modif) ;
            break ;
        case 4 :
            branches(ad, modif) ;
            break ;
        case 7 :
            rtnyes() ;
            break ;
        case 8 :
            ptrtest(modif) ;
            break ;
        case 9 :
            stattest(modif) ;
            break ;
        case 10 :
            setptr(modif) ;
            break ;
        case 11 :
            setstat(modif) ;
            break ;
        case 12 :
            dparith(modif) ;
            break ;
        case 13 :
            datatrans(modif) ;
            break ;
        case 14 :
            nibhex(modif) ;
            break ;
        case 15 :
            lchex(modif) ;
            break ;
        case 16 :
            dxhex(modif) ;
            break ;
        case 17 :
            nibasc(modif) ;
            break ;
        case 18 :
            lcasc(modif) ;
            break ;
        case 19 :
            bss(modif) ;
            break ;
        case 20 :
            eject() ;
            break ;
        case 21 :
            endx() ;
            break ;
        case 23 :
            list(modif) ;
            break ;
        case 24 :
            title(modif) ;
            break ;
        case 25 :
            stitle(modif) ;
            break ;
        case 28 :
            lex(modif, line) ;
            break ;
        case 29 :
            id(modif, line) ;
            break ;
        case 30 :
            msg(modif, line) ;
            break ;
        case 31 :
            poll(modif, line) ;
            break ;
        case 32 :
            entryx(modif, line) ;
            break ;
        case 33 :
            charx(modif, line) ;
            break ;
        case 34 :
            key(modif, line) ;
            break ;
        case 35 :
            token(modif, line) ;
            break ;
        case 36 :
            bin(modif, line) ;
            break ;
        case 38 :
            chain(modif, line) ;
            break ;
        case 39 :
            endtxt(line) ;
            break ;
        case 40 :
            endifx() ;
            break ;
        case 41 :
            absx(modif) ;
            break ;
        case 42 :
            rdsymb(modif) ;
            break ;
        case 43 :
            elsex() ;
            break ;
        case 44 :
            ifx(modif) ;
            break ;
    }
}


/******************************************************************************

                                   FIND_MNEMO


synopsis : struct mnemo_desc *find_mnemo (mnemo)
           char *mnemo
description : finds index of a mnemonic in mnemo_table, and returns it, -1
              if not found.

******************************************************************************/

struct mnemo_desc *find_mnemo (mnemo)
uchar *mnemo ;
{
    int i, m, b = 1 ;
    long int h = 0 ;

    for (i=0; i<6; i++)
        h = (h<<3) + ((b) ? ((b=(int)mnemo[i])&7) : 0) ;
    h %= 43 ;
    i = h_opcode[h] ; m = h_opcode[++h] ;
    while (i<m)
    {
        if (strcmp(mnemo, mnemo_table[i].m_text))  i++ ;
        else break ;
    }
    return ((i==m) ? (struct mnemo_desc *)NULL : &mnemo_table[i]) ;
}


/******************************************************************************

                                   HEX


synopsis : uchar hex (digit)
           int digit
description : returns the hexadecimal representation of integer 'digit' (in
              ['0'..'9','A'..'Z']).

******************************************************************************/

uchar hex (digit)
int digit ;
{
    return ((uchar) ( (digit<=9) ? digit+48 : digit+55) ) ;
}


/*****************************************************************************

                                   DEC


synopsis : int dec (digit)
           uchar digit
description : returns the decimal equivalent of hexadecimal character 'digit'.

*****************************************************************************/

int dec (digit)
uchar digit ;
{
    return ((digit<'A') ? (int) digit - 48 : (int) digit - 55 ) ;
}
@EOF
set `wc -lwc <areuh/assembler/amnemo.c`
if test $1$2$3 != 2355945704
then
	echo ERROR: wc results of areuh/assembler/amnemo.c are $* should be 235 594 5704
fi

chmod 644 areuh/assembler/amnemo.c

echo x - areuh/assembler/aobj.c
cat >areuh/assembler/aobj.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                 AREUH ASSEMBLER

                              OBJECT FILE UTILITIES


o_init (), o_print (), dump_linker_infos ()

******************************************************************************/

#include "aglobal.h"

#define fputl(lg,fd)   fwrite((char *)(&(lg)),sizeof(long int),1,fd)

long int zero = 0L ;
long int magic ;


/******************************************************************************

                                    O_INIT


synopsis : void o_init ()
description : open object file and, if modular assembly, mark information for
  linker (address of second part of file, and size of code in nibs).

******************************************************************************/

void o_init ()
{
    uchar dfl [MAXLEN+1] ;

    if (modular) dfl_extension (dfl, fsource, "ao") ;
    else strcpy (dfl, "lex") ;

    look_obj (fobject, dfl) ;                        /* ensure name validity */
        
    if (modular) fd_o = fopen (fobject, WAO_MODE) ;     /* untranslated mode */
    else         fd_o =fopen (fobject, "w") ;           /* text mode */
    if (fd_o==NULL)
        error (ERROPN, fobject) ;      /* error opening file */
    if (modular)
    {
        magic = AO_MAGIC ;
        fputl (magic, fd_o) ;
        fputl (zero, fd_o) ;
        fputl (zero, fd_o) ;
    }
    else
    {
        magic = AL_MAGIC ;
        fputl (magic, fd_o) ;
    }
    if (ferror (fd_o)) error (ERRWRT, fobject) ;
}


/******************************************************************************

                                   O_PRINT


synopsis : void o_print (str, len)
           uchar *str
           int len
description :  burp

******************************************************************************/

void o_print (str, len)
uchar *str ;
int len ;
{
    int i ;
    
    if (len)
    {
        if (len>18) for (i=0; i<len; i++) putc ((int) '0', fd_o) ;
        else        for (i=0; i<len; i++) putc ((int) str[i], fd_o) ;
    }
    if (ferror (fd_o)) error (ERRWRT, fobject) ;
}


/******************************************************************************

                               DUMP_LINKER_INFOS


synopsis : void dump_linker_infos ()
description : append to objet file external public definitions (symbolic or
  numeric) and external references usages.

******************************************************************************/

void dump_linker_infos ()
{
    int i ;                       /* index in h_label table */
    struct symbol *pl ;           /* points into a label list */
    long int p2, p3 ;             /* addresses of second and third parts */
    long int nl = 0, nu = 0;      /* # labels (part 2), # used (part 3) */
    long int l ;                  /* auxiliar */
    struct xused *h ;

    p2 = ftell (fd_o) ;           /* begin of second part */
    fputl (zero, fd_o) ;          /* marker for address of third part */
    fputl (zero, fd_o) ;          /* number of labels in second  part */
    for (i=0; i<256; i++)
    {
        pl = h_label[i]->s_next ;
        while (pl)
        {
            if ((pl->s_name[0]=='=')&&(pl->s_value!=LBL_EXT)
                                    &&(pl->s_value!=LBL_IVL))
            {
                nl++ ;
                fprintf (fd_o, "%s\n", pl->s_name) ;
                fputl (pl->s_value, fd_o) ;
                if (pl->s_value<0L)
                    fprintf (fd_o, "%s\n", pl->s_def) ;
                else fputc (pl->s_type, fd_o) ;
            }
            pl = pl->s_next ;
        }
    }
    p3 = ftell (fd_o) ;           /* begin of third part */
    fputl (zero, fd_o) ;          /* # used in third part */
    while (headxu)
    {
        nu++ ;
        l = (long int) headxu->u_characteristic ;
        fputl (l, fd_o) ;
        fputl (headxu->u_pc, fd_o) ;
        fprintf (fd_o, "%s\n", headxu->u_expression) ;
        h = headxu ;
        headxu = headxu->u_next ;
        free ((char *) h) ;
    }

    fseek (fd_o, zero, 0) ;
    fputl (magic, fd_o) ;
    fputl (p2, fd_o) ;            /* begin of second part */
    fputl (pc, fd_o) ;            /* # nibs in the code */

    fseek (fd_o, p2, 0) ;
    fputl (p3, fd_o) ;            /* begin of third part */
    fputl (nl, fd_o) ;            /* # labels defined in this module */

    fseek (fd_o, p3, 0) ;
    fputl (nu, fd_o) ;            /* # unresolved references here */

    if (ferror (fd_o)) error (ERRWRT, fobject) ;
}
@EOF
set `wc -lwc <areuh/assembler/aobj.c`
if test $1$2$3 != 1665784778
then
	echo ERROR: wc results of areuh/assembler/aobj.c are $* should be 166 578 4778
fi

chmod 644 areuh/assembler/aobj.c

echo x - areuh/assembler/aopc1.c
cat >areuh/assembler/aopc1.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

				 AREUH ASSEMBLER

			    OPCODE PROCESSING (PART 1)


******************************************************************************/

#include "aglobal.h"
#include "agen.h"

#define UPRC(c)   ((((c)>='a')&&((c)<='z')) ? (c)-32 : (c))

extern uchar *memoire() ;
extern saddr calc_expression () ;
extern uchar hex () ;


/******************************************************************************

				  ADD_XUSED


synopsis : void add_xused (type, pc, len, exp)
	   int type, len
	   saddr pc
	   uchar *exp
description : adds the parameters about the use of an expression containing
	      external references.

******************************************************************************/

void add_xused (type, addr, len, exp)
int type, len ;
saddr addr ;
uchar *exp ;
{
    struct xused *xu ;

    xu = (struct xused *) memoire (sizeof (struct xused)) ;
    if (xu==(struct xused *) NULL)
	error (ERRMEM, "") ;
    xu->u_characteristic = (uchar) (type + len) ;
    xu->u_pc = addr ;
    xu->u_expression = memoire (strlen (exp) + 1) ;
    if (xu->u_expression==(uchar *)NULL)
	error (ERRMEM, "") ;
    strcpy (xu->u_expression, exp) ;
    xu->u_next = headxu ;     /* queue it */
    headxu = xu ;	      /* before the previous head */
}


/******************************************************************************

				  FIELD_SELECT


synopsis : field_select (modif)
	   uchar *modif
description : to be described, in a (far) future...

******************************************************************************/

int field_select (modif)
uchar *modif ;
{
    int r = 0 ;
    char c ;

    switch (UPRC(*modif))
    {
	case 'P' :
	    r = 1 ;
	    break ;
	case 'W' :
	    if (UPRC(modif[1])=='P')
	    {
		r = 2 ;
		modif++ ;
	    }
	    else r = 8 ;
	    break ;
	case 'X' :
	    if (UPRC(modif[1])=='S')
	    {
		r = 3 ;
		modif++ ;
	    }
	    else r = 4 ;
	    break ;
	case 'S' :
	    r = 5 ;
	    break ;
	case 'M' :
	    r = 6 ;
	    break ;
	case 'B' :
	    r = fs_B ;
	    break ;
	case 'A' :
	    r = fs_A ;
	    break ;
    }
    c = *(++modif) ;
    if ((c!=' ')&&(c!=EOL)&&(c!='\t')) r = 0 ;
    return (r) ;
}


void regtest(ad, modif)
struct mnemo_desc *ad ;
uchar *modif ;
{
    int r ;

    if (r=field_select(modif) )
    {
	if (r==fs_A)
	{
	    gen_code[1] = hex (r + ad->m_a) ;
	}
	else
	{
	    gen_code[0] = '9' ;
	    gen_code[1] = hex ((ad->m_a==2) ? r+7 : r-1) ;
	}
    }
    else error (WRNIWS, "") ;
}


void regarith (ad, modif)
struct mnemo_desc *ad ;
uchar *modif ;
{
    int r ;

    if (r=field_select(modif))
    {
	/* gen_len is 3 by default */
	if (r==fs_A)   gen_len = 2 ;

	if (passnb==2)
	{
	    if (r==fs_A)
	    {
		gen_code[0] = hex (ad->m_a + 11) ;
		gen_code[1] = gen_code[2] ;
		gen_code[2] = EOL ;
	    }
	    else
	    {
		gen_code[0] = hex(((ad->m_a==ar_C)||(ad->m_a==ar_D))?10:11) ;
		gen_code[1] = hex(((ad->m_a==ar_C)||(ad->m_a==ar_E))?r-1:r+7) ;
	    }
	}
    }
    else error (WRNIWS, "") ;
}


void reglogic (modif)
uchar *modif ;
{
    int r ;

    if (r=field_select(modif))
	gen_code[2] = (r==fs_A) ? 'F' : hex(r-1) ;
    else error (WRNIWS, "") ;
}


int range (org, dest, nibs, offset)
saddr org, dest, *offset ;
int nibs ;
{
    saddr Sixtine, Fiftine ;
    int r ;

    Sixtine = ((saddr) 1) << (nibs*4) ;
    Fiftine = Sixtine >> 1 ;
    *offset = dest - org ;
    r = ((*offset >= -Fiftine) && (*offset < Fiftine)) ;
    if (*offset<0)   (*offset) += Sixtine ;	   /* -128 = 128 ; -1 = 255 */
    return (r) ;
}


void branches (ad, modif)
struct mnemo_desc *ad ;
uchar *modif ;
{
    saddr val, offset, pc_bis ;
    int fits, i, j ;
    uchar hex_var[MAXLEN+1] ;

    if ((ad->m_flag & F_GOYS) && (!(prev_test)))
	error (WRNTST, "") ;       /* needs previous test instruction */
    else
    {
	val = calc_expression (modif) ;
	if (val >= 0L)
	{
	    if (ad->m_flag & F_ABSL)
	    {
		fits = 1 ;
		offset = val ;
	    }
	    else
	    {
		if (ad->m_flag & F_GSUB) pc_bis = pc + (long int) gen_len ;
		else pc_bis = pc + (long int) (ad->m_a) - 1L ;
		fits = range (pc_bis, val, ad->m_b, &offset) ;
	    }

	    if (!(fits))
	    {
		offset = 0L ;
		error (WRNJVL, "") ;       /* Jump or value too large */
	    }

	    hex6 (hex_var, offset) ;
	    for (i=1, j=5; i<=ad->m_b; i++, j--)
	    {
		gen_code[ad->m_a + i - 2] = hex_var[j] ;
	    }
	    gen_code[gen_len] = EOL ;
	}
	else	       /* EXP_ERR or EXP_EXT */
	{
	    if (val == EXP_EXT)
	    {
		switch (ad->m_flag & (F_GSUB | F_ABSL))
		{
		    case F_GSUB :
			i = XRGSB ;
			break ;
		    case F_ABSL :
		    case F_ABSL | F_GSUB :
			i = XABSL ;
			break ;
		    default :
			i = XRGTO ;
			break ;
		}
		add_xused (i, pc + (long int) ad->m_a - 1L, ad->m_b, extexp) ;
	    }
	    for (i=0; i<ad->m_b; i++) gen_code [ad->m_a - 1 + i] = '0' ;
	    gen_code [gen_len] = EOL ;
	}
    }
}


void rtnyes()
{
    if (!(prev_test))  error (WRNTST, "") ;   /* needs previous test instr. */
}


void ptrtest (modif)
uchar *modif ;
{
    saddr val ;

    val = calc_expression (modif) ;
    if (val == EXP_EXT)
    {
	add_xused (XABSL, pc + 2L, 1, extexp) ;
	val = (saddr) 0 ;			/* FALLS INTO FOLLOWING */
    }
    if (val == EXP_ERR)
	val = (saddr) 0 ;			/* FALLS INTO FOLLOWING */
    if (val>15L)
	error (WRNIPP, "") ;      /* illegal pointer position */
    else gen_code[2] = hex ((int) val) ;
}


void stattest (modif)
uchar *modif ;
{
    saddr val ;

    val = calc_expression (modif) ;
    if (val == EXP_EXT)
    {
	add_xused (XABSL, pc + 2L, 1, extexp) ;
	val = (saddr) 0 ;			/* FALLS INTO FOLLOWING */
    }
    if (val == EXP_ERR)
	    val = (saddr) 0 ;			    /* FALLS INTO FOLLOWING */
    if (val>15L)
	error (WRNISB, "") ;      /* illegal status bit */
    else gen_code[2] = hex ((int) val) ;
}


void setptr (modif)
uchar *modif ;
{
    saddr val ;

    val = calc_expression (modif) ;
    if (val == EXP_EXT)
    {
	add_xused (XABSL, pc + (long int) gen_len - 1L, 1, extexp) ;
	val = (saddr) 0 ;
    }						/* FALLS INTO FOLLOWING */
    if (val == EXP_ERR)
	val = (saddr) 0 ;			/* FALLS INTO FOLLOWING */
    if (val>15L)
	error (WRNIPP, "") ;      /* illegal pointer position */
    else gen_code[gen_len-1] = hex ((int) val) ;
}


void setstat (modif)
uchar *modif ;
{
    saddr val ;

    val = calc_expression (modif) ;
    if (val == EXP_EXT)
    {
	add_xused (XABSL, pc + 2L, 1, extexp) ;
	val = (saddr) 0 ;
    }						/* FALLS INTO FOLLOWING */
    if (val == EXP_ERR)
	val = (saddr) 0 ;			/* FALLS INTO FOLLOWING */
    if (val>15L)
	error (WRNISB, "") ;      /* illegal status bit */
    else gen_code[2] = hex ((int) val) ;
}


void dparith (modif)
uchar *modif ;
{
    saddr val ;

    val = calc_expression (modif) ;
    if (val >= 0L)
    {
	if ((val<1L)||(val>16L))
	    error (WRNIDP, "") ;      /* illegal dp arithmetic value */
	else gen_code[2] = hex (val - 1L) ;
    }
    else if (val == EXP_EXT)
    {
	add_xused (XABSO, pc + 2L, 1, extexp) ;
	val = (saddr) 1 ;
    }
    else		 /* (val == EXP_ERR) */
    {
	val = (saddr) 1 ;
    }
}


void datatrans (modif)
uchar *modif ;
{
    saddr val ;
    int r ;

    r=field_select (modif) ;
    if ((r==fs_A)||(r==fs_B))  gen_len = 3 ;
    if (passnb == 2)
    {
	switch (r)
	{
	    case 0 :	  /* expression instead of field selector */
		val = calc_expression (modif) ;
		if (val >= 0L)
		{
		    if ((val<1L)||(val>16))
			error (WRNTFR, "") ;  /* illegal transfer value */
		    else
		    {
			gen_code[2] = hex (dec(gen_code[2])+8) ;
			gen_code[3] = hex ((int) val - 1L) ;
		    }
		}
		else if (val == EXP_EXT)
		{
		    add_xused (XABSO, pc + 3L, 1, extexp) ;
		    gen_code[2] = hex (dec(gen_code[2])+8) ;  /* ajout */
		    val = 1L ;
		}
		else		 /* (val == EXP_EXT) */
		{
		    val = 1L ;
		}
		break ;
	    case fs_A :
		gen_len = 3 ;
		gen_code[1] = '4' ;
		gen_code[3] = EOL ;
		break ;
	    case fs_B :
		gen_len = 3 ;
		gen_code[1] = '4' ;
		gen_code[2] = hex ( dec(gen_code[2]) + 8) ;
		gen_code[3] = EOL ;
		break ;
	    default :
		gen_code[3] = hex (r-1) ;
		break ;
	}
    }
}


int hex_len (modif)	  /* aCLCHX : AS5 : ED094 */
uchar *modif ;
{
    int i = 0 ;

    if (*modif=='#') modif++ ;
    while (((*modif>='0')&&(*modif<='9'))||
	   ((*modif>='A')&&(*modif<='F'))||
	   ((*modif>='a')&&(*modif<='f')))
    {
	modif++ ;
	i++ ;
    }
    return ((i>16) ? 16 : i) ;
}


void check_last_hex (digit)
uchar digit ;
{
    if ((digit!=EOL)&&(digit!='\t')&&(digit!=' '))
    {
	if ((digit<'0')||
	    ((digit>'9')&&(digit<'A'))||
	    ((digit>'F')&&(digit<'a'))||
	    (digit>'f'))
	    error (WRNTMH, "") ;   /* too many hex digit present    */
	else error (WRNNHX, "") ;  /* non hexadecimal digit present */
    }
}


void nibhex (modif)
uchar *modif ;
{
    int i ;

    gen_len = hex_len (modif) ;
    if (passnb==2)
    {
	if (*modif=='#') modif++ ;
	for (i=0; i<gen_len; i++)
	{
	    if (modif[i]>='a') gen_code[i] = modif[i] - 32 ;
	    else	       gen_code[i] = modif[i] ;
	}
	gen_code[gen_len] = EOL ;
	check_last_hex (modif[gen_len]) ;
    }
}


void lchex (modif)
uchar *modif ;
{
    int i, j ;

    gen_len = hex_len (modif) ;
    if (passnb==2)
    {
	if (*modif=='#') modif++ ;
	if (gen_len)
	{
	    gen_code[1] = hex (gen_len - 1) ;
	    for (i=0, j=gen_len-1; i<gen_len; i++, j--)
	    {
		if (modif[j]>='a') gen_code[2+i] = modif[j] - 32 ;
		else		   gen_code[2+i] = modif[j] ;
	    }
	    gen_code[gen_len + 2] = EOL ;
	    check_last_hex (modif[gen_len]) ;
	}
	else
	{
	    gen_code[0] = EOL ;
	    error (WRNNHX, "") ; /* non hex present (in fact, there is no) */
	}
    }

    gen_len = (gen_len) ? gen_len+2 : 0 ;
}


void dxhex (modif)
uchar *modif ;
{
    int i, j, r ;

    r = hex_len (modif) ;
    if (passnb==2)
    {
	if ((r!=2)&&(r!=4)&&(r!=5))
	    error (WRNIHX, "") ;  /* illegal hex const (number of digits) */
	else
	{
	    if (*modif=='#') modif++ ;
	    /* if 2, no change to the opcode */
	    /* if 4, add 1, if 5 add two     */
	    if (r!=2) gen_code[1] = hex (dec(gen_code[1]) + r - 3) ;
	    for (i=0, j=r-1; i<r; i++, j--)
	    {
		if (modif[j]>='a') gen_code[2+i] = modif[j] - 32 ;
		else		   gen_code[2+i] = modif[j] ;
	    }
	    gen_code[r+2] = EOL ;
	    check_last_hex (modif[r]) ;
	}
    }
    gen_len = ((r==4)||(r==5)) ? r+2 : 4 ;
}


int ascii_len (modif)
uchar *modif ;
{
    uchar limit ;
    int i = 0 ;

    switch (*modif)
    {
	case '\'' :
	case '\\' :
	    limit = *modif++ ;
	    while ((*modif!=limit)&&(*modif))
	    {
		modif++ ;
		i++ ;
	    }
	    break ;
    }
    return ((i>8) ? 8 : i) ;
}


void nibasc (modif)
uchar *modif ;
{
    uchar limit ;
    int i ;

    gen_len = ascii_len (modif) ;
    if (passnb==2)
    {
	limit = *modif ;
	for (i=1; i<=gen_len; i++)
	{
	    gen_code[2*(i-1)] = hex (((int) modif[i]) % 16) ;
	    gen_code[2*i-1] = hex (((int) modif[i]) / 16) ;
	}
	gen_code[2*gen_len] = EOL ;
	switch (modif[gen_len + 1])
	{
	    case '\'' :
	    case '\\' :
		if (modif[gen_len + 1]!=limit)
		    error  (WRNTMA, "") ; /* too many ascii chars present */
		break ;
	    case EOL :
		error (WRNASC, "") ;      /* illegal ascii constant       */
		break ;
	    default :
		error (WRNTMA, "") ;      /* too many ascii chars present */
		break ;
	}
    }
    gen_len *= 2 ;
}


void lcasc (modif)
uchar *modif ;
{
    uchar limit ;
    int i ;

    gen_len = ascii_len (modif) ;
    if (passnb==2)
    {
	limit = *modif ;
	for (i=1; i<=gen_len; i++)
	{
	    gen_code[2*i]   = hex (((int) modif[gen_len - i + 1]) % 16) ;
	    gen_code[2*i+1] = hex (((int) modif[gen_len - i + 1]) / 16) ;
	}
	gen_code[2+2*gen_len] = EOL ;
	switch (modif[gen_len + 1])
	{
	    case '\'' :
	    case '\\' :
		if (modif[gen_len + 1]!=limit)
		    error  (WRNTMA, "") ; /* too many ascii chars present */
		break ;
	    case EOL :
		error (WRNASC, "") ;      /* illegal ascii constant       */
		break ;
	    default :
		error (WRNTMA, "") ;      /* too many ascii chars present */
		break ;
	}
	gen_code[1] = hex (2*gen_len - 1) ;
    }
    gen_len = (gen_len) ? 2+2*gen_len : 0 ;
}
@EOF
set `wc -lwc <areuh/assembler/aopc1.c`
if test $1$2$3 != 630196812298
then
	echo ERROR: wc results of areuh/assembler/aopc1.c are $* should be 630 1968 12298
fi

chmod 644 areuh/assembler/aopc1.c

exit 0

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:33:05 1990
#
# This archive contains:
#	areuh/assembler/aopc2.c		areuh/assembler/apass.c		
#	areuh/assembler/areport.c	areuh/assembler/autil.c		
#	areuh/assembler/common.h	areuh/assembler/err.h		
#	areuh/assembler/exp.c		areuh/assembler/flag.h		
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - areuh/assembler/aopc2.c
cat >areuh/assembler/aopc2.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

				 AREUH ASSEMBLER

			    OPCODE PROCESSING (PART 2)


******************************************************************************/

#include "aglobal.h"
#include "agen.h"

extern void l_new_page(), l_print (), ps_line () ;
extern int ascii_len () ;
extern saddr calc_expression () ;

int ltok = 255 ;	   /* lowest token */
int htok = 0 ;		   /* highest token */
int ctok = 0 ;		   /* current token */
int ckey = 0 ;		   /* current key macro-op */


/******************************************************************************

			       FILE_HEADER

synopsis : file_header (modif, type)
	   uchar *modif, *line
description : expand a macro-op (LEX or BIN)

******************************************************************************/

file_header (modif, type)
uchar *modif, *type ;
{
    uchar line [MAXLEN+1], *pline, limit, c ;
    int i = 0, later = 0 ;

    uprc (modif) ;
    strcpy (line, "  NIBASC ") ;
    pline = line + 9 ;
    limit = *modif ;
    if ((limit!='\'')&&(limit!='\\')) error (ERRIFL, "") ; /* inv. file name */
    *pline = limit ;
    pline++ ;
    modif++ ;
    while ((i<=8)&&((c = *modif)!=limit)&&(c))
    {
	i++ ;
	if (!( ((c>='A')&&(c<='Z')) ||
	       ((later)&&(c>='0')&&(c<='9')) ) )
	    error (ERRIFL, "") ;           /* invalid file name */
	later++ ;
	*pline = c ;
	modif++ ;
	pline++ ;
    }
    if ((i==0)||(i==9)) error (ERRIFL, "") ;
    while (i<8)
    {
	*pline = ' ' ;
	pline++ ;
	i++ ;
    }
    *pline = limit ;
    *(pline+1) = EOL ;
    ps_line (line) ;

    strcpy (line, "  NIBHEX ") ;
    strcat (line, type) ;
    ps_line (line) ;

    ps_line ("  CON(2) 0") ;                /* copy code / secure code */

    for (i=1; i<=5; i++) ps_line ("  CON(2) #00") ;   /* time */

    ps_line ("  REL(5) FiLeNd") ;

    ctok = ckey = 0 ;
}


/******************************************************************************

				      BSS


synopsis : void bss (modif)
	   char *modif
description : areuh

******************************************************************************/

void bss (modif)
uchar *modif ;
{
    saddr val ;
    int i, m ;

    val = calc_expression (modif) ;
    if (val < 0L) error (ERRVMD, "BSS") ;                 /* fatal error */
    gen_len = (int) val ;
    if (passnb==2)
    {
	m = (gen_len>18) ? 18 : gen_len ;
	for (i=0; i<m; i++)
	    gen_code[i] = '0' ;
	gen_code[m] = EOL ;
    }
}


void eject ()
{
    l_new_page (1) ;
    print_this_line = 0 ;
}


void endx ()
{
    running = 0 ;
}


void list (modif)
uchar *modif ;
{
    int r = 0 ;
    uchar c ;

    uprc (modif) ;
    c = *modif++ ;
    if (c=='O')
    {
	c = *modif++ ;
	switch (c)
	{
	    case 'N' :
		r = 1 ;
		break ;
	    case 'F' :
		c = *modif++ ;
		if (c=='F')  r = 0 ;
		else r = -1 ;
		break ;
	    default :
		r = -1 ;
		break ;
	}
    }
    else r = -1 ;

    c = *modif ;
    if ((r==-1)||((c!=' ')&&(c!=EOL)&&(c!='\t')))
	error (WRNLST, "") ;   /* invalid LIST argument */
    else cntlist = r * cntlist_ref ;
}


void title (modif)
uchar *modif ;
{
    if (*l_title==EOL) strcpy (l_title, modif) ;
}


void stitle (modif)
uchar *modif ;
{
    strcpy (l_stitle, modif) ;
    eject () ;
}


void lex (modif, line)
uchar *modif, *line ;
{
    switch (passnb)
    {
	case 1 :
	    if (linenb!=1) error (ERRLEX, "") ; /* invalid macro LEX or BIN */
	    modular = 0 ;
	    gen_len = 37 ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    file_header (modif, "802E") ;
	    print_this_line = 0 ;
	    gen_len = 0 ;
	    break ;
    }
}


void id (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "ID") ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    sprintf (tmp, "   CON(2) %s", modif) ;
	    ps_line (tmp) ;
	    sprintf (tmp, "   CON(2) %03d", ltok) ;
	    ps_line (tmp) ;
	    sprintf (tmp, "   CON(2) %03d", htok) ;
	    ps_line (tmp) ;
	    ps_line ("   CON(5) 0") ;
	    ps_line ("   NIBHEX F") ;
	    ps_line ("   REL(4) 1+TxTbSt") ;
	    print_this_line = gen_len = 0 ;
	    break ;
    } /* du switch */
}


void msg (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;
    saddr val ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "MSG") ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    if (((val = calc_expression (modif)) == 0L) || (val == EXP_ERR))
		ps_line ("   CON(4) 0") ;
	    else
	    {
		sprintf (tmp, "   REL(4) %s", modif) ;
		ps_line (tmp) ;
	    }
	    print_this_line = gen_len = 0 ;
    } /* du switch */
}


void poll (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;
    saddr val ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "POLL") ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    if (((val = calc_expression (modif)) == 0L) || (val == EXP_ERR))
		ps_line ("   CON(5) 0") ;
	    else
	    {
		sprintf (tmp, "   REL(5) %s", modif) ;
		ps_line (tmp) ;
	    }
	    print_this_line = gen_len = 0 ;
    } /* du switch */
}


void entryx (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "ENTRY") ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    if (!ctok) ps_line ("   * * * M A I N   T A B L E * * *") ;
	    sprintf (tmp, "   CON(3) (TxEn%02d)-(TxTbSt)", ++ctok) ;
	    ps_line (tmp) ;
	    sprintf (tmp, "   REL(5) %s", modif) ;
	    ps_line (tmp) ;
	    print_this_line = gen_len = 0 ;
	    break ;
    } /* du switch */
}


void charx (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "CHAR") ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    sprintf (tmp, "   CON(1) %s", modif) ;
	    ps_line (tmp) ;
	    print_this_line = gen_len = 0 ;
	    break ;
    }
}


void key (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "KEY") ;
	    if (!ckey) ps_line (" TxTbSt") ;
	    sprintf (tmp, " TxEn%02d", ++ckey) ;
	    ps_line (tmp) ;
	    gen_len = ((ascii_len(modif))*2) + 1 ;
	    break ;
	case 2 :
	    uprc (modif) ;
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    if (!ckey)
	    {
		ps_line ("   * * * T E X T   T A B L E * * *") ;
		ps_line (" TxTbSt") ;
	    }
	    sprintf (tmp, " TxEn%02d", ++ckey) ;
	    ps_line (tmp) ;
	    sprintf (tmp, "   CON(1) %02d", ((ascii_len(modif))*2) - 1) ;
	    ps_line (tmp) ;
	    sprintf (tmp, "   NIBASC %s", modif) ;
	    ps_line (tmp) ;
	    print_this_line = gen_len = 0 ;
	    break ;
    } /* du switch */
}


void token (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;
    saddr tok ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "TOKEN") ;
	    tok = calc_expression (modif) ;
	    if (tok<ltok) ltok = tok ;
	    if (tok>htok) htok = tok ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    sprintf (tmp, "   CON(2) %s", modif) ;
	    ps_line (tmp) ;
	    print_this_line = gen_len = 0 ;
	    break ;
    } /* du switch */
}


void bin (modif, line)
uchar *modif, *line ;
{
    switch (passnb)
    {
	case 1 :
	    if (linenb!=1) error (ERRLEX, "") ; /* invalid macro LEX or BIN */
	    modular = 0 ;
	    gen_len = 37 ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    file_header (modif, "402E") ;
	    print_this_line = 0 ;
	    gen_len = 0 ;
	    break ;
    }
}


void chain (modif, line)
uchar *modif, *line ;
{
    uchar tmp [MAXLEN+1] ;

    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "CHAIN") ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    if (calc_expression (modif) == EXP_ERR)
		ps_line ("   CON(5) -1") ;
	    else
	    {
		sprintf (tmp, "   REL(5) %s", modif) ;
		ps_line (tmp) ;
	    }
	    ps_line ("   CON(5) -1") ;
	    ps_line ("   NIBHEX 20") ;
	    print_this_line = gen_len = 0 ;
	    break ;
    }
}


void endtxt (line)
uchar *line ;
{
    switch (passnb)
    {
	case 1 :
	    if (modular) error (ERRIMO, "ENDTXT") ;
	    if (!ckey) ps_line (" TxTbSt") ;
/*	      if (!ckey) add_label (" TxTbSt", pc, "", LREL, 0) ; */
	    gen_len = 3 ;
	    break ;
	case 2 :
	    if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ;
	    if (!ckey) ps_line (" TxTbSt") ;
	    ps_line ("   NIBHEX 1FF") ;
	    print_this_line = gen_len = 0 ;
	    break ;
    } /* du switch */
}

void endifx ()
{
    if (!(in_if || in_else))
	error (WRNIIF, "") ;      /* Invalid conditional structure */
    in_if = in_else = 0 ;
    exec = 1 ;
}

void absx (modif)	/* FUTURE USE... */
uchar *modif ;
{
}

void rdsymb (modif)
uchar *modif ;
{
    uchar *pmodif ;

    if (passnb==1)
    {
	pmodif = modif ;
	while ((*pmodif!=EOL)&&(*pmodif!='\t')&&(*pmodif!=' ')) pmodif++ ;
	*pmodif = EOL ;
	load_file (modif) ;
    }
}

void elsex ()
{
    if (!in_if)
    {
	error (WRNIIF, "") ;      /* Invalid conditional structure */
	in_if = in_else = 0 ;
	exec = 1 ;
    }
    else
    {
	in_if = 0 ; in_else = 1 ;
	exec = ! exec ;
    }
}

void ifx (modif)
uchar *modif ;
{
    saddr val ;

    if (in_if || in_else)
    {
	error (WRNIIF, "") ;      /* Invalid conditional structure */
	in_if = in_else = 0 ;
	exec = 1 ;
    }
    else
    {
	val = calc_expression (modif) ;
	if (val==EXP_EXT)
	    error (WRNEXP, "") ;  /* Illegal expression */
	in_if = 1 ; in_else = 0 ;
	exec = (int) val ;
    }
}
@EOF
set `wc -lwc <areuh/assembler/aopc2.c`
if test $1$2$3 != 513162210067
then
	echo ERROR: wc results of areuh/assembler/aopc2.c are $* should be 513 1622 10067
fi

chmod 644 areuh/assembler/aopc2.c

echo x - areuh/assembler/apass.c
cat >areuh/assembler/apass.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

				AREUH ASSEMBLER

				PASS PROCESSING


pass

******************************************************************************/

#include "aglobal.h"
#include "agen.h"

extern struct mnemo_desc *find_mnemo() ;
extern int read_line();
extern void parse_line(), ps_label(), process_mnemo(),
	    l_new_page(), l_print(), o_print() ;
extern struct symbol *add_label() ;

void ps_line() ;


/******************************************************************************

				     PASS


synopsis : void pass()
description :

******************************************************************************/

void pass()
{
    uchar line[MAXLEN+1];
    int c;

    pc = 0 ;
    prev_test = 0 ;
    running = 1 ;
    exec = 1 ; in_if = in_else = 0 ;

    while (running)
    {
	c = read_line (fd_s, line) ;
	error_this_line = 0 ;
	if (c) running = 0 ;
	else ps_line (line) ;
    }

    if (passnb==1)
    {
	add_label("FiLeNd", pc, "", LREL, 0) ;
    }
}


/******************************************************************************

				  PS_LINE


synopsis : void ps_line (line)
	   uchar *line
description : parses the line read from the input (breaks the line into three
	      components), processes the label if necessary, processes the
	      mnemonic if necessary, and does the listing and object file
	      actualization, if pass one.

******************************************************************************/

void ps_line (line)
uchar *line ;
{
    uchar label[LBLLEN+2], mnemo[7], modif[MAXLEN+1] ;
    struct mnemo_desc *ad ;

    parse_line (line, label, mnemo, modif) ;

    if (!exec)
    {
	if ( (strcmp(mnemo, "IF"))&&
	     (strcmp(mnemo, "ELSE"))&&
	     (strcmp(mnemo, "ENDIF"))&&
	     (strcmp(mnemo, "END")) )
	    return ;	  /* Neither IF nor ELSE nor ENDIF */
    }
    if (*label)
	ps_label (label, mnemo, modif) ;

    *gen_code = EOL ;
    gen_len = 0 ;

    if (*mnemo)
    {
	ad = find_mnemo (mnemo) ;
	if (ad)
	{
	    gen_len = ad->m_len ;
	    switch (passnb)
	    {
		case 1 :
		    if (!((ad->m_flag)&F_LSET))
			 ps_mnemo (line, modif, ad) ;
		    break ;
		case 2 :
		    strcpy (gen_code, ad->m_code) ;
		    ps_mnemo (line, modif, ad) ;
		    if ((prev_test)&&(!(ad->m_flag & F_GOYS)))
			error (WRNYES, "") ;     /* GOYES or RTNYES required */
		    break ;
	    }
	}
	else
	{
	    error (WRNOPC, "") ;       /* unknown oopcode */
	    if (prev_test)
		error (WRNYES, "") ;     /* GOYES or RTNYES required */
	}
    }
    else ad = (struct mnemo_desc *) NULL ;

    if (passnb==2)
    {
	if ((cntlist)&&(print_this_line++))
	    l_print (pc, gen_code, line, F_PC+F_LN+F_GC+F_TL) ;
	o_print (gen_code, gen_len) ;
	if (ad) prev_test = ((ad->m_flag)&F_RETY) ? 1 : 0 ;
    }

    pc += gen_len ;
}
@EOF
set `wc -lwc <areuh/assembler/apass.c`
if test $1$2$3 != 1443803049
then
	echo ERROR: wc results of areuh/assembler/apass.c are $* should be 144 380 3049
fi

chmod 644 areuh/assembler/apass.c

echo x - areuh/assembler/areport.c
cat >areuh/assembler/areport.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                AREUH ASSEMBLER

                            END OF ASSEMBLY REPORT



print_ref, print_status, print_label, print_xref

******************************************************************************/

#include "aglobal.h"

extern void l_print (), l_new_page () ;

uchar format [15], formateq [16], xformat [MAXLEN], xf[15] ;

void print_status (), print_label (), print_xref () ;

/******************************************************************************

                                   PRINT_REF

synopsis : void print_ref () 
description : at the end of assembly (end of second pass), programmer want some
  informations on the program. This includes :
  - list of labels with their value, and cross reference
  - error count
  - time and date
  - that's all folks

******************************************************************************/

void print_ref ()
{
    sprintf (format, " %%-%ds %%s", LBLLEN) ;
    sprintf (formateq, "%%-%ds %%s", LBLLEN+1) ;
    sprintf (xf, "%%%ds+ ", LBLLEN+18) ;
    sprintf (xformat, xf, "") ;

    if ((cntlist) || (xref))
        print_label() ;

    if (cntlist) print_status() ;
    else
    {
        if (errcnt)
            printf ("aas: %d errors in file %s\n", errcnt, fsource) ;
    }
}


/******************************************************************************

                                 PRINT_STATUS


synopsis : void print_status ()
description : reports some status lines after the assembly

******************************************************************************/

void print_status()
{
    uchar line[MAXLEN+1], tmp[MAXLEN+1] ;

    l_print (0L, "", "", F_TL) ;
    l_print (0L, "", "", F_TL) ;
    l_print (0L, "", "", F_TL) ;
    l_print (0L, "", "", F_TL) ;
    l_print (0L, "", "", F_TL) ;
    l_print (0L, "", "", F_TL) ;

    sprintf (line, "Source  : %s", fsource) ;
    l_print (0L, "", line, F_TL) ;
    l_print (0L, "", "", F_TL) ;

    sprintf (line, "Object  : %s", fobject) ;
    l_print (0L, "", line, F_TL) ;
    l_print (0L, "", "", F_TL) ;

    strcpy (line, "Listing : ") ;
    if (cntlist == 1) strcat (line, "stdout") ;
    else strcat (line, flisting) ;
    l_print (0L, "", line, F_TL) ;
    l_print (0L, "", "", F_TL) ;

    format_time (tmp) ;
    sprintf (line, "Date    : %s", tmp) ;
    l_print (0L, "", line, F_TL) ;
    l_print (0L, "", "", F_TL) ;

    sprintf (line, "Errors  : %03d", errcnt) ;
    l_print (0L, "", line, F_TL) ;
    l_print (0L, "", "", F_TL) ;

    l_print (0L, "", "", F_TL) ;
    l_print (0L, "", "", F_TL) ;
    l_print (0L, "", "Areuh Assembler/Linker V2.4, (c) P. David & J. Taillandier 1986 Paris, France", F_TL) ;
}


/******************************************************************************

                                  PRINT_LABEL

synopsis : void print_label()
description : prints a complete list of labels encoutered in the assembly.

******************************************************************************/

void print_label ()
{
    struct symbol *t ;
    struct xtable *x ;
    uchar line[MAXLEN+1], tmp[MAXLEN+1] ;
    int i ;

    strcpy (l_stitle, "**** SYMBOL TABLE ****") ;
    l_new_page (1) ;

    for (i=0; i<256; i++)
    {
        t = h_label[i]->s_next ;
        while (t)
        {
            if (!t->s_os)
            {
                if (t->s_value >= (saddr) 0)
                {
                        hex5 (tmp, t->s_value) ;
                }
                else if (t->s_value == LBL_UDF)
                {
                        strcpy (tmp, "Undef") ;
                }
                else if (t->s_value == LBL_EXT)
                {
                        strcpy (tmp, "Extrn") ;
                }
                else /* (t->s_value == LBL_SEQ) || (t->s_value == LBL_XEQ) */
                {
                        strcpy (tmp, "Unkwn") ;
                }

                if (*(t->s_name)=='=')
                     sprintf (line, formateq, t->s_name, tmp) ;
                else sprintf (line, format, t->s_name, tmp) ;
                if (xref)
                {
                    switch (t->s_type)
                    {
                        case LUDF : strcat (line, " Ukn") ; break ;
                        case LABS : strcat (line, " Abs") ; break ;
                        case LREL : strcat (line, " Rel") ; break ;
                    }
                    if ((t->s_value!=LBL_UDF)&&(t->s_value!=LBL_EXT))
                        sprintf (tmp, "%s  %04d - ", line, t->s_decl) ;
                    else sprintf (tmp, "%s       - ", line, t->s_decl) ;
                    x = t->s_xref ;
                    if (x)
                    {
                        while (x->x_next)  x = x->x_next ;
                        print_xref (x, tmp) ;
                    }
                    else
                    {
                        if (cntlist) l_print (0L, "", tmp, F_TL) ;
                        else printf ("%s\n", tmp) ;
                    }
                }
                else l_print (0L, "", line, F_TL) ;
            } /* if not (O.S. entry point not used) */
            t = t->s_next ;
        } /* while */
    } /* for */
}


/******************************************************************************

                                   PRINT_XREF


synopsis : void print_xref (x, line)
           struct xtable *x
           uchar *line
description : prints the complete cross-reference list backward from the end.
              x is the end of xref list, line is the line to be printed first.

******************************************************************************/

void print_xref (x, line)
struct xtable *x ;
uchar *line ;
{
    int col = LBLLEN+21 ;        /* column number */
    uchar tmp[MAXLEN+1], strnum[MAXLEN+1] ;

    strcpy (tmp, line) ;
    while (x)
    {
        if (col>75) 
        {
            if (cntlist) l_print (0L, "", tmp, F_TL) ;
            else printf ("%s\n", tmp) ;
            col = LBLLEN+21 ;
            strcpy (tmp, xformat) ;
        }
        sprintf (strnum, " %04d", x->x_line) ;
        strcat (tmp, strnum) ;
        col += 5 ;
        x = x->x_prev ;
    }
    if (cntlist) l_print (0L, "", tmp, F_TL) ;
    else printf ("%s\n", tmp) ;
}
@EOF
set `wc -lwc <areuh/assembler/areport.c`
if test $1$2$3 != 2297616584
then
	echo ERROR: wc results of areuh/assembler/areport.c are $* should be 229 761 6584
fi

chmod 644 areuh/assembler/areport.c

echo x - areuh/assembler/autil.c
cat >areuh/assembler/autil.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

				TITAN ASSEMBLER

			       GENERAL UTILITIES


hard_init, soft_init, between, term, memoire

******************************************************************************/


#include "aglobal.h"

void free_mem () ;

extern void o_init() ;
extern void dump_linker_infos () ;
extern void l_init(), l_flush() ;
extern void s_init() ;
extern void i_tab0(), i_tab1(), i_tab2(), i_tab3(), i_tab4(), i_tab5() ;
extern void print_ref() ;

extern char *malloc () ;

/******************************************************************************

				   INIT


synopsis : void init()
description : initiates the pass one. Opens source file, initializes the symbol
	      list. Called for each file assembled.

******************************************************************************/

void init ()
{
    uchar file [MAXLEN+1], *psource, *pfile ;

    if (!try_source (fsource))	     /* if can't open succesfully */
    {
	pfile = file ; psource = fsource ;
	while ((*pfile = *psource) && (*pfile != '.'))
        {
	    pfile++ ;
            psource++ ;
        }
	if (*pfile == EOL)
	{
	    strcpy (pfile, ".as") ;
	    if (try_source (file)) strcpy (fsource, file) ;
	}
    }
    if (fd_s==NULL) error (ERROPN, fsource) ;

    s_init() ;                                  /* symbol table init */

    passnb = 1 ;
    linenb = 0 ;
    cntlist = 0 ;
    modular = 1 ;
    *l_title = *l_stitle = EOL ;
}


/******************************************************************************

				    BETWEEN


synopsis : void between()
description : terminates the passe one, and prepares pass two.
	      Restore file source pointer, opens object file.

******************************************************************************/

void between()
{
    int r ;

    r =  fseek (fd_s,0L,0);
    if (r)  error (ERRREW, fsource) ;
    o_init() ;
    cntlist = cntlist_ref ;
    l_init() ;
    linenb = 0 ;
    passnb = 2 ;
    print_this_line = 1 ;
    errcnt = 0 ;
    headxu = (struct xused *) NULL ;
}

/******************************************************************************

				     TERM


synopsis : void term ()
description : ends the pass two, and thus the assembly.
	      Closes source file, and flushes object files.

******************************************************************************/

void term ()
{
    if (fclose (fd_s)) error (ERRCLO, fsource) ;
    if (modular) dump_linker_infos () ;
    if (fclose (fd_o)) error (ERRCLO, fobject) ;
    print_ref () ;
    l_flush () ;

    free_mem () ;
}


int try_source (file)
uchar *file ;
{
    long int magic ;

    fd_s = fopen (file, "r") ;
    if (fd_s)
    {
	fread (&magic, sizeof (long int), 1, fd_s) ;
	if (((magic>=ALF_MAGIC)&&(magic<=AL_MAGIC))||
	    ((magic>=AOF_MAGIC)&&(magic<=AO_MAGIC)))
	{
	    fclose (fd_s) ;
	    fd_s = (FILE *) NULL ;
	}
	else fseek (fd_s, 0L, 0) ;
    }
    return ((int) fd_s) ;
}


/******************************************************************************

				  MEMOIRE


synopsis : uchar *memoire (size)
	   int size
description : get memory from heap using malloc. It is just a layer above
	      malloc, including a test.

******************************************************************************/

uchar *memoire (size)
int size ;
{
    uchar *x ;

    if ((x = (uchar *) malloc (size)) == NULL)
	error (ERRMEM, "") ;
    return (x) ;
}


/******************************************************************************

				    UPRC


synopsis : void uprc (str)
	   uchar *str
description : uppercase a string

******************************************************************************/

void uprc (str)
uchar *str ;
{
    while (*str)
    {
	if ((*str >= 'a') && (*str <= 'z'))
	    *str -= 32 ;
	str++ ;
    }
}


/******************************************************************************

				 FORMAT_HEX


synopsis : void format_hex (str, val, dig)
	   uchar *str
           saddr val
           int dig
description : stores into str the hexadecimal string representing the dig
              low order hex digits of val.

******************************************************************************/

void format_hex (str, val, dig)
uchar *str ;
saddr val ;
int dig ;
{
    register int i, h ;

    for (i=dig-1; i>=0; i--)
    {
	h = (int) (val & ((saddr) 0xf)) ;
	str [i] = h + ((h < 10) ? '0' : 'A' - 10) ;
	val >>= 4 ;
    }
    str [dig] = EOL ;
}


/******************************************************************************

				 FREE_MEM


synopsis : void free_mem ()
description : frees all dynamically allocated memory during both passes.

******************************************************************************/

void free_mem ()
{
    struct xused *u ;
    struct symbol *s1, *s2 ;
    struct xtable *x1, *x2 ;
    int i ;

    for (i=0; i<=255; i++)
    {
        s1 = h_label[i]->s_next ;
        while (s1)
        {
            if (xref)
            {
                x1 = s1->s_xref ;
                while (x1)
                {
                    x2 = x1->x_next ;
                    free ((char *) x1) ;
                    x1 = x2 ;
                }
            }
            if (s1->s_def)  free ((char *) s1->s_def) ;
            s2 = s1->s_next ;
            free ((char *) s1) ;
            s1 = s2 ;
        }
    }
    free ((char *) h_label [0]) ;
}
@EOF
set `wc -lwc <areuh/assembler/autil.c`
if test $1$2$3 != 2656915648
then
	echo ERROR: wc results of areuh/assembler/autil.c are $* should be 265 691 5648
fi

chmod 644 areuh/assembler/autil.c

echo x - areuh/assembler/common.h
cat >areuh/assembler/common.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include <stdio.h>


#define MAXLEN 256
#define EOL    '\0'
#define LBLLEN 12

/******************************************************************************
 TYPE DEFINITIONS
******************************************************************************/

typedef long int saddr ;	      /* Saturne address. At least 32 bits   */
typedef unsigned char uchar ;	      /* unsigned characters, for accents    */
typedef short int sint ;	      /* 16 bits */

/******************************************************************************
 MAGIC NUMBERS
******************************************************************************/

#define  AL_MAGIC 0x1b080100	      /* ... areuh_lex */
#define  AO_MAGIC 0x1b0d0100	      /* ... areuh_output of assembler */
#define ALF_MAGIC 0x1b080100	      /* first version of object file format */
#define AOF_MAGIC 0x1b0d0100	      /* first version of object file format */


/******************************************************************************
 USAGE TYPES IN .ao FILES
******************************************************************************/

#define XABSL 0x10     /* absolute reference */
#define XABSO 0x20     /* absolute reference, with one bias */
#define XRGTO 0x40     /* relative reference, goto type */
#define XRGSB 0x80     /* relative reference, gosub type */


/******************************************************************************
 LABEL VALUES IN .ao FILES
******************************************************************************/

#define LBL_UDF -1L
    /* label not declared (implicit or explicit) <=> only used */
#define LBL_IVL -2L
    /* invalid label (invalid expression for an EQU during pass one) */
#define LBL_EXT -3L
    /* external label not defined here (or yet) */
#define LBL_XEQ -4L
    /* global label which is defined here, with an external reference */
#define LBL_SEQ -5L
    /* local label which is defined with an external reference */


/******************************************************************************
 LABEL TYPES IN .ao FILES
******************************************************************************/

#define LUDF 0
    /* undefined type (external label) */
#define LABS 1
    /* absolute local label (declared explicitly, with constants) */
#define LREL 2
    /* relative local label (declared implicitly, or explicitly with at least
       one relative) */


/******************************************************************************
 VALUES RETURNED BY EXPRESSION EVALUATOR
******************************************************************************/

#define EXP_ERR -1L
#define EXP_EXT -2L

extern int relabs ;
extern uchar extexp[] ;

#include "err.h"
extern void error () ;

#define hex5(str,val) format_hex (str, val, 5) ;
#define hex6(str,val) format_hex (str, val, 6) ;

/******************************************************************************
 MACHINE DEPENDANCIES
******************************************************************************/

#define HPUX		     1
#define ATARI_LATTICE	     0
#define PC_MSC		     0		/* PC (beuark, Microsoft C) */

#if HPUX
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "r"
#define WAO_MODE "w"
#define skip(fp)
#endif

#if ATARI_LATTICE
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "rb"
#define WAO_MODE "wb"
extern char skipvar ;
#define skip(fp) fread(&skipvar,1,1,fp) ;
#endif

#if PC_MSC
extern void format_time(), load_file() ;
#define HP71EP "hp71.ep"
#define RAO_MODE "rb"
#define WAO_MODE "wb"
extern char skipvar ;
#define skip(fp) fread(&skipvar,1,1,fp) ;
#endif
@EOF
set `wc -lwc <areuh/assembler/common.h`
if test $1$2$3 != 1244243878
then
	echo ERROR: wc results of areuh/assembler/common.h are $* should be 124 424 3878
fi

chmod 644 areuh/assembler/common.h

echo x - areuh/assembler/err.h
cat >areuh/assembler/err.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                           AREUH ASSEMBLER / LINKER


                          ERROR NUMBERS DECLARATIONS

******************************************************************************/




/* FATAL ERRORS */

#define ERROPN  -1                                       /* A L */
    /* system error opening file */
#define ERRCLO  -2                                       /* A L */
    /* system error closing file */
#define ERRREW  -3                                       /* A */
    /* system error on file at start of pass two */
#define ERRWRT  -4                                       /* A L */
    /* system error writing file */
#define ERRRD   -5                                       /* A L */
    /* system error reading file */
#define ERRMEM  -6                                       /* A L */
    /* not enough memory */

#define ERRLEX  -10                                      /* A */
    /* invalid macro pseudo-op LEX or BIN */
#define ERRPGS  -11                                      /* A */
    /* invalid page size */
#define ERRFLN  -12                                      /* A */
    /* restricted label FiLeNd exists */
#define ERRIFL  -13                                      /* A L */
    /* invalid file name */
#define ERRIMO  -14                                      /* A */
    /* invalid macro-op xx in modular assembling */
#define ERRVMD  -15                                      /* A */
    /* value must be defined for xx */

#define ERRUSA  -20                                      /* A L */
    /* usage: ass [ [-l] source_file ] */
    /* usage: ald ... */

#define ERRNOA  -30                                      /* L */
    /* file not output from aas */
#define ERRICV  -31                                      /* L */
    /* incompatible version */



/* NON FATAL ERRORS */

#define WRNEQU  10                                       /* A */
    /* cannot resolve equate */
#define WRNDUP  11                                       /* A L */
    /* duplicate label */
#define WRNLBL  12                                       /* A */
    /* illegal label */
#define WRNULB  13                                       /* A */
    /* unrecognized label */
#define WRNURF  14                                       /* L */
    /* unresolved reference */
#define WRNURL  15                                       /* L */
    /* unresolved label */

#define WRNEXP  20                                       /* A */
    /* illegal expression */
#define WRNASC  21                                       /* A */
    /* illegal ascii constant */
#define WRNPAR  22                                       /* A */
    /* mismatched parenthesis */
#define WRNIHX  23                                       /* A */
    /* illegal hexadecimal constant */
#define WRNNUL  24                                       /* A */
    /* null divisor */
#define WRNIXP  25                                       /* A */
    /* illegal exponentiation */
#define WRNIBC  26                                       /* A */
    /* illegal binary constant */
#define WRNENA  27                                       /* A */
    /* external references not allowed */

#define WRNYES  30                                       /* A */
    /* GOYES or RTNYES required */
#define WRNIDP  31                                       /* A */
    /* illegal dp arithmetic value */
#define WRNIPP  32                                       /* A */
    /* illegal pointer position */
#define WRNISB  33                                       /* A */
    /* illegal status bit */
#define WRNTFR  34                                       /* A */
    /* illegal transfer value */
#define WRNIWS  35                                       /* A */
    /* illegal word select */
#define WRNLST  36                                       /* A */
    /* invalid LIST argument */
#define WRNJVL  37                                       /* A L */
    /* jump or value too large */
#define WRNMLB  38                                       /* A */
    /* missing label */
#define WRNTST  39                                       /* A */
    /* needs previous test instruction */
#define WRNNHX  40                                       /* A */
    /* non hexadecimal digits present */
#define WRNTMA  41                                       /* A */
    /* too many ascii characters present */
#define WRNTMH  42                                       /* A */
    /* too many hexadecimal digits present */
#define WRNOPC  43                                       /* A */
    /* unknown opcode */

#define WRNIIF  50                                       /* A */
    /* invalid conditional structure */

extern void error() ;
@EOF
set `wc -lwc <areuh/assembler/err.h`
if test $1$2$3 != 1275845010
then
	echo ERROR: wc results of areuh/assembler/err.h are $* should be 127 584 5010
fi

chmod 644 areuh/assembler/err.h

echo x - areuh/assembler/exp.c
cat >areuh/assembler/exp.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

                                TITAN ASSEMBLER

                             EXPRESSION EVALUATION


calc_expression, reduce_E, reduce_T, reduce_F, reduce_B, reduce_X,
reduce_P, dec_value, hex_value, bin_value, ascii_value, label_value, apply,
trunc, next_char, append_extexp

******************************************************************************/

#include "flag.h"

#if ASSEMBLER
#include "aglobal.h"
#else
#include "lglobal.h"
#endif

uchar extexp [4*MAXLEN] ;
uchar *pexp, *pextexp ;
uchar *xlabel ;
int relabs ;

extern saddr symbol_value() ;

saddr reduce_E(), reduce_T(), reduce_F(), reduce_B(), reduce_X(), reduce_P(),
      dec_value(), hex_value(), bin_value(), ascii_value(), label_value(),
      apply(), trunc() ;
void next_char(), append_extexp() ;


/******************************************************************************

                               CALC_EXPRESSION


synopsis : saddr calc_expression (exp)
           uchar *exp
description : That's the expression evaluator. Productions used are :

    E -> T { {+|-} T }*
    T -> F { {*|/} F }*
    F -> B { {&|!} B }*
    B -> X | -X | `X           (two's and one's complement)
    X -> N { {~|^} N }*
    P -> D | #<hex> | %<bin> | '<ascii>' | \<ascii>\ | <label> | * | (E)

    D -> <dec>                 if expression evaluated by ASSSEMBLER
    D -> <dec> | <dec> r       if expression evaluated by LINKER

    where   E : expression
            T : term
            F : factor
            B : boolean
            X : exponentiation
            P : primary
            D : decimal number
warning : with this grammar, 5--5 is valid (5 minus -5), but 5---5 is not.
          This can be modified by : B -> -B | P . The code is more complex,
          and I'm not sure that it's a real improvement.
note : Algorithm used is recursive descent (Mr Vermeulen would be horrified !)
       like Forth/Assembler rom based assembler, but is quietly different...

******************************************************************************/

saddr calc_expression (exp)
uchar *exp;
{
    saddr val;

    pextexp = extexp ;
    pexp = exp ;
    val = reduce_E() ;
    if (((val>=0L)||(val==EXP_EXT))&&(*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t'))
    {
        error(WRNEXP, "") ;    /* illegal expression */
        val = EXP_ERR ;
    }
    *pextexp = EOL ;
    return (val) ;
}


/******************************************************************************

                                   REDUCE_E


synopsis : saddr reduce_E()
description : This function reduces a given expression starting at pexp.

******************************************************************************/
saddr reduce_E()
{
    saddr val1, val2;
    uchar op, lrelabs;

    val1 = reduce_T () ;

    while ((((op = *pexp)=='+')||(op=='-'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_T () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_T


synopsis : saddr reduce_T ()
description : same as above, for T-production

******************************************************************************/

saddr reduce_T ()
{
    saddr val1, val2 ;
    uchar op, lrelabs ;

    val1 = reduce_F () ;
    while ((((op = *pexp)=='*')||(op=='/'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_F () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_F


synopsis : saddr reduce_F ()
description : same as reduce_E

******************************************************************************/

saddr reduce_F ()
{
    saddr val1, val2;
    uchar op, lrelabs ;

    val1 = reduce_B () ;
    while ((((op = *pexp)=='&')||(op=='!'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_B () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_B


synopsis : saddr reduce_B ()
description : reduces a boolean factor. This must be done by reduction of minus
              sign eventually.

******************************************************************************/

saddr reduce_B ()
{
    saddr val;
    uchar op ;

    op = *pexp ;

    if ((op=='-')||(op=='\`')) next_char () ;
    val = reduce_X () ;
    if (val<0L)
        return(val) ;
    switch (op)
    {
        case '-' :
            return (trunc (-val)) ;
        case '\`' :
            return (trunc (~val)) ;
        default :
            return (val) ;
    }
}


/******************************************************************************

                                   REDUCE_X


synopsis : saddr reduce_X ()
description : same as reduce_E

******************************************************************************/

saddr reduce_X ()
{
    saddr val1, val2;
    uchar op, lrelabs;

    val1 = reduce_P () ;
    while ((((op = *pexp)=='~')||(op=='^'))&&(val1!=EXP_ERR))
    {
        lrelabs = relabs ;
        next_char () ;
        val2 = reduce_P () ;
        val1 = apply (val1, op, val2, lrelabs, relabs) ;
    }
    return (val1) ;
}


/******************************************************************************

                                   REDUCE_P


synopsis : saddr reduce_P ()
description : these are the terminal rules.
note : rule P -> D is implemented "in line" in this code (not as a separate
  function).

******************************************************************************/

saddr reduce_P ()
{
    saddr val ;
    uchar limit, line[MAXLEN] ;

    switch (*pexp)
    {
        case '#' :
            next_char () ;
            if (((*pexp>='0')&&(*pexp<='9')) ||
               ((*pexp>='A')&&(*pexp<='F')) ||
               ((*pexp>='a')&&(*pexp<='f')))
                val = hex_value () ;
            else
            {
                error (WRNIHX,"");          /* illegal hexadecimal constant */
                val = EXP_ERR ;
            }
            relabs = LABS ;
            break ;
        case '%' :
            next_char () ;
            if ((*pexp=='0')||(*pexp=='1'))
                val = bin_value () ;
            else
            {
                error (WRNIBC, "") ;        /* illegal binary constant */
                val = EXP_ERR ;
            }
            relabs = LABS ;
            break ;
        case '\'' :
        case '\\' :
            limit = *pexp ;
            next_char () ;
            val = ascii_value (limit) ;
            if (*pexp!=limit)
            {
                error (WRNASC,"");                 /* illegal ascii constant */
                val = EXP_ERR ;
            }
            next_char () ;
            relabs = LABS ;
            break ;
        case '*' :
            val = pc ;
            pexp++ ;
            sprintf (line, "%ldr", pc) ;
            relabs = LREL ;
            append_extexp (line) ;
            break ;
        case '(' :
            next_char () ;
            val = reduce_E () ;
            if ((*pexp!=')')&&(val>=0))
            {
                error (WRNPAR, "") ;         /* mismatched parenthesis */
                val = EXP_ERR ;
            }
            next_char () ;
            break ;
        case EOL :
            error (WRNEXP,"") ;              /* illegal expression     */
            val = EXP_ERR ;
            break ;

        default :
            if ((*pexp>='0')&&(*pexp<='9'))
            {
                val = dec_value () ;
                relabs = LABS ;
#if LINKER
                if (*pexp=='r')
                {
                    next_char() ;
                    relabs = LREL ;
                    val += tmodule[file].m_ad ;
                }
#endif
            }
            else val = label_value () ;
            break ;
    }
    return (val) ;
}


/******************************************************************************

                                   DEC_VALUE


synopsis : saddr dec_value ()
descrption : This function returns the decimal value of a constant. The search
             is stopped when a non numeric digit is reached.
             (this can be ),+,-,*,/,&,!).
             Finally, the founded value is returned.
note : this function doesn't check overflow. If there is, numbers are treated
       as 20 bits words, and overflow doesn't propagate on 32 bits of an
       integer (-1 is never reached when calculus).

******************************************************************************/

saddr dec_value ()
{
    saddr val=0L ;

    do
    {
        val = trunc (val * 10L + (saddr) (*pexp-'0') ) ;
        next_char () ;
    }
    while ((*pexp>='0')&&(*pexp<='9')) ;
    return (val);
}


/******************************************************************************

                                   HEX_VALUE


synopsis : saddr hex_value ()
description : same as above for hexadecimal constants

******************************************************************************/

saddr hex_value ()
{
    saddr i, val = 0L ;

    while ( ((*pexp>='0')&&(*pexp<='9')) ||
            ((*pexp>='A')&&(*pexp<='F')) ||
            ((*pexp>='a')&&(*pexp<='f')) )
    {
        if (*pexp<='9') i = (long int) ((*pexp) - '0') ;
        else if (*pexp<='F') i = (long int) ((*pexp) - 'A' + 10) ;
        else i = (long int) ((*pexp) - 'a' + 10) ;
        val = trunc (val*16L +  i) ;
        next_char () ;
    }
    return (val) ;
}


/******************************************************************************

                                   BIN_VALUE


synopsis : saddr bin_value ()
description : same as above for binary constants

******************************************************************************/

saddr bin_value ()
{
    saddr val = 0L ;

    while ((*pexp=='0')||(*pexp=='1'))
    {
        val = trunc (val*2L + ((saddr) ((*pexp) - '0'))) ;
        next_char () ;
    }
    return (val) ;
}


/******************************************************************************

                                  ASCII_VALUE


synopsis : saddr ascii_value ()
description : same as above, but the search is stopped when encoutered a '.
              The pointer *pexp stands on this character.

******************************************************************************/

saddr ascii_value (limit)
uchar limit ;
{
    saddr val = 0 ;

    while ((*pexp!=EOL)&&(*pexp!=limit))
    {
        val = trunc (val*256L + ((saddr) *pexp)) ;
        next_char () ;
    }
    return (val) ;
}


/******************************************************************************

                                  LABEL_VALUE


synopsis : saddr label_value ()
description : parses the symbol, then tries to return the value founded in the
              symbol list.

******************************************************************************/

saddr label_value ()
{
    uchar label[LBLLEN+2], *plabel ;
    int mx, need_par = 0, j = 0 ;
    saddr val ;

    mx = LBLLEN + ((*pexp=='=') ? 1 : 0) ;
    while ((*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t')&&
           (*pexp!=')')&&(*pexp!='\\'))
    {
        if (j<mx) label[j++] = *pexp ;
        pexp++ ;
    }
    label[j] = EOL ;
    plabel = label ;

    if ((val = symbol_value (label)) >= (saddr) 0)
    {                             /* found, copy value */
     
        if (relabs==LREL) sprintf (label, "%ldr", val) ;
        else sprintf (label, "%ld", val) ;
    }
    else if ((val == LBL_UDF) || (val == LBL_IVL))
    {   /* UDF : label not (yet) declared, IVl : invalid label */
        *plabel = EOL ;                /* incoherent value */
        val = EXP_ERR ;
    }
    else if ((val == LBL_EXT) || (val == LBL_XEQ))
    {   /* LBL_EXT: ext. label not known, LBL_XEQ: global defined with ext. */
        val = EXP_EXT ;                        /* keep label name */
    }
    else                       /* (val == LBL_SEQ) */
    {   /* LBL_SEQ : synonym, expandable */
        plabel = xlabel ;              /* get definition of label */
        need_par = 1 ;                 /* enclose label with (...) */
        val = EXP_EXT ;                /* and store it into extep */
    }

    if (need_par) append_extexp ("(") ;
    append_extexp (plabel) ;
    if (need_par) append_extexp (")") ;

    return (val) ;
}


/******************************************************************************

                                     APPLY


synopsis : saddr apply (val1, op, val2, relabs1, relabs2)
           saddr val1, val2
           uchar op, relabs1, relabs2
description : calculate the value of binary operator op applied to operands
              val1 & val2.
note : under overflow condition, numbers are truncated to 20 bits.

******************************************************************************/

saddr apply (val1, op, val2, relabs1, relabs2)
uchar op, relabs1, relabs2 ;
saddr val1, val2 ;
{
    saddr val ;

    if (val2==EXP_ERR)                    return (EXP_ERR) ;
    if ((val1==EXP_EXT)||(val2==EXP_EXT)) return (EXP_EXT) ;

    switch (op)
    {
        case '+' :
            val = trunc (val1 + val2) ;
            break ;
        case '-' :
            val = trunc (val1 - val2 ) ;
            break ;
        case '*' :
            val = trunc (val1 * val2 ) ;
            break ;
        case '/' :
#if ASSEMBLER
            val = (val2 ? val1 / val2 : EXP_ERR ) ;
#else
            val = (val2 ? val1 / val2 : EXP_EXT ) ;
#endif
            if (val2==0L)   error (WRNNUL, "") ;   /* null divisor */
            break ;
        case '&' :
            val = val1 & val2 ;
            break ;
        case '!' :
            val = val1 | val2 ;
            break ;
        case '~' :
            val = trunc (val1*256 + val2) ;
            break ;
        case '^' :
            if ((val1<0)||(val2<0)||((val1==0)&&(val2==0)))
            {
                error (WRNIXP, "") ;           /* Illegal exponentiation */
#if ASSEMLER
                val = EXP_ERR ;
#else
                val = EXP_EXT ;
#endif
            }
            else
            {
                val = 1 ;
                for (;val2>0 ; val2--) val *= val1 ;
                val = trunc (val) ;
            }
            break ;
    }
    if ((relabs1==LUDF)||(relabs2==LUDF))      relabs = LUDF ;
    else if ((relabs1==LREL)||(relabs2==LREL)) relabs = LREL ;
    else                                       relabs = LABS ;
    return (val) ;
}


/******************************************************************************

                                     TRUNC


synopsis : saddr trunc (val)
           saddr val
description : truncates 32 bits integer to 24 bits.

******************************************************************************/

saddr trunc (val)
saddr val ;
{
    return (val & 0xffffff) ;
}


/******************************************************************************

                                   NEXT_CHAR


synopsis : void next_char ()
description : stores the current character in extexp variable, and moves the
              expression pointer (pexp) forward one position.

******************************************************************************/
void next_char ()
{
    *pextexp = *pexp ;
    pextexp++ ;
    pexp++ ;
}


/******************************************************************************

                                 APPEND_EXTEXP


synopsis : void append_extexp (line)
           uchar *line ;
description : append line to extexp string.

******************************************************************************/

void append_extexp (line)
uchar *line ;
{
    while (*line)
    {
        *pextexp = *line ;
        pextexp++ ;
        line++ ;
    }
}
@EOF
set `wc -lwc <areuh/assembler/exp.c`
if test $1$2$3 != 634182916414
then
	echo ERROR: wc results of areuh/assembler/exp.c are $* should be 634 1829 16414
fi

chmod 644 areuh/assembler/exp.c

echo x - areuh/assembler/flag.h
cat >areuh/assembler/flag.h <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/****************************************************************************/
/* !!! CONTENTS OF THIS FILE MUST BE DIFFERENT FOR ASSEMBLER AND LINKER !!! */
/****************************************************************************/
#define ASSEMBLER 1
#define LINKER    0
@EOF
set `wc -lwc <areuh/assembler/flag.h`
if test $1$2$3 != 1663507
then
	echo ERROR: wc results of areuh/assembler/flag.h are $* should be 16 63 507
fi

chmod 644 areuh/assembler/flag.h

exit 0

pda@litp.ibp.fr (Pierre DAVID) (07/05/90)

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Pierre David <pda@janick> on Sun Jul  1 12:33:08 1990
#
# This archive contains:
#	areuh/assembler/mdep.c		areuh/assembler/tabgrp.c	
#	areuh/assembler/tabopc.c	areuh/assembler/Makefile	
#	areuh/assembler/aas.1		areuh/README			
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - areuh/assembler/mdep.c
cat >areuh/assembler/mdep.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

/******************************************************************************

      M A C H I N E    D E P E N D E N C I E S

******************************************************************************/

#include "flag.h"

#if ASSEMBLER
#include "aglobal.h"
#else
#include "lglobal.h"
#endif

extern struct symbol *add_label() ;

#if HPUX

void format_time (str)
uchar *str ;
{
    long int l ;

    extern long int time () ;
    extern char *ctime () ;

    l = time (0L) ;
    strcpy (str, ctime (&l)) ;
    str [strlen (str) - 1] = EOL ;
}

char *tab[] = { "",
		"/usr/lib/",
		"/usr/local/lib/",
		"/lib/",
		"/hp71/lib/",
		"/local/lib/",
		0 } ;

void load_file (file)
uchar *file ;
{
    int i = 0 ;
    uchar name [MAXLEN+1] ;
    saddr val ;
    FILE *fp ;

    fp = (FILE *) NULL ;
    while ((tab[i])&&(!fp))
    {
	sprintf (name, "%s%s", tab[i++], file) ;
	fp = fopen (name, "r") ;
    }
    if (!fp) error (ERROPN, file) ;

#if LINKER
    file = 0 ;
#endif
    while (fscanf (fp, "%s\n%X\n", name, &val) != EOF)
    {
#if ASSEMBLER
	add_label (name, val, "", LABS, 1) ;
#else
	add_label (name, val, 1) ;
#endif
    }
    if (ferror (fp)) error (ERRWRT, file) ;
    if (fclose (fp)) error (ERRCLO, file) ;
}

#include <sys/types.h>
#include <sys/stat.h>

/* look for object file (object code or listing file)
 *   if non existent, ok
 *   if exists and not directory, ok
 *   if exists and directory, then append "<dir>/<default>" */

look_obj (fname, dfl)
uchar *fname, *dfl ;
{
    struct stat buf ;

    if (*fname == EOL)		   /* if fname == "" then default it */
	strcpy (fname, dfl) ;

    if (!stat (fname, &buf))	   /* file exists. Is it a directory ? */
    {
	if ((buf.st_mode & S_IFMT) == S_IFDIR)
	    sprintf (fname, "%s/%s", fname, dfl) ;
    }
}

/* build a default file name, based on "source" basename and a given
 * default extension.
 */

dfl_extension (object, source, extension)
uchar *object, *source, *extension ;
{
    uchar *pname ;

    strcpy (object, source) ;
    pname = object ;
    while ((*pname)&&(*pname!='.')) pname++ ;
    if (*pname==EOL) *pname = '.' ;
    strcpy (pname+1, extension) ;
}

#endif	   /* HPUX */


#if ATARI_LATTICE

char skipvar ;

void format_time (str)
uchar *str ;
{
    strcpy (str, "Areuh Tagada Bouzouh bouzouh areuh areuh... et toc !") ;
}

char *optarg ;
int optind = 0, opterr = 0 ;

int getopt (argc, argv, optstr)
int argc ;
char *argv[], *optstr ;
{
    char *o, car ;
    static char *index = 0 ;
    extern char *strchr () ;

    if ((index==(char *)0)||(*(index+1)==0))
    {
	if (++optind>argc-1) return (EOF) ;
	index = argv[optind] ;
	if (*index!='-') return (EOF) ;
    }
    car = *(++index) ;	      /* state 6 */
    if (!(o = strchr (optstr, car))) return ('?') ;
    if (*(o+1)!=':')     return ((int) car) ;
    if (*(index+1)) optarg = index+1 ;
    else
    {
	if (++optind>argc-1) return (EOF) ;
	else optarg = argv[optind] ;
    }
    index = (char *) 0 ;
    return ((int) car) ;
}

uchar *tab[] = { "",
		 "A:",
		 "A:\\TABLE\\",
		 0 } ;

void load_file (file)
uchar *file ;
{
    int i = 0 ;
    uchar name [MAXLEN+1] ;
    saddr val ;
    FILE *fp ;

    fp = (FILE *) NULL ;
    while ((tab[i])&&(!fp))
    {
	sprintf (name, "%s%s", tab[i++], file) ;
	fp = fopen (name, "r") ;
    }
    if (!fp) error (ERROPN, file) ;

#if LINKER
    file = 0 ;
#endif
    while (fscanf (fp, "%s\n%x\n", name, &val) != EOF)
    {
#if ASSEMBLER
	add_label (name, val, "", LABS, 1) ;
#else
	add_label (name, val, 1) ;
#endif
    }
    if (fclose (fp)) error (ERRCLO, file) ;
}

#endif	  /* ATARI_LATTICE */


#if PC_MSC

char skipvar ;

void format_time (str)
uchar *str ;
{
    long int l ;

    extern long int time () ;
    extern char *ctime () ;

    time (&l) ;
    strcpy (str, ctime (&l)) ;
    str [strlen (str) - 1] = EOL ;
}

char *optarg ;
int optind = 0, opterr = 0 ;

int getopt (argc, argv, optstr)
int argc ;
char *argv[], *optstr ;
{
    char *o, car ;
    static char *index = 0 ;
    extern char *strchr () ;

    if ((index==(char *)0)||(*(index+1)==0))
    {
	if (++optind>argc-1) return (EOF) ;
	index = argv[optind] ;
	if (*index!='-') return (EOF) ;
    }
    car = *(++index) ;	      /* state 6 */
    if (!(o = strchr (optstr, car))) return ('?') ;
    if (*(o+1)!=':')     return ((int) car) ;
    if (*(index+1)) optarg = index+1 ;
    else
    {
	if (++optind>argc-1) return (EOF) ;
	else optarg = argv[optind] ;
    }
    index = (char *) 0 ;
    return ((int) car) ;
}

uchar *tab[] = { "",
		 "c:",
		 "c:\\hp71\\",
		 "c:\\lib\\hp71\\",
		 "c:\\lib\\",
		 "c:\\areuh\\lib\\",
		 0 } ;

void load_file (file)
uchar *file ;
{
    int i = 0 ;
    uchar name [MAXLEN+1] ;
    saddr val ;
    FILE *fp ;

    fp = (FILE *) NULL ;
    while ((tab[i])&&(!fp))
    {
	sprintf (name, "%s%s", tab[i++], file) ;
	fp = fopen (name, "r") ;
    }
    if (!fp) error (ERROPN, file) ;

#if LINKER
    file = 0 ;
#endif
    while (fscanf (fp, "%s\n%X\n", name, &val) != EOF)
    {
#if ASSEMBLER
	add_label (name, val, "", LABS, 1) ;
#else
	add_label (name, val, 1) ;
#endif
    }
    if (fclose (fp)) error (ERRCLO, file) ;
}

#include <sys\types.h>
#include <sys\stat.h>

/* look for object file (object code or listing file)
 *   if non existent, ok
 *   if exists and not directory, ok
 *   if exists and directory, then append "<dir>/<default>" */

look_obj (fname, dfl)
uchar *fname, *dfl ;
{
    struct stat buf ;

    if (*fname == EOL)		   /* if fname == "" then default it */
	strcpy (fname, dfl) ;

    if (!stat (fname, &buf))	   /* file exists. Is it a directory ? */
    {
	if ((buf.st_mode & S_IFMT) == S_IFDIR)
	    sprintf (fname, "%s\\%s", fname, dfl) ;
    }
}

/* build a default file name, based on "source" basename and a given
 * default extension.
 */

dfl_extension (object, source, extension)
uchar *object, *source, *extension ;
{
    uchar *pname ;

    strcpy (object, source) ;
    pname = object ;
    while ((*pname)&&(*pname!='.')) pname++ ;
    if (*pname==EOL) *pname = '.' ;
    strcpy (pname+1, extension) ;
}

#endif	  /* PC_MSC */
@EOF
set `wc -lwc <areuh/assembler/mdep.c`
if test $1$2$3 != 32610286303
then
	echo ERROR: wc results of areuh/assembler/mdep.c are $* should be 326 1028 6303
fi

chmod 644 areuh/assembler/mdep.c

echo x - areuh/assembler/tabgrp.c
cat >areuh/assembler/tabgrp.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "aglobal.h"

int h_opcode [] = {
/* 00 */	0,
/* 01 */	9,
/* 02 */	24,
/* 03 */	33,
/* 04 */	40,
/* 05 */	53,
/* 06 */	64,
/* 07 */	72,
/* 08 */	79,
/* 09 */	93,
/* 10 */	100,
/* 11 */	107,
/* 12 */	114,
/* 13 */	125,
/* 14 */	134,
/* 15 */	140,
/* 16 */	152,
/* 17 */	162,
/* 18 */	168,
/* 19 */	174,
/* 20 */	180,
/* 21 */	185,
/* 22 */	191,
/* 23 */	200,
/* 24 */	207,
/* 25 */	212,
/* 26 */	224,
/* 27 */	230,
/* 28 */	239,
/* 29 */	244,
/* 30 */	250,
/* 31 */	257,
/* 32 */	267,
/* 33 */	275,
/* 34 */	287,
/* 35 */	295,
/* 36 */	305,
/* 37 */	312,
/* 38 */	318,
/* 39 */	328,
/* 40 */	337,
/* 41 */	342,
/* 42 */	351,
/* 43 */	356,
			} ;
@EOF
set `wc -lwc <areuh/assembler/tabgrp.c`
if test $1$2$3 != 59225883
then
	echo ERROR: wc results of areuh/assembler/tabgrp.c are $* should be 59 225 883
fi

chmod 644 areuh/assembler/tabgrp.c

echo x - areuh/assembler/tabopc.c
cat >areuh/assembler/tabopc.c <<'@EOF'
/*
 * Authors :
 *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
 *   Janick TAILLANDIER
 *
 * This program can be freely used or distributed as long as this
 * note is kept.
 *
 * This program is provided "as is".
 */

#include "aglobal.h"

struct mnemo_desc mnemo_table [] = {

/* 000 */	{1, "?A>B", 3, 3, "800", 2, 0},
/* 001 */	{5, "CR1EX", 5, 3, "129", 0, 0},
/* 002 */	{5, "AR0EX", 5, 3, "120", 0, 0},
/* 003 */	{10, "P=C", 33, 4, "80D0", 0, 0},
/* 004 */	{5, "SETDEC", 5, 2, "05", 0, 0},
/* 005 */	{3, "C=C!B", 1, 4, "0E0D", 0, 0},
/* 006 */	{5, "CSLC", 1, 3, "812", 0, 0},
/* 007 */	{5, "D1=CS", 5, 3, "13D", 0, 0},
/* 008 */	{40, "ENDIF", 0, 0, "", 0, 0},
/* 009 */	{4, "GOYES", 41, 2, "00", 1, 2},
/* 010 */	{4, "GOSBVL", 53, 7, "8F000", 3, 5},
/* 011 */	{13, "DAT0=A", 32, 4, "1500", 0, 0},
/* 012 */	{4, "GONC", 33, 3, "500", 2, 2},
/* 013 */	{22, "EQU", 36, 0, "", 0, 0},
/* 014 */	{1, "?C>A", 3, 3, "802", 2, 0},
/* 015 */	{1, "?A>=C", 3, 3, "80E", 2, 0},
/* 016 */	{1, "?B#C", 7, 3, "805", 1, 0},
/* 017 */	{1, "?A<=B", 7, 3, "80C", 2, 0},
/* 018 */	{2, "B=B+B", 4, 3, "005", 1, 0},
/* 019 */	{5, "RTNC", 5, 3, "400", 0, 0},
/* 020 */	{33, "CHAR", 32, 1, "0", 0, 0},
/* 021 */	{5, "D1=AS", 5, 3, "138", 0, 0},
/* 022 */	{5, "NOP4", 5, 4, "6300", 0, 0},
/* 023 */	{5, "RTI", 1, 2, "0F", 0, 0},
/* 024 */	{2, "A=C", 4, 3, "00A", 2, 0},
/* 025 */	{7, "RTNYES", 13, 2, "00", 0, 0},
/* 026 */	{2, "A=A-B", 0, 3, "000", 3, 0},
/* 027 */	{1, "?B#A", 7, 3, "804", 1, 0},
/* 028 */	{5, "RTNNC", 1, 3, "500", 0, 0},
/* 029 */	{2, "C=D", 0, 3, "00B", 2, 0},
/* 030 */	{5, "DSLC", 5, 3, "813", 0, 0},
/* 031 */	{8, "?P#", 39, 3, "880", 0, 0},
/* 032 */	{6, "?MP=0", 3, 3, "838", 0, 0},
/* 033 */	{13, "DAT0=C", 32, 4, "1540", 0, 0},
/* 034 */	{2, "A=A+B", 0, 3, "000", 1, 0},
/* 035 */	{2, "C=D+C", 4, 3, "00B", 1, 0},
/* 036 */	{1, "?D#0", 7, 3, "80F", 1, 0},
/* 037 */	{29, "ID", 36, 16, "", 0, 0},
/* 038 */	{27, "WORDI", 32, 0, "", 0, 0},
/* 039 */	{4, "LC(6)", 177, 8, "35000", 3, 6},
/* 040 */	{2, "B=C", 4, 3, "005", 2, 0},
/* 041 */	{5, "R0=C", 5, 3, "108", 0, 0},
/* 042 */	{5, "CR0EX", 1, 3, "128", 0, 0},
/* 043 */	{1, "?A=B", 7, 3, "800", 1, 0},
/* 044 */	{2, "ABEX", 4, 3, "00C", 2, 0},
/* 045 */	{1, "?B<=A", 3, 3, "808", 2, 0},
/* 046 */	{2, "D=D-C", 4, 3, "003", 3, 0},
/* 047 */	{3, "C=D!C", 1, 4, "0E0F", 0, 0},
/* 048 */	{3, "A=A!B", 5, 4, "0E08", 0, 0},
/* 049 */	{5, "ASRC", 1, 3, "814", 0, 0},
/* 050 */	{4, "LC(4)", 177, 6, "33000", 3, 4},
/* 051 */	{5, "C=ST", 5, 2, "09", 0, 0},
/* 052 */	{5, "A=R4", 1, 3, "114", 0, 0},
/* 053 */	{1, "?C=A", 3, 3, "802", 1, 0},
/* 054 */	{1, "?A=0", 7, 3, "808", 1, 0},
/* 055 */	{5, "R0=A", 1, 3, "100", 0, 0},
/* 056 */	{2, "B=A+B", 0, 3, "008", 1, 0},
/* 057 */	{4, "LC(2)", 177, 4, "3100", 3, 2},
/* 058 */	{5, "A=R2", 5, 3, "112", 0, 0},
/* 059 */	{23, "LIST", 5, 0, "", 0, 0},
/* 060 */	{2, "D=D+C", 4, 3, "003", 1, 0},
/* 061 */	{4, "D0=(2)", 177, 4, "1900", 3, 2},
/* 062 */	{5, "R4=C", 5, 3, "10C", 0, 0},
/* 063 */	{5, "BUSCC", 5, 3, "80B", 0, 0},
/* 064 */	{5, "A=R0", 1, 3, "110", 0, 0},
/* 065 */	{2, "A=B", 4, 3, "004", 2, 0},
/* 066 */	{4, "CON(4)", 49, 4, "0000", 1, 4},
/* 067 */	{3, "B=A!B", 1, 4, "0E0C", 0, 0},
/* 068 */	{5, "RTNSXM", 5, 2, "00", 0, 0},
/* 069 */	{3, "D=D!C", 5, 4, "0E0B", 0, 0},
/* 070 */	{5, "BSRC", 5, 3, "815", 0, 0},
/* 071 */	{5, "R4=A", 1, 3, "104", 0, 0},
/* 072 */	{4, "GOTO", 33, 4, "6000", 2, 3},
/* 073 */	{1, "?C>=A", 7, 3, "80A", 2, 0},
/* 074 */	{2, "C=C+C", 4, 3, "006", 1, 0},
/* 075 */	{9, "?ST=0", 35, 3, "860", 0, 0},
/* 076 */	{3, "A=C&A", 5, 4, "0E06", 0, 0},
/* 077 */	{5, "ST=C", 5, 2, "0A", 0, 0},
/* 078 */	{5, "A=IN", 1, 3, "802", 0, 0},
/* 079 */	{13, "A=DAT0", 36, 4, "1520", 0, 0},
/* 080 */	{5, "D0=C", 5, 3, "134", 0, 0},
/* 081 */	{12, "D1=D1+", 33, 3, "170", 0, 0},
/* 082 */	{5, "CSRC", 1, 3, "816", 0, 0},
/* 083 */	{1, "?A<B", 7, 3, "804", 2, 0},
/* 084 */	{9, "?ST#0", 35, 3, "870", 0, 0},
/* 085 */	{11, "ST=1", 33, 3, "850", 0, 0},
/* 086 */	{2, "CBEX", 0, 3, "00D", 2, 0},
/* 087 */	{2, "B=B-C", 0, 3, "001", 3, 0},
/* 088 */	{2, "D=C", 4, 3, "007", 2, 0},
/* 089 */	{5, "CLRST", 5, 2, "08", 0, 0},
/* 090 */	{5, "SB=0", 1, 3, "822", 0, 0},
/* 091 */	{5, "C=R4", 5, 3, "11C", 0, 0},
/* 092 */	{5, "SR=0", 5, 3, "824", 0, 0},
/* 093 */	{13, "A=DAT1", 36, 4, "1530", 0, 0},
/* 094 */	{5, "D0=A", 1, 3, "130", 0, 0},
/* 095 */	{1, "?A<=C", 7, 3, "80A", 2, 0},
/* 096 */	{1, "?C<A", 3, 3, "806", 2, 0},
/* 097 */	{2, "B=B+C", 0, 3, "001", 1, 0},
/* 098 */	{5, "C=R2", 5, 3, "11A", 0, 0},
/* 099 */	{4, "REL(1)", 37, 1, "0", 1, 1},
/* 100 */	{12, "D1=D1-", 37, 3, "1C0", 0, 0},
/* 101 */	{2, "C=B", 4, 3, "009", 2, 0},
/* 102 */	{5, "C=R0", 1, 3, "118", 0, 0},
/* 103 */	{2, "A=A-C", 4, 3, "00A", 3, 0},
/* 104 */	{3, "B=B!C", 1, 4, "0E09", 0, 0},
/* 105 */	{5, "DSRC", 1, 3, "817", 0, 0},
/* 106 */	{5, "OUT=C", 5, 3, "801", 0, 0},
/* 107 */	{2, "A=A+C", 0, 3, "00A", 1, 0},
/* 108 */	{2, "C=B+C", 0, 3, "009", 1, 0},
/* 109 */	{3, "C=C&A", 5, 4, "0E02", 0, 0},
/* 110 */	{3, "A=B&A", 5, 4, "0E00", 0, 0},
/* 111 */	{1, "?D>C", 7, 3, "803", 2, 0},
/* 112 */	{35, "TOKEN", 36, 2, "00", 0, 0},
/* 113 */	{5, "C=IN", 1, 3, "803", 0, 0},
/* 114 */	{13, "C=DAT0", 32, 4, "1560", 0, 0},
/* 115 */	{14, "NIBHEX", 4, 0, "", 1, 14},
/* 116 */	{10, "P=", 33, 2, "20", 0, 0},
/* 117 */	{2, "B=A", 0, 3, "008", 2, 0},
/* 118 */	{1, "?A#B", 7, 3, "804", 1, 0},
/* 119 */	{1, "?B>=C", 3, 3, "809", 2, 0},
/* 120 */	{3, "A=A!C", 5, 4, "0E0E", 0, 0},
/* 121 */	{3, "C=B!C", 5, 4, "0E0D", 0, 0},
/* 122 */	{5, "C=ID", 1, 3, "806", 0, 0},
/* 123 */	{5, "RESET", 5, 3, "80A", 0, 0},
/* 124 */	{41, "ABS", 0, 0, "", 0, 0},
/* 125 */	{13, "C=DAT1", 36, 4, "1570", 0, 0},
/* 126 */	{1, "?C#A", 3, 3, "806", 1, 0},
/* 127 */	{1, "?A#0", 7, 3, "80C", 1, 0},
/* 128 */	{2, "D=D+D", 0, 3, "007", 1, 0},
/* 129 */	{3, "B=B&A", 1, 4, "0E04", 0, 0},
/* 130 */	{6, "?XM=0", 3, 3, "831", 0, 0},
/* 131 */	{2, "A=-A-1", 4, 3, "00C", 4, 0},
/* 132 */	{5, "OUT=CS", 5, 3, "800", 0, 0},
/* 133 */	{42, "RDSYMB", 0, 0, "", 0, 0},
/* 134 */	{2, "C=A", 0, 3, "006", 2, 0},
/* 135 */	{2, "A=0", 4, 3, "000", 2, 0},
/* 136 */	{2, "C=A-C", 4, 3, "00E", 3, 0},
/* 137 */	{4, "CON(5)", 53, 5, "00000", 1, 5},
/* 138 */	{34, "KEY", 32, 0, "", 0, 0},
/* 139 */	{2, "C=C-D", 0, 3, "00B", 3, 0},
/* 140 */	{2, "C=A+C", 4, 3, "002", 1, 0},
/* 141 */	{5, "R1=C", 5, 3, "109", 0, 0},
/* 142 */	{2, "ACEX", 0, 3, "00E", 2, 0},
/* 143 */	{1, "?C<=A", 7, 3, "80E", 2, 0},
/* 144 */	{1, "?C>=B", 3, 3, "80D", 2, 0},
/* 145 */	{1, "?D=C", 7, 3, "803", 1, 0},
/* 146 */	{2, "C=C+D", 0, 3, "00B", 1, 0},
/* 147 */	{9, "?ST=1", 35, 3, "870", 0, 0},
/* 148 */	{2, "A=-A", 4, 3, "008", 4, 0},
/* 149 */	{30, "MSG", 32, 4, "0000", 0, 0},
/* 150 */	{6, "?SB=0", 3, 3, "832", 0, 0},
/* 151 */	{6, "?SR=0", 7, 3, "834", 0, 0},
/* 152 */	{5, "R1=A", 5, 3, "101", 0, 0},
/* 153 */	{2, "B=0", 4, 3, "001", 2, 0},
/* 154 */	{9, "?ST#1", 35, 3, "860", 0, 0},
/* 155 */	{1, "?B=0", 7, 3, "809", 1, 0},
/* 156 */	{4, "D1=(2)", 177, 4, "1D00", 3, 2},
/* 157 */	{2, "D=C-D", 4, 3, "00F", 3, 0},
/* 158 */	{3, "C=A!C", 5, 4, "0E0A", 0, 0},
/* 159 */	{2, "C=-C-1", 0, 3, "00E", 4, 0},
/* 160 */	{3, "C=C!D", 1, 4, "0E0F", 0, 0},
/* 161 */	{31, "POLL", 32, 5, "00000", 0, 0},
/* 162 */	{15, "LCHEX", 4, 2, "30", 3, 2},
/* 163 */	{2, "D=C+D", 4, 3, "003", 1, 0},
/* 164 */	{2, "BCEX", 0, 3, "00D", 2, 0},
/* 165 */	{3, "B=C&B", 5, 4, "0E01", 0, 0},
/* 166 */	{4, "REL(2)", 33, 2, "00", 1, 2},
/* 167 */	{21, "END", 0, 0, "", 0, 0},
/* 168 */	{2, "C=0", 4, 3, "002", 2, 0},
/* 169 */	{5, "AD1EX", 5, 3, "133", 0, 0},
/* 170 */	{10, "C=P", 33, 4, "80C0", 0, 0},
/* 171 */	{2, "C=-C", 0, 3, "00A", 4, 0},
/* 172 */	{3, "D=C!D", 5, 4, "0E0B", 0, 0},
/* 173 */	{43, "ELSE", 0, 0, "", 0, 0},
/* 174 */	{4, "GOLONG", 33, 6, "8C000", 3, 4},
/* 175 */	{5, "D1=C", 1, 3, "135", 0, 0},
/* 176 */	{1, "?D<C", 7, 3, "807", 2, 0},
/* 177 */	{3, "C=C&B", 5, 4, "0E05", 0, 0},
/* 178 */	{2, "ASL", 0, 3, "000", 4, 0},
/* 179 */	{39, "ENDTXT", 4, 3, "", 0, 0},
/* 180 */	{5, "D1=A", 1, 3, "131", 0, 0},
/* 181 */	{17, "NIBASC", 36, 0, "", 1, 14},
/* 182 */	{1, "?B<=C", 7, 3, "80D", 2, 0},
/* 183 */	{2, "D=0", 4, 3, "003", 2, 0},
/* 184 */	{28, "LEX", 32, 0, "", 0, 0},
/* 185 */	{1, "?A>C", 7, 3, "806", 2, 0},
/* 186 */	{4, "D0=(4)", 177, 6, "1A000", 3, 4},
/* 187 */	{2, "DCEX", 4, 3, "00F", 2, 0},
/* 188 */	{1, "?C>D", 3, 3, "807", 2, 0},
/* 189 */	{20, "EJECT", 1, 0, "", 0, 0},
/* 190 */	{2, "BSL", 4, 3, "001", 4, 0},
/* 191 */	{13, "DAT1=A", 36, 4, "1510", 0, 0},
/* 192 */	{5, "C=RSTK", 5, 2, "07", 0, 0},
/* 193 */	{5, "CD1EX", 1, 3, "137", 0, 0},
/* 194 */	{5, "AD0EX", 1, 3, "132", 0, 0},
/* 195 */	{1, "?C>B", 7, 3, "805", 2, 0},
/* 196 */	{5, "NOP5", 1, 5, "64000", 0, 0},
/* 197 */	{5, "SHUTDN", 5, 3, "807", 0, 0},
/* 198 */	{4, "CON(6)", 53, 6, "00000", 1, 6},
/* 199 */	{5, "PC=(A)", 1, 4, "808C", 0, 0},
/* 200 */	{1, "?C<=B", 7, 3, "809", 2, 0},
/* 201 */	{3, "A=A&B", 5, 4, "0E00", 0, 0},
/* 202 */	{3, "C=D&C", 5, 4, "0E07", 0, 0},
/* 203 */	{1, "?D#C", 3, 3, "807", 1, 0},
/* 204 */	{2, "CSL", 0, 3, "002", 4, 0},
/* 205 */	{5, "NOP3", 5, 3, "420", 0, 0},
/* 206 */	{5, "AD1XS", 1, 3, "13B", 0, 0},
/* 207 */	{5, "RTN", 5, 2, "01", 0, 0},
/* 208 */	{13, "DAT1=C", 36, 4, "1550", 0, 0},
/* 209 */	{1, "?B#0", 7, 3, "80D", 1, 0},
/* 210 */	{32, "ENTRY", 32, 8, "00000", 0, 0},
/* 211 */	{5, "C+P+1", 1, 3, "809", 0, 0},
/* 212 */	{1, "?A=C", 7, 3, "802", 1, 0},
/* 213 */	{5, "RTNCC", 1, 2, "03", 0, 0},
/* 214 */	{5, "RTNSC", 5, 2, "02", 0, 0},
/* 215 */	{4, "REL(3)", 37, 3, "000", 1, 3},
/* 216 */	{4, "LC(5)", 177, 7, "34000", 3, 5},
/* 217 */	{1, "?C=D", 3, 3, "803", 1, 0},
/* 218 */	{3, "B=A&B", 5, 4, "0E04", 0, 0},
/* 219 */	{3, "D=D&C", 1, 4, "0E03", 0, 0},
/* 220 */	{19, "BSS", 32, 0, "", 0, 0},
/* 221 */	{2, "DSL", 4, 3, "003", 4, 0},
/* 222 */	{4, "CON(1)", 53, 1, "0", 1, 1},
/* 223 */	{44, "IF", 0, 0, "", 0, 0},
/* 224 */	{5, "CD0EX", 1, 3, "136", 0, 0},
/* 225 */	{5, "R2=C", 1, 3, "10A", 0, 0},
/* 226 */	{5, "A=R3", 1, 3, "113", 0, 0},
/* 227 */	{1, "?C=B", 7, 3, "801", 1, 0},
/* 228 */	{5, "ASRB", 5, 3, "81C", 0, 0},
/* 229 */	{4, "LC(3)", 181, 5, "32000", 3, 3},
/* 230 */	{1, "?C=0", 7, 3, "80A", 1, 0},
/* 231 */	{5, "A=R1", 1, 3, "111", 0, 0},
/* 232 */	{5, "R2=A", 5, 3, "102", 0, 0},
/* 233 */	{4, "LC(1)", 177, 3, "300", 3, 1},
/* 234 */	{2, "ASR", 4, 3, "004", 4, 0},
/* 235 */	{5, "AR4EX", 1, 3, "124", 0, 0},
/* 236 */	{5, "CD1XS", 1, 3, "13F", 0, 0},
/* 237 */	{5, "AD0XS", 5, 3, "13A", 0, 0},
/* 238 */	{5, "CLRHST", 5, 3, "82F", 0, 0},
/* 239 */	{4, "GOSUB", 101, 4, "7000", 2, 3},
/* 240 */	{5, "BSRB", 5, 3, "81D", 0, 0},
/* 241 */	{16, "D0=HEX", 0, 4, "1900", 3, 2},
/* 242 */	{38, "CHAIN", 32, 12, "00000", 0, 0},
/* 243 */	{5, "CONFIG", 5, 3, "805", 0, 0},
/* 244 */	{4, "D0=(5)", 177, 7, "1B000", 3, 5},
/* 245 */	{1, "?A<C", 7, 3, "802", 2, 0},
/* 246 */	{1, "?C<D", 3, 3, "803", 2, 0},
/* 247 */	{10, "CPEX", 37, 4, "80F0", 0, 0},
/* 248 */	{3, "B=B&C", 5, 4, "0E01", 0, 0},
/* 249 */	{2, "BSR", 0, 3, "005", 4, 0},
/* 250 */	{2, "A=C+A", 0, 3, "00A", 1, 0},
/* 251 */	{2, "CDEX", 0, 3, "00F", 2, 0},
/* 252 */	{5, "CSRB", 5, 3, "81E", 0, 0},
/* 253 */	{5, "C=R3", 5, 3, "11B", 0, 0},
/* 254 */	{11, "ST=0", 33, 3, "840", 0, 0},
/* 255 */	{1, "?C<B", 7, 3, "801", 2, 0},
/* 256 */	{5, "UNCNFG", 5, 3, "804", 0, 0},
/* 257 */	{5, "C=R1", 1, 3, "119", 0, 0},
/* 258 */	{5, "AR3EX", 1, 3, "123", 0, 0},
/* 259 */	{3, "A=A&C", 1, 4, "0E06", 0, 0},
/* 260 */	{3, "A=C!A", 5, 4, "0E0E", 0, 0},
/* 261 */	{2, "D=D-1", 4, 3, "00F", 1, 0},
/* 262 */	{1, "?C>=D", 7, 3, "80F", 2, 0},
/* 263 */	{2, "CSR", 0, 3, "006", 4, 0},
/* 264 */	{3, "C=B&C", 5, 4, "0E05", 0, 0},
/* 265 */	{5, "CR4EX", 5, 3, "12C", 0, 0},
/* 266 */	{5, "CD0XS", 1, 3, "13E", 0, 0},
/* 267 */	{4, "GOSUBL", 97, 6, "8E000", 3, 4},
/* 268 */	{12, "D0=D0+", 33, 3, "160", 0, 0},
/* 269 */	{2, "D=D+1", 0, 3, "007", 3, 0},
/* 270 */	{4, "D1=(4)", 181, 6, "1E000", 3, 4},
/* 271 */	{1, "?B>C", 7, 3, "801", 2, 0},
/* 272 */	{5, "DSRB", 5, 3, "81F", 0, 0},
/* 273 */	{5, "D0=CS", 1, 3, "13C", 0, 0},
/* 274 */	{5, "INTON", 5, 4, "8080", 0, 0},
/* 275 */	{1, "?A#C", 7, 3, "806", 1, 0},
/* 276 */	{2, "C=C-A", 0, 3, "002", 3, 0},
/* 277 */	{2, "C=C-1", 4, 3, "00E", 1, 0},
/* 278 */	{2, "A=B-A", 0, 3, "00C", 3, 0},
/* 279 */	{1, "?C#D", 7, 3, "807", 1, 0},
/* 280 */	{1, "?B>A", 3, 3, "804", 2, 0},
/* 281 */	{4, "CON(2)", 53, 2, "00", 1, 2},
/* 282 */	{4, "REL(4)", 37, 4, "0000", 1, 4},
/* 283 */	{2, "DSR", 4, 3, "007", 4, 0},
/* 284 */	{5, "D0=AS", 1, 3, "138", 0, 0},
/* 285 */	{5, "MP=0", 1, 3, "828", 0, 0},
/* 286 */	{5, "RSI", 1, 5, "80810", 0, 0},
/* 287 */	{4, "GOVLNG", 53, 7, "8D000", 3, 5},
/* 288 */	{2, "C=C+1", 0, 3, "006", 3, 0},
/* 289 */	{2, "C=C+A", 4, 3, "002", 1, 0},
/* 290 */	{12, "D0=D0-", 33, 3, "180", 0, 0},
/* 291 */	{2, "A=B+A", 0, 3, "000", 1, 0},
/* 292 */	{1, "?C#B", 7, 3, "805", 1, 0},
/* 293 */	{1, "?D>=C", 3, 3, "80B", 2, 0},
/* 294 */	{36, "BIN", 36, 0, "", 0, 0},
/* 295 */	{1, "?C#0", 7, 3, "80E", 1, 0},
/* 296 */	{2, "B=B-1", 0, 3, "00D", 1, 0},
/* 297 */	{2, "B=B-A", 4, 3, "008", 3, 0},
/* 298 */	{5, "AR2EX", 5, 3, "122", 0, 0},
/* 299 */	{5, "CR3EX", 1, 3, "12B", 0, 0},
/* 300 */	{3, "C=C!A", 1, 4, "0E0A", 0, 0},
/* 301 */	{3, "A=B!A", 1, 4, "0E08", 0, 0},
/* 302 */	{3, "C=A&C", 1, 4, "0E02", 0, 0},
/* 303 */	{3, "C=C&D", 5, 4, "0E07", 0, 0},
/* 304 */	{5, "XM=0", 5, 3, "821", 0, 0},
/* 305 */	{4, "GOC", 37, 3, "400", 2, 2},
/* 306 */	{2, "B=B+A", 4, 3, "008", 1, 0},
/* 307 */	{1, "?B=C", 3, 3, "801", 1, 0},
/* 308 */	{2, "B=B+1", 0, 3, "005", 3, 0},
/* 309 */	{1, "?A>=B", 7, 3, "808", 2, 0},
/* 310 */	{2, "B=-B-1", 4, 3, "00D", 4, 0},
/* 311 */	{37, "FORTH", 0, 0, "", 0, 0},
/* 312 */	{2, "A=A-1", 4, 3, "00C", 1, 0},
/* 313 */	{8, "?P=", 35, 3, "890", 0, 0},
/* 314 */	{5, "R3=C", 1, 3, "10B", 0, 0},
/* 315 */	{1, "?B=A", 7, 3, "800", 1, 0},
/* 316 */	{3, "B=B!A", 1, 4, "0E0C", 0, 0},
/* 317 */	{3, "D=C&D", 5, 4, "0E03", 0, 0},
/* 318 */	{2, "A=A+1", 0, 3, "004", 3, 0},
/* 319 */	{18, "LCASC", 32, 2, "30", 3, 2},
/* 320 */	{1, "?D=0", 7, 3, "80B", 1, 0},
/* 321 */	{5, "R3=A", 5, 3, "103", 0, 0},
/* 322 */	{25, "STITLE", 1, 0, "", 0, 0},
/* 323 */	{2, "A=A+A", 4, 3, "004", 1, 0},
/* 324 */	{2, "B=-B", 0, 3, "009", 4, 0},
/* 325 */	{2, "BAEX", 4, 3, "00C", 2, 0},
/* 326 */	{5, "INTOFF", 1, 4, "808F", 0, 0},
/* 327 */	{26, "WORD", 36, 0, "", 0, 0},
/* 328 */	{5, "P=P-1", 5, 2, "0D", 0, 0},
/* 329 */	{2, "B=C-B", 4, 3, "00D", 3, 0},
/* 330 */	{5, "AR1EX", 5, 3, "121", 0, 0},
/* 331 */	{5, "CR2EX", 1, 3, "12A", 0, 0},
/* 332 */	{1, "?B>=A", 7, 3, "80C", 2, 0},
/* 333 */	{1, "?C<=D", 3, 3, "80B", 2, 0},
/* 334 */	{5, "ASLC", 1, 3, "810", 0, 0},
/* 335 */	{16, "D1=HEX", 4, 4, "1D00", 3, 2},
/* 336 */	{2, "D=-D-1", 0, 3, "00F", 4, 0},
/* 337 */	{4, "D1=(5)", 177, 7, "1F000", 3, 5},
/* 338 */	{5, "P=P+1", 5, 2, "0C", 0, 0},
/* 339 */	{2, "B=C+B", 0, 3, "001", 1, 0},
/* 340 */	{1, "?B<C", 7, 3, "805", 2, 0},
/* 341 */	{2, "CAEX", 4, 3, "00E", 2, 0},
/* 342 */	{5, "RSTK=C", 1, 2, "06", 0, 0},
/* 343 */	{2, "C=C-B", 0, 3, "009", 3, 0},
/* 344 */	{1, "?B<A", 7, 3, "800", 2, 0},
/* 345 */	{4, "REL(5)", 37, 5, "00000", 1, 5},
/* 346 */	{4, "CON(3)", 53, 3, "000", 1, 3},
/* 347 */	{5, "BSLC", 5, 3, "811", 0, 0},
/* 348 */	{3, "B=C!B", 1, 4, "0E09", 0, 0},
/* 349 */	{2, "D=-D", 0, 3, "00B", 4, 0},
/* 350 */	{24, "TITLE", 4, 0, "", 0, 0},
/* 351 */	{2, "C=C+B", 0, 3, "009", 1, 0},
/* 352 */	{5, "SETHEX", 1, 2, "04", 0, 0},
/* 353 */	{1, "?D<=C", 7, 3, "80F", 2, 0},
/* 354 */	{5, "CSTEX", 5, 2, "0B", 0, 0},
/* 355 */	{5, "SREQ?", 5, 3, "80E", 0, 0},

	} ;
@EOF
set `wc -lwc <areuh/assembler/tabopc.c`
if test $1$2$3 != 373361015611
then
	echo ERROR: wc results of areuh/assembler/tabopc.c are $* should be 373 3610 15611
fi

chmod 644 areuh/assembler/tabopc.c

echo x - areuh/assembler/Makefile
cat >areuh/assembler/Makefile <<'@EOF'
#
# Makefile genere automatiquement par mkmf (le masque par defaut a ete adapte)
#

CFLAGS	      = -O
LDFLAGS	      =
LIBS	      =
SYSLIBS	      =
BINDEST	      = /usr/local/bin

#
# S'il y a plus d'un programme, il faut aussi remplacer la cible
# $(PROGRAM) par autant de cibles que necessaire.
#

PROGRAM       = aas

SRCS	      = aerror.c \
		ainput.c \
		alabel.c \
		alist.c \
		amain.c \
		amnemo.c \
		aobj.c \
		aopc1.c \
		aopc2.c \
		apass.c \
		areport.c \
		autil.c \
		exp.c \
		mdep.c \
		tabgrp.c \
		tabopc.c

HDRS	      = agen.h \
		aglobal.h \
		common.h \
		err.h \
		flag.h

EXTHDRS	      = /usr/include/stdio.h \
		/usr/include/sys/stat.h \
		/usr/include/sys/types.h

OBJS	      = aerror.o \
		ainput.o \
		alabel.o \
		alist.o \
		amain.o \
		amnemo.o \
		aobj.o \
		aopc1.o \
		aopc2.o \
		apass.o \
		areport.o \
		autil.o \
		exp.o \
		mdep.o \
		tabgrp.o \
		tabopc.o

MANDEST	      = /usr/local/man/man1.Z

MANPAGES      = aas.1

#
# Les cibles :
#	all : compiler tout
#	clean : effacer les .o et les core
#	clobber : effacer tout ce qui peut etre regenere
#	depend : recalculer toutes les dependances et les inserer ici
#	install : installe le programme dans l'aborescence
#	tags : cree les tags
#

all:		$(PROGRAM)

$(PROGRAM):     $(OBJS) $(LIBS)
		cc $(LDFLAGS) $(OBJS) $(LIBS) $(SYSLIBS) -o $(PROGRAM)

clean:;		rm -f $(OBJS) core

clobber:;	rm -f $(OBJS) $(PROGRAM) core tags

depend:;	mkmf ROOT=$(ROOT)

install:	$(PROGRAM)
		-strip $(PROGRAM)
		if [ $(BINDEST) != . ] ; \
		then \
		    (cd $(BINDEST) ; rm -f $(PROGRAM)) ; \
		    cp $(PROGRAM) $(BINDEST) ; \
		    if [ "$(MANPAGES)" != none ] ; \
		    then \
			(cd $(MANDEST) ; rm -f $(MANPAGES)) ; \
			for i in $(MANPAGES) ; \
			do \
			    compress < $$i > $(MANDEST)/$$i ; \
			done ; \
		    fi ; \
		fi

tags:           $(HDRS) $(SRCS)
		ctags $(HDRS) $(SRCS)

#
# Dependances calculees automatiquement par mkmf.
# Ne rien changer apres cette ligne !
#
###
aerror.o: aglobal.h common.h /usr/include/stdio.h err.h
ainput.o: aglobal.h common.h /usr/include/stdio.h err.h
alabel.o: aglobal.h common.h /usr/include/stdio.h err.h
alist.o: aglobal.h common.h /usr/include/stdio.h err.h
amain.o: aglobal.h common.h /usr/include/stdio.h err.h
amnemo.o: aglobal.h common.h /usr/include/stdio.h err.h
aobj.o: aglobal.h common.h /usr/include/stdio.h err.h
aopc1.o: aglobal.h common.h /usr/include/stdio.h err.h agen.h
aopc2.o: aglobal.h common.h /usr/include/stdio.h err.h agen.h
apass.o: aglobal.h common.h /usr/include/stdio.h err.h agen.h
areport.o: aglobal.h common.h /usr/include/stdio.h err.h
autil.o: aglobal.h common.h /usr/include/stdio.h err.h
exp.o: flag.h aglobal.h common.h /usr/include/stdio.h err.h
mdep.o: flag.h aglobal.h common.h /usr/include/stdio.h err.h \
	/usr/include/sys/types.h /usr/include/sys/stat.h
tabgrp.o: aglobal.h common.h /usr/include/stdio.h err.h
tabopc.o: aglobal.h common.h /usr/include/stdio.h err.h
@EOF
set `wc -lwc <areuh/assembler/Makefile`
if test $1$2$3 != 1274032926
then
	echo ERROR: wc results of areuh/assembler/Makefile are $* should be 127 403 2926
fi

chmod 644 areuh/assembler/Makefile

echo x - areuh/assembler/aas.1
cat >areuh/assembler/aas.1 <<'@EOF'
.TH AAS 1L
.SH NAME
aas \- areuh assembler
.SH SYNOPSIS
.B aas
[
.B -p
] [
.B -l
.I page length
] [
.B -A
] [
.B -a
.I listing file
] [
.B -x
] [
.B -o
.I object file
] [ file1 ... filen ]
.SH DESCRIPTION
.I Aas
est le cross-assembleur pour le HP-71, qui prend un ou des
fichiers sources, les assemble et place dans le fichier objet
soit un Lex ou Bin complet, soit un fichier intermediaire
pour edition de liens ulterieure (voir
.IR ald (1L)).
.PP
Les options sont :
.TP 17
.B -p
Utilisation interactive : demande les noms des fichiers
au clavier. Option par defaut lorsqu'il n'y a aucun parametre.
.TP
.BI -l " page length"
La longueur des pages du
.I listing file
est fixee a
.I page length
lignes (72 par defaut).
.TP
.B -A
Genere un listing d'assemblage avec offset, codes hexadecimaux,
et texte source. Le listing est envoye sur la sortie standard.
.TP
.BI -a " listing file"
Genere un listing d'assemblage dans le fichier
.IR "listing file" .
.TP
.I -x
Genere dans le
.I listing file
une table des references croisees, indiquant pour chaque
symbole sa valeur et les numeros des lignes y faisant
reference.
.TP
.BI -o " object file"
Place le code objet dans le fichier specifie. Par defaut,
le nom est celui du fichier source avec le suffixe
.IR .as ,
remplace par
.I .ao
en cas d'assemblage separe, ou
.B lex
en assemblage complet. Si
.I object file
est un repertoire, le fichier est place dans le repertoire
indique avec les regles de renommage ci-dessus (note :
c'est l'utilisation la plus simple lorsque plusieurs sources
sont donnes sur la ligne de commandes).
.SH AUTHORS
Pierre David
Janick Taillandier
.SH SEE ALSO
ald(1L),
adp(1L),
amg(1L),
cp71(1L).
.br
.I "IDS vol I"
for HP-71.
@EOF
set `wc -lwc <areuh/assembler/aas.1`
if test $1$2$3 != 823141696
then
	echo ERROR: wc results of areuh/assembler/aas.1 are $* should be 82 314 1696
fi

chmod 644 areuh/assembler/aas.1

echo x - areuh/README
cat >areuh/README <<'@EOF'
AUTHORS
-------

Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
Janick TAILLANDIER

You are free to use or distribute these programs as long as
you keep this note

These programs are provided as is.  They are in no way
supported by us.


PRESENTATION
------------

These programs provide you with a complete development
system for the Saturn processor (used on the HP-71, HP-28,
HP-48 among others).  It includes an assembler, a linker for
separate assembly, and various utilities to generate message
tables for the HP-71 as well as download programs to the
HP-71 via HP-IL or RS-232.


HISTORY
-------

It was developped for the HP-71 in order for us to produce
more easily the JPC Rom (PPC Paris Rom) for the HP-71.  The
final Rom module was 45 KB (executable) for a total of 1.5
MB source files.

The speed was one of the main design objectives.

These programs were written in C for the HP Integral PC
(under HP-UX) in 1986 and have been adaptated for PC
compatibles (Microsoft C 4.0 in 1987).

It was also used as the final stage of a simple C compiler
for the HP-71.


HP-71 DEPENDENCIES
------------------

This development system is fully compatible with the
assembler described in the HP-71 Internal Design
Specifications (Volumes I or IV).  The opcode syntax is the
one used by HP :  it seems crazy to invent a new one, just
to confuse everyone!

Some macros (LEX, BIN, FORTH, TOKEN...)  are specific to the
HP-71, but you are free not to use them.

You may also want to write specific HP-48 macros to generate
specific objects (it would be nice if HP give us the syntax
they use).

Some opcodes used in newer machines (28, 48...)  are not
present in the HP-71.  Those opcodes (but PC=(A) and RSI)
are not in our opcode table, but could be easily added if
they are known.

The linker preloads a special file (/usr/local/lib/hp71.ep)
containing all HP-71 operating system entry points.  Do not
use any name contained in this file, or remove the loading
of this file.

In summary, HP-71 dependencies should not be a problem.
However if you want to use new opcodes, you will have to add
them.  Please, post your modifications.


CONTENTS
--------

Makefile
	The global Makefile (HP-UX) to generate all programs.

assembler
	Source code for aas (the assembler).  Some files are
	shared between assembler, linker and dump (common.h,
	err.h), some are shared between assembler and linker
	(exp.c, mdep.c).
	Contains a manual page in French.

linker
	Source code for ald (the linker).
	Contains a manual page in French.

dump
	Source code for adp (the file dumper, used for
	debugging).
	Contains a manual page in French.

cpy
	Source code for downloading files from a PC to an
	HP-71 using HP-IL Link card or RS-232.  This should
	now superseded for HP-48 by Kermit.

load
	Source code for acp, utility for copying an
	executable file generated by the linker to a LIF
	disk (to be read by an HP-71 with HP-9114).

equ
	Source for all HP-71 operating system entry points.

jmpdoc
	Some thoughts about adding a new generic branch macro.
	In French. Garbage.

msg
	Source code for amg (HP-71 message table generator).
	Contains a manual page in French.

doc
	Various documentations.


PORTING
-------

If you are using HP-UX, just type make, then make install.

If you are using another flavor of Unix, the Makefile should
work. We think there are no special system dependencies (it was
successfully compiled on Suns 3 and 4 with SunOS 4 and a Vax
under BSD 4.3).

If you are using PC compatibles, we cannot do anything for you.
The Makefiles will probably be difficult to use...

If you are using an Amiga, a Mac or anything else, good work !



Have fun !

Pierre DAVID & Janick TAILLANDIER (July 1st, 1990)
@EOF
set `wc -lwc <areuh/README`
if test $1$2$3 != 1406303718
then
	echo ERROR: wc results of areuh/README are $* should be 140 630 3718
fi

chmod 644 areuh/README

exit 0

akcs.scotty@hpcvbbs.UUCP (SCOTTY THOMPSON) (11/20/90)

I DON'T BELIEVE THIS!!!  THINKING THAT THERE MAY BE FURTHER ADDENDUMS
(I.E., 1/8, 2/8, 3/8 [WHICH I know I'VE SEEN HERE SOMEWHERE...]), I
SEARCHED THE entire! COMP.SYS.HANDHELDS AND ENDED-UP WITH ZILTCH?!

GOD AM I IRKED (RATHER, PO'ED, ACTUALLY).

WILL SOMEONE PLEASE POST SOMETHING HERE SO THAT I, TOO, CAN "HAVE FUN!"
AS A PRESUMEDLY SADISTIC AUTHOR ONCE WROTE.

THIS RUN ON THE BBS WAS STRICTLY TO GET SATURN MATERIAL/ASSEMBLER/ETC.

BOY, AM I DISSAPOINTED NOW.

PLEASE CALL AND ADVISE WHEN SOMETHING'S ACTUALLY POSTED.

SCOTT (213) 539-3611 (WK) 9780 (Hm)

akcs.hpjr@hpcvbbs.UUCP (Jerry Raia) (11/27/90)

drop me a line and we'll work something out.
It's too big to try and post and would take longer
than I want to spend on it.