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 0pda@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 0pda@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 0pda@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 0pda@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 (§or[(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 0pda@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 0pda@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 0pda@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 0akcs.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.