jmorriso@fs0.ee.ubc.ca (John Paul Morrison) (06/11/90)
A while ago, I saw a posting for the sass assembler for the HP. I have the .tar file still here, but I saw some follow ups that the IBM PC version of the source code was buggy. Someone also said that the executable file was on some ftp site. Could some- one please tell me where I can get the IBM PC version? I think it is odd that I have seen no other comments about this assembler It is pretty unique to have an assembler for your calculator! jp
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
This posting contains a complete development system for the Saturn processor used on HP-71, HP-28, HP-48 etc. Hereafter is the README file. Enjoy ! pda@masi.ibp.fr ------------------------------------------------------------------------------ AUTHORS ------- Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) Janick TAILLANDIER You are free to use or distribute these programs as long as you keep this note These programs are provided as is. They are in no way supported by us. PRESENTATION ------------ These programs provide you with a complete development system for the Saturn processor (used on the HP-71, HP-28, HP-48 among others). It includes an assembler, a linker for separate assembly, and various utilities to generate message tables for the HP-71 as well as download programs to the HP-71 via HP-IL or RS-232. HISTORY ------- It was developped for the HP-71 in order for us to produce more easily the JPC Rom (PPC Paris Rom) for the HP-71. The final Rom module was 45 KB (executable) for a total of 1.5 MB source files. The speed was one of the main design objectives. These programs were written in C for the HP Integral PC (under HP-UX) in 1986 and have been adaptated for PC compatibles (Microsoft C 4.0 in 1987). It was also used as the final stage of a simple C compiler for the HP-71. HP-71 DEPENDENCIES ------------------ This development system is fully compatible with the assembler described in the HP-71 Internal Design Specifications (Volumes I or IV). The opcode syntax is the one used by HP : it seems crazy to invent a new one, just to confuse everyone! Some macros (LEX, BIN, FORTH, TOKEN...) are specific to the HP-71, but you are free not to use them. You may also want to write specific HP-48 macros to generate specific objects (it would be nice if HP give us the syntax they use). Some opcodes used in newer machines (28, 48...) are not present in the HP-71. Those opcodes (but PC=(A) and RSI) are not in our opcode table, but could be easily added if they are known. The linker preloads a special file (/usr/local/lib/hp71.ep) containing all HP-71 operating system entry points. Do not use any name contained in this file, or remove the loading of this file. In summary, HP-71 dependencies should not be a problem. However if you want to use new opcodes, you will have to add them. Please, post your modifications. CONTENTS -------- Makefile The global Makefile (HP-UX) to generate all programs. assembler Source code for aas (the assembler). Some files are shared between assembler, linker and dump (common.h, err.h), some are shared between assembler and linker (exp.c, mdep.c). Contains a manual page in French. linker Source code for ald (the linker). Contains a manual page in French. dump Source code for adp (the file dumper, used for debugging). Contains a manual page in French. cpy Source code for downloading files from a PC to an HP-71 using HP-IL Link card or RS-232. This should now superseded for HP-48 by Kermit. load Source code for acp, utility for copying an executable file generated by the linker to a LIF disk (to be read by an HP-71 with HP-9114). equ Source for all HP-71 operating system entry points. jmpdoc Some thoughts about adding a new generic branch macro. In French. Garbage. msg Source code for amg (HP-71 message table generator). Contains a manual page in French. doc Various documentations. PORTING ------- If you are using HP-UX, just type make, then make install. If you are using another flavor of Unix, the Makefile should work. We think there are no special system dependencies (it was successfully compiled on Suns 3 and 4 with SunOS 4 and a Vax under BSD 4.3). If you are using PC compatibles, we cannot do anything for you. The Makefiles will probably be difficult to use... If you are using an Amiga, a Mac or anything else, good work ! Have fun ! Pierre DAVID & Janick TAILLANDIER (July 1st, 1990)
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:32:48 1990 # # This archive contains: # areuh areuh/cpy # areuh/linker areuh/dump # areuh/doc areuh/equ # areuh/load areuh/msg # areuh/jmpdoc areuh/assembler # areuh/cpy/a2lex.c areuh/cpy/a2rs.c # areuh/cpy/copy.h areuh/linker/mdep.c # areuh/linker/exp.c areuh/linker/err.h # areuh/linker/common.h areuh/linker/lutil.c # areuh/linker/lpass.c areuh/linker/lmain.c # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo mkdir - areuh mkdir areuh chmod 755 areuh echo mkdir - areuh/cpy mkdir areuh/cpy chmod 755 areuh/cpy echo mkdir - areuh/linker mkdir areuh/linker chmod 755 areuh/linker echo mkdir - areuh/dump mkdir areuh/dump chmod 755 areuh/dump echo mkdir - areuh/doc mkdir areuh/doc chmod 755 areuh/doc echo mkdir - areuh/equ mkdir areuh/equ chmod 755 areuh/equ echo mkdir - areuh/load mkdir areuh/load chmod 755 areuh/load echo mkdir - areuh/msg mkdir areuh/msg chmod 755 areuh/msg echo mkdir - areuh/jmpdoc mkdir areuh/jmpdoc chmod 755 areuh/jmpdoc echo mkdir - areuh/assembler mkdir areuh/assembler chmod 755 areuh/assembler echo x - areuh/cpy/a2lex.c cat >areuh/cpy/a2lex.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "copy.h" char outname [100] ; FILE *fpdev ; init () { #ifdef unix fpdev = stdout ; #else sprintf (outname, "%s.lex", file) ; if ((fpdev = fopen (outname, "wb")) == NULL) error (ERROPN, outname) ; #endif } output (c) uchar c ; { putc ((int) c, fpdev) ; if (ferror (fpdev)) error (ERRWRT, outname) ; } term () { if (fclose (fpdev)) error (ERRCLO, outname) ; } @EOF set `wc -lwc <areuh/cpy/a2lex.c` if test $1$2$3 != 39108641 then echo ERROR: wc results of areuh/cpy/a2lex.c are $* should be 39 108 641 fi chmod 644 areuh/cpy/a2lex.c echo x - areuh/cpy/a2rs.c cat >areuh/cpy/a2rs.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "copy.h" #include <dos.h> union REGS inregs, outregs ; init () { inregs.h.ah = 0 ; inregs.h.al = 0xe3 ; inregs.x.dx = 0 ; /* com1 */ int86 (0x14, &inregs, &outregs) ; } output (c) char c ; { int ok ; ok = 0 ; while (!ok) { inregs.h.ah = 0x03 ; /* get line status */ inregs.x.dx = 0x0000 ; int86 (0x14, &inregs, &outregs) ; ok = (outregs.h.al & 0x30) == 0x30 ; /* handshake lines */ } inregs.h.ah = 1 ; /* send char */ inregs.h.al = c ; inregs.x.dx = 0 ; int86 (0x14, &inregs, &outregs) ; } term () { } @EOF set `wc -lwc <areuh/cpy/a2rs.c` if test $1$2$3 != 47146813 then echo ERROR: wc results of areuh/cpy/a2rs.c are $* should be 47 146 813 fi chmod 644 areuh/cpy/a2rs.c echo x - areuh/cpy/copy.h cat >areuh/cpy/copy.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include <stdio.h> long int con () ; typedef unsigned char uchar ; typedef unsigned long int int32 ; typedef unsigned short int int16 ; #define ERRUSA 1 /* usage */ #define ERROPN 2 /* cannot open */ #define ERRNAL 3 /* not a Lex */ #define ERRCLO 4 /* cannot close */ #define ERRRD 5 /* error reading */ #define ERRWRT 6 /* error writing */ #define ERRLEN 7 /* bad REL(5) FiLeNd field */ #define ERRINT 8 /* interface error */ uchar *file ; uchar name [10] ; FILE *fp ; int16 ftype ; int32 lnib, lbyte, lsect ; uchar *pgm ; /* name of current program */ main (argc, argv) int argc ; char *argv[] ; { long int magic ; int32 l ; uchar tab [4] ; int i, j, m ; int mod ; pgm = (uchar *) argv [0] ; /* program name */ switch (argc) { case 1 : file = (uchar *) "lex" ; /* default name */ break ; case 2 : file = (uchar *) argv [1] ; break ; default : error (ERRUSA, "") ; break ; } fp = fopen (file, "rb") ; /* binary file for MS-DOS machines */ if (fp == NULL) error (ERROPN, file) ; /* get Lex file header */ fread ((char *) &magic, sizeof (long int), 1 , fp) ; if (magic!=0x1b080100) error (ERRNAL, file) ; /* not a Lex file */ for (i=0; i<8; i++) name [i] = (uchar) con (2) ; name [8] = name [9] = ' ' ; ftype = (int32) con (4) ; /* file type */ skip (12) ; /* skip date and time */ lnib = (int32)con (5) - (int32)5 ; /* get length */ lsect = (lnib + 511) / 512 ; if (ferror (fp)) /* read error */ error (ERRRD, file) ; /* initialize output channel */ init () ; /* header output */ for (i=0; i<10; i++) /* file name */ output ((uchar) name [i]) ; output ((uchar) (ftype / 256)) ; /* file type */ output ((uchar) (ftype % 256)) ; for (i=1; i<=4; i++) /* start sector */ output ((uchar) 0) ; l = lsect ; for (i=3; i>=0; i--) /* length in sectors */ { tab [i] = (uchar) l & 0xff ; l >>= 8 ; } for (i=0; i<4; i++) output (tab [i]) ; for (i=0; i<6; i++) /* date and time */ output ((uchar) 0) ; output ((uchar) 0x80) ; /* 80 */ output ((uchar) 0x01) ; /* 01 */ l = lnib ; for (i=0; i<4; i++) /* length in nibbles */ { output ((uchar) (l & (int32) 0xff)) ; l >>= 8 ; } /* data output */ lbyte = (lnib+1) >> 1 ; mod = lbyte % 256 ; for (i=1; i<=lsect; i++) { m = (i == lsect && mod != 0) ? min (256, mod) : 256 ; for (j=0; j<m ; j++) output ((uchar) con (2)) ; } for (j=m; j<256; j++) output ((uchar) 0) ; /* end */ if (getc (fp) != EOF) /* bad file len */ error (ERRLEN, file) ; term () ; exit (0) ; } long int con (n) int n ; { int i ; long int res ; uchar buf [1024] ; int first ; res = 0 ; first = 1 ; for (i=0; i<n; i++) { buf [i] = (uchar) getc (fp) ; if (first && feof (fp)) error (ERRLEN, "") ; first = 0 ; } if (ferror (fp)) error (ERRRD, file) ; for (i=n-1; i>=0; i--) res = (res << 4) | hex (buf [i]) ; return res ; } skip (n) int n ; { uchar buf [1024] ; fread (buf, n, 1, fp) ; if (ferror (fp)) error (ERRRD, file) ; if (feof (fp)) error (ERRLEN, "") ; } int min (a, b) int a, b ; { return a <= b ? a : b ; } int hex (c) uchar c ; { return (c >= 'A' && c <= 'F') ? c - 'A' + 10 : c - '0' ; } error (code, str) int code ; uchar *str ; { switch (code) { case ERRUSA : /* usage */ fprintf (stderr, "usage: %s [file]\n", pgm) ; break ; case ERROPN : /* cannot open */ fprintf (stderr, "%s: cannot open %s\n", pgm, str) ; break ; case ERRNAL : /* not a Lex */ fprintf (stderr, "%s: %s is not a lex file\n", pgm, str) ; break ; case ERRCLO : /* cannot close */ fprintf (stderr, "%s: cannot close %s\n", pgm, str) ; break ; case ERRRD : /* error reading */ fprintf (stderr, "%s: error reading %s\n", pgm, str) ; break ; case ERRWRT : /* error writing */ fprintf (stderr, "%s: error writing %s\n", pgm, str) ; break ; case ERRLEN : /* bad REL(5) FiLeNd field */ fprintf (stderr, "%s: bad REL(5) FiLeNd field\n", pgm) ; break ; case ERRINT : /* interface error */ fprintf (stderr, "%s: interface error\n", pgm) ; break ; default : fprintf (stderr, "%s: internal error\n", pgm) ; break ; } exit (1) ; } @EOF set `wc -lwc <areuh/cpy/copy.h` if test $1$2$3 != 2249004719 then echo ERROR: wc results of areuh/cpy/copy.h are $* should be 224 900 4719 fi chmod 644 areuh/cpy/copy.h echo x - areuh/linker/mdep.c cat >areuh/linker/mdep.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** M A C H I N E D E P E N D E N C I E S ******************************************************************************/ #include "flag.h" #if ASSEMBLER #include "aglobal.h" #else #include "lglobal.h" #endif extern struct symbol *add_label() ; #if HPUX void format_time (str) uchar *str ; { long int l ; extern long int time () ; extern char *ctime () ; l = time (0L) ; strcpy (str, ctime (&l)) ; str [strlen (str) - 1] = EOL ; } char *tab[] = { "", "/usr/lib/", "/usr/local/lib/", "/lib/", "/hp71/lib/", "/local/lib/", 0 } ; void load_file (file) uchar *file ; { int i = 0 ; uchar name [MAXLEN+1] ; saddr val ; FILE *fp ; fp = (FILE *) NULL ; while ((tab[i])&&(!fp)) { sprintf (name, "%s%s", tab[i++], file) ; fp = fopen (name, "r") ; } if (!fp) error (ERROPN, file) ; #if LINKER file = 0 ; #endif while (fscanf (fp, "%s\n%X\n", name, &val) != EOF) { #if ASSEMBLER add_label (name, val, "", LABS, 1) ; #else add_label (name, val, 1) ; #endif } if (ferror (fp)) error (ERRWRT, file) ; if (fclose (fp)) error (ERRCLO, file) ; } #include <sys/types.h> #include <sys/stat.h> /* look for object file (object code or listing file) * if non existent, ok * if exists and not directory, ok * if exists and directory, then append "<dir>/<default>" */ look_obj (fname, dfl) uchar *fname, *dfl ; { struct stat buf ; if (*fname == EOL) /* if fname == "" then default it */ strcpy (fname, dfl) ; if (!stat (fname, &buf)) /* file exists. Is it a directory ? */ { if ((buf.st_mode & S_IFMT) == S_IFDIR) sprintf (fname, "%s/%s", fname, dfl) ; } } /* build a default file name, based on "source" basename and a given * default extension. */ dfl_extension (object, source, extension) uchar *object, *source, *extension ; { uchar *pname ; strcpy (object, source) ; pname = object ; while ((*pname)&&(*pname!='.')) pname++ ; if (*pname==EOL) *pname = '.' ; strcpy (pname+1, extension) ; } #endif /* HPUX */ #if ATARI_LATTICE char skipvar ; void format_time (str) uchar *str ; { strcpy (str, "Areuh Tagada Bouzouh bouzouh areuh areuh... et toc !") ; } char *optarg ; int optind = 0, opterr = 0 ; int getopt (argc, argv, optstr) int argc ; char *argv[], *optstr ; { char *o, car ; static char *index = 0 ; extern char *strchr () ; if ((index==(char *)0)||(*(index+1)==0)) { if (++optind>argc-1) return (EOF) ; index = argv[optind] ; if (*index!='-') return (EOF) ; } car = *(++index) ; /* state 6 */ if (!(o = strchr (optstr, car))) return ('?') ; if (*(o+1)!=':') return ((int) car) ; if (*(index+1)) optarg = index+1 ; else { if (++optind>argc-1) return (EOF) ; else optarg = argv[optind] ; } index = (char *) 0 ; return ((int) car) ; } uchar *tab[] = { "", "A:", "A:\\TABLE\\", 0 } ; void load_file (file) uchar *file ; { int i = 0 ; uchar name [MAXLEN+1] ; saddr val ; FILE *fp ; fp = (FILE *) NULL ; while ((tab[i])&&(!fp)) { sprintf (name, "%s%s", tab[i++], file) ; fp = fopen (name, "r") ; } if (!fp) error (ERROPN, file) ; #if LINKER file = 0 ; #endif while (fscanf (fp, "%s\n%x\n", name, &val) != EOF) { #if ASSEMBLER add_label (name, val, "", LABS, 1) ; #else add_label (name, val, 1) ; #endif } if (fclose (fp)) error (ERRCLO, file) ; } #endif /* ATARI_LATTICE */ #if PC_MSC char skipvar ; void format_time (str) uchar *str ; { long int l ; extern long int time () ; extern char *ctime () ; time (&l) ; strcpy (str, ctime (&l)) ; str [strlen (str) - 1] = EOL ; } char *optarg ; int optind = 0, opterr = 0 ; int getopt (argc, argv, optstr) int argc ; char *argv[], *optstr ; { char *o, car ; static char *index = 0 ; extern char *strchr () ; if ((index==(char *)0)||(*(index+1)==0)) { if (++optind>argc-1) return (EOF) ; index = argv[optind] ; if (*index!='-') return (EOF) ; } car = *(++index) ; /* state 6 */ if (!(o = strchr (optstr, car))) return ('?') ; if (*(o+1)!=':') return ((int) car) ; if (*(index+1)) optarg = index+1 ; else { if (++optind>argc-1) return (EOF) ; else optarg = argv[optind] ; } index = (char *) 0 ; return ((int) car) ; } uchar *tab[] = { "", "c:", "c:\\hp71\\", "c:\\lib\\hp71\\", "c:\\lib\\", "c:\\areuh\\lib\\", 0 } ; void load_file (file) uchar *file ; { int i = 0 ; uchar name [MAXLEN+1] ; saddr val ; FILE *fp ; fp = (FILE *) NULL ; while ((tab[i])&&(!fp)) { sprintf (name, "%s%s", tab[i++], file) ; fp = fopen (name, "r") ; } if (!fp) error (ERROPN, file) ; #if LINKER file = 0 ; #endif while (fscanf (fp, "%s\n%X\n", name, &val) != EOF) { #if ASSEMBLER add_label (name, val, "", LABS, 1) ; #else add_label (name, val, 1) ; #endif } if (fclose (fp)) error (ERRCLO, file) ; } #include <sys\types.h> #include <sys\stat.h> /* look for object file (object code or listing file) * if non existent, ok * if exists and not directory, ok * if exists and directory, then append "<dir>/<default>" */ look_obj (fname, dfl) uchar *fname, *dfl ; { struct stat buf ; if (*fname == EOL) /* if fname == "" then default it */ strcpy (fname, dfl) ; if (!stat (fname, &buf)) /* file exists. Is it a directory ? */ { if ((buf.st_mode & S_IFMT) == S_IFDIR) sprintf (fname, "%s\\%s", fname, dfl) ; } } /* build a default file name, based on "source" basename and a given * default extension. */ dfl_extension (object, source, extension) uchar *object, *source, *extension ; { uchar *pname ; strcpy (object, source) ; pname = object ; while ((*pname)&&(*pname!='.')) pname++ ; if (*pname==EOL) *pname = '.' ; strcpy (pname+1, extension) ; } #endif /* PC_MSC */ @EOF set `wc -lwc <areuh/linker/mdep.c` if test $1$2$3 != 32610286303 then echo ERROR: wc results of areuh/linker/mdep.c are $* should be 326 1028 6303 fi chmod 644 areuh/linker/mdep.c echo x - areuh/linker/exp.c cat >areuh/linker/exp.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** TITAN ASSEMBLER EXPRESSION EVALUATION calc_expression, reduce_E, reduce_T, reduce_F, reduce_B, reduce_X, reduce_P, dec_value, hex_value, bin_value, ascii_value, label_value, apply, trunc, next_char, append_extexp ******************************************************************************/ #include "flag.h" #if ASSEMBLER #include "aglobal.h" #else #include "lglobal.h" #endif uchar extexp [4*MAXLEN] ; uchar *pexp, *pextexp ; uchar *xlabel ; int relabs ; extern saddr symbol_value() ; saddr reduce_E(), reduce_T(), reduce_F(), reduce_B(), reduce_X(), reduce_P(), dec_value(), hex_value(), bin_value(), ascii_value(), label_value(), apply(), trunc() ; void next_char(), append_extexp() ; /****************************************************************************** CALC_EXPRESSION synopsis : saddr calc_expression (exp) uchar *exp description : That's the expression evaluator. Productions used are : E -> T { {+|-} T }* T -> F { {*|/} F }* F -> B { {&|!} B }* B -> X | -X | `X (two's and one's complement) X -> N { {~|^} N }* P -> D | #<hex> | %<bin> | '<ascii>' | \<ascii>\ | <label> | * | (E) D -> <dec> if expression evaluated by ASSSEMBLER D -> <dec> | <dec> r if expression evaluated by LINKER where E : expression T : term F : factor B : boolean X : exponentiation P : primary D : decimal number warning : with this grammar, 5--5 is valid (5 minus -5), but 5---5 is not. This can be modified by : B -> -B | P . The code is more complex, and I'm not sure that it's a real improvement. note : Algorithm used is recursive descent (Mr Vermeulen would be horrified !) like Forth/Assembler rom based assembler, but is quietly different... ******************************************************************************/ saddr calc_expression (exp) uchar *exp; { saddr val; pextexp = extexp ; pexp = exp ; val = reduce_E() ; if (((val>=0L)||(val==EXP_EXT))&&(*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t')) { error(WRNEXP, "") ; /* illegal expression */ val = EXP_ERR ; } *pextexp = EOL ; return (val) ; } /****************************************************************************** REDUCE_E synopsis : saddr reduce_E() description : This function reduces a given expression starting at pexp. ******************************************************************************/ saddr reduce_E() { saddr val1, val2; uchar op, lrelabs; val1 = reduce_T () ; while ((((op = *pexp)=='+')||(op=='-'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_T () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_T synopsis : saddr reduce_T () description : same as above, for T-production ******************************************************************************/ saddr reduce_T () { saddr val1, val2 ; uchar op, lrelabs ; val1 = reduce_F () ; while ((((op = *pexp)=='*')||(op=='/'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_F () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_F synopsis : saddr reduce_F () description : same as reduce_E ******************************************************************************/ saddr reduce_F () { saddr val1, val2; uchar op, lrelabs ; val1 = reduce_B () ; while ((((op = *pexp)=='&')||(op=='!'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_B () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_B synopsis : saddr reduce_B () description : reduces a boolean factor. This must be done by reduction of minus sign eventually. ******************************************************************************/ saddr reduce_B () { saddr val; uchar op ; op = *pexp ; if ((op=='-')||(op=='\`')) next_char () ; val = reduce_X () ; if (val<0L) return(val) ; switch (op) { case '-' : return (trunc (-val)) ; case '\`' : return (trunc (~val)) ; default : return (val) ; } } /****************************************************************************** REDUCE_X synopsis : saddr reduce_X () description : same as reduce_E ******************************************************************************/ saddr reduce_X () { saddr val1, val2; uchar op, lrelabs; val1 = reduce_P () ; while ((((op = *pexp)=='~')||(op=='^'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_P () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_P synopsis : saddr reduce_P () description : these are the terminal rules. note : rule P -> D is implemented "in line" in this code (not as a separate function). ******************************************************************************/ saddr reduce_P () { saddr val ; uchar limit, line[MAXLEN] ; switch (*pexp) { case '#' : next_char () ; if (((*pexp>='0')&&(*pexp<='9')) || ((*pexp>='A')&&(*pexp<='F')) || ((*pexp>='a')&&(*pexp<='f'))) val = hex_value () ; else { error (WRNIHX,""); /* illegal hexadecimal constant */ val = EXP_ERR ; } relabs = LABS ; break ; case '%' : next_char () ; if ((*pexp=='0')||(*pexp=='1')) val = bin_value () ; else { error (WRNIBC, "") ; /* illegal binary constant */ val = EXP_ERR ; } relabs = LABS ; break ; case '\'' : case '\\' : limit = *pexp ; next_char () ; val = ascii_value (limit) ; if (*pexp!=limit) { error (WRNASC,""); /* illegal ascii constant */ val = EXP_ERR ; } next_char () ; relabs = LABS ; break ; case '*' : val = pc ; pexp++ ; sprintf (line, "%ldr", pc) ; relabs = LREL ; append_extexp (line) ; break ; case '(' : next_char () ; val = reduce_E () ; if ((*pexp!=')')&&(val>=0)) { error (WRNPAR, "") ; /* mismatched parenthesis */ val = EXP_ERR ; } next_char () ; break ; case EOL : error (WRNEXP,"") ; /* illegal expression */ val = EXP_ERR ; break ; default : if ((*pexp>='0')&&(*pexp<='9')) { val = dec_value () ; relabs = LABS ; #if LINKER if (*pexp=='r') { next_char() ; relabs = LREL ; val += tmodule[file].m_ad ; } #endif } else val = label_value () ; break ; } return (val) ; } /****************************************************************************** DEC_VALUE synopsis : saddr dec_value () descrption : This function returns the decimal value of a constant. The search is stopped when a non numeric digit is reached. (this can be ),+,-,*,/,&,!). Finally, the founded value is returned. note : this function doesn't check overflow. If there is, numbers are treated as 20 bits words, and overflow doesn't propagate on 32 bits of an integer (-1 is never reached when calculus). ******************************************************************************/ saddr dec_value () { saddr val=0L ; do { val = trunc (val * 10L + (saddr) (*pexp-'0') ) ; next_char () ; } while ((*pexp>='0')&&(*pexp<='9')) ; return (val); } /****************************************************************************** HEX_VALUE synopsis : saddr hex_value () description : same as above for hexadecimal constants ******************************************************************************/ saddr hex_value () { saddr i, val = 0L ; while ( ((*pexp>='0')&&(*pexp<='9')) || ((*pexp>='A')&&(*pexp<='F')) || ((*pexp>='a')&&(*pexp<='f')) ) { if (*pexp<='9') i = (long int) ((*pexp) - '0') ; else if (*pexp<='F') i = (long int) ((*pexp) - 'A' + 10) ; else i = (long int) ((*pexp) - 'a' + 10) ; val = trunc (val*16L + i) ; next_char () ; } return (val) ; } /****************************************************************************** BIN_VALUE synopsis : saddr bin_value () description : same as above for binary constants ******************************************************************************/ saddr bin_value () { saddr val = 0L ; while ((*pexp=='0')||(*pexp=='1')) { val = trunc (val*2L + ((saddr) ((*pexp) - '0'))) ; next_char () ; } return (val) ; } /****************************************************************************** ASCII_VALUE synopsis : saddr ascii_value () description : same as above, but the search is stopped when encoutered a '. The pointer *pexp stands on this character. ******************************************************************************/ saddr ascii_value (limit) uchar limit ; { saddr val = 0 ; while ((*pexp!=EOL)&&(*pexp!=limit)) { val = trunc (val*256L + ((saddr) *pexp)) ; next_char () ; } return (val) ; } /****************************************************************************** LABEL_VALUE synopsis : saddr label_value () description : parses the symbol, then tries to return the value founded in the symbol list. ******************************************************************************/ saddr label_value () { uchar label[LBLLEN+2], *plabel ; int mx, need_par = 0, j = 0 ; saddr val ; mx = LBLLEN + ((*pexp=='=') ? 1 : 0) ; while ((*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t')&& (*pexp!=')')&&(*pexp!='\\')) { if (j<mx) label[j++] = *pexp ; pexp++ ; } label[j] = EOL ; plabel = label ; if ((val = symbol_value (label)) >= (saddr) 0) { /* found, copy value */ if (relabs==LREL) sprintf (label, "%ldr", val) ; else sprintf (label, "%ld", val) ; } else if ((val == LBL_UDF) || (val == LBL_IVL)) { /* UDF : label not (yet) declared, IVl : invalid label */ *plabel = EOL ; /* incoherent value */ val = EXP_ERR ; } else if ((val == LBL_EXT) || (val == LBL_XEQ)) { /* LBL_EXT: ext. label not known, LBL_XEQ: global defined with ext. */ val = EXP_EXT ; /* keep label name */ } else /* (val == LBL_SEQ) */ { /* LBL_SEQ : synonym, expandable */ plabel = xlabel ; /* get definition of label */ need_par = 1 ; /* enclose label with (...) */ val = EXP_EXT ; /* and store it into extep */ } if (need_par) append_extexp ("(") ; append_extexp (plabel) ; if (need_par) append_extexp (")") ; return (val) ; } /****************************************************************************** APPLY synopsis : saddr apply (val1, op, val2, relabs1, relabs2) saddr val1, val2 uchar op, relabs1, relabs2 description : calculate the value of binary operator op applied to operands val1 & val2. note : under overflow condition, numbers are truncated to 20 bits. ******************************************************************************/ saddr apply (val1, op, val2, relabs1, relabs2) uchar op, relabs1, relabs2 ; saddr val1, val2 ; { saddr val ; if (val2==EXP_ERR) return (EXP_ERR) ; if ((val1==EXP_EXT)||(val2==EXP_EXT)) return (EXP_EXT) ; switch (op) { case '+' : val = trunc (val1 + val2) ; break ; case '-' : val = trunc (val1 - val2 ) ; break ; case '*' : val = trunc (val1 * val2 ) ; break ; case '/' : #if ASSEMBLER val = (val2 ? val1 / val2 : EXP_ERR ) ; #else val = (val2 ? val1 / val2 : EXP_EXT ) ; #endif if (val2==0L) error (WRNNUL, "") ; /* null divisor */ break ; case '&' : val = val1 & val2 ; break ; case '!' : val = val1 | val2 ; break ; case '~' : val = trunc (val1*256 + val2) ; break ; case '^' : if ((val1<0)||(val2<0)||((val1==0)&&(val2==0))) { error (WRNIXP, "") ; /* Illegal exponentiation */ #if ASSEMLER val = EXP_ERR ; #else val = EXP_EXT ; #endif } else { val = 1 ; for (;val2>0 ; val2--) val *= val1 ; val = trunc (val) ; } break ; } if ((relabs1==LUDF)||(relabs2==LUDF)) relabs = LUDF ; else if ((relabs1==LREL)||(relabs2==LREL)) relabs = LREL ; else relabs = LABS ; return (val) ; } /****************************************************************************** TRUNC synopsis : saddr trunc (val) saddr val description : truncates 32 bits integer to 24 bits. ******************************************************************************/ saddr trunc (val) saddr val ; { return (val & 0xffffff) ; } /****************************************************************************** NEXT_CHAR synopsis : void next_char () description : stores the current character in extexp variable, and moves the expression pointer (pexp) forward one position. ******************************************************************************/ void next_char () { *pextexp = *pexp ; pextexp++ ; pexp++ ; } /****************************************************************************** APPEND_EXTEXP synopsis : void append_extexp (line) uchar *line ; description : append line to extexp string. ******************************************************************************/ void append_extexp (line) uchar *line ; { while (*line) { *pextexp = *line ; pextexp++ ; line++ ; } } @EOF set `wc -lwc <areuh/linker/exp.c` if test $1$2$3 != 634182916414 then echo ERROR: wc results of areuh/linker/exp.c are $* should be 634 1829 16414 fi chmod 644 areuh/linker/exp.c echo x - areuh/linker/err.h cat >areuh/linker/err.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER / LINKER ERROR NUMBERS DECLARATIONS ******************************************************************************/ /* FATAL ERRORS */ #define ERROPN -1 /* A L */ /* system error opening file */ #define ERRCLO -2 /* A L */ /* system error closing file */ #define ERRREW -3 /* A */ /* system error on file at start of pass two */ #define ERRWRT -4 /* A L */ /* system error writing file */ #define ERRRD -5 /* A L */ /* system error reading file */ #define ERRMEM -6 /* A L */ /* not enough memory */ #define ERRLEX -10 /* A */ /* invalid macro pseudo-op LEX or BIN */ #define ERRPGS -11 /* A */ /* invalid page size */ #define ERRFLN -12 /* A */ /* restricted label FiLeNd exists */ #define ERRIFL -13 /* A L */ /* invalid file name */ #define ERRIMO -14 /* A */ /* invalid macro-op xx in modular assembling */ #define ERRVMD -15 /* A */ /* value must be defined for xx */ #define ERRUSA -20 /* A L */ /* usage: ass [ [-l] source_file ] */ /* usage: ald ... */ #define ERRNOA -30 /* L */ /* file not output from aas */ #define ERRICV -31 /* L */ /* incompatible version */ /* NON FATAL ERRORS */ #define WRNEQU 10 /* A */ /* cannot resolve equate */ #define WRNDUP 11 /* A L */ /* duplicate label */ #define WRNLBL 12 /* A */ /* illegal label */ #define WRNULB 13 /* A */ /* unrecognized label */ #define WRNURF 14 /* L */ /* unresolved reference */ #define WRNURL 15 /* L */ /* unresolved label */ #define WRNEXP 20 /* A */ /* illegal expression */ #define WRNASC 21 /* A */ /* illegal ascii constant */ #define WRNPAR 22 /* A */ /* mismatched parenthesis */ #define WRNIHX 23 /* A */ /* illegal hexadecimal constant */ #define WRNNUL 24 /* A */ /* null divisor */ #define WRNIXP 25 /* A */ /* illegal exponentiation */ #define WRNIBC 26 /* A */ /* illegal binary constant */ #define WRNENA 27 /* A */ /* external references not allowed */ #define WRNYES 30 /* A */ /* GOYES or RTNYES required */ #define WRNIDP 31 /* A */ /* illegal dp arithmetic value */ #define WRNIPP 32 /* A */ /* illegal pointer position */ #define WRNISB 33 /* A */ /* illegal status bit */ #define WRNTFR 34 /* A */ /* illegal transfer value */ #define WRNIWS 35 /* A */ /* illegal word select */ #define WRNLST 36 /* A */ /* invalid LIST argument */ #define WRNJVL 37 /* A L */ /* jump or value too large */ #define WRNMLB 38 /* A */ /* missing label */ #define WRNTST 39 /* A */ /* needs previous test instruction */ #define WRNNHX 40 /* A */ /* non hexadecimal digits present */ #define WRNTMA 41 /* A */ /* too many ascii characters present */ #define WRNTMH 42 /* A */ /* too many hexadecimal digits present */ #define WRNOPC 43 /* A */ /* unknown opcode */ #define WRNIIF 50 /* A */ /* invalid conditional structure */ extern void error() ; @EOF set `wc -lwc <areuh/linker/err.h` if test $1$2$3 != 1275845010 then echo ERROR: wc results of areuh/linker/err.h are $* should be 127 584 5010 fi chmod 644 areuh/linker/err.h echo x - areuh/linker/common.h cat >areuh/linker/common.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include <stdio.h> #define MAXLEN 256 #define EOL '\0' #define LBLLEN 12 /****************************************************************************** TYPE DEFINITIONS ******************************************************************************/ typedef long int saddr ; /* Saturne address. At least 32 bits */ typedef unsigned char uchar ; /* unsigned characters, for accents */ typedef short int sint ; /* 16 bits */ /****************************************************************************** MAGIC NUMBERS ******************************************************************************/ #define AL_MAGIC 0x1b080100 /* ... areuh_lex */ #define AO_MAGIC 0x1b0d0100 /* ... areuh_output of assembler */ #define ALF_MAGIC 0x1b080100 /* first version of object file format */ #define AOF_MAGIC 0x1b0d0100 /* first version of object file format */ /****************************************************************************** USAGE TYPES IN .ao FILES ******************************************************************************/ #define XABSL 0x10 /* absolute reference */ #define XABSO 0x20 /* absolute reference, with one bias */ #define XRGTO 0x40 /* relative reference, goto type */ #define XRGSB 0x80 /* relative reference, gosub type */ /****************************************************************************** LABEL VALUES IN .ao FILES ******************************************************************************/ #define LBL_UDF -1L /* label not declared (implicit or explicit) <=> only used */ #define LBL_IVL -2L /* invalid label (invalid expression for an EQU during pass one) */ #define LBL_EXT -3L /* external label not defined here (or yet) */ #define LBL_XEQ -4L /* global label which is defined here, with an external reference */ #define LBL_SEQ -5L /* local label which is defined with an external reference */ /****************************************************************************** LABEL TYPES IN .ao FILES ******************************************************************************/ #define LUDF 0 /* undefined type (external label) */ #define LABS 1 /* absolute local label (declared explicitly, with constants) */ #define LREL 2 /* relative local label (declared implicitly, or explicitly with at least one relative) */ /****************************************************************************** VALUES RETURNED BY EXPRESSION EVALUATOR ******************************************************************************/ #define EXP_ERR -1L #define EXP_EXT -2L extern int relabs ; extern uchar extexp[] ; #include "err.h" extern void error () ; #define hex5(str,val) format_hex (str, val, 5) ; #define hex6(str,val) format_hex (str, val, 6) ; /****************************************************************************** MACHINE DEPENDANCIES ******************************************************************************/ #define HPUX 1 #define ATARI_LATTICE 0 #define PC_MSC 0 /* PC (beuark, Microsoft C) */ #if HPUX extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "r" #define WAO_MODE "w" #define skip(fp) #endif #if ATARI_LATTICE extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "rb" #define WAO_MODE "wb" extern char skipvar ; #define skip(fp) fread(&skipvar,1,1,fp) ; #endif #if PC_MSC extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "rb" #define WAO_MODE "wb" extern char skipvar ; #define skip(fp) fread(&skipvar,1,1,fp) ; #endif @EOF set `wc -lwc <areuh/linker/common.h` if test $1$2$3 != 1244243878 then echo ERROR: wc results of areuh/linker/common.h are $* should be 124 424 3878 fi chmod 644 areuh/linker/common.h echo x - areuh/linker/lutil.c cat >areuh/linker/lutil.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "lglobal.h" extern char *malloc () ; extern saddr calc_expression () ; uchar *memoire () ; /****************************************************************************** FIND_LABEL synopsis : struct symbol *find_label (label) char *label description : find address of label, return address of structure describing it. ******************************************************************************/ struct symbol *find_label (label) char *label ; { struct symbol *p ; int test ; p = h_label [label[1]]->s_next ; while (p) { test = strcmp (label, p->s_name) ; if (test==0) break ; p = p->s_next ; if (test<0) p = (struct symbol *) NULL ; } return (p) ; } /****************************************************************************** ADD_LABEL synopsis : void add_label (label, val, os) uchar *label saddr val int os description : add a label in label table and, if already defined, add it to multiply defined lists. ******************************************************************************/ void add_label (label, val, os) uchar *label ; saddr val ; int os ; { uchar error_text [MAXLEN+1] ; struct symbol *p, *s ; int b = 1 ; p = find_label (label) ; if (p) { sprintf (error_text, "%s in files %s and %s", label, fname[p->s_file], fname[file]) ; error (WRNDUP, error_text) ; /* duplicate label */ } else { s = p = h_label [label[1]] ; while ((b)&&(s)) { if (strcmp (label, s->s_name)<0) b = 0 ; else { p = s ; s = s->s_next ; } } s = (struct symbol *) memoire (sizeof (struct symbol)) ; s->s_next = p->s_next ; p->s_next = s ; strcpy (s->s_name, label) ; s->s_xref = (struct xtable *) NULL ; p = s ; } p->s_value = val ; p->s_file = (uchar) file ; p->s_os = os ; } /****************************************************************************** ADD_UNRES synopsis : void add_unres (label, def) char *label, *def int file description : during first part of pass one, if a label is undefined, add it to a special list. During second part, if this list is scaned. If value is then defined, the label will be removed. At the end of first pass, this queue will be the undefined labels queue, which should be empty... ******************************************************************************/ void add_unres (label, def) uchar *label, *def ; { struct unres *x ; x = (struct unres *) memoire (sizeof (struct unres)) ; strcpy (x->u_label, label) ; x->u_file = (uchar) file ; x->u_def = memoire (strlen (def) + 1) ; strcpy (x->u_def, def) ; x->u_next = head_unres ; head_unres = x ; } /****************************************************************************** READ_USAGE synopsis : void read_usage (characteristic, def, fp) long int *characteristic char *def FILE *fp description : read an entry in third part of object file fp. ******************************************************************************/ void read_usage (characteristic, def, fp) long int *characteristic ; char *def ; FILE *fp ; { int i ; fread (characteristic, sizeof (long int), 1, fp) ; fread (&pc, sizeof (saddr), 1, fp) ; i = 0 ; while ((def [i] = (uchar) fgetc (fp)) != '\n') i++ ; def [i] = EOL ; if (ferror (fp)) error (ERRRD, fname [file]) ; } int lrange (offset, nibs) saddr *offset ; int nibs ; { saddr Sixtine, Fiftine ; int r ; Sixtine = ((saddr) 1) << (nibs*4) ; Fiftine = Sixtine >> 1 ; r = ((*offset>=-Fiftine)&&(*offset<Fiftine)) ; if (*offset<0) *offset += Sixtine ; return (r) ; } /****************************************************************************** RESOLVE_USAGE synopsis : void resolve_usage (characteristic, def, file, fp, code) long int characteristic char *def, *code FILE *fp int file description : make all the work which is to be made by a linker. Resolve all usages. ******************************************************************************/ void resolve_usage (characteristic, def, fp, code) saddr characteristic ; uchar *def, *code ; FILE *fp ; { uchar hexa [MAXLEN+1] ; saddr type, source, dest, offset ; int i, j ; type = characteristic & (XABSL | XABSO | XRGTO | XRGSB) ; characteristic &= ~type ; dest = calc_expression (def) ; if (dest < (saddr) 0) { error (WRNURF, def) ; /* unresolved reference */ dest = (saddr) 0 ; } switch ((int) type) { case XABSL : source = 0 ; break ; case XABSO : source = 1 ; break ; case XRGTO : source = tmodule [file].m_ad + pc ; break ; case XRGSB : source = tmodule [file].m_ad + pc + characteristic ; break ; } offset = dest - source ; if ((type==XRGTO)||(type==XRGSB)) { if (!lrange (&offset, characteristic)) { offset = (saddr) 0 ; error (WRNJVL, def) ; /* Jump or value too large */ } } hex6 (hexa, offset) ; for (i=0, j=5; i<characteristic; i++, j--) { code [pc+i] = hexa[j] ; } } /****************************************************************************** SYMBOL_VALUE synopsis : saddr symbol_value (label) uchar *label description : fetch a label, and return its value. ******************************************************************************/ saddr symbol_value (label) uchar *label ; { struct symbol *ad ; struct xtable *x, *y, *z ; ad = find_label (label) ; if ((ad)&&(passnb==2)&&xref) { x = (struct xtable *) memoire (sizeof (struct xtable)) ; x->x_pc = pc ; x->x_file = file ; z = y = ad->s_xref ; while ((y)&&(y->x_file<file)) { z = y ; y = y->x_next ; } if (y==z) ad->s_xref = x ; /* insert at begining of the list */ else z->x_next = x ; /* insert in middle of list */ x->x_next = y ; ad->s_os = 0 ; } return ((ad) ? ad->s_value : EXP_EXT) ; } /****************************************************************************** MEMOIRE synopsis : uchar *memoire (size) int size description : get memory from heap using malloc. It is just a layer above malloc, including a test. ******************************************************************************/ uchar *memoire (size) int size ; { uchar *x ; if ((x = (uchar *) malloc (size)) == NULL) error (ERRMEM, "") ; return (x) ; } /****************************************************************************** FORMAT_HEX synopsis : void format_hex (str, val, dig) uchar *str saddr val int dig description : stores into str the hexadecimal string representing the dig low order hex digits of val. ******************************************************************************/ format_hex (str, val, dig) uchar *str ; saddr val ; int dig ; { register int i, h ; for (i=dig-1; i>=0; i--) { h = (int) (val & ((saddr) 0xf)) ; str [i] = h + ((h < 10) ? '0' : 'A' - 10) ; val >>= 4 ; } str [dig] = EOL ; } @EOF set `wc -lwc <areuh/linker/lutil.c` if test $1$2$3 != 32910407349 then echo ERROR: wc results of areuh/linker/lutil.c are $* should be 329 1040 7349 fi chmod 644 areuh/linker/lutil.c echo x - areuh/linker/lpass.c cat >areuh/linker/lpass.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "lglobal.h" extern void add_label (), add_unres () ; extern long int calc_expression () ; extern uchar *memoire () ; /****************************************************************************** PASS1 synopsis : pass1 () description : processes the first pass on the object files. Open each file, read part one (code) and two (public label definitions), and close it. ******************************************************************************/ pass1 () { tmodule [1].m_ad = (saddr) 0 ; for (file=1; file<=nfile; file++) ps_part12 () ; /* still undefined labels ? */ file = nfile + 1 ; add_label ("=FiLeNd", tmodule[file].m_ad, 0) ; if (head_unres) pass1_bis () ; /* yes, try to resolve */ } /****************************************************************************** PS_PART12 synopsis : ps_part12 () description : in first pass, process parts one and two of an object file, and store all necessary informations in tmodule array. name is the file name, i is the entry in tmodule array. ******************************************************************************/ ps_part12 () { FILE *fp ; uchar label [LBLLEN+2], def [MAXLEN+1], type ; saddr size, val ; long int part2, nl, magic ; int j, k ; if (!(fp = fopen (fname[file], RAO_MODE))) error (ERROPN, fname[file]) ; /* error opening file */ fgetl (magic, fp) ; if ((magic<AOF_MAGIC)||(magic>AO_MAGIC)) error (ERRNOA, fname[file]) ; /* not output of aas */ if (magic!=AO_MAGIC) error (ERRICV, fname[file]) ; /* incompatible version */ fgetl (part2, fp) ; fgetl (size, fp) ; /* length of code */ tmodule[file+1].m_ad = tmodule[file].m_ad + size ; fseek (fp, part2, 0) ; fgetl (tmodule[file].m_part3, fp) ; fgetl (nl, fp) ; if (ferror (fp)) error (ERRRD, fname [file]) ; for (j=1; j<=nl; j++) { k = 0 ; while ((label [k] = (uchar) fgetc (fp)) != '\n') k++ ; label [k] = EOL ; fgetl (val, fp) ; if (ferror (fp)) error (ERRRD, fname [file]) ; if (val<0L) { k = 0 ; while ((def [k] = (uchar) fgetc (fp)) != '\n') k++ ; def [k] = EOL ; val = calc_expression (def) ; } else { type = (uchar) getc (fp) ; switch (type) { case LABS : break ; case LREL : val += tmodule[file].m_ad ; break ; case LUDF : default : fprintf (stderr, "Internal error. Aie aie aie. LUDF\n") ; exit (1) ; } } if (val>=0L) add_label (label, val, 0) ; else add_unres (label, def) ; } if (fclose (fp)) error (ERRCLO, fname[file]) ; /* error closing file */ } /****************************************************************************** PASS1_BIS synopsis : pass1_bis () description : at the end of first pass, if still undefined labels, try to resolve all definitions. If not succesful, exit on error. ******************************************************************************/ pass1_bis () { struct unres *xdef ; saddr val ; passbis = 1 ; /* signal to error message driver */ while (head_unres) { file = head_unres->u_file ; val = calc_expression (head_unres->u_def) ; if (val<0) error (WRNURL, head_unres->u_label) ; /* unresolved label */ else add_label (head_unres->u_label, val, 0) ; xdef = head_unres ; head_unres = head_unres->u_next ; free ((char *) xdef->u_def) ; free ((char *) xdef) ; } passbis = 0 ; } /****************************************************************************** PASS2 synopsis : void pass2 () description : during pass two, we open each file, we read the code into a string variable properly dimensioned. Then, for each external reference usage, we store the proper value into the proper place (we hope so !). At last, we append the code to the final lex file. That's grehate. ******************************************************************************/ void pass2 () { FILE *fp ; uchar def [MAXLEN+1], *code ; int j ; long int size, bidon, nu, characteristic ; for (file=1; file<=nfile; file++) { fp = fopen (fname[file], RAO_MODE) ; if (!fp) error (ERROPN, fname[file]) ; fgetl (bidon, fp) ; fgetl (bidon, fp) ; fgetl (size, fp) ; code = memoire (size) ; fread ((char *) code, (int) size, 1, fp) ; fseek (fp, tmodule[file].m_part3, 0) ; fgetl (nu, fp) ; if (ferror (fp)) error (ERRRD, fname [file]) ; for (j=1; j<=nu; j++) { read_usage (&characteristic, def, fp) ; resolve_usage (characteristic, def, fp, code) ; } fwrite (code, (int) size, 1, fplex) ; free ((char *) code) ; if (ferror (fplex)) error (ERRWRT, flex) ; if (fclose (fp)) error (ERRCLO, fname[file]) ; } } @EOF set `wc -lwc <areuh/linker/lpass.c` if test $1$2$3 != 1997114979 then echo ERROR: wc results of areuh/linker/lpass.c are $* should be 199 711 4979 fi chmod 644 areuh/linker/lpass.c echo x - areuh/linker/lmain.c cat >areuh/linker/lmain.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "lglobal.h" saddr pc ; int nfile, file ; uchar flex [MAXLEN+1], flisting [MAXLEN+1] ; FILE *fplex ; struct module tmodule[MAXMOD] ; struct unres *head_unres ; struct symbol *h_label[256] ; uchar *code ; uchar *fname[MAXMOD+2] ; int page_size, cntlist, xref, passnb, errnb ; int passbis = 0 ; void prompt (), read_line (), make_name () ; extern uchar *memoire () ; main (argc, argv) int argc ; uchar *argv[] ; { int r = 0, c, i ; int errflg = 0 ; extern char *optarg ; extern int optind, opterr ; opterr = 0 ; xref = 0 ; page_size = 0 ; strcpy (flex, "") ; strcpy (flisting, "") ; fname[0] = memoire (sizeof(HP71EP)+1) ; strcpy (fname[0], HP71EP) ; nfile = 0 ; while ((c = getopt (argc, argv, "xa:Apl:o:")) != EOF) switch (c) { case 'x' : xref = 1 ; break ; case 'a' : strcpy (flisting, optarg) ; cntlist = 2 ; break ; case 'A' : cntlist = 1 ; break ; case 'p' : r++ ; break ; case 'l' : sscanf (optarg, "%d", &page_size) ; break ; case 'o' : strcpy (flex, optarg) ; break ; case '?' : errflg++ ; break ; } if ((r)||(argc==1)) prompt () ; if (errflg || ((optind==argc)&&(nfile==0))) error (ERRUSA, "") ; for (i=optind; i<argc; i++) make_name (nfile+i-optind+1, argv [i]) ; nfile += argc - optind ; if (*flex==EOL) strcpy (flex, "lex") ; if (page_size==0) page_size = 72 ; fname [nfile + 1] = memoire (sizeof("eof.ep")+1) ; strcpy (fname[nfile + 1], "eof.ep") ; init () ; pass1 () ; between () ; pass2 () ; term () ; exit (errnb) ; } /****************************************************************************** PROMPT synopsis : void prompt () description : if "-p" option is used, or if no parameters are passed to "ald", asks the user for missing arguments. ******************************************************************************/ void prompt () { uchar line [MAXLEN+1] ; do { printf ("Input module : ") ; read_line (stdin, line) ; if (*line) make_name (++nfile, line) ; } while (*line) ; if (*flex==EOL) { printf ("Object file : ") ; read_line (stdin, flex) ; } if (cntlist==0) { printf ("Listing file : ") ; read_line (stdin, flisting) ; if (*flisting) { cntlist = 2 ; xref = 1 ; } else cntlist = 0 ; } if (cntlist) { if (page_size==0) { printf ("Page length : ") ; read_line (stdin, line) ; sscanf (line, "%d", &page_size) ; } } } void read_line (fp, line) FILE *fp ; uchar *line ; { int c, i = -1 ; do { c = getc (fp) ; if (i<MAXLEN) line[++i] = c ; } while ((c!=EOF)&&(c!='\n')) ; line[i] = EOL ; if (ferror (fp)) error (ERRRD, "stdin") ; /* il se trouve que c'est stdin */ } /****************************************************************************** MAKE_NAME synopsis : void make_name (i, file) int i uchar *file description : parse file name, and store file name with proper extension in fname table. ******************************************************************************/ void make_name (i, file) int i ; uchar *file ; { uchar *pfile ; pfile = file ; while ((*pfile)&&(*pfile!='.')) pfile++ ; fname [i] = memoire (strlen(file) + ((*pfile) ? 1 : 4) ) ; strcpy (fname[i], file) ; if (!(*pfile)) strcat (fname[i], ".ao") ; } @EOF set `wc -lwc <areuh/linker/lmain.c` if test $1$2$3 != 1885714190 then echo ERROR: wc results of areuh/linker/lmain.c are $* should be 188 571 4190 fi chmod 644 areuh/linker/lmain.c exit 0
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:32:51 1990 # # This archive contains: # areuh/linker/llist.c areuh/linker/linit.c # areuh/linker/lglobal.h areuh/linker/lerror.c # areuh/linker/flag.h areuh/linker/ald.1 # areuh/linker/Makefile areuh/dump/adp.c # areuh/dump/common.h areuh/dump/err.h # areuh/dump/adp.1 areuh/dump/Makefile # areuh/doc/areuh.doc # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - areuh/linker/llist.c cat >areuh/linker/llist.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "lglobal.h" FILE *fd_l ; int l_line = 0, l_page = 1 ; void l_files (), l_xref () ; void l_init () { uchar dfl [MAXLEN+1] ; switch (cntlist) { case 0 : break ; case 1 : fd_l = stdout ; strcpy (flisting, "stdout") ; break ; case 2 : dfl_extension (dfl, "list", "al") ; look_obj (flisting, dfl) ; if (!(fd_l = fopen (flisting, "w"))) error (ERROPN, flisting) ; break ; } } void l_new_page (flag) int flag ; { if (!cntlist) return ; for (; l_line<page_size; l_line++) fprintf (fd_l, "\n") ; if (flag) { fprintf (fd_l,"AREUH LINKER V2.2 - Page %03d - File: %s\n", ++l_page, flex) ; fprintf (fd_l,"\n") ; l_line = 2 ; } if (ferror (fd_l)) error (ERRWRT, flisting) ; } void l_flush () { if (!cntlist) return ; l_new_page (0) ; if (cntlist==2) if (fclose (fd_l)) error (ERRCLO, flisting) ; } void l_print (line) uchar *line ; { if (!cntlist) { printf ("%s\n", line) ; return ; } if (l_line==page_size-6) l_new_page (1) ; fprintf (fd_l, "%s\n", line) ; l_line++ ; if (ferror (fd_l)) error (ERRWRT, flisting) ; } void report () { if (cntlist && errnb) l_new_page (1) ; if (xref) l_xref () ; if (cntlist && xref) l_new_page (1) ; if (cntlist) l_files () ; else if (xref && errnb) { printf ("Areuh linker : %03d errors", errnb) ; if (ferror (fd_l)) error (ERRWRT, flisting) ; } } void l_files () { uchar line[MAXLEN+1], start[MAXLEN+1], end[MAXLEN+1], length[MAXLEN+1] ; int i ; saddr val ; sprintf (line, "Output module : %s", flex) ; l_print (line) ; l_print ("") ; for (file=1; file<=nfile; file++) { sprintf (line, "Source module : %s", fname [file]) ; l_print (line) ; hex5 (start, tmodule[file].m_ad) ; val = (tmodule[file].m_ad==tmodule[file+1].m_ad) ? 0 : 1 ; hex5 (end, tmodule[file+1].m_ad - val) ; hex5 (length, tmodule[file+1].m_ad - tmodule[file].m_ad) ; sprintf (line, "%10sStart = %s, End = %s, Length = %s", "", start, end, length) ; l_print (line) ; l_print ("") ; } for (i=0; i<4; i++) l_print ("") ; strcpy (line, "Date : ") ; format_time (line+7) ; l_print (line) ; l_print ("") ; sprintf (line, "Errors : %03d", errnb) ; l_print (line) ; l_print ("") ; l_print ("") ; l_print ("Areuh Assembler/Linker V2.2, (c) P. David & J. Taillandier 1986 Paris, France") ; l_new_page (0) ; } void l_xref () { uchar line [MAXLEN+1], tmp [MAXLEN+1], rel [MAXLEN+1] ; uchar format [MAXLEN+1], xformat [MAXLEN+1] ; struct symbol *t ; struct xtable *x ; int i ; sprintf (format, "%%-%ds = %%s File : %%s", LBLLEN+1) ; sprintf (xformat, "%%%ds+ %%s (Rel %%s in %%s)", LBLLEN+11) ; for (i=0; i<=255; i++) { t = h_label [i]->s_next ; while (t) { if (!t->s_os) { hex5 (tmp, t->s_value) ; sprintf (line, format, t->s_name, tmp, fname[t->s_file]) ; l_print (line) ; x = t->s_xref ; while (x) { hex5 (tmp, tmodule[x->x_file].m_ad + x->x_pc) ; hex5 (rel, x->x_pc) ; sprintf (line, xformat, "", tmp, rel, fname[x->x_file]) ; l_print (line) ; x = x->x_next ; } } /* du if */ t = t->s_next ; } /* du while */ } /* du for */ } @EOF set `wc -lwc <areuh/linker/llist.c` if test $1$2$3 != 1675564008 then echo ERROR: wc results of areuh/linker/llist.c are $* should be 167 556 4008 fi chmod 644 areuh/linker/llist.c echo x - areuh/linker/linit.c cat >areuh/linker/linit.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "lglobal.h" extern void l_init () ; extern uchar *memoire () ; void free_mem () ; init() { struct symbol *s ; int i ; head_unres = (struct unres *) NULL ; s = (struct symbol *) memoire (256*sizeof(struct symbol)) ; for (i=0; i<256; i++) { strcpy (s->s_name, "") ; s->s_value = 0L ; s->s_file = 0 ; s->s_os = 1 ; s->s_xref = (struct xtable *) NULL ; s->s_next = (struct symbol *) NULL ; h_label [i] = s++ ; } l_init () ; file = errnb = passbis = 0 ; load_file (HP71EP) ; passnb = 1 ; } between () { long int magic = AL_MAGIC ; uchar dfl [MAXLEN+1] ; strcpy (dfl, "lex") ; look_obj (flex, dfl) ; if (!(fplex = fopen (flex, "w"))) error (ERROPN, flex) ; fwrite (&magic, sizeof (long int), 1, fplex) ; if (ferror (fplex)) error (flex) ; passnb = 2 ; } term () { if (fclose (fplex)) error (ERRCLO, flex) ; if (cntlist || xref) report () ; l_flush () ; free_mem () ; } void free_mem () { struct symbol *s1, *s2 ; struct xtable *x1, *x2 ; int i ; for (i=0; i<=255; i++) { s1 = h_label[i]->s_next ; while (s1) { if (xref) { x1 = s1->s_xref ; while (x1) { x2 = x1->x_next ; free ((char *) x1) ; x1 = x2 ; } } s2 = s1->s_next ; free ((char *) s1) ; s1 = s2 ; } } free ((char *) h_label [0]) ; for (i=0; i<=nfile+1; i++) free ((char *) fname [i]) ; } @EOF set `wc -lwc <areuh/linker/linit.c` if test $1$2$3 != 993011925 then echo ERROR: wc results of areuh/linker/linit.c are $* should be 99 301 1925 fi chmod 644 areuh/linker/linit.c echo x - areuh/linker/lglobal.h cat >areuh/linker/lglobal.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "common.h" #define fgetl(lg,fp) fread(&(lg),sizeof(long int),1,fp) /****************************************************************************** MODULE TABLE ******************************************************************************/ #define MAXMOD 80 /* maximum number of modules */ struct module /* module descriptor */ { long int m_part3 ; /* address of utilisations part */ saddr m_ad ; /* Saturn address of start of code */ } ; extern struct module tmodule [] ; /* module descriptors table */ /****************************************************************************** UNRESOLVED LABELS LIST ******************************************************************************/ struct unres /* unresolved label element */ { uchar u_label [LBLLEN+2] ; /* label name (with leading '=') */ uchar u_file ; /* file where declared */ uchar *u_def ; /* definition address */ struct unres *u_next ; /* next element */ } ; extern struct unres *head_unres ; /* unresolved label list */ /****************************************************************************** CROSS-REFERENCE LIST ******************************************************************************/ struct xtable { saddr x_pc ; /* relative addr. where symb. is used */ uchar x_file ; /* file where symbol is used */ struct xtable *x_next ; /* link */ } ; /****************************************************************************** LABEL TABLE ******************************************************************************/ struct symbol { uchar s_name [LBLLEN+2] ; /* label name */ saddr s_value ; /* label value */ uchar s_file ; /* last file where label is declared */ uchar s_os ; /* 1 is O.S. entry point not used */ struct xtable *s_xref ; /* head of xref list */ struct symbol *s_next ; /* next label */ } ; extern struct symbol *h_label [] ; /* pseudo-hash table */ /****************************************************************************** CODE ******************************************************************************/ extern uchar *code ; extern uchar *fname[] ; extern uchar flex [], flisting [] ; extern FILE *fplex ; extern saddr pc ; extern nfile, file ; extern int cntlist, page_size, xref, passnb, errnb, passbis ; extern uchar hp71ep [] ; @EOF set `wc -lwc <areuh/linker/lglobal.h` if test $1$2$3 != 893152897 then echo ERROR: wc results of areuh/linker/lglobal.h are $* should be 89 315 2897 fi chmod 644 areuh/linker/lglobal.h echo x - areuh/linker/lerror.c cat >areuh/linker/lerror.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH LINKER ERROR PROCESSING error ******************************************************************************/ #include "lglobal.h" /****************************************************************************** ERROR synopsis : void error (errno, msg) int errno char *msg descritpion : reports an error message on listing file, if any, else on standard output. ******************************************************************************/ void error (errno, msg) int errno ; uchar *msg ; { uchar txt[MAXLEN+1], tmp[MAXLEN+1]; switch (errno) { case ERROPN : sprintf (txt, "system error opening file %s", msg) ; break ; case ERRCLO : sprintf (txt, "system error closing file %s", msg) ; break ; case ERRWRT : sprintf (txt, "system error writing file %s", msg) ; break ; case ERRRD : sprintf (txt, "system error reading file %s", msg) ; break ; case ERRMEM : strcpy (txt, "not enough memory"); break ; case ERRUSA : strcpy (txt, "usage: ald [-p] [-l n] [-A] [-a file]") ; strcat (txt, " [-o object_file] file1 file2..filen") ; break ; case ERRICV : sprintf (txt, "incompatible version of file %s", fname[file]) ; break ; case ERRNOA : sprintf (txt, "file %s not an output from aas", fname[file]) ; break ; case WRNDUP : sprintf (txt, "duplicate label %s", msg) ; break ; case WRNURF : hex5 (tmp, pc) ; sprintf (txt, "unresolved reference at %s in file %s : %s", tmp, fname[file], msg) ; break ; case WRNURL : sprintf (txt, "unresolved label %s in file %s", msg, fname[file]) ; break ; case WRNEXP : strcpy (txt, "illegal expression"); break ; case WRNASC : strcpy (txt, "illegal ascii constant"); break ; case WRNPAR : strcpy (txt, "mismatched parenthesis"); break ; case WRNIHX : strcpy (txt, "illegal hexadecimal constant"); break ; case WRNNUL : strcpy (txt, "null divisor"); break ; case WRNIXP : strcpy (txt, "illegal exponentiation") ; break ; case WRNIBC : strcpy (txt, "illegal binary constant") ; break ; case WRNJVL : hex5 (tmp, pc) ; sprintf (txt, "jump or value too large at %s in file %s : %s", tmp, fname[file], msg) ; break ; } if (errno<0) { fprintf (stderr, "ald: %s\n", txt) ; exit (errno) ; } else { errnb++ ; if (! ((passnb==1)&&(!passbis)&&(errno==WRNURL)) ) l_print (txt) ; } } /* end of "error()" */ @EOF set `wc -lwc <areuh/linker/lerror.c` if test $1$2$3 != 1233933481 then echo ERROR: wc results of areuh/linker/lerror.c are $* should be 123 393 3481 fi chmod 644 areuh/linker/lerror.c echo x - areuh/linker/flag.h cat >areuh/linker/flag.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************/ /* !!! CONTENTS OF THIS FILE MUST BE DIFFERENT FOR ASSEMBLER AND LINKER !!! */ /****************************************************************************/ #define ASSEMBLER 0 #define LINKER 1 @EOF set `wc -lwc <areuh/linker/flag.h` if test $1$2$3 != 1663507 then echo ERROR: wc results of areuh/linker/flag.h are $* should be 16 63 507 fi chmod 644 areuh/linker/flag.h echo x - areuh/linker/ald.1 cat >areuh/linker/ald.1 <<'@EOF' .TH ALD 1L .SH NAME ald \- areuh link editor .SH SYNOPSIS .B ald [ .B -p ] [ .B -l .I page length ] [ .B -A ] [ .B -a .I listing file ] [ .B -x ] [ .B -o .I object file ] [ file1 ... filen ] .SH DESCRIPTION .I Ald est le cross-link-editor pour le HP-71, qui prend un ou des fichiers intermediaires, les fusionne et place dans le fichier objet un fichier pret a etre transmis au HP-71 (voir .IR cp71 (1L)). .PP Les options sont : .TP 17 .B -p Utilisation interactive : demande les noms des fichiers au clavier. Option par defaut lorsqu'il n'y a aucun parametre. .TP .BI -l " page length" La longueur des pages du .I listing file est fixee a .I page length lignes (72 par defaut). .TP .B -A Genere un listing d'edition avec table des symboles. Le listing est envoye sur la sortie standard. .TP .BI -a " listing file" Genere un listing d'edition dans le fichier .IR "listing file" . .TP .I -x Genere dans le .I listing file une table des references croisees, indiquant pour chaque symbole sa valeur et les offsets dans les fichiers des instructions y faisant reference. .TP .BI -o " object file" Place le code objet dans le fichier specifie .RB ( lex par defaut) .SH AUTHORS Pierre David Janick Taillandier .SH SEE ALSO aas(1L), adp(1L), amg(1L), cp71(1L). .br .I "IDS vol I" for HP-71. @EOF set `wc -lwc <areuh/linker/ald.1` if test $1$2$3 != 712461284 then echo ERROR: wc results of areuh/linker/ald.1 are $* should be 71 246 1284 fi chmod 644 areuh/linker/ald.1 echo x - areuh/linker/Makefile cat >areuh/linker/Makefile <<'@EOF' # # Makefile genere automatiquement par mkmf (le masque par defaut a ete adapte) # CFLAGS = -O LDFLAGS = LIBS = SYSLIBS = BINDEST = /usr/local/bin # # S'il y a plus d'un programme, il faut aussi remplacer la cible # $(PROGRAM) par autant de cibles que necessaire. # PROGRAM = ald SRCS = exp.c \ lerror.c \ linit.c \ llist.c \ lmain.c \ lpass.c \ lutil.c \ mdep.c HDRS = common.h \ err.h \ flag.h \ lglobal.h EXTHDRS = /usr/include/stdio.h \ /usr/include/sys/stat.h \ /usr/include/sys/types.h OBJS = exp.o \ lerror.o \ linit.o \ llist.o \ lmain.o \ lpass.o \ lutil.o \ mdep.o MANDEST = /usr/local/man/man1.Z MANPAGES = ald.1 # # Les cibles : # all : compiler tout # clean : effacer les .o et les core # clobber : effacer tout ce qui peut etre regenere # depend : recalculer toutes les dependances et les inserer ici # install : installe le programme dans l'aborescence # tags : cree les tags # all: $(PROGRAM) $(PROGRAM): $(OBJS) $(LIBS) cc $(LDFLAGS) $(OBJS) $(LIBS) $(SYSLIBS) -o $(PROGRAM) clean:; rm -f $(OBJS) core clobber:; rm -f $(OBJS) $(PROGRAM) core tags depend:; mkmf ROOT=$(ROOT) install: $(PROGRAM) -strip $(PROGRAM) if [ $(BINDEST) != . ] ; \ then \ (cd $(BINDEST) ; rm -f $(PROGRAM)) ; \ cp $(PROGRAM) $(BINDEST) ; \ if [ "$(MANPAGES)" != none ] ; \ then \ (cd $(MANDEST) ; rm -f $(MANPAGES)) ; \ for i in $(MANPAGES) ; \ do \ compress < $$i > $(MANDEST)/$$i ; \ done ; \ fi ; \ fi tags: $(HDRS) $(SRCS) ctags $(HDRS) $(SRCS) # # Dependances calculees automatiquement par mkmf. # Ne rien changer apres cette ligne ! # ### exp.o: flag.h lglobal.h common.h /usr/include/stdio.h err.h lerror.o: lglobal.h common.h /usr/include/stdio.h err.h linit.o: lglobal.h common.h /usr/include/stdio.h err.h llist.o: lglobal.h common.h /usr/include/stdio.h err.h lmain.o: lglobal.h common.h /usr/include/stdio.h err.h lpass.o: lglobal.h common.h /usr/include/stdio.h err.h lutil.o: lglobal.h common.h /usr/include/stdio.h err.h mdep.o: flag.h lglobal.h common.h /usr/include/stdio.h err.h \ /usr/include/sys/types.h /usr/include/sys/stat.h @EOF set `wc -lwc <areuh/linker/Makefile` if test $1$2$3 != 1023262244 then echo ERROR: wc results of areuh/linker/Makefile are $* should be 102 326 2244 fi chmod 644 areuh/linker/Makefile echo x - areuh/dump/adp.c cat >areuh/dump/adp.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "common.h" #define fgetl(lg,fp) fread(&(lg),sizeof(long int),1,fp) main (argc, argv) int argc ; char *argv[] ; { FILE *fp ; uchar line [MAXLEN + 1], hexvar[MAXLEN+1], type ; saddr magic, pc, p2, p3, nu, nl, i, j, characteristic, value ; if (argc!=2) { fprintf (stderr, "usage: adp file\n") ; exit (1) ; } fp = fopen (argv[1], RAO_MODE) ; if (fp==NULL) { fprintf (stderr, "adp: error opening %s\n", argv[1]) ; exit (1) ; } printf ("file %s : ", argv[1]) ; fgetl (magic, fp) ; if ((magic<AOF_MAGIC)||(magic>AO_MAGIC)) { fprintf (stderr, "adp: %s is not an Areuh object file\n", argv [1]) ; exit (1) ; } printf ("version %d\n", magic - AOF_MAGIC) ; if (magic!=AO_MAGIC) { fprintf (stderr, "Wrong version\n") ; exit (1) ; } fgetl (p2, fp) ; fgetl (pc, fp) ; printf ("code: length (in nibbles) = %ld\n", pc) ; fseek (fp, p2, 0) ; fgetl (p3, fp) ; fgetl (nl, fp) ; printf ("public definitions : number = %ld\n", nl) ; for (i=1; i<=nl; i++) { printf ("%4d:", i) ; j = 0 ; while ((line [j] = (uchar) getc (fp)) != '\n') j++ ; line [j]= EOL ; printf (" %-13s, val = ", line) ; /* LBLLEN + 1 */ fgetl (value, fp) ; if (value >= (saddr) 0) { hex5 (hexvar, value) ; printf ("%s, ", hexvar) ; type = getc (fp) ; switch (type) { case LABS : printf ("Abs") ; break ; case LREL : printf ("Rel") ; break ; case LUDF : printf ("Udf") ; break ; default : printf ("Type aie aie aie") ; break ; } } else if (value == LBL_UDF) { printf ("-UDF-") ; } else if (value == LBL_IVL) { printf ("-IVL-") ; } else if (value == LBL_EXT) { printf ("-EXT-") ; } else if (value == LBL_XEQ) { printf ("-XEQ-") ; fscanf (fp, "%s\n", line) ; printf (", definition = %s", line) ; } else /* (value == LBL_SEQ) */ { printf ("-SEQ-") ; } printf ("\n") ; } fgetl (nu, fp) ; printf ("references not resolved: number = %d\n", nu) ; for (i=1; i<=nu; i++) { fgetl (characteristic, fp) ; fgetl (pc, fp) ; fscanf (fp, "%s\n", line) ; printf ("%4d:", i) ; hex5 (hexvar, pc) ; printf (" pc = %s", hexvar) ; printf (", type = ") ; switch ((int) (characteristic & 0xf0)) { case XABSL : printf ("XABSL") ; break ; case XABSO : printf ("XABSO") ; break ; case XRGTO : printf ("XRGTO") ; break ; case XRGSB : printf ("XRGSB") ; break ; } printf (", length = %1d", characteristic & 0xf) ; printf (", val = %s\n", line) ; } } /* function called indirectly, via hex5 */ format_hex (str, val, dig) uchar *str ; saddr val ; int dig ; { register int i, h ; for (i=dig-1; i>=0; i--) { h = (int) (val & ((saddr) 0xf)) ; str [i] = h + ((h < 10) ? '0' : 'A' - 10) ; val >>= 4 ; } str [dig] = EOL ; } @EOF set `wc -lwc <areuh/dump/adp.c` if test $1$2$3 != 1465473093 then echo ERROR: wc results of areuh/dump/adp.c are $* should be 146 547 3093 fi chmod 644 areuh/dump/adp.c echo x - areuh/dump/common.h cat >areuh/dump/common.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include <stdio.h> #define MAXLEN 256 #define EOL '\0' #define LBLLEN 12 /****************************************************************************** TYPE DEFINITIONS ******************************************************************************/ typedef long int saddr ; /* Saturne address. At least 32 bits */ typedef unsigned char uchar ; /* unsigned characters, for accents */ typedef short int sint ; /* 16 bits */ /****************************************************************************** MAGIC NUMBERS ******************************************************************************/ #define AL_MAGIC 0x1b080100 /* ... areuh_lex */ #define AO_MAGIC 0x1b0d0100 /* ... areuh_output of assembler */ #define ALF_MAGIC 0x1b080100 /* first version of object file format */ #define AOF_MAGIC 0x1b0d0100 /* first version of object file format */ /****************************************************************************** USAGE TYPES IN .ao FILES ******************************************************************************/ #define XABSL 0x10 /* absolute reference */ #define XABSO 0x20 /* absolute reference, with one bias */ #define XRGTO 0x40 /* relative reference, goto type */ #define XRGSB 0x80 /* relative reference, gosub type */ /****************************************************************************** LABEL VALUES IN .ao FILES ******************************************************************************/ #define LBL_UDF -1L /* label not declared (implicit or explicit) <=> only used */ #define LBL_IVL -2L /* invalid label (invalid expression for an EQU during pass one) */ #define LBL_EXT -3L /* external label not defined here (or yet) */ #define LBL_XEQ -4L /* global label which is defined here, with an external reference */ #define LBL_SEQ -5L /* local label which is defined with an external reference */ /****************************************************************************** LABEL TYPES IN .ao FILES ******************************************************************************/ #define LUDF 0 /* undefined type (external label) */ #define LABS 1 /* absolute local label (declared explicitly, with constants) */ #define LREL 2 /* relative local label (declared implicitly, or explicitly with at least one relative) */ /****************************************************************************** VALUES RETURNED BY EXPRESSION EVALUATOR ******************************************************************************/ #define EXP_ERR -1L #define EXP_EXT -2L extern int relabs ; extern uchar extexp[] ; #include "err.h" extern void error () ; #define hex5(str,val) format_hex (str, val, 5) ; #define hex6(str,val) format_hex (str, val, 6) ; /****************************************************************************** MACHINE DEPENDANCIES ******************************************************************************/ #define HPUX 1 #define ATARI_LATTICE 0 #define PC_MSC 0 /* PC (beuark, Microsoft C) */ #if HPUX extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "r" #define WAO_MODE "w" #define skip(fp) #endif #if ATARI_LATTICE extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "rb" #define WAO_MODE "wb" extern char skipvar ; #define skip(fp) fread(&skipvar,1,1,fp) ; #endif #if PC_MSC extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "rb" #define WAO_MODE "wb" extern char skipvar ; #define skip(fp) fread(&skipvar,1,1,fp) ; #endif @EOF set `wc -lwc <areuh/dump/common.h` if test $1$2$3 != 1244243878 then echo ERROR: wc results of areuh/dump/common.h are $* should be 124 424 3878 fi chmod 644 areuh/dump/common.h echo x - areuh/dump/err.h cat >areuh/dump/err.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER / LINKER ERROR NUMBERS DECLARATIONS ******************************************************************************/ /* FATAL ERRORS */ #define ERROPN -1 /* A L */ /* system error opening file */ #define ERRCLO -2 /* A L */ /* system error closing file */ #define ERRREW -3 /* A */ /* system error on file at start of pass two */ #define ERRWRT -4 /* A L */ /* system error writing file */ #define ERRRD -5 /* A L */ /* system error reading file */ #define ERRMEM -6 /* A L */ /* not enough memory */ #define ERRLEX -10 /* A */ /* invalid macro pseudo-op LEX or BIN */ #define ERRPGS -11 /* A */ /* invalid page size */ #define ERRFLN -12 /* A */ /* restricted label FiLeNd exists */ #define ERRIFL -13 /* A L */ /* invalid file name */ #define ERRIMO -14 /* A */ /* invalid macro-op xx in modular assembling */ #define ERRVMD -15 /* A */ /* value must be defined for xx */ #define ERRUSA -20 /* A L */ /* usage: ass [ [-l] source_file ] */ /* usage: ald ... */ #define ERRNOA -30 /* L */ /* file not output from aas */ #define ERRICV -31 /* L */ /* incompatible version */ /* NON FATAL ERRORS */ #define WRNEQU 10 /* A */ /* cannot resolve equate */ #define WRNDUP 11 /* A L */ /* duplicate label */ #define WRNLBL 12 /* A */ /* illegal label */ #define WRNULB 13 /* A */ /* unrecognized label */ #define WRNURF 14 /* L */ /* unresolved reference */ #define WRNURL 15 /* L */ /* unresolved label */ #define WRNEXP 20 /* A */ /* illegal expression */ #define WRNASC 21 /* A */ /* illegal ascii constant */ #define WRNPAR 22 /* A */ /* mismatched parenthesis */ #define WRNIHX 23 /* A */ /* illegal hexadecimal constant */ #define WRNNUL 24 /* A */ /* null divisor */ #define WRNIXP 25 /* A */ /* illegal exponentiation */ #define WRNIBC 26 /* A */ /* illegal binary constant */ #define WRNENA 27 /* A */ /* external references not allowed */ #define WRNYES 30 /* A */ /* GOYES or RTNYES required */ #define WRNIDP 31 /* A */ /* illegal dp arithmetic value */ #define WRNIPP 32 /* A */ /* illegal pointer position */ #define WRNISB 33 /* A */ /* illegal status bit */ #define WRNTFR 34 /* A */ /* illegal transfer value */ #define WRNIWS 35 /* A */ /* illegal word select */ #define WRNLST 36 /* A */ /* invalid LIST argument */ #define WRNJVL 37 /* A L */ /* jump or value too large */ #define WRNMLB 38 /* A */ /* missing label */ #define WRNTST 39 /* A */ /* needs previous test instruction */ #define WRNNHX 40 /* A */ /* non hexadecimal digits present */ #define WRNTMA 41 /* A */ /* too many ascii characters present */ #define WRNTMH 42 /* A */ /* too many hexadecimal digits present */ #define WRNOPC 43 /* A */ /* unknown opcode */ #define WRNIIF 50 /* A */ /* invalid conditional structure */ extern void error() ; @EOF set `wc -lwc <areuh/dump/err.h` if test $1$2$3 != 1275845010 then echo ERROR: wc results of areuh/dump/err.h are $* should be 127 584 5010 fi chmod 644 areuh/dump/err.h echo x - areuh/dump/adp.1 cat >areuh/dump/adp.1 <<'@EOF' .TH ADP 1L .SH NAME adp \- areuh intermediate file dump .SH SYNOPSIS .B adp file .SH DESCRIPTION .I Adp affiche des informations sur le fichier intermediaire specifie. En particulier, .B adp affiche la taille du code, les symboles externes definis dans ce fichier, ainsi que les expressions n'ayant pas pu etre resolues a l'assemblage. .PP .B Adp a ete developpe pour des besoins internes et ne doit normalement pas etre utilise. .SH AUTHORS Pierre David Janick Taillandier .SH SEE ALSO aas(1L), ald(1L), amg(1L), cp71(1L). .br .I "IDS vol I" for HP-71. @EOF set `wc -lwc <areuh/dump/adp.1` if test $1$2$3 != 3092554 then echo ERROR: wc results of areuh/dump/adp.1 are $* should be 30 92 554 fi chmod 644 areuh/dump/adp.1 echo x - areuh/dump/Makefile cat >areuh/dump/Makefile <<'@EOF' # # Makefile genere automatiquement par mkmf (le masque par defaut a ete adapte) # CFLAGS = -O LDFLAGS = LIBS = SYSLIBS = BINDEST = /usr/local/bin # # S'il y a plus d'un programme, il faut aussi remplacer la cible # $(PROGRAM) par autant de cibles que necessaire. # PROGRAM = adp SRCS = adp.c HDRS = common.h \ err.h EXTHDRS = /usr/include/stdio.h OBJS = adp.o MANDEST = /usr/local/man/man1.Z MANPAGES = adp.1 # # Les cibles : # all : compiler tout # clean : effacer les .o et les core # clobber : effacer tout ce qui peut etre regenere # depend : recalculer toutes les dependances et les inserer ici # install : installe le programme dans l'aborescence # tags : cree les tags # all: $(PROGRAM) $(PROGRAM): $(OBJS) $(LIBS) cc $(LDFLAGS) $(OBJS) $(LIBS) $(SYSLIBS) -o $(PROGRAM) clean:; rm -f $(OBJS) core clobber:; rm -f $(OBJS) $(PROGRAM) core tags depend:; mkmf ROOT=$(ROOT) install: $(PROGRAM) -strip $(PROGRAM) if [ $(BINDEST) != . ] ; \ then \ (cd $(BINDEST) ; rm -f $(PROGRAM)) ; \ cp $(PROGRAM) $(BINDEST) ; \ if [ "$(MANPAGES)" != none ] ; \ then \ (cd $(MANDEST) ; rm -f $(MANPAGES)) ; \ for i in $(MANPAGES) ; \ do \ compress < $$i > $(MANDEST)/$$i ; \ done ; \ fi ; \ fi tags: $(HDRS) $(SRCS) ctags $(HDRS) $(SRCS) # # Dependances calculees automatiquement par mkmf. # Ne rien changer apres cette ligne ! # ### adp.o: common.h /usr/include/stdio.h err.h @EOF set `wc -lwc <areuh/dump/Makefile` if test $1$2$3 != 762491533 then echo ERROR: wc results of areuh/dump/Makefile are $* should be 76 249 1533 fi chmod 644 areuh/dump/Makefile echo x - areuh/doc/areuh.doc sed 's/^@//' >areuh/doc/areuh.doc <<'@EOF' ASSEMBLEUR / EDITEUR DE LIENS POUR LE HP71 I - PRINCIPE A: Presentation Le systeme de developpement pour HP71 que nous presentons ici est base sur un assembleur et un editeur de liens ecrits en Langage C. Ce systeme fonctionne a l'heure actuelle sur des ordinateurs differents : - Les ordinateurs fonctionnant sous systeme HP-UX en particulier, et sous systeme Unix en general. - les ordinateurs Atari 520 et 1040 ST sous systeme d'exploitation TOS. - une adaptation est en cours pour l'ordinateur HP Vectra et autres IBM PC sous systeme MS-DOS. Tous nos efforts se sont portes vers la reduction des temps d'assemblage. Voir les temps d'execution donnes en exemple pour plus de details. B: Introduction a l'assembleur L'assembleur a deux modes de fonctionnement : Le mode "assemblage complet", qui permet d'avoir la compatibilite avec le "machin" (l'assembleur du module Forth). En particulier, toutes les macro-operations de generation de fichiers lex ou bin sont supportees. Le mode "assemblage separe" permet de se rapprocher des conditions de travail de l'equipe de developpement du HP71 aux laboratoires de Corvallis (OR 97330) en autorisant l'assemblage de modules separes, et leur reunion en seul fichier par l'intermediaire de l'editeur de liens. C: Avantages et inconvenients Parmi les nombreux avantages que procure ce systeme, nous pouvons citer : Utilisation des points d'entree HP sans avoir a les declarer explicitement par une operation du type EQU. Edition d'une table des references croisees donnant pour chaque symbole le nom, la valeur, la ligne ou il est declare et les lignes ou il est utilise. Introduction de nouveaux operateurs dans les expressions, et possibilite d'introduire des valeurs en binaire. Les noms des labels sont maintenant significatifs sur 12 caracteres. Quant aux inconvenients, il manque les pseudo-operations FORTH, WORD et WORDI. Et, bien sur, il faut un "gros" ordinateur. D: Principe de l'assemblage separe L'assemblage d'un fichier en modules separes se fait en deux phases. IL faut d'abord assembler tous les fichiers (modules) constituant le source. Ensuite, il faut proceder a l'edition de liens, qui rassemble ces modules en un seul fichier. Si il s'avere necessaire de modifier une partie du texte source, il suffit seulement de re-assembler le module contenant ce texte, et de refaire l'edition de liens. Le gain de temps est enorme. Cette gestion modulaire permet egalement un traitement plus efficace des labels. Un module peut appeler une routine ecrite dans un autre module a partir du moment ou le label est precede d'un signe '=' dans les modules concernes. Ceci a pour role de declarer le label externe (dans le module appelant) ou public (dans le module ou le label est declare) et accessible a tous. Ce sont les labels globaux. A cette categorie s'ajoute celle des labels locaux. Ils ne comportent pas de signe '=', et des modules peuvent avoir des labels portant le meme nom. Ceci permet d'avoir, par exemple, plusieurs labels "argerr" dans des modules differents, sans causer le moindre conflit. C'est le meme systeme que celui employe par HP, et decrit dans les IDS Vol. I (ch. 16). Seul ce systeme permet le developpement de grands programmes en assembleur. II - DIFFERENCES AVEC LE "MACHIN" A: Selection du mode La selection du mode d'assemblage (complet ou separe) est faite par la presence de la macro LEX ou BIN en premiere ligne du fichier source. B: Majuscules / Minuscules Mis a part les labels, tous les op-codes et toutes les expressions sont compris aussi bien en majuscules qu'en minuscules. C: Macro-operation interdites En assemblage separe, les pseudo-operations de generation de fichiers LEX ou BIN sont interdites. Ainsi, LEX, ID, MSG, POLL, ENTRY, CHAR, TOKEN, KEY, ENDTXT, BIN et CHAIN sont interdites hors d'un assemblage complet. On exerce ainsi un controle plus precis sur la generation du code. Par ailleurs, les macro FORTH, WORD et WORDI sont interdites. Seule la premiere utilisation de TITLE est prise en compte. D: Macro-operations ajoutees En premier lieu, il y a RDSYMB (ReaD SYMBols). Elle permet de charger un fichier contenant des points d'entree sans avoir a attendre l'edition de liens. Par exemple, en assemblage complet, ceci permet d'avoir les points d'entree supportes par HP (fichier "hp71.ep"). La syntaxe est : RDSYMB <fichier> Ensuite, nous avons l'assemblage conditionnel. Par exemple, si nous avons : AREUH EQU 1 IF AREUH P=P+1 RTN ELSE ASRB C+P+1 ENDIF Seul le code P=P+1 et RTN sera assemble. Inversement, si AREUH avait ete declare avec une valeur nulle, le code ASRB et C+P+1 aurait ete assemble. Ceci permet de gerer simplement des versions differents d'un meme programme (versions de mise au point). Attention cependant : il ne peut y avoir imbrication d'une telle structure conditionnelle. E: Opcodes ajoutes D0=HEX et D1=HEX (presents, mais non documentes dans le "machin") fonctionnent a merveille. LC(6) et CON(6) (utilises par HP) sont presents. F: Valeurs numeriques Les valeurs numeriques calculees dans les expressions, ou renvoyees par des labels comportent six chiffres hexadecimaux et non cinq comme dans le "machin". Comme dans les IDS. En revanche, les valeurs affichees dans les tables de symboles le sont sur cinq chiffres seulement. Cette limitation ne concerne que l'affichage et non le stockage interne. Ceci est conforme a l'affichage fourni par l'assembleur des IDS, et a ete conserve en raison de l'habitude acquise a la lecture des adresses du HP71. G: Les Expressions Les expressions peuvent contenir des labels, la valeur du compteur ordinal (PC), des constantes et des operateurs. Il n'y a pas de limitation du niveau d'imbrication des parentheses. Maintenant, les labels sont significatifs sur 12 caracteres. Le symbole '*' (en position d'operande) est considere comme la valeur du compteur ordinal. Dans le cas d'une compilation separee, cette valeur est la valeur reelle, tenant compte de la position du module dans le fichier complet. Les constantes de valeur superieure a six chiffres hexadecimaux sont tronquees. Les constantes Ascii sont delimitees soit par des apostrophes ('), soit par des anti-slash (\). Un nouveau type de constante est ajoutee : les constantes binaires. Elles doivent etre precedees d'un signe '%', comme dans : %01110001 Les operateurs : nous en donnons la liste complete, par ordre de priorite decroissante. Les operateurs de meme priorite sont evalues de gauche a droite. @~ (*256+) ^ (puissance) - (moins unaire) ` (complement a 1) & (et logique) ! (ou logique) * (multiplication) / (division entiere) + (addition) - (soustraction) H: FiLeNd Le label FiLeNd est ajoute systematiquement a la fin de chaque fichier ou module assemble. En outre, le label global "=FiLeNd" est ajoute automatiquement en fin de fichier lors de l'edition de liens pour l'assemblage separe. III - MODE D'EMPLOI DES PROGRAMMES Les deux programmes "aas" et "ald" admettent les memes options. -o Specifie le nom du fichier resultant de l'assemblage ou de l'edition de liens. -a <fichier> Demande l'impression d'un listing d'assemblage ou d'edition de liens. Le listing est envoye dans le fichier specifie. -A Demande l'impression d'un listing d'assemblage ou d'edition de liens. Le listing est envoye a l'affichage (ou stdout sur les systemes Unix). -l <longueur de page> Specifie la longueur physique des pages, en nombre de lignes. La longueur du texte sera inferieure de 6 lignes. -x Demande l'impression d'une table des references croisees. -p Active la saisie interactive des options decrites precedemment. Notons que ne donner aucun parametre active implicitement cette option. Pour aas, il faut ensuite fournir le nom du fichier source. Pour ald, il faut fournir les noms de tous les modules. Par defaut, le fichier genere a pour nom "lex". Les fichiers source ont ".as" comme suffixe (extension), et les fichiers intermediaires (entre l'assembleur et l'editeur de liens) ont ".ao" comme suffixe. En general, il n'est pas necessaire d'indiquer ces extensions. IV - EXEMPLES Assembler le fichier f1.as (qui commence par une macro LEX), et fichier assemble dans "lex" : aas f1 Assembler le fichier f1.as avec listing, references croisees dans le fichier "list", et fichier resultat dans "lex" : aas -xalist f1 aas -x -a list f1 Meme exemple que precedemment avec une longueur de page de 66 lignes (papier 11") : aas -xalist -l66 f1 Assembler le fichier f1.as, avec resultat dans "toto", avec parametrage interactif : aas puis entrer "f1" puis entrer "toto" puis entrer [RETURN] Les fichiers f1.as, f2.as et f3.as continennent le source d'un fichier lex. Assemblage des trois fichiers : aas f1 aas f2 aas f3 Edition de liens des fichiers f1, f2 et f3 (fi.ao pour i=1..3), avec demande d'un listing et d'une table des references croisees dans le fichier "list", et fichier assemble nomme "totolex". ald -xalist -ototolex f1 f2 f3 Pierre David (PC37, SIG1, CHHU616) Janick Taillandier (PC246, SIG6, CHHU178) @EOF set `wc -lwc <areuh/doc/areuh.doc` if test $1$2$3 != 36314359707 then echo ERROR: wc results of areuh/doc/areuh.doc are $* should be 363 1435 9707 fi chmod 644 areuh/doc/areuh.doc exit 0
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:32:54 1990 # # This archive contains: # areuh/doc/readme.dos areuh/doc/compc.doc # areuh/doc/areuh110.doc # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - areuh/doc/readme.dos cat >areuh/doc/readme.dos <<'@EOF' HP-71 DEVELOPMENT SYSTEM NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR MMERCIAL DISTRIBUTION - NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR COMMERCIA ISTRIBUTION - NOT FOR COMMERCIAL DISTRIBUTION - NOT FOR COMMERCIAL DISTRIBU Notice : this is a public domain software. You are encouraged to make copies of it. Feel free to distribute it. The only restriction is that it cannot be distributed on a commercial basis. INTRODUCTION ------------ This disk contains the AREUH development system. It is intended to produce LEX or BIN files for the HP-71B, using a PC or compatible computer. This system includes an assembler, a linker, a message table generator, and miscellaneous useful tools. It is a sophisticated set of programs. They have been optimized for speed without compromising capabilities. The assembler is able to process source files either compatible with Forth / Assembler Rom or HP development system. It should be able to understand all source file formats. The linker is a convenient tool to develop large projects as well as small ones. The table message generator (like other tools) is very easy to use, and greatly simplify the creation of such tables. It was written by Pierre David and Janick Taillandier, from PPC-Paris. We are happy to thank Stephane Barizien for its efficient help for all MS-DOS problems. As described above, you are welcome to copy and distribute it free. We hope it will help HP-71 software development. It is our common interest. It was used by the authors to develop : - JPCROM (19+ KB Lex file, 461 KB source files, assembled in 2.20 minutes) JPCROM is the PPC-Paris LEX file, including 100 various keywords. - GRAPHIC (9 KB Lex file, 290 KB source files, assembled in 1.15 minutes) GRAPHIC is a commercial product, providing graphic capabilities similar to HP-85, HP-41, HP-200 graphic languages on a ThinkJet (MOVE, DRAW, LABEL...). I - HISTORY ----------- The AREUH development system (AREUH stands for Assembleur Relogeable En Utilisation Heuristique) was developed from April to August 1986 on a UNIX machine : the HP Integral Personal Computer. Unfortunately, many people are now using PC or compatible. So, in July 1987, we have decided to adapt AREUH to these so called computers. The process was rather hard for us : we had to find a PC, a C compiler, an HPIL card, etc. We also had a lot of difficulties with the surprising C compiler implementation, as well as with the numerous but powerless text editors... We have no personal interest in this MS-DOS version. It was a tough job to get it work, and we get no profit from it. This was done to allow all HP-71 developers to benefit from our tool and stop using archaic ones, and we hope to see more HP-71 software. We wish this could help. We hope the time we have spent on this project will not be a wasted time. We would appreciate receiving feed-back from you. It would also be nice to mention that your software has been developed with this assembler. II - WHY A LINKER ? ------------------- If you take a look at the IDS Vol. III, or HPIL IDS, you may notice that HP used a linker. Other large projects, such as JPCROM or GRAPHIC have been using a linker. Using a linker allows splitting a large problem into small, manageable units : you have only small files to edit and assemble. You divide your problem into functional units, with clear interfaces. You work on one module at a time, you don't have to take care of the others. Incidentally, you spare time because you have only one module to assemble, and you have small convenient facilities, such as local labels known only inside the module, and global ones known everywhere. III - PRINCIPLE --------------- A : THE TWO MODES ----------------- The assembler has two operating modes : - compatibility mode - modular mode The first one is intended to assemble all source files written for the Assembler Rom. All macro-operations such as LEX, BIN, CHAIN... are supported. No linkage step is needed. The second one is similar to the description given in IDS Vol. I, chapter 16. In fact, it has more features than this one. This mode needs a linkage step, and supports local and global labels. A global label is preceded by an "=" character. To use the compatibility mode, the first line of the file must be a LEX or BIN macro-operation. Any other first line activates modular mode. If you wish to use system entry points in compatibility mode, you can use the RDSYMB macro-operation. It will read the specified file to load all supported entry points. You don't need any more to write long lists of EQU to use system entry points. In modular mode, everything is automatic. The system entry points addresses are loaded at link time. In both modes, you cannot use FORTH, WORD and WORDI macro-operations. In modular mode, you cannot use LEX, ID, MSG, POLL, ENTRY, CHAR, TOKEN, KEY, ENDTXT, BIN and CHAIN. B : LISTINGS ------------ You can output assembler or linker listings, with optional complete cross-reference section. For an example, see FINPUT listing in JPC43 (April 1987). C : ADDED FEATURES ------------------ Compared with the Assembler Rom, or HP's one, the following features have been added : - label names may have up to 12 significant characters (13 if they are preceded by an "=" symbol). - all opcodes and modifiers are not case sensitive. You can mix freely lower and upper case characters. Label names are always case sensitive. - conditional assembly is allowed, with macro-operation IF. The syntax is : IF <expression> <assembled if expression # 0> ELSE <assembled if expression = 0> ENDIF The ELSE part is optional. - the macro-operation RDSYMB (ReaD SYMBol) was implemented to load a file containing entry points. The syntax is : RDSYMB <filename> In this MS-DOS version, <filename> can be an absolute file reference (such as a:\lib\hp71.ep), or a relative one. In the last case, the file is looked for in specific locations. - D0=HEX and D1=HEX, undocumented and bugged opcodes in the Assembler Rom are present and unbugged ! - numerical values are processed on 6 hexadecimal digits (nibbles), as in HP's assembler. This allows providing LC(6) and CON(6) instructions. - litteral constants may be delimited either by ' (quote) or by \ (backslash) symbols. - there is no limit on parenthesis level. - a new constant type is supported : binary constants. They are used with a % symbol : for example : %01110001 = #71 = 113. - new operators have been added. They are ~ -> *256+ ^ -> power ` -> one's complement All operators are listed below, in descending order or precedence. ~ (*256+) ^ (power) - (unary minus) ` (one's complement) & (logical and) ! (logical or) * (multiplication) / (integer division) + (addition) - (binary subtraction) - FiLeNd label is automatically added at the end of each assembled file or module. In modular mode, a global label =FiLeNd is automatically added after the last module during link step. IV - USING THE PROGRAMS ----------------------- A : File naming conventions : ----------------------------- - source files have the ".as" (Areuh Source) extension, - object file resulting from assembly in modular mode have the ".ao" (Areuh Object) extension, - list files have the ".al" (Areuh List) extension, - message description files have the ".am" (Areuh Message) extension, - entry points files have the ".ep" (Entry Point) extension, - complete lex files (result of aas in compatibility mode or ald) are named "lex". These are suggested names. You can override them using full names. However, using them is easier. B : Assembler (aas) and Linker (ald) ------------------------------------ Both programs share the same options. -o <file> specifies the name of output file. If the specified name is a directory, the output file is written in this directory, using default name. -a <file> produces a listing in the specified file. If the specified name is a directory, the listing file is written in this directory, using default name. -A produces a listing on standard output. -l <page length> specifies the physical page length in number of lines (default is 72, for 12" paper). Text length is (page length - 6). -x asks for a cross-reference table. Should be used only when -a or -A options are specified. -p enables interactive options input. If no option or file name is specified after aas or ald, you automatically enter interactive prompt mode. After aas, you have to supply the source file names (wild card characters allowed). File names order is irrelevant. After ald, you have to supply the intermediate file names (wild card characters allowed). File names order is very important, it corresponds to the link order. The linker is limited to 80 files. As far as MS-DOS command lines are limited to a small numbers of characters, you may have difficulties to specify a full ald command. In this case, you can use interactive prompting : ald <answer where "answer" is a text file containing the answers to all questions. C : Message table generator (amg) --------------------------------- Amg reads on standard input a message table description, and writes on standard output an HP-71 message table, ready to be assembled. The message table description contains several lines with the following structure : <message label>:<message text> For example : =eDIRFL:Directory Full If you want to use building blocks, the building block text must be enclosed within square brackets, for example : =eUNEXP:Unexpected [Message ] [Message ] (with a white space) is a local building block. It will be created in the message table. Amg recognizes automatically mainframe building blocks. For example : =eBADMD:[Invalid ]Mode [Invalid ] (with a white space) is a mainframe building block. The message table will reference it without creating it. Messages are numbered from 0. If an argument is given, it must be a number, and messages will be numbered from it. Amg checks that there is a message whose total length is multiple of 16 nibbles, as requested by the HP-71 Operating System. Otherwise, an error is written in the generated file. D : Downloading to HP-71 : -------------------------- Two utilities are provided to download the assembled files to the HP-71. You can use either the RS232 interface or the HP82973 HPIL interface. RS232 : (program a2rs) ---------------------- The syntax is : a2rs [ <file> ] If no file name is specified, the default is "lex". For the connection, we have used the following cable : PC HP82164A RS232/HPIL 2 ----\ /---- 2 x 3 ----/ \---- 3 4 ----\ /---- 4 x 5 ----/ \---- 5 6 ----\ /---- 6 x 20 ----/ \---- 20 7 ----------- 7 The HP82164A must be configured from the HP-71 by : REMOTE @ OUTPUT :RS232;"LI5;C0" @ LOCAL before running a2rs, you have to enter on your HP-71 : COPY :RS232 HPIL : (program a2lex) ---------------------- Prior to transfer your assembled file, you must use a2lex to convert the file to the format needed by HPILLINK. The syntax is : a2lex [ <file> ] If no file name is specified, the default is "lex". The ".lex" extension is automatically appended to the converted file. Then, you can download using HPILLINK. CUSTOMIZING YOUR DOWNLOADING PROGRAM : (program a2?) ---------------------------------------------------- The syntax will be : a2? [ <file> ] If no file name is specified, the default is "lex". In order to allow you to use any device you may wish to download your LEX, we give you the source code for a2lex (file a2lex.c) as an example. You have to write only three functions in C : init () : initializes your interface output (char c) : outputs the character c to your interface term () : terminates the process. These functions can be empty. They are only responsible for the interface, and not for the conversion process. V - EXAMPLES ------------ To assemble "compat.as" (compatibility mode), you must type : aas compat The output will be in "lex" file. To assemble "compat.as" with listing and cross-reference section, sent to file "list", type : aas -xalist -l66 compat or aas -x -a list -l 66 compat.as To assemble the same file with interactive options input, simply type : aas then enter "compat" then press [RETURN] (output is default, "lex") then enter "list" (for listing file) then enter "yes" (for cross reference) then enter "66" (for page length) To assemble files "x1.as", "x2.as", "x3.as" (modular mode), you must type : aas x*.as or aas x1 x2 x3 To link these files, with a listing and cross-reference in file "list", and a lex file in "totolex", you must type : ald -xalist -ototolex x1 x2 x3 Warning : the order of object modules if important. To create a message table from "jpc.am", you must type : amg <jpc.am >mes.as If you wish to number these messages starting from 27, you must type : amg 27 <jpc.am >mes.as VI - ENTRY POINTS FILES ----------------------- AREUH is provided with two files : hp71.ep : mainframe supported entry points and symbols hpil.ep : hpil supported entry points These files are looked for in the following directories : current directory c:\hp71\ c:\lib\hp71\ c:\lib\ c:\areuh\lib\ or at the location specifed by RDSYMB. You can add entry points to these files, or use other files. Only hp71.ep is automatically loaded at link time. If you want to use hpil.ep or your own file, you must load them explicitly at assembly time with RDSYMB. The supplied files are sorted in reverse order. This is only for speed considerations. Each label has its name, followed by its hexadecimal value on the next line. If you find any error in these files, please inform us. VII - IN CASE OF PROBLEMS ------------------------- If you have a problem, before reporting it to us, please check if the problem is not in your source code or computer system. We will try to answer your questions or solve your problems (NOT hardware or connection problems). Send us on a 3.5" LIF (or MS-DOS) format your source code, with a complete description and localization of your problem. This is not a programming aid service... Write to : Pierre David or Janick Taillandier 33 Bd St Martin 335 rue Lecourbe 75003 Paris 75015 Paris FRANCE FRANCE APPENDIX 1 : DISTRIBUTION DISK ------------------------------ This disks contains the following files : aas.exe Areuh ASsembler ald.exe Areuh LoaDer (Loader = Linker under UNIX) amg.exe Areuh Message table Generator a2lex.exe Areuh To HPILLINK LEX format a2rs.exe Areuh To RS232 adp.exe Areuh DumP (utility to dump intermediate files) readme This file xmp\compat.as Example for compatibility mode xmp\x1.as Example for modular mode (file header) xmp\x2.as Example for modular mode (execution routine) xmp\x3.as Example for modular mode (decomparse routines) xmp\jpc.am Example of message table description (from JPCROM) src\copy.h body of a2lex program src\a2lex.c dedicated I/O routines lib\hp71.ep HP-71 supported entry points and symbols lib\hpil.ep HP-IL supported entry points APPENDIX 2 : MS-DOS NOTE ------------------------ These programs have been successfully tested on an HP 150, MS-DOS 2.11 and on an AT compatible MS-DOS 3.20. We have used Microsoft C 4.0 to compile all programs. Enjoy ! Pierre David & Janick Taillandier @EOF set `wc -lwc <areuh/doc/readme.dos` if test $1$2$3 != 501253715946 then echo ERROR: wc results of areuh/doc/readme.dos are $* should be 501 2537 15946 fi chmod 644 areuh/doc/readme.dos echo x - areuh/doc/compc.doc cat >areuh/doc/compc.doc <<'@EOF' COMMUNICATION HP-71 <=> PC Michael Markov (PPC Paris 301) This file documments three HP-71 programs I use to upload and download files to and from my HP110. They can also be used to do the same with IBM PC or compatible machines equipped with an HP82973 HPIL Interface. Why do I need special programs to do this, when HPILLINK provides the ability to upload and download files from the PC keyboard? Because I only want to exchange files with the PC, not use a remote keyboard for my HP-71. The editor I have on the PC or the HP110 (Ed Gilbert's Editor, NOT memomaker) is much faster than any text editors I have on the HP-71, they handle long text files without slowing down to the speed of cold molasses, and have features HP-71 users only dream of. Editing BASIC programs is usually faster without the delays introduced by the remote keyboard. Finally - HPILLINK set-up with the remote keyboard does a number of unfriendly things, such as mess-up my STARTUP, my key assignments, or even FREEPORT memory I do not want FREEPORTED, if I do not have KEYBOARD LEX in my machine. Still, it is nice to have mass storage and printers at work, by way of HPILLINK and the IBM XT in my department. Being able to share data stored in my HP-71 using the HPILLINK /C option helps keep my bosses happy with my HP-71. Hence, the routines below. NOTE: LINK 1.02 (Southern Software) provides similar capabilities. I hear there soon will be a new version called LINK PLUS, with many interesting features. I use LINK 1.02 rather than HPILLINK if I want to use the PC as a printer or as a video interface for my HP-71. The first program is intended to upload or download a single file at a time, from the HP-71 keyboard. Before using this program, you must run the HPILLINK.EXE program on the PC, and connect the HP-71 to the PC HP-IL port. When you download a file, you must provide the full file name, such as: JUNK.TEX When you upload a file, the program will automatically supply the correct file extension if you have the FTYPE$ keyword available. See source code below. If not, the extension will be left blank, and you will have to RENAME the file from the PC keyboard if you want the correct extension. The file transfer takes little or no time. Once done, disconnect the HP-71, exit HPILLINK with the F8 key, and do whatever you desire with either the PC or the HP-71. Enjoy! 0010 ! PC71EX - Transfer HP71 files between a PC and an HP71 with HPILLINK 0020 ! Copyright Michael Markov 1988 0030 ! 0040 ! Uses FTYPE$ keyword from DATACOM ROM - See FLTYPELXS for source 0050 ! This is required if you want to provide the proper file extension 0060 ! when uploading files to an IBM PC via HPILLINK /HP82973 Interface card 0070 ! or to an HP110 running HPILLINK. 0080 ! 0090 ! If you do not have the FTYPE$ keyword, comment-out the line 300 : 0100 ! 300 T$=FTYPE$(F$) 0110 ! 0120 ! The advantage of this program is that it allows file transfers without 0130 ! messing-up your favorite STARTUP, your key assignments, or FREEPORTing 0140 ! stuff you may not want free-ported. This was developed when I started 0150 ! to make heavy use of my HP110 to edit HP71 source code files, which I 0160 ! then assembled using the AREUH (PPC-Paris) assembler-linker before 0170 ! downloading the resulting LEX for testing in the HP71. I had no need for 0180 ! an external keyboard since the EDITOR I use on my HP110 is considerably 0190 ! faster than EDTEXT, and provides more flexibility. 0200 ! 0210 LOCAL @ DISP 'Up or Download?(U/D)' 0220 A$=UPRC$(KEYWAIT$) @ IF A$='D' THEN 240 0230 IF A$='U' THEN 280 ELSE 210 0240 LOCAL @ INPUT 'DOWNLOAD FILE? ';F$ @ IF F$='' THEN END 0250 P=DEVADDR(':PC') 0260 SEND UNT TALK P DDT 0 UNT MTA LISTEN P DATA F$ EOL 0270 COPY :P @ GOTO 240 0280 INPUT 'Upload file? ';F$ @ IF F$='' THEN END 0290 P=DEVADDR(':PC') @ T$='' 0300 T$=FTYPE$(F$)[1,3] ! comment out if FTYPES keyword not available 0310 SEND UNL LISTEN P MTA DDL 0 DATA F$,'.',T$,10 0320 COPY F$ TO :P @ GOTO 280 The second program is a minor variant of the PC71EX program given above. It allows you to upload or download ROM images just as if the PC was an HPIL disk drive. There is one interesting difference: the file stored on the DOS disk will take less space than on HPIL mass storage. Apparently, HPILLINK and ROMCOPY version RCPY:E were designed to work together better than the mass storage option! Here, we see the advantages of an intelligent mass storage device. 0010 ! PCROM - Transfer HP71 ROM images between a PC and an HP71 with HPILLINK 0011 ! and ROMCOPY LEX. 0020 ! Copyright Michael Markov 1988 0030 ! 0040 ! This program is a slightly modified version of PC71EX, elsewhere on this 0041 ! swapdisk. See PCCOMM for documentation. 0042 ! 0210 LOCAL @ DISP 'Up or Download?(U/D)' 0220 A$=UPRC$(KEYWAIT$) @ IF A$='D' THEN 240 0230 IF A$='U' THEN 280 ELSE 210 0240 LOCAL @ INPUT 'DOWNLOAD FILE? ';F$ @ IF F$='' THEN END 0241 INPUT 'To :PORT(#)? ','5';N 0250 P=DEVADDR(':PC') @ IF NOT POS(F$,'.ROM') THEN F$=F$&'.ROM' 0260 SEND UNT TALK P DDT 0 UNT MTA LISTEN P DATA F$ EOL 0261 X=POS(UPRC$(F$),'.ROM') @ F$=F$[1,X-1]&':'&STR$(P) 0270 ROMCOPY F$ TO ':PORT('&STR$(N)&')' @ GOTO 240 0280 INPUT 'Upload file? ';F$ @ IF F$='' THEN END 0281 INPUT 'From :PORT(#)? ','5';N 0290 P=DEVADDR(':PC') @ X=POS(UPRC$(F$),'.ROM') @ IF X THEN F$=F$[1,X-1] 0310 SEND UNL LISTEN P MTA DDL 0 DATA F$,'.ROM',10 0320 ROMCOPY ':PORT('&STR$(N)&')' TO :P @ GOTO 280 The last program allows you to upload many files to the PC, under the control of an HP-71 program. I have used it to transfer entire swapdisks to my HP110, for friends that have HP-71 machines and PC's, but not HP9114 drives. They then read the disks as best they can. I understand that there is a new package from Personalized Software called READHP, that allows IBM machines to read 3.5" disks formatted by HP machines. It should be possible to download files from the PC with a PCTODISK program, just as easily as you can upload entire disks. The easiest approach would be to start things going by creating a TEXT file with all the desired filenames and extensions with the DIR A: >DIR.TEX. Then use PC71EX to download the file, and let your HP-71 control the download to an HPIL mass storage device. I have not needed to do this, since I am not (as of this date) getting any contributions on DOS disks. However, if HP abandons HPIL, this may be the only way to have peripherals for our HP41/HP75/HP71 computers, may they last many years. (Have you purchased a spare HP-71 yet? NO? Why?). NOTE: PCTODISK does not yet exist, except as an idea. It is one of my many 'to do sometime' projects. Anyways, easy PC<==>HP71 communications will greatly ease the transition to the world of DOS/OS2 machines, where instead of HP BASIC you will be forced to learn PASCAL, C, MEGA BASIC or QUICK BASIC if you want to do any serious programming. Obvioulsy, the PC must be running HPILLINK, and the default drive to which HPILLINK writes the files should be as empty as possible. Load HPILLINK with A:HPILLINK, then replace the disk in the default drive (usually A:) with a newly formated disk. On the HP71, run DISKTOPC. When the program stops, replace the disk in the default drive, and run DISKTOPC on the HP71 to continue the upload. NOTE: Do NOT purge the temporary directory file (default DIRFL), except at the start of the upload, before the first file is transfered. This allows the PDIR keyword (JPCROM) to create a new file that contains all the information you need to upload the disk. The HP-71 automatically deletes file entries as the upload goes on. Any time the DISKTOPC program stops, you can LIST DIRFL to find out how many files still ave to be uploaded. Note that the program polls the PC to determine whether the remote load failed for any reason, such as no space remaining available on the PC. This program is intended to be used in conjunction with a video interface on the HPIL loop. The program uses JPCROM to create a directory listing of the disk to be uploaded to the PC. This is by far the most convenient way. Among other things, JPCROM implements a poll handler that allows your HP-71 to identify HP-41, HP-75 and other non-HP71-standard file types. This allows you to tag the file names to help identify the contents of the file. HPILLINK does not recognize HP-41 or HP-75 file types. In fact, it does not recognize all HP-71 file types, atleast, not the version I have (Maybe revision E does better, but I do not have that yet. It should be obvious that minor changes to line 240 allow uploading only HP-71 files, or only HP41 files, etc, should you so desire. 0010 ! DISKTOPC - UPLOAD FILES TO PC WITH HPILLINK 0020 ! This program is available, at least in concept, in the HPILLINK 0030 ! documentation. It implements the task in a way that helps minimizes 0040 ! user intervention. It was written to facilitate uploading Swapdisks 0050 ! to an IBM PC equipped with an HPIL interface card. 0060 ! 0070 ! Since the HP71 is the controller, you can have a disk drive on the loop, 0080 ! and copy each file from the drive to the IBM PC, using a minimum of 0090 ! HP-71 memory. 0100 ! JPCROM REQUIRED. IF NOT AVAILABLE, CREATE DISK DIRECTORY LISTING WITH 0110 ! SOME BASIC ROUTINE SUCH AS DIR71 0120 CONTROL ON @ RESET HPIL @ RESTORE IO @ DISPLAY IS :DISPLAY 0130 INPUT "Which drive? ";D 0140 P=DEVADDR('%16('&STR$(D)&')') 0150 INPUT 'temp. file? ','DIRFL';F$ 0155 ON ERROR GOTO 161 0160 PDIR :P TO F$ @ GOTO 169 0161 OFF ERROR @ DISP ERRM$;'Purge? (Y/N)' 0162 A$=UPRC$(KEYWAIT$) @ IF A$='Y' THEN PURGE F$ @ GOTO 155 0169 OFF ERROR @ ASSIGN #1 TO F$ @ RESTORE #1 0180 DIM A$[60] @ D=DEVADDR(':PC') @ STANDBY ON @ REMOTE 0190 FOR I=0 TO FILESZR(F$)-1 @ READ #1;A$ @ DISP I;A$ 0200 IF SPOLL(D)#5 THEN 270 0210 F$=TRIM$(A$[1,10]) 0220 T$=TRIM$(A$[14,19])[1,3] 0230 IF T$='41:' OR T$='75:' THEN G$=F$&T$[1,2] @ T$='UNK' ELSE G$=F$ 0240 SEND UNL LISTEN D MTA DDL 0 DATA G$,'.',T$,10 0250 COPY F$&':'&STR$(P) TO :D 0260 NEXT I 0270 LOCAL @ DISP 'HP110 Drive A full-delete last file copied' 0280 READ #1,I-2;A$ @ DISP 'last file copied: ';I-2;A$ 0281 FOR J=I-2 TO 0 STEP -1 @ DELETE #1,J @ NEXT J 0290 STANDBY OFF @ CONTROL OFF @ END LEX 'FTYPELEX' LEX file name TITLE FTYPELEX, File type LEX, Samuel H Chau [242] * ID #F6 compatible with DCLEX in DATACOMM ROM MSG 0 no message table POLL 0 no poll handler * ENTRY FTYPE CHAR #F string function * KEY 'FTYPE$' Syntax: FTYPE$('file specifier') or * FTYPE$(assign channel #) * Returns file type as a 5-char string * Null string returned if file not found * Example: FTYPE$('FORTHRAM') returns FORTH TOKEN 1 ENDTXT end of text table ************************ * **** EQUate Table **** * AVE=D1 EQU #18BB8 update AVMEME from D1 or C BSERR EQU #0939A BASIC system error D0=AVS EQU #09B2C set D0 to address in AVMEMS D1MSTK EQU #1954E set D1 at MTMSTK (AVMEME) FDCH# EQU #114AC find channel # in assign table FFIB# EQU #122EF find file number in FIB FILXQ$ EQU #09B95 filename execute for a string expression FINDF EQU #09F77 find a file FLTDH EQU #1B223 convert 12-digit flt to HEX integer FNRTN EQU #0F23C function return FTYPDC EQU #06902 file type decompile FUNCR0 EQU #2F89B function scratch RAM start POLL EQU #12337 poll LEX files with process # POPMTH EQU #1B3DB skip past item on MATH stack RSTK<R EQU #014A8 restore RSTK level(s) from RSTKBF buffer R<RSTK EQU #014DD save RSTK level(s) into RSTKBF buffer STRHED EQU #14C2E generate string head on stack pFINDF EQU #00017 poll to find a file pFSPCx EQU #00005 poll to execute file specifier eFSPEC EQU #0003A invalid filespec error * ************************ * NIBHEX C11 one string or numeric parameter FTYPE CD0EX RSTK=C save D0 (PC) on return stack GOSBVL R<RSTK save RSTK level(s) [P=0] A=DAT1 W get top of MATH stack in A LCHEX A load C:0 for parameter type check ?C>A P integer parameter? GOYES FTYP03 yes: interpret as channel # A=A+1 P ?A#0 B not string parameter? GOYES FTYP01 yes: parameter is invalid GOTO FTYP09 no: interpret string as file specifier FTYP01 LC(4) eFSPEC load Invalid filespec error FTYP02 GOVLNG BSERR BASIC error exit FTYP03 D1=D1+ 16 pop integer argument off MATH stack GOSUB ave=d1 update stack top pointer GOSBVL FLTDH convert 12 form channel # to HEX integer B=A B put HEX form in B for FDCH# GOSBVL FDCH# find channel # in assign table GONC FTYP08 not found: ready for exit ?A=0 B channel closed? no: A(B)=FIB# GOYES FTYP08 yes: punt! GOSBVL FFIB# find file # in FIB GOC FTYP08 not found? yes: punt! no: D1 @ file # in FIB D1=D1+ 5 advance to file type entry in FIB FTYP04 GOSBVL D0=AVS set D0 to AVMEMS C=0 W preclear C DAT0=C W blank out word at AVMEMS D0=D0+ 2 point past one null GOSBVL FTYPDC get file type (5 chars), D0 points past it GOSUB d1mstk set D1 to AVMEME GOSBVL D0=AVS set D0 to AVMEMS C=DAT0 W get file type in C ?C=0 B not at file type string? GOYES FTYP06 yes: move pointer down FTYP05 ?C=0 B end of file type string? GOYES FTYP07 yes: ready for string return D1=D1- 2 point D1 down 1 char DAT1=C B push one ASCII char onto stack FTYP06 CSR W CSR W shift to next char in file type string GOTO FTYP05 continue building string on stack FTYP07 GOSBVL STRHED generate string header on stack GOSBVL RSTK<R restore RSTK level(s) C=RSTK CD0EX restore D0 (PC) from RSTK GOVLNG FNRTN function return FTYP08 GOSUB d1mstk set D1 to AVMEME GOTO FTYP07 return with string FTYP09 GOSUB ave=d1 update stack top pointer C=DAT1 W read string header into C CSR W CSR W shift to string length field ?C=0 A null string? GOYES FTYP08 yes: ready for return GOSBVL FILXQ$ execute tokenized file specifier P= 0 LCASC ' ' load C with 2 ASCII spaces R0=C save in R0 GOC FTYP16 file specifier is mainframe recognizable GOSBVL POLL illegal: issue file spec execution poll CON(2) pFSPCx file specifier execute poll GOC FTYP13 error return from poll: error exit ?XM=0 pFSPCx poll handled? GOYES FTYP10 yes: continue GOTO FTYP01 no: Invalid filespec error FTYP10 C=R0 last 2 chars of filename into C R1=C save in R1 R0=A filename (blank filled) into R0 GOSUB d1mstk set D1 to stack top GOSBVL POPMTH skip past current item on stack GOSUB ave=d1 update stack top pointer GOSBVL POLL issue poll to find file CON(2) pFINDF file finder poll GONC FTYP11 no error: continue A=C A save C in A LCHEX 16 load C with HPIL File not found error # ?A=C B file not found on HPIL mass storage? GOYES FTYP12 yes: ready for return C=A A restore C from A GONC FTYP13 B.E.T. FTYP11 ?XM=0 pFINDF poll handled? GOYES FTYP14 yes: continue FTYP12 GOTO FTYP08 no: ready for return FTYP13 GOTO FTYP02 load BASIC error returned from LEX file FTYP14 D1=(5) FUNCR0 set D1 to function scratch RAM C=R0 DAT1=C W put file attributes into function scratch RAM D1=D1+ 11 advance to file type field FTYP15 GOTO FTYP04 go find file type FTYP16 GOSUB ave=d1 update stack top pointer GOSBVL FINDF find the file GOC FTYP12 not found: ready for return D1=D1+ 16 move to file type field in file header GONC FTYP15 B.E.T. ave=d1 GOVLNG AVE=D1 d1mstk GOVLNG D1MSTK END @EOF set `wc -lwc <areuh/doc/compc.doc` if test $1$2$3 != 339269816177 then echo ERROR: wc results of areuh/doc/compc.doc are $* should be 339 2698 16177 fi chmod 644 areuh/doc/compc.doc echo x - areuh/doc/areuh110.doc cat >areuh/doc/areuh110.doc <<'@EOF' USING AREUH WITH A HP110 Michael Markov (PPC Paris 301) Using AREUH with an HP110 presents a variety of problems, most of which are related to the fact that AREUH requires about 200+K of memory to run. This leaves you with 70K of EDISC for your source code, intermediate files, listing files, and anything else you may feel you absolutely have to have, such as ED110, in case you need to edit the source file, or HPILLINK to upload and download LEX files.... Keep in mind that listing files are roughly twice the size of source files, and that the object file takes some room. Needless to say, this means that you cannot keep the 150K byte AAS.EXE program in the A: drive. Therefore, HP100 owners who still want to use AREUH for serious work must resign themselves to loading AAS.EXE from disk each time they wish to assemble a LEX file. Worse, unless they are working with source files of 20K or less, they must also resign themselves to either sending the listing file to a disk file, or to a printer. Either approach means that execution time is much slower than you would expect from the AREUH documentation. Still, my HP110 and AREUH allow me to assemble a 42K source code files about 4 minutes, while my HP71 requires over half an hour to do the same job, in spite of a 1.9 times speed-up. (Yes, I am considering the purchase of a 512K base Portable Plus with a 1 or 2 Meg RAM card, but considering the cost, maybe I would be better off with a full-size desk top machine.) Let me hasten to say that 20K source files are quite sufficient for individual keywords. Assembling such small files is unbelievably fast, and very convenient for debugging sessions. You will have few problems assembling such files using either the compatibility mode or the modular mode. However, source code files show a definite tendency to grow: TXTSORTS, once less than 13K, is now 42K. TKS, the source for DISASMLX, grew to 77K from similar beginnings. The following material describes the work-arounds I developed to allow me to assemble such source files more or less painlessly. Since the major space and memory waster is saving the listing file, you must ask yourself whether you need a listing file. In the compatibility mode, you can use the LIST OFF and LIST ON keywords to suppress the listing file for portions of the files that you have already assembled successfully in previous sessions. For example, with the LIST OFF suppressing most of the TKS listing, DISASMLX can be assembled in about two minutes. This is definitely worth taking advantage of -- just list the portion of the source that includes any new keyword you add to the file you are building. This will let you know if any jumps are out of range, which is the most common problem when adding a new keyword to a file, assuming you have already tested and assembled the keyword separately. However, there always comes the time when you need a complete listing for code-packing/ code review purposes. When this happens, I use the following procedure: 1) If your source code file is more than 20K bytes long, prepare a work disk that contains ONLY HPILLINK, the source code and any symbol files you use, to include the entry point files found in the AREUH disk \LIB subdirectory. You should first format this disk, then copy the symbol files from AREUH to the work disk with COPY C:\LIB\*.EP D: (If you have only one drive, first copy the files to the A: drive, then to the work disk. Next, copy any special Symbol files to be loaded with RDSYMB. Finally, copy the source code file to the work disk. This may sound complicated, but if you use AREUH frequently, you will prepare several work disks in a single session, so that all you have to do in this step is add the source code. You can reuse such work disks at any time by simply deleting old source and listing files. Do not forget to add any special symbol files. When your souce file grows beyond the size that can be edited with MEMOMAKER, you may want to add your favorite EDitor software. While this limits the space remaining free for the source and listing files, it is very convenient. You should seriously consider breaking-up your larger source code files into smaller files (20K or less) that can be assembled from the A: drive, as execution time suffers badly when assembling the source from mass storage. The AREUH loader-linker will allow you to combine the resulting intermediate files into a single large LEX file. See WRITHEAD.BAS and WRITHEAD.DOC on the disk. These files help a lot when using the modular mode. If you do NOT use supported entry points, you can assemble source files of up to about 60K from the A: drive, since you do not need to have the entry point files in either the A: drive (current directory) or the C: drive... 2) Format a blank 3.5" disk in drive C: 3) Backup your HP110 with COPY *.* C: (from MS-DOS) 4) Delete all files except the source code file to be assembled, and PACK.COM. If the file is in excess of 30K or 60K (see step 1 above), delete everything except PACK.COM since you have to assemble the source from the work disk prepared in step 1 above. NOTE: If you use AREUH frequently, you will already have back-up disks, and you need only back-up current work in progress. 5) PACK the A: drive (Type PACK [Return]). 6) You may now delete PACK.COM if you are real short of memory. 7) EXIT MS-DOS, and press the f6 key (System Configuration). 8) Increase the Memory allocation to 200+ Kbytes. 9) Exit the configuration menu, and return to MS-DOS. 10) Replace the disk in your C: drive with the AREUH disk. 11) Copy any entry point files required from the C:\LIB subdirectory to the A: drive (unless these files are available on your work disk). 11) Load AAS.EXE with C:AAS - The interactive mode is a must if you have only one drive. Otherwise, you can use toggles documented in the README file to more or less duplicate what follows. 12) Once the interactive menu comes up, replace the AREUH disk with your work disk. This may be the work disk prepared in step 1, or the back-up disk created in step 2 and 3. This disk will be used to save the listing file. 13) Now, you are ready to respond to the prompts in the interactive menu: Source in drive A: Source in drive C: Source file : TXTSORTS.TEX C:TXTSORTS.TEX Object file : TSORT TSORT output to A: drive Listing File : C:LIST C:LIST listing to disk Cross Reference: Y Y Yes, nice to have Page length : 88 88 I use 8 lines per inch to save paper While assembling version 7 of the above LEX, I got an object file of 3066 bytes and a listing file of 74K bytes. The LEX itself, after conversion to HPILLINK format with the AREUH A2LEX.EXE program and downloading to the HP71 was 1513 bytes long (TSORTLX7). You can read the source from one external drive, direct the object file to the same disk, while having the AREUH disk in a second drive, and send the listing file to a third drive, assuming you can borrow one (I used a cassette drive to check this.) This flexibility should allows HP110 users to assemble LEX files of up to 32K. 14) I actually work with two disk drives, which simplifies things. I keep the AREUH disk in drive C: and the work disk in drive D:, so that I respond to the Listing file : prompt with D:LIST. Minor difference that makes life somewhat easier. 15) Now, I look at the listing file using Ed Gilbert's Editor, which I keep on the work disk: D:ED D:LIST (EDit file LIST on drive D:). If you have only one drive, you may do the same using drive C: 16) If there are errors, edit the source file and go back to step 1. Otherwise, put the AREUH disk in drive C: and execute the A2LEX program: C:A2LEX TSORT This creates a new file in HPILLINK format with the LEX extension. 17) Finally, you are ready to download the LEX file to your HP71 using HPILLINK: D:HPILLINK (or, if you have only one drive, replace the AREUH disk with your work disk, and use C:HPILLINK) 18) See the PCCOMM file elsewhere on this disk to findout how to transfer files between your HP-17 and your HP110 with a minimum of effort. NOTE: The HP-71 MAY REMAIN ON THE LOOP WHILE ALL OF THE ABOVE IS GOING ON, PROVIDED THAT YOU FIRST EXECUTE "CONTROL OFF". WARNING: The HP110 may tell you that your drive has a bad unit if you try any mass storage operation after the HP-71 has been the controller. This is because the HP110 usually works with 512 byte mass storage sectors, while the HP71 normally uses 256 byte sectors. Reply Ignore to the problem prompt. Thereafter, you should no longer have problems. @EOF set `wc -lwc <areuh/doc/areuh110.doc` if test $1$2$3 != 14815489013 then echo ERROR: wc results of areuh/doc/areuh110.doc are $* should be 148 1548 9013 fi chmod 644 areuh/doc/areuh110.doc exit 0
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:32:56 1990 # # This archive contains: # areuh/equ/sasm.ep areuh/equ/hp71.ep # areuh/equ/hpil.ep areuh/equ/Makefile # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - areuh/equ/sasm.ep cat >areuh/equ/sasm.ep <<'@EOF' =xromFF 00095 =xZERO 0001C =xVARS 0005B =xROUND 0004C =xPOS 00042 =xPCRD 0003E =xNEG 0003D =xNEAR 0003C =xMATH 00036 =xINTO 0002E =xFLOW 00029 =xEXTND 00026 =xCLOCK 00015 =xANGLE 00006 =uTEST 0D435 =uSTRPT 000D0 =uRND>P 0C9CF =uRESXT 0C9C1 =uRESTP 000F1 =uRESNX 0C9BD =uRESD1 0E1EE =uRES12 0C994 =uOPNWM 000E0 =uOPNNM 000D8 =uOPNM- 000DF =uNUMNs 000F9 =uNUMNn 000F8 =uNUMFs 000FB =uNUMFn 000FA =uNUMEs 000FD =uNUMEn 000FC =uMULT 000D1 =uMODES 0BDB1 =uLOOPS 000D3 =uLOOPP 000EF =uLOOPB 000D2 =uJMP{} 000D9 =uJMPst 000DA =uJMPdl 000DB =uIMsta 000DE =uIMend 000F0 =uIMbck 000DC =uIMXCH 000D4 =uHKB^ 000F6 =uDELIM 000F4 =uCPLXC 000EE =uALit 000F7 =t^ 00080 =tZERO C01EF =tZ 0005A =tXWORD 000EF =tXFN 000B3 =tWAIT 000D8 =tVARS B01EF =tVAL 000A5 =tUSING 000FD =tUSER 000E2 =tUPRC$ 000AB =tUNF 000B0 =tTRACE 000EA =tTO 000F3 =tTIMER 000E4 =tTIME$ 00095 =tTIME 0007B =tTHEN 000F4 =tTAN 00098 =tTAB 000F7 =tSVAR 0002D =tSUB 000C1 =tSTR$ 000A6 =tSTOP 000D9 =tSTEP 000F6 =tSTAT 000CE =tSQR 00092 =tSMALL 00011 =tSIN 00096 =tSHORT 000CB =tSGN 000A1 =tSFLAG 000FB =tSEMIC 000F2 =tSDEV 0009E =tRUN 000FE =tROUND C01EF =tRND 000A0 =tRMD 0006D =tRFILE 000DE =tRETRN 000DB =tRESTR 000DE =tRES 0007F =tREM 000E6 =tRELOP 0008A =tREAL 000BC =tREAD 000C7 =tRDIAN 000D4 =tRAD 0006E =tPURGE 000EB =tPRMST 000F3 =tPRMEN 000F8 =tPRINT 000CD =tPREDV 0009F =tPOS 201B3 =tPORT 000D1 =tPI 00079 =tPCRD E01EF =tPAUSE 000D7 =tOVF 000AF =tOR 0008D =tOPT'N 000ED =tON 000E0 =tOFF 000E1 =tNUM 000A3 =tNOT 00081 =tNEXT 000C4 =tNEG D01EF =tNEAR C01EF =tNAME 000BD =tMOD 00074 =tMIN 000AC =tMEAN 0009D =tMAXRL 0006C =tMAX 000AD =tMATH 601EF =tMAIN 000D2 =tLR 000B6 =tLPRP 000AA =tLOG10 00093 =tLOG 00090 =tLN 00091 =tLITRL 000C4 =tLIST 000BB =tLINPT 000BF =tLINE# 0000F =tLET 000C0 =tLEN 000A9 =tLBLST 000F6 =tLBLRF 0000E =tKEYS 000CF =tKEY$ 00073 =tKEY 000E5 =tIVL 000AE =tISUB$ 000A7 =tIS 000E7 =tIP 0006A =tINX 000B2 =tINTR 015FF =tINTO E01EF =tINTEG 000CA =tINT9 00005 =tINT8 00006 =tINT7 00007 =tINT6 00008 =tINT5 00009 =tINT4 0000A =tINT3 0000B =tINT2 0000C =tINT12 00002 =tINT11 00003 =tINT10 00004 =tINT 0009C =tINPUT 000C9 =tINF 00070 =tIN 000F2 =tIMAGE 000FF =tIF 000DF =tGOTO 000DD =tGOSUB 000DC =tFP 0006B =tFOR 000C3 =tFN 0007C =tFLT9 00015 =tFLT8 00016 =tFLT7 00017 =tFLT6 00018 =tFLT5 00019 =tFLT4 0001A =tFLT3 0001B =tFLT2 0001C =tFLT12 00012 =tFLT11 00013 =tFLT10 00014 =tFLT1 0001D =tFLOW 901EF =tFFN 000B4 =tFETCH 000C8 =tFACT 000A8 =tEXTND 601EF =tEXTIF 000F4 =tEXP 00094 =tEXOR 0008C =tERROR 000E3 =tERRN 00076 =tERRL 00075 =tEPS 00071 =tEOL 000F0 =tENTER 4FFEF =tENDSB 000C2 =tENDDF 000BA =tEND 000DA =tELSE 000F5 =tEDIT 000B8 =tDVZ 000B1 =tDSTRY 000BE =tDMYAR 0007E =tDIV 00086 =tDISP 000C5 =tDIM 000CC =tDELET 000B7 =tDELAY 000D6 =tDEGRE 000D3 =tDEG 0006F =tDEF 000B9 =tDATE$ 00078 =tDATE 00077 =tDATA 000C6 =tCVAL 000E1 =tCOS 00097 =tCOPY 000B5 =tCOMMA 000F1 =tCOLON 000E2 =tCMPLX 0007A =tCLOCK 501EF =tCHR$ 000A4 =tCFLAG 000FA =tCEIL 00072 =tCAT 000EC =tCARD 000D0 =tCALL 000F9 =tBIG 00010 =tBEEP 000E8 =tBASE 000E9 =tAUTO 000EE =tATAN 0009B =tASIN 00099 =tARRAY 0007D =tANGLE 601B3 =tAND 0008B =tALL 000F8 =tADIG9 00069 =tADIG8 00068 =tADIG7 00067 =tADIG6 00066 =tADIG5 00065 =tADIG4 00064 =tADIG3 00063 =tADIG2 00062 =tADIG1 00061 =tADIG0 00060 =tADD 000D5 =tACOS 0009A =tABS 000A2 =t@ 000F4 =t/ 00084 =t- 00082 =t+ 00087 =t* 00083 =t& 00089 =t% 00085 =t! 000FC =sXWORD 00009 =sXQT 00000 =sXCPT 00004 =sUNDEF 00001 =sSpecl 00006 =sSTOP 00005 =sSTAT 00006 =sSSTdc 00001 =sSST 00002 =sSIGN 00009 =sRUNDC 00007 =sRUNBn 00004 =sRFILE 00008 =sRETRN 00000 =sRESTR 0000A =sRENUM 00008 =sRENAM 00006 =sREADI 00004 =sRDX 0000B =sRAD 00009 =sPRGCF 0000B =sPCRD 00008 =sONTMR 00006 =sONERR 00004 =sNoChn 00002 =sNEGRD 0000B =sMULT 00008 =sMAINc 00005 =sKEYS 00005 =sInit 00003 =sIX 00007 =sIRAM 00002 =sINX 00005 =sINFRD 0000A =sI/OBF 0000A =sGOSUB 00003 =sFOUND 0000A =sEXTGS 00005 =sEXTDV 00000 =sERROR 00000 =sEOF 00007 =sENDx 00001 =sDEST 00003 =sCplxP 00007 =sCntg 00002 =sCURUP 00002 =sCURUD 00004 =sCURBT 00003 =sCONTK 00009 =sCONT 0000A =sCHAIN 0000B =sCARDC 00008 =sCARD 00002 =sC/P 00001 =sBYEx 00000 =sARITH 00007 =pZERPG 000F7 =pWTKY 0001C =pWRCBF 0001A =pWCRD8 00024 =pWCRD 00035 =pWARN 000F3 =pVER$ 00000 =pTRFMx 0003C =pTRANS 000EF =pTIMR# 0003B =pTEST 000F0 =pSysFn 00044 =pSREQ 000F9 =pSREC# 00028 =pRUNnB 00031 =pRUNft 00030 =pRTNTp 0003A =pRNAME 00011 =pREN 00039 =pREAD# 00027 =pRDNBF 00019 =pRDCBF 00018 =pRCRD 00034 =pPWROF 000FC =pPURGE 00010 =pPRTIS 0000F =pPRTCL 0000E =pPRIN# 00026 =pPRGPR 00032 =pPARSE 000F4 =pMRGE2 0002F =pMNLP 000FA =pMERGE 0000D =pMEM 000F1 =pLIST2 0002E =pLIST 0000C =pKYDF 0001B =pIMcpw 00022 =pIMcpi 00021 =pIMbck 00020 =pIMXQT 0001D =pIMXCH 0001F =pIMCHR 0001E =pFTYPE 0002D =pFSPCx 00005 =pFSPCp 00004 =pFPROT 0000B =pFNOUT 0003E =pFNIN 0003D =pFINDF 00017 =pFILXQ 00003 =pFILDC 00002 =pFASCH 0002C =pExcpt 000F8 =pERROR 000F2 =pEOFIL 00025 =pENTER 00012 =pEDIT 0002B =pDSWNK 000FE =pDSWKY 000FD =pDIDST 0000A =pDEVCp 00001 =pDATLN 0002A =pCURSR 00029 =pCRT=8 00023 =pCREAT 00009 =pCRDAB 00033 =pCOPYx 00008 =pCONFG 000FB =pCMPLX 00038 =pCLDST 000FF =pCAT$ 00007 =pCAT 00006 =pCALSV 00037 =pCALRS 00036 =pBSCex 000F6 =pBSCen 000F5 =oTXsod 00005 =oTIMEh 00016 =oSUBLn 00025 =oSPDn2 0000E =oSPDTB 00111 =oSHLNb 00013 =oRTN3p 00014 =oRTN2p 0000F =oRTN1p 0000A =oRLENb 00034 =oRECLb 00024 =oREC#b 00020 =oPROTb 00009 =oPOL#p 0000A =oMSGPT 00009 =oMAINT 0005D =oLXsod 00005 =oKYsod 00005 =oIMPLh 00025 =oFTYPh 00010 =oFTYPb 00005 =oFT-FL 00010 =oFSIZb 00039 =oFNAMh 00000 =oFLSTr 00031 =oFLENh 00020 =oFLAGh 00014 =oFIL#b 00000 =oFBF#b 00002 =oFBEGb 0000D =oDp 0002E =oDLENb 0002E =oDEVCb 0000C =oDBEGb 00015 =oDAsod 0000D =oDATEh 0001A =oD1p 0001E =oD0p 00019 =oCPOSb 00028 =oCOPYb 0000A =oBSsod 00011 =oBPOSp 00005 =oBNsod 00011 =oAp 0003E =oACCSb 0000B =o41sod 00005 =lTIMEh 00004 =lTEXTp 00004 =lSPDn2 00001 =lSPDn 00001 =lSPDTB 0004E =lSHLNb 00002 =lRTN3p 00005 =lRTN2p 00005 =lRTN1p 00005 =lRLENb 00005 =lRECLb 00004 =lREC#b 00004 =lPROTb 00001 =lPOLra 00006 =lPOLSV 0003E =lPOLLp 00005 =lPOL#p 00005 =lMSGp 00004 =lLXTKR 00004 =lLXID 00002 =lLXFAD 00005 =lLXENT 0000B =lLXADR 00005 =lFTYPh 00004 =lFTYPb 00004 =lFSIZb 00006 =lFNAMh 00010 =lFNAM8 00010 =lFNAM+ 00004 =lFLENh 00005 =lFLAGh 00002 =lFILSV 00032 =lFILBF 00100 =lFIL#b 00002 =lFIB 0003F =lFBF#b 00003 =lFBEGb 00006 =lEOL 00002 =lDp 00010 =lDLENb 00006 =lDEVCb 00001 =lDEVC 00005 =lDBEGb 0000B =lDATEh 00006 =lD1p 00005 =lD0p 00005 =lCPOSb 00006 =lCOPYb 00001 =lBPOSp 00005 =lAp 00010 =lACCSb 00001 =kcVIEW 0000B =kcUSEX 0000C =kcUSER 00003 =kcUP 00012 =kcTOP 00014 =kcSST 00011 =kcRUN 0000F =kcRT 00009 =kcOFF 00018 =kcLFT 00008 =kcLERR 0001A =kcLC 00001 =kcLAST 00019 =kcI/R 00002 =kcGON 00016 =kcFRT 00006 =kcFLFT 00005 =kcEOL 0000D =kcDOWN 00013 =kcCTRL 0000A =kcCONT 00010 =kcCALC 00017 =kcBOT 00015 =kcBKSP 00007 =kcATTN 0000E =kc-LIN 00004 =kc-CHR 00000 =k#VIEW 0006E =k#USEX 000A5 =k#USER 0006D =k#UP 00032 =k#TOP 000A2 =k#SST 00066 =k#RUN 0002E =k#RT 00030 =k#OFF 00063 =k#LFT 0002F =k#LERR 000A1 =k#LC 0006A =k#LAST 000A4 =k#I/R 00069 =k#GON 0009B =k#FRT 000A0 =k#FLFT 0009F =k#EOL 00026 =k#DOWN 00033 =k#CTRL 0009E =k#CONT 00070 =k#CALC 0006F =k#BOT 000A3 =k#BKSP 00067 =k#ATTN 0002B =k#3 00029 =k#2 00028 =k#1 00027 =k#-LIN 0006B =k#-CHR 00068 =flVIEW FFFCC =flUSRX FFFC6 =flUSER FFFF7 =flUNF FFFFB =flTNOF FFFCD =flSUSP FFFC1 =flSCEN FFFF2 =flRTN FFFD4 =flRPTD FFFC5 =flRAD FFFF6 =flQIET FFFFF =flPWDN FFFCF =flPRGM FFFC2 =flPDWN FFFEB =flOVF FFFFA =flNZ8 FFFC8 =flNZ7 FFFC9 =flNZ6 FFFCA =flNZ5 FFFCB =flNZ4 FFFE8 =flNOPR FFFE6 =flNOFN FFFD6 =flNEGR FFFF4 =flMKOF FFFCE =flLC FFFF1 =flIVL FFFF8 =flINX FFFFC =flINFR FFFF5 =flFXEN FFFF3 =flEXTD FFFEA =flEXAC FFFD2 =flEOT FFFE9 =flDVZ FFFF9 =flDORM FFFD5 =flDG3 FFFEC =flDG2 FFFED =flDG1 FFFEE =flDG0 FFFEF =flCTRL FFFD0 =flCTON FFFFD =flCMDS FFFD1 =flCLOC FFFD3 =flCALC FFFC0 =flBPLD FFFE7 =flBEEP FFFFE =flBAT FFFC3 =flBASE FFFF0 =flALRM FFFC4 =flAC FFFC7 =fTEXT 00001 =fSOS 000CF =fSDATA 0E0D0 =fROM 0E21C =fMOS 0007F =fLIF1 00001 =fLEX 0E208 =fKEY 0E20C =fEOS 0006F =fEOR 000EF =fEOF 000FF =fDATA 0E0F0 =fBIN 0E204 =fBASIC 0E214 =fASCII 00001 =fAOS 000DF =ew/o 000EB =enull 00000 =eZRO/0 00007 =eZRDIV 00008 =eXWORD 00023 =eXFNNF 00022 =eWRGNM 00049 =eWALGN 0005B =eVFYER 00044 =eVARTY 00032 =eVALGN 0005C =eUNORC 00014 =eUNKCD 00045 =eUNFLW 00001 =eUALGN 0005F =eTUSLO 00048 =eTUFAS 00047 =eTRKOF 000E5 =eTRKDN 00061 =eTOOMI 00027 =eTOOFI 00028 =eTOO 000EF =eTNINF 00004 =eTFWRN 00058 =eTFM 000F1 =eTFFLD 00038 =eSYSER 00017 =eSYNTX 0004B =eSUBSC 0001C =eSTROV 00025 =eSTMNF 0001E =eSQR- 0000A =eSPGNF 00031 =eSIGOP 00013 =eRwoGS 0002C =eRWERR 00046 =eRECOR 0001D =eRALGN 0005D =eR1WRN 00057 =eR0WRN 00056 =eQUOEX 0004D =ePULL 000F6 =ePRTCT 000F8 =ePROTD 00042 =ePRNEX 0004C =ePRMIS 00024 =ePRCER 00054 =ePLLC# 00059 =ePLLC 0005A =ePALGN 0005E =eOVFLW 00002 =eOVFL* 000F5 =eNXwoF 0002B =eNVSTA 00033 =eNUMIN 00026 =eNSVAR 00033 =eNOTIN 00043 =eNODAT 00020 =eNFOUN 000E8 =eNEG^X 00009 =eMSPAR 00052 =eMPI 00019 =eMMCOR 00017 =eMEM 00018 =eLOG- 0000D =eLOBAT 00016 =eLN0 0000C =eL2LNG 00041 =eIVTAB 00030 =eIVSTA 00034 =eIVSOP 00035 =eIVSAR 00033 =eIVARG 0000B =eINX 00015 =eINVUS 0002E =eINVST 000ED =eINVLD 000EC =eINVIM 0002D =eINPUT 000F4 =eINF^0 00012 =eINF 000F3 =eIMGOV 0002F =eILVAR 00053 =eILTFM 00037 =eILPAR 00051 =eILLEG 000E6 =eILKEY 00055 =eILEXP 00050 =eILCNT 0004F =eIF/IF 0000E =eIF-IF 0000F =eIF*ZR 00010 =eFwoNX 0002A =eFnFND 00039 =eFTYPE 0003F =eFSPEC 0003A =eFPROT 0003D =eFOPEN 0003E =eFNNtF 00021 =eFILE 000EA =eFEXST 0003B =eFACCS 0003C =eF2BIG 0004A =eEXPCT 000E7 =eEXP0 00003 =eEXCHR 0004E =eEOFIL 00036 =eDVCNF 00040 =eDATTY 0001F =eCHNL# 00029 =eCALGN 00060 =eALGN 000F0 =eAF 0001B =e2MROM 0001A =e1^INF 00011 =e0^NEG 00005 =e0^0 00006 =e#of# 000F7 =dPORT 00001 =dPCRD 00007 =dMAIN 00000 =dIRAM 00001 =dCARD 00007 =cRCL 00067 =cR->C 00069 =cC->C 00068 =bSTMXQ 00811 =bSTMT 00801 =bSTAT 00806 =bSTART 00808 =bSCRTC 00E00 =bROMTB 00BFE =bPILSV 0080F =bPILAI 00810 =bLEX 00BFC =bIEXKY 00802 =bFLIO5 0080E =bFLIO4 0080D =bFLIO3 0080C =bFLIO2 0080B =bFLIO1 0080A =bFILE 00805 =bFIB 00803 =bFBF#S 00BA0 =bFBF#E 00BCF =bECOMD 00809 =bCHARS 00BFB =bCARD 00807 =bASSGN 00804 =bALTCH 00BFB =a9 00039 =a8 00038 =a7 00037 =a6 00036 =a5 00035 =a4 00034 =a3 00033 =a2 00032 =a1 00031 =a0 00030 =a. 0002E =a' 00027 =a$ 00024 =a" 00022 =a! 00021 =ZERBUF 18B20 =YX2-15 0D27A =YX2-12 0D274 =YMDHMS 130DB =YMDH01 130E5 =YMDDAY 13304 =XYEX 0C697 =XXHEAD 1A44E =XROM01 00001 =XMTADR 08133 =XDelay 00009 =WSTRFX 138B5 =WRTSTR 1396F =WRTNUM 139C4 =WRTFIB 11CEE =WRITNB 1752B =WRDSCN 02C2A =WRDSC+ 02C26 =WIPOUT 1B0AF =WINDST 2F471 =WINDLN 2F473 =WFTMDT 085DD =ValSub 0000A =VRIABL 04BC4 =VIEWD1 15147 =VECTOR 2F43C =VARP 0350E =VARNBR 0E289 =VARNB- 0E28D =VARDC 0537C =VALCHK 1AE61 =VAL00 1AD8F =USst05 1BBD4 =USst03 1BBCE =USnm05 1BD12 =USloop 1C14B =USINGp 03628 =USING 1B446 =USGrst 1BC63 =USGch- 1BC0B =USGch+ 1BC15 =USG*10 1B508 =UPDPC 07B58 =UPDANN 13571 =UPD2ST 2F674 =UPD2EN 2F6A6 =UPD1ST 2F55D =UPD1EN 2F599 =UPCPOS 13C67 =UNP 00001 =UNFNIB 2F6FA =TstEnd 1C0FF =Trace 0000F =TWO* 0DB38 =TST15 0D47A =TST12A 0D476 =TRTO+ 0FE7B =TRTO* 0FEA9 =TRSFMu 16B84 =TRPREG 2F6F9 =TRMNTR 0F1DD =TRKDON 1CFAC =TRFROM 0FE59 =TRFMBF 2F8C5 =TRFLCK 0FE18 =TRC90 0DA11 =TRACEM 2F7B0 =TONE 0EBEB =TODT 13229 =TMRIN3 2F6B6 =TMRIN2 2F6AE =TMRIN1 2F6A6 =TMRAD3 2F6A1 =TMRAD2 2F69C =TMRAD1 2F697 =TKSCN7 08A99 =TKSCN+ 08A6B =TIMOFS 2F763 =TIMLST 2F76F =TIMLAF 2F77B =TIMER3 2E1F8 =TIMER2 2E2F8 =TIMER1 2E3F8 =TIMAF 2F787 =TGSBS 2F5A3 =TFORN 2F59E =TFHDLR 1702F =TERCHR 2F97D =TBMSG$ 099AB =TBLJMP 0242A =TASTK 2F599 =TAN15 0D733 =TAN12 0D72F =SetAVM 1B9FA =SavLvl 00005 =SYSFLG 2F6D9 =SYSEN 2F58A =SYNTXe 02E2B =SWPBYT 17A24 =SVTRC 0FA35 =SVINFO 0845A =SVINF+ 08457 =SUBONE 0C327 =STUFF 1B0B2 =STSCR 0E92C =STSAVE 2F6BE =STRTST 1B1C7 =STRNGP 0379D =STRHED 14C2E =STRHDR 0F09A =STRGCK 036BA =STREQL 1B1EF =STRASN 0F6B3 =STR$SB 18149 =STR$00 1815C =STORE3 0F62F =STORE 0F5F8 =STMTR1 2F881 =STMTR0 2F871 =STMTD1 2F896 =STMTD0 2F891 =STMBUF 090DF =STMBCL 090E7 =STKVCT 1470C =STKCMD 155ED =STKCHR 18504 =STCD2 0D427 =STATSV 1732F =STATRS 172F3 =STATAR 2F7AD =STAB2 0D400 =STAB1 0D3D9 =SRLEAS 015EC =SQRSAV 0D629 =SQR70 0C5C3 =SQR17 0C553 =SQR15 0C534 =SPLTAX 0E62B =SPLTAC 0C934 =SPLITC 0C940 =SPLITA 0C6BF =SPACE 0AD9D =SNDWD+ 17E1F =SNAPSV 015A7 =SNAPRS 01571 =SNAPR* 01578 =SNAPBF 2F7F0 =SLEEP 006C2 =SKIPDC 057F6 =SIN15 0D71A =SIN12 0D716 =SIGTST 0E636 =SIGCHK 0BD98 =SHRT 0F96C =SHFRBD 0DB5F =SHFRAC 0DB51 =SHFLAC 0DB46 =SHF10 0C486 =SFLAGT 13608 =SFLAGS 135FA =SFLAGC 13601 =SFLAG? 1364C =SETTMO 13158 =SETSB 0D641 =SETFMT 0F01F =SETALR 12917 =SETALM 1290D =SENDWD 17E15 =SENDIT 17DE3 =SENDEL 17DC1 =SEND20 17DFA =SECHMS 13252 =SE1-10 04468 =SCRTCH 2F901 =SCRST0 2F901 =SCRPTR 2F966 =SCROLT 2F946 =SCRLLR 0212E =SCREX3 2F971 =SCREX2 2F961 =SCREX1 2F951 =SCREX0 2F941 =SCOPCK 0915B =SCNRT 022B9 =SCAN 04C40 =SB15S 0E19A =SAVSTK 2F59E =SAVGSB 0D64E =SAVEXM 0D663 =SAVESB 0D66E =SAVED0 1149A =SAVD0 1C587 =SALLOC 0153B =S-R1-3 2F890 =S-R1-2 2F88B =S-R1-1 2F886 =S-R1-0 2F881 =S-R0-3 2F880 =S-R0-2 2F87B =S-R0-1 2F876 =S-R0-0 2F871 =ResetC 00008 =RUNRTN 074EA =RUNRT1 074E7 =RSTST 0F5C5 =RSTKBp 2F81F =RSTKBF 2F820 =RSTK<R 014A8 =RSTD0 06832 =RST2<R 014A6 =RPTKY 152BA =RPLSBH 1799B =RPLLIN 013F7 =ROWDVR 2E350 =ROMFND 1102F =ROMCID 00BFE =RNSEED 2F6FE =RNDNRM 0CAB1 =RNDAHX 136CB =RND12+ 0C9D5 =RND-12 1B01F =RMD15 0C77E =RJUST 12AE2 =RFUPD+ 0A66E =RFNBFR 2F57B =RFAD-I 0A659 =RFAD-- 0A652 =RFAD+I 0A702 =RFAD++ 0A6FB =REWIND 11365 =REVPOP 0BD31 =REV$ 1B38E =REST* 03035 =RESREG 2F7C2 =RESPTR 03172 =RESERV 2F986 =RESCAN 04A4C =REPROM 18A1E =RENSUB 1A753 =REM15 0C7D3 =RELJMP 05047 =REDUCE 15977 =RECALL 0F281 =RECADR 0F4B7 =READP5 0323B =READNB 17518 =READIN 0F484 =RDTEXT 17489 =RDLNAS 13A1F =RDINFO 0846B =RDHDR1 076FD =RDCHDR 076F0 =RDCHD+ 076EE =RDBAS 173FF =RDATTY 17CC6 =RCVOFS 1C050 =RCSCR 0E954 =RCLW3 0E9C4 =RCLW2 0E9BE =RCLW1 0E981 =RCL* 0E983 =RCCD2 0D41C =RCCD1 0D3F5 =RAWBFR 2F580 =RANGE 1B07C =RAMROM 0A5F7 =RAMEND 2F5B2 =R<RSTK 014DD =R<RST2 014DB =R4REV 1DBA8 =R3REV 153AB =R3=D10 03526 =R2REV 0AA83 =R1REV 00785 =QUOTCK 0623D =QUOEXe 02E8B =PgmRun 0000D =PWROFF 00526 =PWIDTH 2F958 =PUTRES 18115 =PURGDC 05745 =PUGFIB 12198 =PSHUPD 08F0D =PSHSTL 08C85 =PSHSTK 08C7F =PSHMCR 08F0B =PSHGSB 08F13 =PRT#DC 06841 =PRSscn 1BA88 =PRSsc+ 1BA84 =PRSC00 07B93 =PRPSND 06B17 =PRNTDC 05450 =PRNEXe 02E95 =PRMPTR 2F5B7 =PRMCNT 2F94B =PRINTt 00001 =PRINT* 17F37 =PRGMST 2F562 =PRGMEN 2F567 =PRGFMF 0A146 =PRESCN 04A49 =PREP 0ADAF =PPOS 2F956 =POPUPD 08F3E =POPSTR 1B405 =POPSTK 08F55 =POPMTH 1B3DB =POPBUF 010EE =POP2N+ 0BD58 =POP2N 0BC8C =POP1S 0BD38 =POP1R 0E8FD =POP1N+ 0BD91 =POP1N 0BD1C =POLLD+ 1232D =POLL 12337 =PNDALM 2F761 =PI/4 0DAA1 =PI/2D 0DB7A =PI/2 0DB77 =PFNDZL 078E2 =PFINDL 078DF =PEDITD 0FF62 =PEDIT 0FF5F =PDEV 09E9E =PCADDR 2F679 =PART3 18097 =PARERR 02F08 =P1-10 041C1 =OVP 00002 =OVFNIB 2F6FB =OVFL 0CA73 =OUTVAR 0373E =OUTRES 0BC84 =OUTNIB 02D28 =OUTNBS 05426 =OUTNBC 05423 =OUTLIT 036F3 =OUTLI1 03709 =OUTELA 05303 =OUTEL1 05300 =OUTC15 05421 =OUTBYT 02CE8 =OUTBY+ 02CE5 =OUTBS 2F58F =OUT3TK 02D15 =OUT3TC 02D12 =OUT2TK 02CFF =OUT2TC 02CFD =OUT1TK 02CEB =OUT1T+ 02CDF =ORXM 0D633 =ORSB 0D63C =ORGSB 0D65B =OPENF 11B06 =ONTIMR 08008 =ONP40 02B7B =ONINTR 2F68D =ONDC20 05501 =OKP 00000 =OFFFLG 2F442 =OBEDIT 17687 =OBCOLL 01435 =OAGNXT 03060 =NwOFFS 1C02D =NoCont 0000E =NXTVAR 13E4C =NXTVA- 13E58 =NXTSTM 08A48 =NXTP 03455 =NXTLIN 10031 =NXTIRQ 2F70D =NXTEXP 1C2F7 =NXTELM 148AC =NXTADR 147E8 =NUMSCN 04D18 =NUMCK 0369D =NUMC+O 03696 =NUMC++ 03690 =NULLP 07999 =NTOKNL 048E6 =NTOKEN 0493B =NOSCRL 14C8A =NORDIM 0AE2D =NEEDSC 2F94A =MVMEM+ 0133C =MULTF 0C446 =MTHSTK 2F599 =MTADR+ 081A1 =MTADDR 08195 =MSPARe 02E5C =MSN15 0D557 =MSN12 0D553 =MPY 0ECBB =MPOP2N 0BD54 =MPOP1N 0BD8D =MP2-15 0C43A =MP2-12 0C432 =MP15S 0C440 =MP1-12 0C436 =MOVEUM 1B15C =MOVEUA 1B168 =MOVEU4 1B174 =MOVEU3 1B177 =MOVEU2 1B172 =MOVEU1 1B16F =MOVEU0 1B162 =MOVEDM 1B0EE =MOVEDD 1B106 =MOVEDA 1B0FA =MOVED3 1B109 =MOVED2 1B104 =MOVED1 1B101 =MOVED0 1B0F4 =MOVE*M 01308 =MOD15 0C796 =MLFFLG 2F870 =MGOSUB 1AF01 =MFWRQ8 093C3 =MFWRNQ 093C5 =MFWRN 093BC =MFLG=0 13DA1 =MFERRS 0939E =MFERR* 093F1 =MFERR 09393 =MFER42 0962C =MESSG 0CC17 =MEMERX 0944F =MEMERR 0944D =MEMER* 0945B =MEMCKL 012A5 =MEMBER 1B098 =MBOX^ 2F7A9 =MAXCMD 2F976 =MAKEBF 01751 =MAKE1 0DACE =MAINST 2F558 =MAINLP 002FD =MAINEN 2F571 =MAIN30 0037E =MAIN05 00338 =LXTXTT 1EE9F =LXFND 0979D =LSTLEN 06C27 =LSLEEP 006CD =LOOPST 2F7AC =LOCKWD 2F7B2 =LOCFIL 1721D =LOCADR 0A611 =LNSKP- 089FF =LNPEXT 02617 =LNEP66 027EA =LN30 0CD9C =LN15 0CD81 =LN12 0CD7D =LN1+XF 0CD51 =LN1+15 0CD44 =LISTDC 05839 =LINP 02A07 =LINEP+ 02626 =LINEP 02620 =LIN#DC 05115 =LIN#D+ 05112 =LIN#AU 05122 =LIMITS 0AC3E =LGT15 0D1AE =LEXPTR 2F6CF =LEXBF+ 10DDF =LEEWAY 000D4 =LEAVE 04C01 =LDSST2 04F9E =LDSST1 04F72 =LDCSPC 2F6C1 =LDCSET 05060 =LDCOMP 04F69 =LDCM10 04F6F =LDCEXT 04F5E =LCDINI 00665 =LBLNIF 02A0D =LBLNAM 077E7 =LBLINP 02A04 =LBLIN# 2F871 =LASTFN 000B4 =LABLDC 05702 =LABELP 03E9F =KYDN? 00774 =KEYSCN 00D4D =KEYSAV 2F462 =KEYRD 14E11 =KEYPTR 2F443 =KEYNAM 1AC04 =KEYMRG 08B8F =KEYFND 08CB8 =KEYDEL 08D2C =KEYCOD 1FD22 =KEYBUF 2F444 =KEY$ 1ACA8 =KCOLD 2F462 =KCOLC 2F463 =KCOLB 2F464 =KCOLA 2F465 =KCOL9 2F466 =KCOL8 2F467 =KCOL7 2F468 =KCOL6 2F469 =KCOL5 2F46A =KCOL4 2F46B =KCOL3 2F46C =KCOL2 2F46D =KCOL1 2F46E =KCOL0 2F46F =Insert 00007 =InhEOL 00004 =IVVARe 02E66 =IVPARe 02E3F =IVP 00004 =IVLNIB 2F6FD =IVEXPe 02E35 =IVARG 0D749 =IVAERR 0E920 =ISRAM? 10192 =IS-TBL 2F78D =IS-PRT 2F794 =IS-PLT 2F7A2 =IS-INP 2F79B =IS-DSP 2F78D =IOFSCR 1188E =IOFND0 118C1 =IOBFST 2F571 =IOBFEN 2F576 =INXNIB 2F6F9 =INVNaN 0C65F =INTRPT 0000F =INTR50 000DB =INTR4 2F400 =INTR28 000B9 =INTM 2F430 =INTGR 0F99B =INTB 2F420 =INTA 2F410 =INPOFF 18B49 =INFR15 0C73D =INF*0 0C607 =INBS 2F6C6 =INADDR 2F6D4 =IMxq27 1BB9C =IMoffs 1BA58 =IMinit 1B88F =IMerr 1B989 =IMentr 1B535 =IMGxq1 1BAAB =IMD0-2 1BA21 =IMD0+2 1BA2D =ILCNTe 02E70 =IF12A 0C739 =IDIVA 0EC6E =IDIV 0EC7B =I/ORES 118FF =I/OFND 118BA =I/OEXP 11A11 =I/OEX2 11A0F =I/ODAL 11A41 =I/OCON 11920 =I/OCOL 11979 =I/OALL 1197D =I/OAL+ 1197B =HXDCW 0ECB4 =HXDASC 05FF4 =HUGE 0B75D =HTRAP 0CB2F =HPSCRH 2F97F =HNDLFL 0CBC9 =HMSSEC 13274 =HEXDEC 0ECAF =HEXASC 17148 =HDFLT 1B31B =HASH2 1B0A3 =HASH1 1B0A1 =GetEXP 1C086 =GTXT++ 05192 =GTPTRX 14670 =GTPTRS 14636 =GTKYCD 08D92 =GTKYC+ 08D9B =GTFLAG 1365E =GTEXT1 051A5 =GTEXT+ 05199 =GTEXT 05079 =GSBSTK 2F5A3 =GOTOp 029F6 =GOTODC 0552E =GOTO+ 07A06 =GOTO 079FA =GOSUBp 029F6 =GOSUB 079E9 =GNXTCR 03064 =GETVAL 0DAB2 =GETSTC 07726 =GETST- 07728 =GETST* 07716 =GETSA 0E551 =GETPRO 06BEE =GETPR1 06BFB =GETNAM 1A085 =GETMSK 01BBA =GETDIM 0AD6B =GETCON 0DAA3 =GETCH# 11427 =GETAVM 1864D =GDISP$ 1C3C7 =FUNCR1 2F8AB =FUNCR0 2F89B =FUNCD1 2F8C0 =FUNCD0 2F8BB =FTYPF# 11059 =FTYPDC 06902 =FTBSCH 11093 =FSPECx 09F2D =FSPECp 03CC5 =FSPECe 02F02 =FRange 0B46A =FPOLL 1250A =FORUPD 0A6AE =FORSTK 2F59E =FNRTN4 0F238 =FNRTN3 0F235 =FNRTN2 0F219 =FNRTN1 0F216 =FNPWDS 0D3C0 =FNDFCN 1A0A1 =FNDCLR 1DAEF =FLTYPp 03E71 =FLTDH 1B223 =FLOAT 1B322 =FLIP8 0DB8D =FLIP11 0DBAB =FLIP10 0DB9C =FLGREG 2F6E9 =FLDEVX 01154 =FLADDR 0126B =FIXP 02A6E =FIRSTC 2F47C =FINLIN 18A3A =FINITC 0CD0F =FINITA 0CD03 =FINDLB 07786 =FINDL 0FFE4 =FINDF+ 09F63 =FINDF 09F77 =FINDD0 023E0 =FINDA 023E3 =FIND 0F563 =FILXQ^ 09B76 =FILXQ$ 09B95 =FILSK+ 06F1D =FILFIL 011CE =FILEP1 03EFC =FILEP- 03F00 =FILEP+ 03F07 =FILEP! 03F0F =FILEP 03E9C =FILEF 09FB0 =FILDC* 05759 =FILCRD 1C879 =FIBOFF 12132 =FIBADR 11457 =FIBAD- 11478 =FGTBL 00C9B =FCSTRT 0E757 =FCHLBL 0782C =FASCFD 110C3 =F-R1-3 2F8BA =F-R1-2 2F8B5 =F-R1-1 2F8B0 =F-R1-0 2F8AB =F-R0-3 2F8AA =F-R0-2 2F8A5 =F-R0-1 2F8A0 =F-R0-0 2F89B =Except 0000C =EndNum 000E6 =EXPSKP 1A9AC =EXPRDC 05922 =EXPR 0F23C =EXPPLS 03FDC =EXPPAR 03FD9 =EXPP10 03FE3 =EXPEXC 0F186 =EXPEX- 0F178 =EXPEX+ 0F182 =EXP15 0CF5A =EXF 0D5DF =EXDCLP 0592E =EXCPAR 187E8 =EXCHRe 02E81 =EXCAD+ 08631 =EXACT 128B0 =EXAB2 0D40E =EXAB1 0D3E7 =EX15S 0D5CE =EX15M 0D5CA =EX12 0D5C6 =EX-115 0CF48 =ESCSTA 2F47B =ESCSEQ 023C1 =ERRSUB 2F683 =ERRRTN 074ED =ERRM$f 09806 =ERRLCH 2F97C =ERRL# 2F7EC =ERRADR 2F688 =ERR# 2F7E4 =EOLXCK 05405 =EOLXC* 052EC =EOLSTR 2F95B =EOLSCN 08AA7 =EOLLEN 2F95A =EOLDC 05402 =EOLCKR 02A7A =EOLCK 02A7E =ENDSUB 195A8 =ENDIMG 1C040 =ENDBIN 0764B =ENDALL 0769A =EFIELD 00000 =EDITWF 0A533 =EDIT80 0A5A5 =DZP 00003 =DXP100 0CF7F =DWIDTH 2F94F =DVZNIB 2F6FC =DV2-15 0C4AC =DV2-12 0C4A8 =DV15S 0C4B2 =DV15M 0C4AC =DUSP30 035B1 =DUSP10 03655 =DSTRY* 0B0C9 =DSTRDC 05280 =DSPUPD 01ADA =DSPSTA 2F475 =DSPSET 2F7B1 =DSPRST 02443 =DSPMSK 2F540 =DSPLIN 10127 =DSPLI+ 1010F =DSPFMT 2F6DC =DSPDGT 2F6DD =DSPCNO 09716 =DSPCNB 0971F =DSPCNA 09721 =DSPCL? 020B6 =DSPCHX 2F674 =DSPCHC 01C3C =DSPCHA 01C3E =DSPBUF 09723 =DSPBFS 2F480 =DSPBFE 2F540 =DSP$00 185DB =DSLEEP 0056D =DROPDC 05470 =DRANGE 1B076 =DPVCTR 0AC50 =DPOS 2F94D =DPART3 17EF8 =DPART2 17EA3 =DONNA 09656 =DMNSN 0AE39 =DIVF 0C4B8 =DISPt 00000 =DISPP 035A4 =DISPDC 05450 =DISINT 2F470 =DEST 0F7B0 =DELAYp 02AC6 =DELAYT 2F948 =DEFADR 2F967 =DECP 0328F =DECHEX 1B2D2 =DEBNCE 00CF7 =DD3ST 2E104 =DD3END 2E160 =DD3CTL 2E1FF =DD2ST 2E200 =DD2END 2E260 =DD2CTL 2E2FF =DD1ST 2E300 =DD1END 2E34C =DD1CTL 2E3FF =DCRMNT 1C177 =DCPLIN 10108 =DCONTR 2E3FE =DCHXW 0ECDC =DCHXF 1B223 =DCHX=C 1B2D0 =DBLSUB 0DADD =DBLPI4 0DAFC =DAYYMD 13335 =DAY2JD 13407 =DATPTR 2F692 =DATLEN 0B584 =D=WORD 04C0E =D=AVMS 1A460 =D=AVME 1A476 =D1MSTK 1954E =D1MST+ 13E21 =D1FSTK 1955D =D1C=R3 03047 =D1=AVE 18651 =D12R0A 1BA3C =D0ASCI 09833 =D0ASC+ 0982C =D0=PCA 09B37 =D0=FIB 13AC5 =D0=AVS 09B2C =D0+2RD 13A32 =CurOff 00006 =Clear 00005 =CkLpNC 1B66D =CkLoop 1B669 =CVUCW 03FBC =CURTOP 10063 =CURSRU 1009A =CURSRT 096C1 =CURSRD 100A4 =CURSOR 2F47E =CURSFR 151D7 =CURSFL 151DF =CURRST 2F55D =CURRL 2F7E8 =CURREN 2F56C =CURDVC 0A60B =CURBOT 10059 =CSRC9 1B42F =CSRC8 1B42C =CSRC7 1B415 =CSRC6 1B418 =CSRC5 1B41B =CSRC4 1B41E =CSRC3 1B421 =CSRC2 1B424 =CSRC15 1B441 =CSRC14 1B43E =CSRC13 1B43B =CSRC12 1B438 =CSRC11 1B435 =CSRC10 1B432 =CSRC1 1B427 =CSPEED 2F977 =CSLC9 1B415 =CSLC8 1B42C =CSLC7 1B42F =CSLC6 1B432 =CSLC5 1B435 =CSLC4 1B438 =CSLC3 1B43B =CSLC2 1B43E =CSLC15 1B427 =CSLC14 1B424 =CSLC13 1B421 =CSLC12 1B41E =CSLC11 1B41B =CSLC10 1B418 =CSLC1 1B441 =CSL9R0 1BA0D =CRTF 116C1 =CRLFSD 022A2 =CRLFOF 02296 =CRLFND 0229E =CRFSB- 11664 =CRETF+ 084C4 =CREATE 115A7 =CRDFIL 1D21D =CR 2C000 =CPL#10 07887 =COUNTC 1C346 =COS15 0D725 =COS12 0D721 =CORUPT 09083 =COPYu 08269 =CONVUC 152AA =CONFST 2F9E6 =CONF 10212 =CONCOM 0467E =COMCK+ 032AE =COMCK 036CD =COLLAP 091FB =COLDST 00000 =CNVWUC 03FB8 =CNVUCR 152A7 =CNTADR 2F67E =CNFLCT 0BD15 =CNFFND 109AC =CMPT 125B2 =CMOSTW 2F438 =CMOSTV 0168F =CMDS20 01672 =CMDPTR 2F6D4 =CMDPR" 01627 =CMDINI 016D1 =CMDFND 01693 =CMD1ST 01654 =CLRPRM 04827 =CLRFRC 0C6F4 =CLOSEF 12087 =CLOSEA 120E4 =CLCSTK 2F585 =CLCBFR 2F576 =CLASSA 0D590 =CKSUM4 1DBA6 =CKSUM3 153A9 =CKSUM2 0AA81 =CKSREQ 00721 =CKINFO 18542 =CKINF- 18534 =CK"ON" 076AD =CHNLST 2F5BE =CHNHED 0F579 =CHN#SV 2F96F =CHKmem 012C7 =CHKSPC 012AE =CHKEOL 13D6D =CHIRP 0EC5A =CHEDIT 14C99 =CHAIN- 07C1C =CHAIN+ 07C12 =CATEDT 06435 =CATCHR 03F70 =CATCH+ 03F69 =CATC++ 03F66 =CAT$20 06746 =CALSTK 2F5AD =CALLP 0389C =CALL 18DAE =CALBIN 18D8C =C+A2D1 1C053 =BldIMG 1BA68 =BldIMA 1BA66 =BldIM+ 1BA6A =BitsOK 00001 =BYTscA 1BA4A =BSERR 0939A =BSCEXT 075CF =BSCEXC 07437 =BSCEX2 0743A =BRTF 0DC15 =BRT30 0DBE3 =BP+C 0EB40 =BOPNM- 1B864 =BLNKCK 051C1 =BLDLCD 0189C =BLDDSP 01898 =BLDCON 16279 =BLDBIT 019BC =BIG 0B747 =BIASC+ 0D540 =BIASA+ 0D52D =BF2STK 18663 =BF2DSP 01C0E =BEEP 0EA6E =BASICs 000B5 =BASE 0F953 =BASCHK 0773E =BASCHA 07741 =BACK3B 13B08 =BACK2B 13B0A =BACK1B 13B0C =BACK 1BA4F =AVS2DS 09708 =AVMEMS 2F594 =AVMEME 2F599 =AVE=D1 18BB8 =AVE=C 18BBB =AUTINC 2F6CB =ATNFLG 2F442 =ATNDIS 2F441 =ATNCLR 00510 =ATAN15 0DBBE =ASRW5 0ED0A =ASRW4 0ED0D =ASRW3 0ED10 =ASNMNT 0F5E0 =ASLW5 0ED1B =ASLW4 0ED1E =ASLW3 0ED21 =ASIN15 0DBCC =ASIN12 0DBC8 =ASCII 0079B =ASCICK 0514E =ARYSIZ 0B61B =ARYELM 0B5A7 =ARYDC 05178 =ARRYCK 0366A =ARITH 061E0 =ARGSTA 0E90C =ARGST- 0E910 =ARGPRP 0E8EF =ARGPR+ 0E8EB =ARGF 0D6A4 =ARGERR 0BF19 =ARG15 0D67F =ARG12 0D67B =ANNAD4 2E34E =ANNAD3 2E34C =ANNAD2 2E102 =ANNAD1 2E100 =ANN1.5 2E101 =ALRM6 2F755 =ALRM5 2F749 =ALRM4 2F73D =ALRM3 2F731 =ALRM2 2F725 =ALRM1 2F719 =ALMSRV 1257D =ALLDUN 04BEF =ADRSUB 0F4CF =ADRS80 0F567 =ADRS50 0F551 =ADRS40 0F52B =ADJN 12825 =ADJA 1289A =ADHEAD 181B7 =ADDRSS 0F527 =ADDP 03A03 =ADDONE 0C330 =ADDF 0C372 =AD2-15 0C363 =AD2-12 0C35F =AD15s 0C369 =AD15S 0E19D =AD15M 0C366 =ACTIVE 2F5A8 =ACOS15 0DBD7 =ACOS12 0DBD3 =ACCEPT 0450F =A-MULT 1B349 =?PRFIL 1737E =?PRFI+ 17380 =1/X15 0C33E =-LINE 15275 =#CK 03356 @EOF set `wc -lwc <areuh/equ/sasm.ep` if test $1$2$3 != 1817363424571 then echo ERROR: wc results of areuh/equ/sasm.ep are $* should be 1817 3634 24571 fi chmod 644 areuh/equ/sasm.ep echo x - areuh/equ/hp71.ep cat >areuh/equ/hp71.ep <<'@EOF' =xZERO 0001C =xVARS 0005B =xROUND 0004C =xPOS 00042 =xPCRD 0003E =xNEG 0003D =xNEAR 0003C =xMATH 00036 =xINTO 0002E =xFLOW 00029 =xEXTND 00026 =xCLOCK 00015 =xANGLE 00006 =uTEST 0D435 =uSTRPT 000D0 =uRND>P 0C9CF =uRESXT 0C9C1 =uRESTP 000F1 =uRESNX 0C9BD =uRESD1 0E1EE =uRES12 0C994 =uOPNWM 000E0 =uOPNNM 000D8 =uOPNM- 000DF =uNUMNs 000F9 =uNUMNn 000F8 =uNUMFs 000FB =uNUMFn 000FA =uNUMEs 000FD =uNUMEn 000FC =uMULT 000D1 =uMODES 0BDB1 =uLOOPS 000D3 =uLOOPP 000EF =uLOOPB 000D2 =uJMP{} 000D9 =uJMPst 000DA =uJMPdl 000DB =uIMsta 000DE =uIMend 000F0 =uIMbck 000DC =uIMXCH 000D4 =uHKB^ 000F6 =uDELIM 000F4 =uCPLXC 000EE =uALit 000F7 =t^ 00080 =tZERO C01EF =tZ 0005A =tXWORD 000EF =tXFN 000B3 =tWAIT 000D8 =tVARS B01EF =tVAL 000A5 =tUSING 000FD =tUSER 000E2 =tUPRC$ 000AB =tUNF 000B0 =tTRACE 000EA =tTO 000F3 =tTIMER 000E4 =tTIME$ 00095 =tTIME 0007B =tTHEN 000F4 =tTAN 00098 =tTAB 000F7 =tSVAR 0002D =tSUB 000C1 =tSTR$ 000A6 =tSTOP 000D9 =tSTEP 000F6 =tSTAT 000CE =tSQR 00092 =tSMALL 00011 =tSIN 00096 =tSHORT 000CB =tSGN 000A1 =tSFLAG 000FB =tSEMIC 000F2 =tSDEV 0009E =tRUN 000FE =tROUND C01EF =tRND 000A0 =tRMD 0006D =tRFILE 000DE =tRETRN 000DB =tRESTR 000DE =tRES 0007F =tREM 000E6 =tRELOP 0008A =tREAL 000BC =tREAD 000C7 =tRDIAN 000D4 =tRAD 0006E =tPURGE 000EB =tPRMST 000F3 =tPRMEN 000F8 =tPRINT 000CD =tPREDV 0009F =tPOS 201B3 =tPORT 000D1 =tPI 00079 =tPCRD E01EF =tPAUSE 000D7 =tOVF 000AF =tOR 0008D =tOPT'N 000ED =tON 000E0 =tOFF 000E1 =tNUM 000A3 =tNOT 00081 =tNEXT 000C4 =tNEG D01EF =tNEAR C01EF =tNAME 000BD =tMOD 00074 =tMIN 000AC =tMEAN 0009D =tMAXRL 0006C =tMAX 000AD =tMATH 601EF =tMAIN 000D2 =tLR 000B6 =tLPRP 000AA =tLOG10 00093 =tLOG 00090 =tLN 00091 =tLITRL 000C4 =tLIST 000BB =tLINPT 000BF =tLINE# 0000F =tLET 000C0 =tLEN 000A9 =tLBLST 000F6 =tLBLRF 0000E =tKEYS 000CF =tKEY$ 00073 =tKEY 000E5 =tIVL 000AE =tISUB$ 000A7 =tIS 000E7 =tIP 0006A =tINX 000B2 =tINTR 015FF =tINTO E01EF =tINTEG 000CA =tINT9 00005 =tINT8 00006 =tINT7 00007 =tINT6 00008 =tINT5 00009 =tINT4 0000A =tINT3 0000B =tINT2 0000C =tINT12 00002 =tINT11 00003 =tINT10 00004 =tINT 0009C =tINPUT 000C9 =tINF 00070 =tIN 000F2 =tIMAGE 000FF =tIF 000DF =tGOTO 000DD =tGOSUB 000DC =tFP 0006B =tFOR 000C3 =tFN 0007C =tFLT9 00015 =tFLT8 00016 =tFLT7 00017 =tFLT6 00018 =tFLT5 00019 =tFLT4 0001A =tFLT3 0001B =tFLT2 0001C =tFLT12 00012 =tFLT11 00013 =tFLT10 00014 =tFLT1 0001D =tFLOW 901EF =tFFN 000B4 =tFETCH 000C8 =tFACT 000A8 =tEXTND 601EF =tEXTIF 000F4 =tEXP 00094 =tEXOR 0008C =tERROR 000E3 =tERRN 00076 =tERRL 00075 =tEPS 00071 =tEOL 000F0 =tENTER 4FFEF =tENDSB 000C2 =tENDDF 000BA =tEND 000DA =tELSE 000F5 =tEDIT 000B8 =tDVZ 000B1 =tDSTRY 000BE =tDMYAR 0007E =tDIV 00086 =tDISP 000C5 =tDIM 000CC =tDELET 000B7 =tDELAY 000D6 =tDEGRE 000D3 =tDEG 0006F =tDEF 000B9 =tDATE$ 00078 =tDATE 00077 =tDATA 000C6 =tCVAL 000E1 =tCOS 00097 =tCOPY 000B5 =tCOMMA 000F1 =tCOLON 000E2 =tCMPLX 0007A =tCLOCK 501EF =tCHR$ 000A4 =tCFLAG 000FA =tCEIL 00072 =tCAT 000EC =tCARD 000D0 =tCALL 000F9 =tBIG 00010 =tBEEP 000E8 =tBASE 000E9 =tAUTO 000EE =tATAN 0009B =tASIN 00099 =tARRAY 0007D =tANGLE 601B3 =tAND 0008B =tALL 000F8 =tADIG9 00069 =tADIG8 00068 =tADIG7 00067 =tADIG6 00066 =tADIG5 00065 =tADIG4 00064 =tADIG3 00063 =tADIG2 00062 =tADIG1 00061 =tADIG0 00060 =tADD 000D5 =tACOS 0009A =tABS 000A2 =t@ 000F4 =t/ 00084 =t- 00082 =t+ 00087 =t* 00083 =t& 00089 =t% 00085 =t! 000FC =sXWORD 00009 =sXQT 00000 =sXCPT 00004 =sUNDEF 00001 =sSpecl 00006 =sSTOP 00005 =sSTAT 00006 =sSSTdc 00001 =sSST 00002 =sSIGN 00009 =sRUNDC 00007 =sRUNBn 00004 =sRFILE 00008 =sRETRN 00000 =sRESTR 0000A =sRENUM 00008 =sRENAM 00006 =sREADI 00004 =sRDX 0000B =sRAD 00009 =sPRGCF 0000B =sPCRD 00008 =sONTMR 00006 =sONERR 00004 =sNoChn 00002 =sNEGRD 0000B =sMULT 00008 =sMAINc 00005 =sKEYS 00005 =sInit 00003 =sIX 00007 =sIRAM 00002 =sINX 00005 =sINFRD 0000A =sI/OBF 0000A =sGOSUB 00003 =sFOUND 0000A =sEXTGS 00005 =sEXTDV 00000 =sERROR 00000 =sEOF 00007 =sENDx 00001 =sDEST 00003 =sCplxP 00007 =sCntg 00002 =sCURUP 00002 =sCURUD 00004 =sCURBT 00003 =sCONTK 00009 =sCONT 0000A =sCHAIN 0000B =sCARDC 00008 =sCARD 00002 =sC/P 00001 =sBYEx 00000 =sARITH 00007 =pZERPG 000F7 =pWTKY 0001C =pWRCBF 0001A =pWCRD8 00024 =pWCRD 00035 =pWARN 000F3 =pVER$ 00000 =pTRFMx 0003C =pTRANS 000EF =pTIMR# 0003B =pTEST 000F0 =pSREQ 000F9 =pSREC# 00028 =pRUNnB 00031 =pRUNft 00030 =pRTNTp 0003A =pRNAME 00011 =pREN 00039 =pREAD# 00027 =pRDNBF 00019 =pRDCBF 00018 =pRCRD 00034 =pPWROF 000FC =pPURGE 00010 =pPRTIS 0000F =pPRTCL 0000E =pPRIN# 00026 =pPRGPR 00032 =pPARSE 000F4 =pMRGE2 0002F =pMNLP 000FA =pMERGE 0000D =pMEM 000F1 =pLIST2 0002E =pLIST 0000C =pKYDF 0001B =pIMcpw 00022 =pIMcpi 00021 =pIMbck 00020 =pIMXQT 0001D =pIMXCH 0001F =pIMCHR 0001E =pFTYPE 0002D =pFSPCx 00005 =pFSPCp 00004 =pFPROT 0000B =pFNOUT 0003E =pFNIN 0003D =pFINDF 00017 =pFILXQ 00003 =pFILDC 00002 =pFASCH 0002C =pExcpt 000F8 =pERROR 000F2 =pEOFIL 00025 =pENTER 00012 =pEDIT 0002B =pDSWNK 000FE =pDSWKY 000FD =pDIDST 0000A =pDEVCp 00001 =pDATLN 0002A =pCURSR 00029 =pCRT=8 00023 =pCREAT 00009 =pCRDAB 00033 =pCOPYx 00008 =pCONFG 000FB =pCMPLX 00038 =pCLDST 000FF =pCAT$ 00007 =pCAT 00006 =pCALSV 00037 =pCALRS 00036 =pBSCex 000F6 =pBSCen 000F5 =oTXsod 00005 =oTIMEh 00016 =oSUBLn 00025 =oSPDn2 0000E =oSPDTB 00111 =oSHLNb 00013 =oRTN3p 00014 =oRTN2p 0000F =oRTN1p 0000A =oRLENb 00034 =oRECLb 00024 =oREC#b 00020 =oPROTb 00009 =oPOL#p 0000A =oMSGPT 00009 =oMAINT 0005D =oLXsod 00005 =oKYsod 00005 =oIMPLh 00025 =oFTYPh 00010 =oFTYPb 00005 =oFT-FL 00010 =oFSIZb 00039 =oFNAMh 00000 =oFLSTr 00031 =oFLENh 00020 =oFLAGh 00014 =oFIL#b 00000 =oFBF#b 00002 =oFBEGb 0000D =oDp 0002E =oDLENb 0002E =oDEVCb 0000C =oDBEGb 00015 =oDAsod 0000D =oDATEh 0001A =oD1p 0001E =oD0p 00019 =oCPOSb 00028 =oCOPYb 0000A =oBSsod 00011 =oBPOSp 00005 =oBNsod 00011 =oAp 0003E =oACCSb 0000B =o41sod 00005 =lTIMEh 00004 =lTEXTp 00004 =lSPDn2 00001 =lSPDn 00001 =lSPDTB 0004E =lSHLNb 00002 =lRTN3p 00005 =lRTN2p 00005 =lRTN1p 00005 =lRLENb 00005 =lRECLb 00004 =lREC#b 00004 =lPROTb 00001 =lPOLra 00006 =lPOLSV 0003E =lPOLLp 00005 =lPOL#p 00005 =lMSGp 00004 =lLXTKR 00004 =lLXID 00002 =lLXFAD 00005 =lLXENT 0000B =lLXADR 00005 =lFTYPh 00004 =lFTYPb 00004 =lFSIZb 00006 =lFNAMh 00010 =lFNAM8 00010 =lFNAM+ 00004 =lFLENh 00005 =lFLAGh 00002 =lFILSV 00032 =lFIL#b 00002 =lFIB 0003F =lFBF#b 00003 =lFBEGb 00006 =lEOL 00002 =lDp 00010 =lDLENb 00006 =lDEVCb 00001 =lDEVC 00005 =lDBEGb 0000B =lDATEh 00006 =lD1p 00005 =lD0p 00005 =lCPOSb 00006 =lCOPYb 00001 =lBPOSp 00005 =lAp 00010 =lACCSb 00001 =kcVIEW 0000B =kcUSEX 0000C =kcUSER 00003 =kcUP 00012 =kcTOP 00014 =kcSST 00011 =kcRUN 0000F =kcRT 00009 =kcOFF 00018 =kcLFT 00008 =kcLERR 0001A =kcLC 00001 =kcLAST 00019 =kcI/R 00002 =kcGON 00016 =kcFRT 00006 =kcFLFT 00005 =kcEOL 0000D =kcDOWN 00013 =kcCTRL 0000A =kcCONT 00010 =kcCALC 00017 =kcBOT 00015 =kcBKSP 00007 =kcATTN 0000E =kc-LIN 00004 =kc-CHR 00000 =k#VIEW 0006E =k#USEX 000A5 =k#USER 0006D =k#UP 00032 =k#TOP 000A2 =k#SST 00066 =k#RUN 0002E =k#RT 00030 =k#OFF 00063 =k#LFT 0002F =k#LERR 000A1 =k#LC 0006A =k#LAST 000A4 =k#I/R 00069 =k#GON 0009B =k#FRT 000A0 =k#FLFT 0009F =k#EOL 00026 =k#DOWN 00033 =k#CTRL 0009E =k#CONT 00070 =k#CALC 0006F =k#BOT 000A3 =k#BKSP 00067 =k#ATTN 0002B =k#3 00029 =k#2 00028 =k#1 00027 =k#-LIN 0006B =k#-CHR 00068 =flVIEW FFFCC =flUSRX FFFC6 =flUSER FFFF7 =flUNF FFFFB =flTNOF FFFCD =flSUSP FFFC1 =flSCEN FFFF2 =flRTN FFFD4 =flRPTD FFFC5 =flRAD FFFF6 =flQIET FFFFF =flPWDN FFFCF =flPRGM FFFC2 =flPDWN FFFEB =flOVF FFFFA =flNZ8 FFFC8 =flNZ7 FFFC9 =flNZ6 FFFCA =flNZ5 FFFCB =flNZ4 FFFE8 =flNOPR FFFE6 =flNOFN FFFD6 =flNEGR FFFF4 =flMKOF FFFCE =flLC FFFF1 =flIVL FFFF8 =flINX FFFFC =flINFR FFFF5 =flFXEN FFFF3 =flEXTD FFFEA =flEXAC FFFD2 =flEOT FFFE9 =flDVZ FFFF9 =flDORM FFFD5 =flDG3 FFFEC =flDG2 FFFED =flDG1 FFFEE =flDG0 FFFEF =flCTRL FFFD0 =flCTON FFFFD =flCMDS FFFD1 =flCLOC FFFD3 =flCALC FFFC0 =flBPLD FFFE7 =flBEEP FFFFE =flBAT FFFC3 =flBASE FFFF0 =flALRM FFFC4 =flAC FFFC7 =fTEXT 00001 =fSOS 000CF =fSDATA 0E0D0 =fROM 0E21C =fMOS 0007F =fLIF1 00001 =fLEX 0E208 =fKEY 0E20C =fEOS 0006F =fEOR 000EF =fEOF 000FF =fDATA 0E0F0 =fBIN 0E204 =fBASIC 0E214 =fASCII 00001 =fAOS 000DF =ew/o 000EB =enull 00000 =eZRO/0 00007 =eZRDIV 00008 =eXWORD 00023 =eXFNNF 00022 =eWRGNM 00049 =eWALGN 0005B =eVFYER 00044 =eVARTY 00032 =eVALGN 0005C =eUNORC 00014 =eUNKCD 00045 =eUNFLW 00001 =eUALGN 0005F =eTUSLO 00048 =eTUFAS 00047 =eTRKOF 000E5 =eTRKDN 00061 =eTOOMI 00027 =eTOOFI 00028 =eTOO 000EF =eTNINF 00004 =eTFWRN 00058 =eTFM 000F1 =eTFFLD 00038 =eSYSER 00017 =eSYNTX 0004B =eSUBSC 0001C =eSTROV 00025 =eSTMNF 0001E =eSQR- 0000A =eSPGNF 00031 =eSIGOP 00013 =eRwoGS 0002C =eRWERR 00046 =eRECOR 0001D =eRALGN 0005D =eR1WRN 00057 =eR0WRN 00056 =eQUOEX 0004D =ePULL 000F6 =ePRTCT 000F8 =ePROTD 00042 =ePRNEX 0004C =ePRMIS 00024 =ePRCER 00054 =ePLLC# 00059 =ePLLC 0005A =ePALGN 0005E =eOVFLW 00002 =eOVFL* 000F5 =eNXwoF 0002B =eNVSTA 00033 =eNUMIN 00026 =eNSVAR 00033 =eNOTIN 00043 =eNODAT 00020 =eNFOUN 000E8 =eNEG^X 00009 =eMSPAR 00052 =eMPI 00019 =eMMCOR 00017 =eMEM 00018 =eLOG- 0000D =eLOBAT 00016 =eLN0 0000C =eL2LNG 00041 =eIVTAB 00030 =eIVSTA 00034 =eIVSOP 00035 =eIVSAR 00033 =eIVARG 0000B =eINX 00015 =eINVUS 0002E =eINVST 000ED =eINVLD 000EC =eINVIM 0002D =eINPUT 000F4 =eINF^0 00012 =eINF 000F3 =eIMGOV 0002F =eILVAR 00053 =eILTFM 00037 =eILPAR 00051 =eILLEG 000E6 =eILKEY 00055 =eILEXP 00050 =eILCNT 0004F =eIF/IF 0000E =eIF-IF 0000F =eIF*ZR 00010 =eFwoNX 0002A =eFnFND 00039 =eFTYPE 0003F =eFSPEC 0003A =eFPROT 0003D =eFOPEN 0003E =eFNNtF 00021 =eFILE 000EA =eFEXST 0003B =eFACCS 0003C =eF2BIG 0004A =eEXPCT 000E7 =eEXP0 00003 =eEXCHR 0004E =eEOFIL 00036 =eDVCNF 00040 =eDATTY 0001F =eCHNL# 00029 =eCALGN 00060 =eALGN 000F0 =eAF 0001B =e2MROM 0001A =e1^INF 00011 =e0^NEG 00005 =e0^0 00006 =e#of# 000F7 =dPORT 00001 =dPCRD 00007 =dMAIN 00000 =dIRAM 00001 =dCARD 00007 =cRCL 00067 =cR->C 00069 =cC->C 00068 =bSTMXQ 00811 =bSTMT 00801 =bSTAT 00806 =bSTART 00808 =bSCRTC 00E00 =bROMTB 00BFE =bPILSV 0080F =bPILAI 00810 =bLEX 00BFC =bIEXKY 00802 =bFILE 00805 =bFIB 00803 =bECOMD 00809 =bCHARS 00BFB =bCARD 00807 =bASSGN 00804 =bALTCH 00BFB =a9 00039 =a8 00038 =a7 00037 =a6 00036 =a5 00035 =a4 00034 =a3 00033 =a2 00032 =a1 00031 =a0 00030 =a. 0002E =a' 00027 =a$ 00024 =a" 00022 =a! 00021 =ZERBUF 18B20 =YX2-15 0D27A =YX2-12 0D274 =YMDHMS 130DB =YMDH01 130E5 =YMDDAY 13304 =XYEX 0C697 =XXHEAD 1A44E =XROM01 00001 =XMTADR 08133 =XDelay 00009 =WSTRFX 138B5 =WRTSTR 1396F =WRTNUM 139C4 =WRTFIB 11CEE =WRITNB 1752B =WRDSCN 02C2A =WRDSC+ 02C26 =WRBYTC 13A73 =WIPOUT 1B0AF =WINDST 2F471 =WINDLN 2F473 =WFTMDT 085DD =ValSub 0000A =VRIABL 04BC4 =VIEWD1 15147 =VECTOR 2F43C =VARP 0350E =VARNBR 0E289 =VARNB- 0E28D =VARDC 0537C =VALCHK 1AE61 =VAL00 1AD8F =USst05 1BBD4 =USst03 1BBCE =USnm05 1BD12 =USloop 1C14B =USINGp 03628 =USING 1B446 =USGrst 1BC63 =USGch- 1BC0B =USGch+ 1BC15 =USG*10 1B508 =UPDPCC 07B65 =UPDANN 13571 =UPD2ST 2F674 =UPD2EN 2F6A6 =UPD1ST 2F55D =UPD1EN 2F599 =UPCPOS 13C67 =UNP 00001 =UNFNIB 2F6FA =TstEnd 1C0FF =Trace 0000F =TWO* 0DB38 =TST15 0D47A =TST12A 0D476 =TRTO+ 0FE7B =TRSFMu 16B84 =TRPREG 2F6F9 =TRMNTR 0F1DD =TRKDON 1CFAC =TRFROM 0FE59 =TRFMBF 2F8C5 =TRC90 0DA11 =TRACEM 2F7B0 =TRACDC 052FC =TONE 0EBEB =TODT 13229 =TMRIN3 2F6B6 =TMRIN2 2F6AE =TMRIN1 2F6A6 =TMRAD3 2F6A1 =TMRAD2 2F69C =TMRAD1 2F697 =TKSCN7 08A99 =TKSCN+ 08A6B =TIMOFS 2F763 =TIMLST 2F76F =TIMLAF 2F77B =TIMER3 2E1F8 =TIMER2 2E2F8 =TIMER1 2E3F8 =TIMAF 2F787 =TGSBS 2F5A3 =TFORN 2F59E =TFHDLR 1702F =TERCHR 2F97D =TBMSG$ 099AB =TBLJMP 0242A =TBLJMC 02426 =TBLJM2 0243D =TASTK 2F599 =TAN15 0D733 =TAN12 0D72F =SetAVM 1B9FA =SavLvl 00005 =SYSFLG 2F6D9 =SYSEN 2F58A =SYNTXe 02E2B =SWPBYT 17A24 =SVTRC 0FA35 =SVINFO 0845A =SVINF+ 08457 =SUBONE 0C327 =STUFF 1B0B2 =STSCR 0E92C =STSAVE 2F6BE =STRTST 1B1C7 =STRNGP 0379D =STRHED 14C2E =STRHDR 0F09A =STRGCK 036BA =STREQL 1B1EF =STRASN 0F6B3 =STRALL 1AF5D =STR$SB 18149 =STR$00 1815C =STORE 0F5F8 =STMTR1 2F881 =STMTR0 2F871 =STMTD1 2F896 =STMTD0 2F891 =STMBUF 090DF =STMBCL 090E7 =STKVCT 1470C =STKCMD 155ED =STKCHR 18504 =STCD2 0D427 =STATSV 1732F =STATRS 172F3 =STATAR 2F7AD =STAB2 0D400 =STAB1 0D3D9 =SRLEAS 015EC =SQRSAV 0D629 =SQR70 0C5C3 =SQR17 0C553 =SQR15 0C534 =SPLTAX 0E62B =SPLTAC 0C934 =SPLITC 0C940 =SPLITA 0C6BF =SPACE 0AD9D =SNDWD+ 17E1F =SNAPSV 015A7 =SNAPRS 01571 =SNAPR* 01578 =SNAPBF 2F7F0 =SLEEP 006C2 =SKIPDC 057F6 =SIN15 0D71A =SIN12 0D716 =SIGTST 0E636 =SIGCHK 0BD98 =SHUTDN 005E2 =SHRT 0F96C =SHFRBD 0DB5F =SHFRAC 0DB51 =SHFLAC 0DB46 =SHF10 0C486 =SFLAGT 13608 =SFLAGS 135FA =SFLAGC 13601 =SFLAG? 1364C =SETTMO 13158 =SETSB 0D641 =SETFMT 0F01F =SETALR 12917 =SETALM 1290D =SENDWD 17E15 =SENDIT 17DE3 =SENDEL 17DC1 =SEND20 17DFA =SECHMS 13252 =SE1-10 04468 =SCRTCH 2F901 =SCRST0 2F901 =SCRPTR 2F966 =SCROLT 2F946 =SCRLLR 0212E =SCREX3 2F971 =SCREX2 2F961 =SCREX1 2F951 =SCREX0 2F941 =SCOPCK 0915B =SCNRT 022B9 =SCAN 04C40 =SB15S 0E19A =SAVSTK 2F59E =SAVGSB 0D64E =SAVEXM 0D663 =SAVESB 0D66E =SAVD1 1C578 =SAVD0 1C587 =SALLOC 0153B =S-R1-3 2F890 =S-R1-2 2F88B =S-R1-1 2F886 =S-R1-0 2F881 =S-R0-3 2F880 =S-R0-2 2F87B =S-R0-1 2F876 =S-R0-0 2F871 =ResetC 00008 =RUNRTN 074EA =RUNRT1 074E7 =RTNX10 08FF2 =RSTST 0F5C5 =RSTKBp 2F81F =RSTKBF 2F820 =RSTK<R 014A8 =RSTD1 1C596 =RSTD0 06832 =RST2<R 014A6 =RPTKY 152BA =RPLSBH 1799B =RPLLIN 013F7 =ROWDVR 2E350 =ROMFND 1102F =ROMCK5 10FE4 =ROMCID 00BFE =ROMCHK 10FDE =RNSEED 2F6FE =RNDNRM 0CAB1 =RNDAHX 136CB =RND12+ 0C9D5 =RND-12 1B01F =RJUST 12AE2 =RFUPD+ 0A66E =RFNBFR 2F57B =RFAD-I 0A659 =RFAD-- 0A652 =RFAD+I 0A702 =RFAD++ 0A6FB =REWIND 11365 =REVPOP 0BD31 =REV$ 1B38E =REST* 03035 =RESREG 2F7C2 =RESPTR 03172 =RESERV 2F986 =RESCAN 04A4C =REPROM 18A1E =RENSUB 1A753 =RELJMP 05047 =REDUCE 15977 =RECALL 0F281 =RECADR 0F4B7 =READP5 0323B =READNB 17518 =READIN 0F484 =RDTEXT 17489 =RDLNAS 13A1F =RDINFO 0846B =RDHDR1 076FD =RDCHDR 076F0 =RDCHD+ 076EE =RDBYTA 13A2F =RDBAS 173FF =RDATTY 17CC6 =RCVOFS 1C050 =RCURON 14C80 =RCSCR 0E954 =RCLW3 0E9C4 =RCLW2 0E9BE =RCLW1 0E981 =RCLALL 1AFBF =RCL* 0E983 =RCCD2 0D41C =RCCD1 0D3F5 =RAWBFR 2F580 =RANGE 1B07C =RAMROM 0A5F7 =RAMEND 2F5B2 =R<RSTK 014DD =R<RST2 014DB =R4REV 1DBA8 =R3REV 153AB =R3=D10 03526 =R2REV 0AA83 =R1REV 00785 =QUOTCK 0623D =QUOEXe 02E8B =PgmRun 0000D =PWROFF 00526 =PWIDTH 2F958 =PUTRES 18115 =PURGEF 17359 =PURGDC 05745 =PUGFIB 12198 =PSHUPD 08F0D =PSHSTL 08C85 =PSHSTK 08C7F =PSHMCR 08F0B =PSHGSB 08F13 =PRT#DC 06841 =PRSscn 1BA88 =PRSsc+ 1BA84 =PRSC00 07B93 =PRPSND 06B17 =PRNTDC 05450 =PRNEXe 02E95 =PRMPTR 2F5B7 =PRMCNT 2F94B =PRMCHN 0B375 =PRINTt 00001 =PRINT* 17F37 =PRGMST 2F562 =PRGMEN 2F567 =PRGFMF 0A146 =PRESCN 04A49 =PREP 0ADAF =PPOS 2F956 =POPUPD 08F3E =POPSTR 1B405 =POPSTK 08F55 =POPMTH 1B3DB =POPBUF 010EE =POP2N+ 0BD58 =POP2N 0BC8C =POP1S 0BD38 =POP1R 0E8FD =POP1N+ 0BD91 =POP1N 0BD1C =POLLD+ 1232D =POLL 12337 =PNDALM 2F761 =PI/4 0DAA1 =PI/2D 0DB7A =PI/2 0DB77 =PFNDZL 078E2 =PFINDL 078DF =PEDITM 0FF70 =PEDITD 0FF62 =PEDIT 0FF5F =PDEV 09E9E =PCEXPR 06828 =PCADDR 2F679 =PART3 18097 =PARERR 02F08 =P1-10 041C1 =OVP 00002 =OVFNIB 2F6FB =OVFL 0CA73 =OUTVAR 0373E =OUTRES 0BC84 =OUTNIB 02D28 =OUTNBS 05426 =OUTNBC 05423 =OUTLIT 036F3 =OUTLI1 03709 =OUTELA 05303 =OUTEL1 05300 =OUTC15 05421 =OUTBYT 02CE8 =OUTBY+ 02CE5 =OUTBS 2F58F =OUT3TK 02D15 =OUT3TC 02D12 =OUT2TK 02CFF =OUT2TC 02CFD =OUT1TK 02CEB =OUT1T+ 02CDF =ORXM 0D633 =ORSB 0D63C =ORGSB 0D65B =OPENF 11B06 =ONTIMR 08008 =ONP40 02B7B =ONINTR 2F68D =ONDC20 05501 =OKP 00000 =OFFFLG 2F442 =OBEDIT 17687 =OBCOLL 01435 =OAGNXT 03060 =NwOFFS 1C02D =NoCont 0000E =NXTVA- 13E58 =NXTSTM 08A48 =NXTP 03455 =NXTLIN 10031 =NXTIRQ 2F70D =NXTEXP 1C2F7 =NXTELM 148AC =NXTADR 147E8 =NXPRMP 0B3A5 =NXPR10 0B3B0 =NUMSCN 04D18 =NUMCK 0369D =NUMC+O 03696 =NUMC++ 03690 =NULLP 07999 =NTOKNL 048E6 =NTOKEN 0493B =NRMCON 161AF =NOSCRL 14C8A =NORDIM 0AE2D =NEEDSC 2F94A =MVMEM+ 0133C =MULTF 0C446 =MTHSTK 2F599 =MTADR+ 081A1 =MTADDR 08195 =MSPARe 02E5C =MSN15 0D557 =MSN12 0D553 =MSIZE+ 1040A =MSIZE 10407 =MPY 0ECBB =MPOP2N 0BD54 =MPOP1N 0BD8D =MP2-15 0C43A =MP2-12 0C432 =MP15S 0C440 =MP1-12 0C436 =MOVEUM 1B15C =MOVEUA 1B168 =MOVEU4 1B174 =MOVEU3 1B177 =MOVEU2 1B172 =MOVEU1 1B16F =MOVEU0 1B162 =MOVEDM 1B0EE =MOVEDD 1B106 =MOVEDA 1B0FA =MOVED3 1B109 =MOVED2 1B104 =MOVED1 1B101 =MOVED0 1B0F4 =MOVE*M 01308 =MOD15 0C796 =MLFFLG 2F870 =MGOSUB 1AF01 =MFWRQ8 093C3 =MFWRNQ 093C5 =MFWRN 093BC =MFLG=0 13DA1 =MFERsp 0940D =MFERRS 0939E =MFERR* 093F1 =MFERR 09393 =MFER42 0962C =MESSG 0CC17 =MEMERX 0944F =MEMERR 0944D =MEMER* 0945B =MEMCKL 012A5 =MEMBER 1B098 =MBOX^ 2F7A9 =MAXCMD 2F976 =MANSTK 196D3 =MAKEBF 01751 =MAKE1 0DACE =MAINST 2F558 =MAINLP 002FD =MAINEN 2F571 =MAIN30 0037E =MAIN05 00338 =LXTXTT 1EE9F =LXFND 0979D =LSTLEN 06C27 =LSLEEP 006CD =LOOPST 2F7AC =LOCKWD 2F7B2 =LOCFIL 1721D =LOCADR 0A611 =LNSKP- 089FF =LNPEXT 02617 =LNEP66 027EA =LN30 0CD9C =LN15 0CD81 =LN12 0CD7D =LN1+XF 0CD51 =LN1+15 0CD44 =LISTDC 05839 =LINSKP 08A05 =LINP 02A07 =LINEP+ 02626 =LINEP* 02634 =LINEP 02620 =LIN#DC 05115 =LIN#D+ 05112 =LIN#AU 05122 =LIMITS 0AC3E =LGT15 0D1AE =LEXPTR 2F6CF =LEXBF+ 10DDF =LEEWAY 000D4 =LEAVE 04C01 =LDSST2 04F9E =LDSST1 04F72 =LDCSPC 2F6C1 =LDCSET 05060 =LDCOMP 04F69 =LDCM10 04F6F =LDCEXT 04F5E =LCDINI 00665 =LBLNIF 02A0D =LBLNAM 077E7 =LBLINP 02A04 =LBLIN# 2F871 =LASTFN 000B4 =LABLDC 05702 =LABELP 03E9F =KYDN? 00774 =KEYSCN 00D4D =KEYSAV 2F462 =KEYRD 14E11 =KEYPTR 2F443 =KEYNAM 1AC04 =KEYMRG 08B8F =KEYFND 08CB8 =KEYDEL 08D2C =KEYCOD 1FD22 =KEYBUF 2F444 =KEY$ 1ACA8 =KCOLD 2F462 =KCOLC 2F463 =KCOLB 2F464 =KCOLA 2F465 =KCOL9 2F466 =KCOL8 2F467 =KCOL7 2F468 =KCOL6 2F469 =KCOL5 2F46A =KCOL4 2F46B =KCOL3 2F46C =KCOL2 2F46D =KCOL1 2F46E =KCOL0 2F46F =Insert 00007 =InhEOL 00004 =IVVARe 02E66 =IVPARe 02E3F =IVP 00004 =IVLNIB 2F6FD =IVEXPe 02E35 =IVARG 0D749 =IVAERR 0E920 =ISRAM? 10192 =IS-TBL 2F78D =IS-PRT 2F794 =IS-PLT 2F7A2 =IS-INP 2F79B =IS-DSP 2F78D =IOFSCR 1188E =IOFND0 118C1 =IOBFST 2F571 =IOBFEN 2F576 =INXNIB 2F6F9 =INVNaN 0C65F =INTRPT 0000F =INTR50 000DB =INTR4 2F400 =INTM 2F430 =INTGR 0F99B =INTB 2F420 =INTA 2F410 =INPOFF 18B49 =INFR15 0C73D =INF*0 0C607 =INBS 2F6C6 =INADDR 2F6D4 =IN/REP 15255 =IMxq27 1BB9C =IMoffs 1BA58 =IMinit 1B88F =IMerr 1B989 =IMentr 1B535 =IMGxq1 1BAAB =IMD0-2 1BA21 =IMD0+2 1BA2D =ILCNTe 02E70 =IF12A 0C739 =IDIVA 0EC6E =IDIV 0EC7B =I/ORES 118FF =I/OFND 118BA =I/OEXP 11A11 =I/OEX2 11A0F =I/ODAL 11A41 =I/OCON 11920 =I/OCOL 11979 =I/OALL 1197D =I/OAL+ 1197B =HXDCW 0ECB4 =HXDASC 05FF4 =HUGE 0B75D =HTRAP 0CB2F =HPSCRH 2F97F =HNDLFL 0CBC9 =HMSSEC 13274 =HEXDEC 0ECAF =HEXASC 17148 =HDFLT 1B31B =HASH2 1B0A3 =HASH1 1B0A1 =GetEXP 1C086 =GTXT++ 05192 =GTPTRX 14670 =GTPTRS 14636 =GTKYCD 08D92 =GTKYC+ 08D9B =GTKY54 08E9A =GTFLAG 1365E =GTEXT1 051A5 =GTEXT+ 05199 =GTEXT 05079 =GSBSTK 2F5A3 =GOTOp 029F6 =GOTODC 0552E =GOTO 079FA =GOSUBp 029F6 =GOSUB 079E9 =GNXTCR 03064 =GETVAL 0DAB2 =GETSTC 07726 =GETST- 07728 =GETST* 07716 =GETSA 0E551 =GETPRO 06BEE =GETPR1 06BFB =GETPR+ 06BF5 =GETNAM 1A085 =GETMSK 01BBA =GETDIM 0AD6B =GETCON 0DAA3 =GETCNT 1A076 =GETCH# 11427 =GETAVM 1864D =GDISP$ 1C3C7 =FUNCR1 2F8AB =FUNCR0 2F89B =FUNCD1 2F8C0 =FUNCD0 2F8BB =FTYPF# 11059 =FTYPDC 06902 =FTBSCH 11093 =FSPECx 09F2D =FSPECp 03CC5 =FSPECe 02F02 =FRange 0B46A =FRAC15 0C70E =FPOLL 1250A =FORUPD 0A6AE =FORSTK 2F59E =FNRTN4 0F238 =FNRTN3 0F235 =FNRTN2 0F219 =FNRTN1 0F216 =FNPWDS 0D3C0 =FNDFCN 1A0A1 =FNDCLR 1DAEF =FLTYPp 03E71 =FLTDH 1B223 =FLOAT 1B322 =FLIP8 0DB8D =FLIP11 0DBAB =FLIP10 0DB9C =FLGREG 2F6E9 =FLDEVX 01154 =FLADDR 0126B =FIXP 02A6E =FIXDC 05493 =FIRSTC 2F47C =FINLIN 18A3A =FINITC 0CD0F =FINITA 0CD03 =FINDLR 0FFDE =FINDLB 07786 =FINDL0 0FFFD =FINDL 0FFE4 =FINDF+ 09F63 =FINDF 09F77 =FINDD0 023E0 =FINDA 023E3 =FIND 0F563 =FILXQ^ 09B76 =FILXQ$ 09B95 =FILSK+ 06F1D =FILFIL 011CE =FILEP1 03EFC =FILEP- 03F00 =FILEP+ 03F07 =FILEP! 03F0F =FILEP 03E9C =FILEF 09FB0 =FILDC* 05759 =FILCRD 1C879 =FIBOFF 12132 =FIBADR 11457 =FIBAD- 11478 =FGTBL 00C9B =FCSTRT 0E757 =FCHLBL 0782C =FASCFD 110C3 =FAC15S 0E72B =F-R1-3 2F8BA =F-R1-2 2F8B5 =F-R1-1 2F8B0 =F-R1-0 2F8AB =F-R0-3 2F8AA =F-R0-2 2F8A5 =F-R0-1 2F8A0 =F-R0-0 2F89B =Except 0000C =EndNum 000E6 =EXPSKP 1A9AC =EXPRDC 05922 =EXPR 0F23C =EXPPLS 03FDC =EXPPAR 03FD9 =EXPP10 03FE3 =EXPEXC 0F186 =EXPEX- 0F178 =EXPEX+ 0F182 =EXP15 0CF5A =EXF 0D5DF =EXDCLP 0592E =EXCPAR 187E8 =EXCHRe 02E81 =EXCAD+ 08631 =EXACT 128B0 =EXAB2 0D40E =EXAB1 0D3E7 =EX15S 0D5CE =EX15M 0D5CA =EX12 0D5C6 =EX-115 0CF48 =ESCSTA 2F47B =ESCSEQ 023C1 =ERRSUB 2F683 =ERRRTN 074ED =ERRM$f 09806 =ERRL# 2F7EC =ERRADR 2F688 =ERR# 2F7E4 =EOLXCK 05405 =EOLXC* 052EC =EOLSTR 2F95B =EOLSN5 08AB1 =EOLSCN 08AA7 =EOLLEN 2F95A =EOLDC 05402 =EOLCKR 02A7A =EOLCK8 02A92 =EOLCK 02A7E =ENDSUB 195A8 =ENDIMG 1C040 =ENDBIN 0764B =ENDALL 0769A =EFIELD 00000 =EDITWF 0A533 =EDIT80 0A5A5 =DZP 00003 =DXP100 0CF7F =DWIDTH 2F94F =DVZNIB 2F6FC =DV2-15 0C4AC =DV2-12 0C4A8 =DV15S 0C4B2 =DV15M 0C4AC =DSTRDC 05280 =DSPUPD 01ADA =DSPSTA 2F475 =DSPSET 2F7B1 =DSPRST 02443 =DSPMSK 2F540 =DSPLIN 10127 =DSPLI+ 1010F =DSPFMT 2F6DC =DSPDGT 2F6DD =DSPCNO 09716 =DSPCNB 0971F =DSPCNA 09721 =DSPCL? 020B6 =DSPCHX 2F674 =DSPCHC 01C3C =DSPCHA 01C3E =DSPBUF 09723 =DSPBFS 2F480 =DSPBFE 2F540 =DSP$00 185DB =DSLEEP 0056D =DROPDC 05470 =DRANGE 1B076 =DPVCTR 0AC50 =DPOS 2F94D =DPART3 17EF8 =DPART2 17EA3 =DONNA 09656 =DMNSN 0AE39 =DIVF 0C4B8 =DISPt 00000 =DISPP 035A4 =DISPDC 05450 =DISINT 2F470 =DEST 0F7B0 =DELAYp 02AC6 =DELAYT 2F948 =DEFADR 2F967 =DEFADC 052FC =DECP 0328F =DECHEX 1B2D2 =DEBNCE 00CF7 =DD3ST 2E104 =DD3END 2E160 =DD3CTL 2E1FF =DD2ST 2E200 =DD2END 2E260 =DD2CTL 2E2FF =DD1ST 2E300 =DD1END 2E34C =DD1CTL 2E3FF =DCRMNT 1C177 =DCPLIN 10108 =DCONTR 2E3FE =DCHXW 0ECDC =DCHXF 1B223 =DCHX=C 1B2D0 =DBLSUB 0DADD =DBLPI4 0DAFC =DAYYMD 13335 =DAY2JD 13407 =DATPTR 2F692 =DATLEN 0B584 =D=WORD 04C0E =D=AVMS 1A460 =D=AVME 1A476 =D1MSTK 1954E =D1MST+ 13E21 =D1FSTK 1955D =D1C=R3 03047 =D1@AVS 01299 =D1=AVE 18651 =D12R0A 1BA3C =D0ASCI 09833 =D0ASC+ 0982C =D0=PCA 09B37 =D0=OBS 05067 =D0=FIB 13AC5 =D0=AVS 09B2C =D0+2RD 13A32 =CurOff 00006 =Clear 00005 =CkLpNC 1B66D =CkLoop 1B669 =CVUCW 03FBC =CURTOP 10063 =CURSRU 1009A =CURSRT 096C1 =CURSRR 151C7 =CURSRL 151CF =CURSRD 100A4 =CURSOR 2F47E =CURSFR 151D7 =CURSFL 151DF =CURRST 2F55D =CURRL 2F7E8 =CURREN 2F56C =CURDVC 0A60B =CURBOT 10059 =CSRW5 0ED2C =CSRW4 0ED2F =CSRW3 0ED32 =CSRC9 1B42F =CSRC8 1B42C =CSRC7 1B415 =CSRC6 1B418 =CSRC5 1B41B =CSRC4 1B41E =CSRC3 1B421 =CSRC2 1B424 =CSRC15 1B441 =CSRC14 1B43E =CSRC13 1B43B =CSRC12 1B438 =CSRC11 1B435 =CSRC10 1B432 =CSRC1 1B427 =CSPEED 2F977 =CSLW5 0ED3D =CSLW4 0ED40 =CSLW3 0ED43 =CSLC9 1B415 =CSLC8 1B42C =CSLC7 1B42F =CSLC6 1B432 =CSLC5 1B435 =CSLC4 1B438 =CSLC3 1B43B =CSLC2 1B43E =CSLC15 1B427 =CSLC14 1B424 =CSLC13 1B421 =CSLC12 1B41E =CSLC11 1B41B =CSLC10 1B418 =CSLC1 1B441 =CSL9R0 1BA0D =CRTF 116C1 =CRLFSD 022A2 =CRLFOF 02296 =CRLFND 0229E =CRFSB- 11664 =CRETF+ 084C4 =CREATE 115A7 =CRDFIL 1D21D =CR 2C000 =CPL#10 07887 =COUNTC 1C346 =COS15 0D725 =COS12 0D721 =CORUPT 09083 =COPYu 08269 =CONVUC 152AA =CONFST 2F9E6 =CONF 10212 =CONCOM 0467E =COMPL# 07870 =COMCKO 032AA =COMCK+ 032AE =COMCK 036CD =COLLAP 091FB =COLDST 00000 =CNVWUC 03FB8 =CNVUCR 152A7 =CNTADR 2F67E =CNFLCT 0BD15 =CNFFND 109AC =CMPT 125B2 =CMOSTW 2F438 =CMOSTV 0168F =CMDS20 01672 =CMDPTR 2F6D4 =CMDPR" 01627 =CMDINI 016D1 =CMDFND 01693 =CMD1ST 01654 =CLRPRM 04827 =CLRFRC 0C6F4 =CLOSEF 12087 =CLOSEA 120E4 =CLLINK 1A72C =CLCSTK 2F585 =CLCBFR 2F576 =CLASSA 0D590 =CKSUM4 1DBA6 =CKSUM3 153A9 =CKSUM2 0AA81 =CKSREQ 00721 =CKINFO 18542 =CKINF- 18534 =CK"ON" 076AD =CHNLST 2F5BE =CHNHED 0F579 =CHN#SV 2F96F =CHKmem 012C7 =CHKSUM 1CDEE =CHKEOL 13D6D =CHIRP 0EC5A =CHEDIT 14C99 =CHAIN- 07C1C =CHAIN+ 07C12 =CATEDT 06435 =CATCHR 03F70 =CATCH+ 03F69 =CATC++ 03F66 =CAT$90 068D7 =CAT$83 068D4 =CAT$20 06746 =CALSTK 2F5AD =CALLP 0389C =CALL 18DAE =CALBIN 18D8C =C+A2D1 1C053 =BldIMG 1BA68 =BldIMA 1BA66 =BldIM+ 1BA6A =BitsOK 00001 =BSERR 0939A =BSCEXT 075CF =BSCEXC 07437 =BSCEX2 0743A =BRTF 0DC15 =BRT30 0DBE3 =BP+C 0EB40 =BOPNM- 1B864 =BLNKCK 051C1 =BLNC+ 07810 =BLDLCD 0189C =BLDDSP 01898 =BLDCON 16279 =BLDBIT 019BC =BLANKC 07818 =BIG 0B747 =BIASC+ 0D540 =BIASA+ 0D52D =BF2STK 18663 =BF2DSP 01C0E =BF2DS+ 01C08 =BEEP 0EA6E =BCKSPC 151E7 =BASICs 000B5 =BASE 0F953 =BASCHK 0773E =BASCHA 07741 =BACK3B 13B08 =BACK2B 13B0A =BACK1B 13B0C =BACK 1BA4F =AVS=D0 01494 =AVS2DS 09708 =AVMEMS 2F594 =AVMEME 2F599 =AVM2DS 01C01 =AVE=D1 18BB8 =AVE=C 18BBB =AUTINC 2F6CB =ATNFLG 2F442 =ATNDIS 2F441 =ATNCLR 00510 =ATAN15 0DBBE =ASRW5 0ED0A =ASRW4 0ED0D =ASRW3 0ED10 =ASNMNT 0F5E0 =ASLW5 0ED1B =ASLW4 0ED1E =ASLW3 0ED21 =ASIN15 0DBCC =ASIN12 0DBC8 =ASCII 0079B =ASCICK 0514E =ARYSIZ 0B61B =ARYELM 0B5A7 =ARYDC 05178 =ARRYCK 0366A =ARITH 061E0 =ARGSTA 0E90C =ARGST- 0E910 =ARGPRP 0E8EF =ARGPR+ 0E8EB =ARGF 0D6A4 =ARGERR 0BF19 =ARG15 0D67F =ARG12 0D67B =ANNAD4 2E34E =ANNAD3 2E34C =ANNAD2 2E102 =ANNAD1 2E100 =ANN1.5 2E101 =ALRM6 2F755 =ALRM5 2F749 =ALRM4 2F73D =ALRM3 2F731 =ALRM2 2F725 =ALRM1 2F719 =ALMSRV 1257D =ALLDUN 04BEF =ALINFO 01531 =ADRSUB 0F4CF =ADRS80 0F567 =ADRS50 0F551 =ADRS40 0F52B =ADJN 12825 =ADJA 1289A =ADHEAD 181B7 =ADDRSS 0F527 =ADDRCK 1C5A5 =ADDP 03A03 =ADDONE 0C330 =ADDF 0C372 =AD2-15 0C363 =AD2-12 0C35F =AD15s 0C369 =AD15S 0E19D =AD15M 0C366 =ACTIVE 2F5A8 =ACOS15 0DBD7 =ACOS12 0DBD3 =ACCEPT 0450F =A-MULT 1B349 =?PRFIL 1737E =?PRFI+ 17380 =1/X15 0C33E =-LINE 15275 =-CHAR 1527D =#CK 03356 @EOF set `wc -lwc <areuh/equ/hp71.ep` if test $1$2$3 != 3714371225112 then echo ERROR: wc results of areuh/equ/hp71.ep are $* should be 3714 3712 25112 fi chmod 644 areuh/equ/hp71.ep echo x - areuh/equ/hpil.ep cat >areuh/equ/hpil.ep <<'@EOF' =YTML 00C9B =WRITIT 0691A =WRITE# 0453F =UTLEND 007CC =ULYL 00C55 =TSTATA 04205 =TSTAT 041FE =START- 007F1 =START+ 007EE =START 007E8 =SKP-LF 02248 =SETUP 03D33 =SETLP 03B7D =SENDIT 0698F =SENDI+ 06989 =SEEKRD 062D8 =SEEKB 04239 =SEEKA 04232 =SAVEIT 03DB6 =ROMTYP 040D2 =RESTRT 02FF8 =RESTOR 03E5C =REDCHR 02262 =REDC00 02252 =RED-LF 0224F =READSU 0663D =READRG 06805 =READIT 06649 =READ# 044FF =RDST01 0226C =PUTX 06A02 =PUTGF- 00BE9 =PUTGF+ 00BED =PUTGF 00BF1 =PUTEX 06AC8 =PUTEN 06AF1 =PUTE 06AC0 =PUTDX 00E55 =PUTD 06AAE =PUTCN 06AEC =PUTC+N 06AE8 =PUTC+ 06B18 =PUTC 06B1C =PUTARL 00E25 =PUTALR 00E3D =PROCST 06EBB =PROCLT 071CE =PROCDW 07180 =PRNTSp 07468 =PRNTSd 07B3E =PRMSGA 00CB9 =PREND 01022 =PRASCI 00FEA =PACKd 07B4A =NXTENT 04A1E =NEWFIL 04A65 =NEWFI+ 04A49 =NAMEpb 07994 =NAMEp 07998 =MTYLL 00C8A =MTYL 00C83 =MOVEFL 04571 =LSTENT 04A34 =LOOP#p 076A7 =LOOP#d 07CAA =LISTEN 00C5C =INITFL 068E4 =GTYPST 06FF3 =GTYPRM 03F6E =GTYPR+ 03F6C =GTYPE 00BFF =GLOOP# 02D5A =GHEXBT 03F7D =GHEXB+ 03F81 =GFTYPE 02D96 =GETX 066B0 =GETST- 0679E =GETST 06787 =GETPIL 06E0B =GETPI+ 06E14 =GETNE 0673B =GETMBX 03B62 =GETLPs 01D15 =GETID+ 067FA =GETID 0680E =GETHSS 0313A =GETERR 06791 =GETEND 067E5 =GETDev 00B5B =GETDVW 07133 =GETDR+ 047F9 =GETDR# 047E0 =GETDR" 047DE =GETDIX 06DA2 =GETDIR 04820 =GETDID 06D84 =GETDI! 047D7 =GETD 067C8 =GET 06751 =GDIRST 04843 =GADRST 07064 =GADRRM 03FAB =GADRR+ 03FBA =GADDR 008FF =FXQPIL 0734F =FRASPp 07CC9 =FRASPp 076D4 =FRAMEE 06B43 =FRAME- 0073B =FRAME+ 0072D =FORMAT 04291 =FNDMBX 03BE0 =FNDMBD 03BCA =FNDMB- 03BAB =FNDMB+ 03BA7 =FNDCHK 00B86 =FNDCH- 00B7B =FINDFx 04732 =FINDFL 0469F =FINDF+ 046A6 =ENDTAP 044D9 =ENDFN 007C0 =DVCSPp 07925 =DSPCAT 06571 =DEVPR$ 01C36 =DEVPAR 01BF0 =DDT 06B34 =DDL 06B25 =CHKSTS 00B8F =CHKST+ 03160 =CHKSET 03149 =CHKMAS 0425C =CHKASN 03C57 =CHKAIO 04086 =BLDCAT 06300 =BDISPJ 035A2 @EOF set `wc -lwc <areuh/equ/hpil.ep` if test $1$2$3 != 2722721854 then echo ERROR: wc results of areuh/equ/hpil.ep are $* should be 272 272 1854 fi chmod 644 areuh/equ/hpil.ep echo x - areuh/equ/Makefile cat >areuh/equ/Makefile <<'@EOF' # # Ce Makefile fait un minimum de choses # LIBDEST = /usr/local/lib EP = hp71.ep hpil.ep # # Les cibles : # all : rien (ne fait que signaler l'absence eventuelle de hp71.ep) # install : installe le programme dans l'aborescence # clean : rien (compatibilite avec le Makefile general) # clobber : rien (compatibilite avec le Makefile general) # tags : rien (compatibilite avec le Makefile general) # all: $(EP) depend:; mkmf ROOT=$(ROOT) install: $(EP) if [ "$(LIBDEST)" != . ] ; \ then \ (cd $(LIBDEST) ; rm -f $(EP)) ; \ cp $(EP) $(LIBDEST) ;\ fi ; clean: ; clobber: ; tags: ; @EOF set `wc -lwc <areuh/equ/Makefile` if test $1$2$3 != 33107618 then echo ERROR: wc results of areuh/equ/Makefile are $* should be 33 107 618 fi chmod 644 areuh/equ/Makefile exit 0
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:32:59 1990 # # This archive contains: # areuh/load/acp.c areuh/msg/amg.c # areuh/msg/amg.1 areuh/msg/Makefile # areuh/jmpdoc/A areuh/jmpdoc/sauts # areuh/jmpdoc/algo areuh/jmpdoc/jmpparam # areuh/jmpdoc/jmp.c areuh/Makefile # areuh/assembler/aerror.c areuh/assembler/agen.h # areuh/assembler/aglobal.h # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - areuh/load/acp.c cat >areuh/load/acp.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include <stdio.h> #include <time.h> typedef unsigned short uint16 ; typedef unsigned long uint32 ; struct disc_hdr { uint16 mlfi ; /* Lif Id (0x8000) */ char l_label [6] ; /* volume label */ uint32 l_dstart ; /* directory start record (usually 2) */ uint16 l_sys3000 ; /* system 3000 (0x1000) */ uint16 l_spare1 ; /* 0x0000 */ uint32 l_dirlen ; /* directory length */ uint16 l_version ; /* 0x0001 */ uint16 l_spare2 ; /* 0x0000 */ uint32 trkpersurf ; /* tracks per surface */ uint32 surfpermed ; /* number of surfaces */ uint32 sectpertrk ; /* records per track */ char l_date [6] ; /* date & time */ char l_spare [213] ; /* padding */ } ; struct lif_filent { char l_filnam [10] ; /* file name */ uint16 l_filtyp ; /* file type */ uint32 l_startsec ; /* start record */ uint32 l_fillen ; /* file length */ char l_create_time [6] ; /* date & time created */ uint16 l_flagwd ; /* volume flag/number 0x8001 */ uint32 l_startexec ; /* implementation */ } ; FILE *fp, *fplif, *fpw ; char filename[10] ; int type ; long int dir_sec, data_sec ; struct lif_filent dir_entry, areuh_dir ; struct disc_hdr header ; long int a = 0, b = 0, eod = 0 ; #define DISK "/dev/dsk/floppy" main (argc, argv) int argc ; char *argv[] ; { long int magic ; if (argc!=2) { fprintf (stderr, "usage: acp file\n") ; exit (1) ; } if (!(fp=fopen (argv[1], "r"))) { fprintf (stderr, "acp: cannot open file %s\n", argv[1]) ; exit (1) ; } fread (&magic, sizeof (long int), 1 , fp) ; if (magic!=0x1b080100) { fprintf (stderr, "acp: %s not a lex file\n", argv[1]) ; exit (1) ; } if (!(fplif=fopen (DISK, "r"))) { fprintf (stderr, "acp: cannot open %s for read\n", DISK) ; exit (1) ; } if (!read_lif ()) { fprintf (stderr, "acp: not a LIF disk\n") ; exit (1) ; } read_file_infos () ; search_dir () ; if (!(fpw=fopen (DISK, "w"))) { fprintf (stderr, "acp: cannot open %s for write\n", DISK) ; exit (1) ; } write_data () ; write_dir () ; if (fclose (fplif)) { fprintf (stderr, "acp: cannot close %s opened for read\n", DISK) ; exit (1) ; } if (fclose (fpw)) { fprintf (stderr, "acp: cannot close %s opened for write\n", DISK) ; exit (1) ; } if (fclose (fp)) { fprintf (stderr, "acp: cannot close file %s\n", argv[1]) ; exit (1) ; } exit (0) ; } skip (n) int n ; { char c ; int i ; for (i=1; i<=n; i++) fread (&c, 1, 1, fp) ; } con (pvar, n) unsigned int *pvar ; int n ; { int i ; unsigned char areuh [256] ; fread (areuh, n, 1, fp) ; *pvar = 0 ; for (i=n-1; i>=0; i--) { *pvar = (*pvar * 16) + hex(areuh[i]) ; } } read_file_infos () { int i ; unsigned int c ; int length, length_sect ; for (i=0; i<8; i++) { con (&c, 2) ; dir_entry.l_filnam[i] = (unsigned char) c ; } dir_entry.l_filnam[8] = ' ' ; dir_entry.l_filnam[9] = ' ' ; con (&c, 4) ; dir_entry.l_filtyp = (unsigned short) c ; skip (12) ; con (&length, 5) ; length_sect = (length -= 5 ) ; read_date (dir_entry.l_create_time) ; dir_entry.l_startexec = 0 ; for (i=0; i<4; i++) { c = length&0xff ; dir_entry.l_startexec = (((unsigned int) dir_entry.l_startexec)*0x100) + c ; length /= 256 ; } dir_entry.l_fillen = length_sect / 512 + ((length_sect%512) ? 1 : 0) ; dir_entry.l_flagwd = (unsigned short int) 0x8001 ; } read_date (str) char *str ; { int i ; long clock ; struct tm *ptm ; clock = time ((long *) 0) ; ptm = localtime (&clock) ; str [0] = bcd (ptm->tm_year) ; str [1] = bcd (ptm->tm_mon + 1) ; str [2] = bcd (ptm->tm_mday) ; str [3] = bcd (ptm->tm_hour) ; str [4] = bcd (ptm->tm_min) ; str [5] = '\0' ; } int bcd (n) int n ; { return (((n / 10) * 16) + (n % 10)) ; } int read_lif () { fread (&header, sizeof (header), 1, fplif) ; if (((unsigned short)header.mlfi)!=0x8000) return (0) ; return (1) ; } search_dir() { struct lif_filent cur_dir_entry ; long int compteur = 1, sod, sodn, limite ; sod = header.l_dstart + header.l_dirlen ; limite = ((unsigned) header.l_dirlen)*8 ; fseek (fplif, header.l_dstart*0x100, 0) ; fread (&cur_dir_entry, sizeof(cur_dir_entry), 1, fplif) ; while ((cur_dir_entry.l_filtyp != 0xffff)&&(compteur<=limite)) { if ((cur_dir_entry.l_filtyp == 0) && (cur_dir_entry.l_fillen >= dir_entry.l_fillen) && !a ) { a = ftell (fplif) - 32 ; sodn = cur_dir_entry.l_startsec ; } else if (strncmp (cur_dir_entry.l_filnam, dir_entry.l_filnam, 10) == 0) { b = ftell (fplif) - 32 ; memcpy ((char *) &areuh_dir, (char *) &cur_dir_entry, 32) ; } sod = cur_dir_entry.l_startsec + cur_dir_entry.l_fillen ; fread (&cur_dir_entry, sizeof(cur_dir_entry), 1, fplif) ; compteur++ ; } if ((b) && (areuh_dir.l_fillen >= dir_entry.l_fillen)) { a = b ; b = 0 ; sodn = areuh_dir.l_startsec ; } else if (!a) { if (compteur <= limite) { eod = ftell (fplif) ; a = eod - 32 ; sodn = sod ; if (sodn+((unsigned) dir_entry.l_fillen)>= ((unsigned) header.trkpersurf) * ((unsigned) header.surfpermed) * ((unsigned) header.sectpertrk)) { fprintf (stderr, "acp: no room in data area\n") ; exit (1) ; } } else { fprintf (stderr, "acp: no room in directory area\n") ; exit (1) ; } } dir_entry.l_startsec = sodn ; } write_data () { int c = 0, d ; fseek (fpw, ((unsigned long) dir_entry.l_startsec)*0x100, 0) ; while ((d=getc (fp))!=EOF) { if (c) { fputc (hex(d)*16+hex(c), fpw) ; c = 0 ; } else c = d ; } if (c) fputc (hex(c), fpw) ; } int hex (c) int c ; { return (((c>='A')&&(c<='F'))?c-'A'+10:c-'0') ; } write_dir () { long int *plong, i ; update (a, &dir_entry) ; if (b) { areuh_dir.l_filtyp = 0 ; update (b, &areuh_dir) ; } if (eod) { plong = (long int *) &areuh_dir ; for (i=1; i<=8; i++) { *plong = -1 ; plong++ ; } update (eod, &areuh_dir) ; } } update (x, pdir) long int x ; struct lif_filent *pdir ; { struct lif_filent sector[8] ; /* fclose(fpw) ; fpw = fopen (DISK, "w") ; fclose(fplif) ; fplif = fopen (DISK, "r") ; fseek (fplif, x, 0) ; fread (sector, sizeof (sector), 1, fplif) ; write (sector, sizeof (sector), 1, fpw) ; memcpy (§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 0
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:33:03 1990 # # This archive contains: # areuh/assembler/ainput.c areuh/assembler/alabel.c # areuh/assembler/alist.c areuh/assembler/amain.c # areuh/assembler/amnemo.c areuh/assembler/aobj.c # areuh/assembler/aopc1.c # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - areuh/assembler/ainput.c cat >areuh/assembler/ainput.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** TITAN ASSEMBLER INPUT STREAM READING & PARSING read_line, parse_line, next_token, stcp ******************************************************************************/ #include "aglobal.h" /****************************************************************************** READ_LINE synopsis : int read_line (fd, line) FILE *fd uchar *line description : read_line reads a line from the source file, or stdin. note : read_line returns -1 if EOF reached, 0 otherwise. ******************************************************************************/ int read_line (fd, line) FILE *fd ; uchar line[] ; { int c, i = -1 ; do { c = getc (fd) ; if (i<MAXLEN) line[++i] = (uchar) c ; } while ((c!=EOF)&&(c!='\n')) ; line[i] = EOL ; if (c==EOF) { if (ferror (fd)) error (ERRRD, fsource) ; /* stdin doesn't fail */ } else c = 0 ; linenb++ ; return (c) ; } /****************************************************************************** PARSE_LINE synopsis : void parse_line (line, label, mnemo, modif) uchar *line, *label, *mnemo, *modif description : parse_line breaks the line read from the source file in three components : - label : max LBLLEN or LBLLEN+1 characters - mnemonic : max 6 characters - modifier : not limited (in fact, MAXLEN characters) note : parse_line doesn't return a result, the line is always valid. ******************************************************************************/ void parse_line(line, label, mnemo, modif) uchar *line, *label, *mnemo, *modif ; { int i=0, j ; *label = EOL ; *mnemo = EOL ; *modif = EOL ; /* label parse */ /* no label comment null line tab * * | | | | * * v v v v */ if ((*line!=' ')&&(*line!='*')&&(*line!=EOL)&&(*line!='\t')) i = stcp (label, line, 0, (*line=='=') ? LBLLEN+1 : LBLLEN) ; else if ((*line!='\t')&&(*line!='*')&&(*line!=EOL)&& (line[1]!=' ')&&(line[1]!='*')&&(line[1]!=EOL)&&(line[1]!='\t')) i = stcp (label, line, 1, (line[1]=='=') ? LBLLEN+1 : LBLLEN) ; /* mnemonic parse */ i = next_token (line, i) ; if (i<0) return ; if (line[i]=='*') return ; i = stcp (mnemo, line, i, 6) ; for (j=0; j<6; j++) mnemo[j] -= ((mnemo[j]<'a')||(mnemo[j]>'z')) ? 0 : 32 ; /* modifier parse */ i = next_token (line, i) ; if (i<0) return ; strcpy (modif, line+i) ; } /****************************************************************************** NEXT_TOKEN synopsis : int next_token (line, i) uchar *line int i descrption : next_token looks the line, from the i-th position, for the next non-blank character or end of line. If end-of-line is reached, a negative value (-1) is returned to caller. Otherwise, the position of character is returned, which permits to reassign the line index (i=next_token(line, i)). ******************************************************************************/ int next_token (line, i) uchar *line ; int i ; { while ((line[i]!=EOL)&&((line[i]==' ')||(line[i]=='\t'))) i++ ; return ((line[i]) ? i : -1); } /****************************************************************************** STCP synopsis : int stcp (str1, str2, i, lmax) uchar *str1, *str2 int i, lmax description : stcp is an alternate name for "string_copy". In fact, stcp copies str2 (from i-th position) into str1 (from 0-th position) until a blank character of end-of-line is reached. If lmax (max length of str1) is is reached, the rest of the field is ignored. The returned value is the new line index value. note : we assume that stcp works well. No error value is returned. replace with "strncpy" in C library for future releases ******************************************************************************/ int stcp (str1, str2, i, lmax) uchar *str1, *str2; int i, lmax; { int j=0; do { if (j<lmax) str1[j++] = str2[i]; } while ((str2[++i]!=' ')&&(str2[i]!='\t')&&(str2[i]!=EOL)); str1[j] = EOL; return (i); } @EOF set `wc -lwc <areuh/assembler/ainput.c` if test $1$2$3 != 1775724915 then echo ERROR: wc results of areuh/assembler/ainput.c are $* should be 177 572 4915 fi chmod 644 areuh/assembler/ainput.c echo x - areuh/assembler/alabel.c cat >areuh/assembler/alabel.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** TITAN ASSEMBLER LABEL PROCESSING ps_label, find_label, add_label, label_value, s_init ******************************************************************************/ #include "aglobal.h" extern saddr calc_expression() ; extern uchar *memoire() ; struct symbol *find_label(), *add_label() ; /****************************************************************************** PS_LABEL synopsis : void ps_label (label, mnemo, modif) uchar *label, *mnemo, *modif description : "pass" function call "ps_label" when a label is encoutered. Thus, in function of pass number, we must process the label. If pass one, the label is declared and its value is assigned (if possible, else -1), only if it is not yet declared. If pass two, the label is declared. We calculate the value of the label. If it had a value, we compare both. If not, the value is assigned. ******************************************************************************/ void ps_label (label, mnemo, modif) uchar *label, *mnemo, *modif; { struct symbol *ad; saddr val ; /* la ligne ci-dessous teste si la partie "utile" du label est "FiLeNd" */ if (strcmp(label + (*label=='='), "FiLeNd")==0) error (ERRFLN, "") ; ad = find_label (label) ; /* during pass two, label must be found. Otherwise, the assembler is bug-full !!! */ if (strcmp (mnemo, "EQU")) { /* implicit declaration */ switch (passnb) { case 1 : if (ad==NULL) add_label (label, pc, "", LREL, 0) ; else if ((ad->s_value==LBL_UDF)||(ad->s_value==LBL_EXT)) { ad->s_value = pc ; ad->s_type = LREL ; } break ; case 2 : if ((ad->s_value!=pc)||(ad->s_type!=LREL)) error (WRNDUP, ""); /* duplicate label */ break ; } } else /* explicit declaration (EQU) */ { val = calc_expression (modif) ; switch (passnb) { case 1: if (ad==NULL) { if (val >= 0L) { add_label (label, val, "", relabs, 0) ; } else if (val == EXP_ERR) { add_label (label, LBL_IVL, "", LUDF, 0) ; } else /* (val == EXP_EXT) */ { if (*label=='=') add_label (label, LBL_XEQ, extexp, LUDF, 0) ; else add_label (label, LBL_SEQ, extexp, LUDF, 0) ; } } else if ((ad->s_value==LBL_UDF)||(ad->s_value==LBL_EXT)) { if (val >= 0L) { ad->s_value = val ; ad->s_type = relabs ; } else if (val == EXP_ERR) { ad->s_value = LBL_IVL ; ad->s_type = LUDF ; } else /* (val == EXP_EXT) */ { ad->s_value = (*label=='=') ? LBL_XEQ : LBL_SEQ ; ad->s_def = memoire (strlen (extexp) + 1) ; strcpy (ad->s_def, extexp) ; ad->s_type = LUDF ; } } break; /* du 'case pass one' */ case 2: if (ad->s_value >= 0L) /* first value of label in first pass */ if (val!=ad->s_value) error (WRNDUP, "") ; else if (ad->s_value == LBL_IVL) { if (val >= 0L) { ad->s_value = val ; ad->s_type = relabs ; } else if (val == EXP_ERR) { ad->s_value = 0L ; ad->s_type = LABS ; } else /* EXP_EXT */ { ad->s_def = memoire (strlen(extexp)+1); if (ad->s_def == (uchar *) NULL) error (ERRMEM, "") ; strcpy (ad->s_def, extexp) ; ad->s_value = (*label=='=')? LBL_XEQ :LBL_SEQ ; ad->s_type = LUDF ; } } else if ((ad->s_value == LBL_XEQ) || (ad->s_value == LBL_SEQ)) { if (val == EXP_EXT) { if (strcmp(ad->s_def, extexp)) error (WRNDUP, "") ; /* duplicate label */ } else { ad->s_value = val ; ad->s_type = relabs ; } } break; /* end of 'case pass 2' */ } } } /****************************************************************************** FIND_LABEL synopsis : struct symbol *find_label (label) uchar *label description : find_label searches the symbol list for a given label. If the search is succesful, find_label returns a pointer to the structure. If not, NULL is returned. ******************************************************************************/ struct symbol *find_label (label) uchar *label ; { struct symbol *p ; int test ; if ((!modular)&&(*label=='=')) label++ ; p = h_label[(int) ((*label=='=') ? label[1] : label[0])]->s_next ; while (p) { test = strcmp (label, p->s_name) ; if (test==0) break ; p = p->s_next ; if (test<0) p = NULL ; /* label < p->s_name : not found */ } return (p) ; } /****************************************************************************** ADD_LABEL synopsis : struct symbol *add_label (label, val, exp, type, os) uchar *label, *exp saddr val uchar type, os description : add_label inserts the label (name and value) in the symbol list. note : the symbol list is always sorted by label name. ******************************************************************************/ struct symbol *add_label (label, val, exp, type, os) uchar *label, *exp ; saddr val ; uchar type, os ; { struct symbol *p, *s ; int b=1 ; if ((!modular)&&(*label=='=')) label++ ; p = h_label[(int) ((*label=='=') ? label[1] : label[0]) ] ; s = p ; while ((b) && (s)) { if (strcmp(label, s->s_name)<0) b = 0 ; else { p = s ; s = s->s_next ; } } s = (struct symbol *) memoire (sizeof(struct symbol)) ; if (s) { s->s_next = p->s_next ; p->s_next = s ; strcpy (s->s_name, label) ; s->s_decl = (sint) linenb ; s->s_xref = (struct xtable *) NULL ; s->s_value = val ; s->s_type = type ; s->s_os = os ; if ((val==LBL_XEQ)||(val==LBL_SEQ)) { s->s_def = memoire (strlen (exp) + 1) ; strcpy (s->s_def, exp) ; } else s->s_def = (uchar *) NULL ; } else error (ERRMEM, "") ; return (s) ; } /****************************************************************************** SYMBOL_VALUE synopsis : saddr symbol_value (label) uchar *label description : label_value returns the value of the label, knowing its name. If it doesn't exist, and this occurs during the second pass, an error message is generated. note : if symbol not found in the symbol list, -1 is returned. It's to the caller (label_value) to report the error "unrecognized label". ******************************************************************************/ saddr symbol_value (label) uchar *label ; { struct symbol *ad; struct xtable *x ; saddr val ; ad = find_label (label) ; if (ad) val = ad->s_value ; else { val = ((*label=='=')&&(modular)) ? LBL_EXT : LBL_UDF ; ad = add_label (label, val, "", LUDF, 0) ; } if (passnb==2) { /* label must be found in pass two */ if (xref) /* need to store it in cross-ref. table */ { x = (struct xtable *) memoire (sizeof(struct xtable)) ; if (x) { x->x_next = ad->s_xref ; if (ad->s_xref) ad->s_xref->x_prev = x ; ad->s_xref = x ; x->x_prev = (struct xtable *) NULL ; x->x_line = (sint) linenb ; } else error (ERRMEM, "") ; } if (val==LBL_UDF) error (WRNULB, "") ; /* undefined label */ } if (val==LBL_SEQ) xlabel = ad->s_def ; ad->s_os = 0 ; /* (O.S.) label is used */ relabs = ad->s_type ; return (val) ; } /****************************************************************************** S_INIT synopsis : void s_init () description : initializes the symbol list. It is structured as follow : - a table (0..255) which points to a list of labels beginning with the character (index in this table is the first char.) - a chained list of labels, - a doubly linked list of references on this label. This is not initialized here. ******************************************************************************/ void s_init () { struct symbol *s ; int i ; s = (struct symbol *) memoire (256*sizeof(struct symbol)) ; if (!(s)) error (ERRMEM, "") ; for (i=0; i<256; i++) { strcpy (s->s_name, "") ; s->s_value = (saddr) 0 ; s->s_type = LUDF ; s->s_decl = (sint) 0 ; s->s_xref = (struct xtable *) NULL ; s->s_next = (struct symbol *) NULL ; h_label[i] = s++ ; } } @EOF set `wc -lwc <areuh/assembler/alabel.c` if test $1$2$3 != 346120010937 then echo ERROR: wc results of areuh/assembler/alabel.c are $* should be 346 1200 10937 fi chmod 644 areuh/assembler/alabel.c echo x - areuh/assembler/alist.c cat >areuh/assembler/alist.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER LISTING FILE PROCESSING l_init, l_flush, l_print, l_new_page, l_line, l_page ******************************************************************************/ #include "aglobal.h" int l_line, l_page ; void l_new_page (), l_page_header () ; uchar fstdout [] = "stdout" ; /****************************************************************************** L_INIT synopsis : l_init() description : initiates the listing mechanism, if necessary. ******************************************************************************/ void l_init() { uchar tmp [MAXLEN+1] ; switch (cntlist) { case 0 : break ; case 1 : fd_l = stdout ; break ; case 2 : dfl_extension (tmp, fsource, "al") ; look_obj (flisting, tmp) ; if ((fd_l = fopen (flisting, "w")) == NULL) error (ERROPN, flisting) ; break ; } l_page = 0 ; if (cntlist) l_page_header () ; } /****************************************************************************** L_FLUSH synospsis : void l_flush () description : forces a new page, then closes the listing file if necessary. ******************************************************************************/ void l_flush() { if (cntlist==0) return ; l_new_page(0) ; if (cntlist == 2) { if (fclose (fd_l)) error (ERRCLO, flisting) ; } } /****************************************************************************** L_PRINT synopsis : void l_print (pc, code, msg, flags) saddr pc uchar *code, *msg int flags description : prints a line on the listing file. The line may contain - program counter value F_PC - line number F_LN - generated code F_GC - text line F_TL according the "flags" variable. E.g. : to print pc and generated code, call l_print(pc, gen_code, "", F_PC + F_GC) ******************************************************************************/ void l_print (address, code, msg, flags) saddr address ; uchar *code, *msg ; int flags ; { uchar line[MAXLEN+1], tmp[MAXLEN+1] ; if (!(cntlist)) return ; if (flags==F_TL) { sprintf (line, "%.79s", msg) ; } else { if (flags & F_LN) sprintf (line, "%04d ", linenb) ; /* 5 chars */ else strcpy (line, " ") ; if (flags & F_PC) /* 6 chars */ { hex5 (tmp, address) ; strcat (line, tmp) ; strcat (line, " ") ; } else strcat (line, " ") ; if (flags & F_GC) /* 9 chars */ { sprintf (tmp, "%-9.8s", code) ; strcat (line, tmp) ; } else strcat (line, " ") ; if (flags & F_TL) /* 60 chars */ { sprintf (tmp, "%.60s", msg) ; strcat (line, tmp) ; } } if (l_line==(page_size-6)) l_new_page (1) ; fprintf (fd_l, "%s\n", line) ; if (ferror (fd_l)) error (ERRWRT, (cntlist == 1) ? fstdout : flisting) ; l_line++ ; if (strlen(code)>8) l_print (address+8, code+8, "", F_PC + F_GC) ; } /****************************************************************************** L_NEW_PAGE synopsis : void l_new_page (flag) int flag description : forces a new page on listing file, and if flag # 0, prints a header composed by page number, l_stitle and l_title. ******************************************************************************/ void l_new_page (flag) int flag ; { if (!(cntlist)) return ; for (; l_line<page_size; l_line++) fprintf (fd_l, "\n") ; if (ferror (fd_l)) error (ERRWRT, (cntlist == 1) ? fstdout : flisting) ; if (flag) l_page_header () ; } void l_page_header () { fprintf (fd_l, "Page %03d %.60s\n", ++l_page, l_title) ; fprintf (fd_l, "AREUH ASS. V2.4 %.60s\n", l_stitle) ; fprintf (fd_l, "\n") ; l_line = 3 ; if (ferror (fd_l)) error (ERRWRT, (cntlist == 1) ? fstdout : flisting) ; } @EOF set `wc -lwc <areuh/assembler/alist.c` if test $1$2$3 != 1925374204 then echo ERROR: wc results of areuh/assembler/alist.c are $* should be 192 537 4204 fi chmod 644 areuh/assembler/alist.c echo x - areuh/assembler/amain.c cat >areuh/assembler/amain.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** TITAN ASSEMBLER MAIN FONCTION main, prompt ******************************************************************************/ #include "aglobal.h" struct symbol *h_label[256] ; struct xused *headxu ; uchar fsource [MAXLEN+1], flisting [MAXLEN+1], fobject [MAXLEN+1] ; FILE *fd_s, *fd_l, *fd_o ; int cntlist, cntlist_ref ; int page_size ; uchar l_title[MAXLEN+1], l_stitle[MAXLEN+1]; int errcnt, error_this_line ; int print_this_line ; int xref ; int running ; int passnb ; int linenb ; saddr pc ; int gen_len ; uchar gen_code[19] ; int prev_test ; int exec, in_if, in_else ; int modular, linker ; extern void init(), between(), term(), pass() ; extern int read_line() ; /****************************************************************************** MAIN synopsis : aas [-p] [-l n] [-A] [-a afile] [-o objfile] [file1 [... filen]] description : Aas is a cross assembler which runs on UNIX based machines. Aas assembles the named file, or the standard input if no file is specified. The optional arguments -a or -A may be used to obtain an assembly listing. If -A is used, listing goes to standard output. If -a is used, the listing goes to afile. -l option specifies page length. The output of assembly is left in the filoe objfile; if that is omitted, then the output is left in a file "lex". ******************************************************************************/ main (argc, argv) int argc ; char *argv[] ; { int r = 0, c, i ; int errflg = 0 ; int errrep = 0 ; char saveo [MAXLEN+1], savel [MAXLEN+1] ; extern char *optarg ; extern int optind, opterr ; opterr = 0 ; /* par defaut, on a : */ xref = 0 ; /* pas de cross ref */ page_size = 0 ; /* taille de page non fournie */ cntlist_ref = 0 ; /* pas de listing */ strcpy (fobject, "") ; /* fichier objet := "" */ strcpy (fsource, "") ; /* fichier source := "" */ strcpy (flisting, "") ; /* fichier listing := "" */ /* analyse des options */ while ((c = getopt(argc, argv, "xa:Apl:o:")) != EOF) switch (c) { case 'x' : /* cross-ref */ xref = 1 ; break ; case 'a' : /* listing sur fichier */ strcpy (flisting, optarg) ; cntlist_ref = 2 ; break ; case 'A' : /* listing sur stdout */ cntlist_ref = 1 ; break ; case 'p' : /* prompt */ r++ ; /* r := 1 */ break ; case 'l' : /* page length */ sscanf (optarg, "%d", &page_size) ; /* page_size := -l <n> */ break ; case 'o' : /* object file */ strcpy (fobject, optarg) ; break ; case '?' : /* non reconnu */ errflg++ ; break ; } /* si on a demande "-p", ou si pas d'argument : interface interactive */ if ((r)||(argc==1)) prompt () ; /* si option non reconnue ou si pas de nom de source, alors erreur */ if (errflg || ((optind==argc)&&(fsource[0]==EOL))) error (ERRUSA, "") ; /* page_size = 72 par defaut */ if (page_size==0) page_size = 72 ; if (*fsource) /* got source file name with prompt() */ { init() ; pass() ; between() ; pass() ; term() ; errrep = errcnt ; } else { for (i=optind; i<argc; i++) { strcpy (saveo, fobject) ; strcpy (savel, flisting) ; strcpy (fsource, argv [i]) ; if (optind != argc-1) printf ("%s:\n", fsource) ; init() ; pass() ; between() ; pass() ; term() ; strcpy (fobject, saveo) ; strcpy (flisting, savel) ; errrep += errcnt ; } } exit (errrep) ; /* permet de signaler les erreurs */ } /****************************************************************************** PROMPT synopsis : prompt() description : if "-p" option is used, prompts the user for files to be used. ******************************************************************************/ prompt () { uchar line[MAXLEN+1] ; while (fsource[0]==EOL) { printf ("Source file : ") ; read_line (stdin, fsource) ; } if (fobject[0]==EOL) { printf ("Object file : ") ; read_line (stdin, fobject) ; } if (cntlist_ref==0) { printf ("Listing file : ") ; read_line (stdin, flisting) ; cntlist_ref = (flisting[0]) ? 2 : 0 ; } if (cntlist_ref) { if (xref==0) { printf ("Cross reference (y/n) : ") ; read_line (stdin, line) ; if ((*line=='y')||(*line=='Y')||(*line=='o')||(*line=='O')) xref = 1 ; } if (page_size==0) { printf ("Page length : ") ; read_line (stdin, line) ; sscanf (line, "%d", &page_size) ; } } } @EOF set `wc -lwc <areuh/assembler/amain.c` if test $1$2$3 != 2117355948 then echo ERROR: wc results of areuh/assembler/amain.c are $* should be 211 735 5948 fi chmod 644 areuh/assembler/amain.c echo x - areuh/assembler/amnemo.c cat >areuh/assembler/amnemo.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER MNEMONIC PROCESSING ps_mnemo, find_mnemo, hex, dec ******************************************************************************/ #include "aglobal.h" extern void regtest(), regarith(), reglogic(), branches(), rtnyes(), ptrtest(), stattest(), setptr(), setstat(), dparith(), datatrans(), nibhex(), lchex(), dxhex(), nibasc(), lcasc(), bss(), eject(), endx(), list(), title(), stitle(), lex(), id(), msg(), poll(), entryx(), charx(), key(), token(), bin(), chain(), endtxt(), endifx(), absx(), rdsymb(), elsex(), ifx() ; /****************************************************************************** PROCESS_MNEMO synopsis : ps_mnemo (line, modif, ad) uchar *line, *modif struct mnemo_desc *ad description : pass control to the appropriate routine, to process the opcode. ******************************************************************************/ ps_mnemo (line, modif, ad) uchar *line, *modif ; struct mnemo_desc *ad ; { switch (ad->m_class) { case 1 : regtest(ad, modif) ; break ; case 2 : regarith(ad, modif) ; break ; case 3 : reglogic(modif) ; break ; case 4 : branches(ad, modif) ; break ; case 7 : rtnyes() ; break ; case 8 : ptrtest(modif) ; break ; case 9 : stattest(modif) ; break ; case 10 : setptr(modif) ; break ; case 11 : setstat(modif) ; break ; case 12 : dparith(modif) ; break ; case 13 : datatrans(modif) ; break ; case 14 : nibhex(modif) ; break ; case 15 : lchex(modif) ; break ; case 16 : dxhex(modif) ; break ; case 17 : nibasc(modif) ; break ; case 18 : lcasc(modif) ; break ; case 19 : bss(modif) ; break ; case 20 : eject() ; break ; case 21 : endx() ; break ; case 23 : list(modif) ; break ; case 24 : title(modif) ; break ; case 25 : stitle(modif) ; break ; case 28 : lex(modif, line) ; break ; case 29 : id(modif, line) ; break ; case 30 : msg(modif, line) ; break ; case 31 : poll(modif, line) ; break ; case 32 : entryx(modif, line) ; break ; case 33 : charx(modif, line) ; break ; case 34 : key(modif, line) ; break ; case 35 : token(modif, line) ; break ; case 36 : bin(modif, line) ; break ; case 38 : chain(modif, line) ; break ; case 39 : endtxt(line) ; break ; case 40 : endifx() ; break ; case 41 : absx(modif) ; break ; case 42 : rdsymb(modif) ; break ; case 43 : elsex() ; break ; case 44 : ifx(modif) ; break ; } } /****************************************************************************** FIND_MNEMO synopsis : struct mnemo_desc *find_mnemo (mnemo) char *mnemo description : finds index of a mnemonic in mnemo_table, and returns it, -1 if not found. ******************************************************************************/ struct mnemo_desc *find_mnemo (mnemo) uchar *mnemo ; { int i, m, b = 1 ; long int h = 0 ; for (i=0; i<6; i++) h = (h<<3) + ((b) ? ((b=(int)mnemo[i])&7) : 0) ; h %= 43 ; i = h_opcode[h] ; m = h_opcode[++h] ; while (i<m) { if (strcmp(mnemo, mnemo_table[i].m_text)) i++ ; else break ; } return ((i==m) ? (struct mnemo_desc *)NULL : &mnemo_table[i]) ; } /****************************************************************************** HEX synopsis : uchar hex (digit) int digit description : returns the hexadecimal representation of integer 'digit' (in ['0'..'9','A'..'Z']). ******************************************************************************/ uchar hex (digit) int digit ; { return ((uchar) ( (digit<=9) ? digit+48 : digit+55) ) ; } /***************************************************************************** DEC synopsis : int dec (digit) uchar digit description : returns the decimal equivalent of hexadecimal character 'digit'. *****************************************************************************/ int dec (digit) uchar digit ; { return ((digit<'A') ? (int) digit - 48 : (int) digit - 55 ) ; } @EOF set `wc -lwc <areuh/assembler/amnemo.c` if test $1$2$3 != 2355945704 then echo ERROR: wc results of areuh/assembler/amnemo.c are $* should be 235 594 5704 fi chmod 644 areuh/assembler/amnemo.c echo x - areuh/assembler/aobj.c cat >areuh/assembler/aobj.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER OBJECT FILE UTILITIES o_init (), o_print (), dump_linker_infos () ******************************************************************************/ #include "aglobal.h" #define fputl(lg,fd) fwrite((char *)(&(lg)),sizeof(long int),1,fd) long int zero = 0L ; long int magic ; /****************************************************************************** O_INIT synopsis : void o_init () description : open object file and, if modular assembly, mark information for linker (address of second part of file, and size of code in nibs). ******************************************************************************/ void o_init () { uchar dfl [MAXLEN+1] ; if (modular) dfl_extension (dfl, fsource, "ao") ; else strcpy (dfl, "lex") ; look_obj (fobject, dfl) ; /* ensure name validity */ if (modular) fd_o = fopen (fobject, WAO_MODE) ; /* untranslated mode */ else fd_o =fopen (fobject, "w") ; /* text mode */ if (fd_o==NULL) error (ERROPN, fobject) ; /* error opening file */ if (modular) { magic = AO_MAGIC ; fputl (magic, fd_o) ; fputl (zero, fd_o) ; fputl (zero, fd_o) ; } else { magic = AL_MAGIC ; fputl (magic, fd_o) ; } if (ferror (fd_o)) error (ERRWRT, fobject) ; } /****************************************************************************** O_PRINT synopsis : void o_print (str, len) uchar *str int len description : burp ******************************************************************************/ void o_print (str, len) uchar *str ; int len ; { int i ; if (len) { if (len>18) for (i=0; i<len; i++) putc ((int) '0', fd_o) ; else for (i=0; i<len; i++) putc ((int) str[i], fd_o) ; } if (ferror (fd_o)) error (ERRWRT, fobject) ; } /****************************************************************************** DUMP_LINKER_INFOS synopsis : void dump_linker_infos () description : append to objet file external public definitions (symbolic or numeric) and external references usages. ******************************************************************************/ void dump_linker_infos () { int i ; /* index in h_label table */ struct symbol *pl ; /* points into a label list */ long int p2, p3 ; /* addresses of second and third parts */ long int nl = 0, nu = 0; /* # labels (part 2), # used (part 3) */ long int l ; /* auxiliar */ struct xused *h ; p2 = ftell (fd_o) ; /* begin of second part */ fputl (zero, fd_o) ; /* marker for address of third part */ fputl (zero, fd_o) ; /* number of labels in second part */ for (i=0; i<256; i++) { pl = h_label[i]->s_next ; while (pl) { if ((pl->s_name[0]=='=')&&(pl->s_value!=LBL_EXT) &&(pl->s_value!=LBL_IVL)) { nl++ ; fprintf (fd_o, "%s\n", pl->s_name) ; fputl (pl->s_value, fd_o) ; if (pl->s_value<0L) fprintf (fd_o, "%s\n", pl->s_def) ; else fputc (pl->s_type, fd_o) ; } pl = pl->s_next ; } } p3 = ftell (fd_o) ; /* begin of third part */ fputl (zero, fd_o) ; /* # used in third part */ while (headxu) { nu++ ; l = (long int) headxu->u_characteristic ; fputl (l, fd_o) ; fputl (headxu->u_pc, fd_o) ; fprintf (fd_o, "%s\n", headxu->u_expression) ; h = headxu ; headxu = headxu->u_next ; free ((char *) h) ; } fseek (fd_o, zero, 0) ; fputl (magic, fd_o) ; fputl (p2, fd_o) ; /* begin of second part */ fputl (pc, fd_o) ; /* # nibs in the code */ fseek (fd_o, p2, 0) ; fputl (p3, fd_o) ; /* begin of third part */ fputl (nl, fd_o) ; /* # labels defined in this module */ fseek (fd_o, p3, 0) ; fputl (nu, fd_o) ; /* # unresolved references here */ if (ferror (fd_o)) error (ERRWRT, fobject) ; } @EOF set `wc -lwc <areuh/assembler/aobj.c` if test $1$2$3 != 1665784778 then echo ERROR: wc results of areuh/assembler/aobj.c are $* should be 166 578 4778 fi chmod 644 areuh/assembler/aobj.c echo x - areuh/assembler/aopc1.c cat >areuh/assembler/aopc1.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER OPCODE PROCESSING (PART 1) ******************************************************************************/ #include "aglobal.h" #include "agen.h" #define UPRC(c) ((((c)>='a')&&((c)<='z')) ? (c)-32 : (c)) extern uchar *memoire() ; extern saddr calc_expression () ; extern uchar hex () ; /****************************************************************************** ADD_XUSED synopsis : void add_xused (type, pc, len, exp) int type, len saddr pc uchar *exp description : adds the parameters about the use of an expression containing external references. ******************************************************************************/ void add_xused (type, addr, len, exp) int type, len ; saddr addr ; uchar *exp ; { struct xused *xu ; xu = (struct xused *) memoire (sizeof (struct xused)) ; if (xu==(struct xused *) NULL) error (ERRMEM, "") ; xu->u_characteristic = (uchar) (type + len) ; xu->u_pc = addr ; xu->u_expression = memoire (strlen (exp) + 1) ; if (xu->u_expression==(uchar *)NULL) error (ERRMEM, "") ; strcpy (xu->u_expression, exp) ; xu->u_next = headxu ; /* queue it */ headxu = xu ; /* before the previous head */ } /****************************************************************************** FIELD_SELECT synopsis : field_select (modif) uchar *modif description : to be described, in a (far) future... ******************************************************************************/ int field_select (modif) uchar *modif ; { int r = 0 ; char c ; switch (UPRC(*modif)) { case 'P' : r = 1 ; break ; case 'W' : if (UPRC(modif[1])=='P') { r = 2 ; modif++ ; } else r = 8 ; break ; case 'X' : if (UPRC(modif[1])=='S') { r = 3 ; modif++ ; } else r = 4 ; break ; case 'S' : r = 5 ; break ; case 'M' : r = 6 ; break ; case 'B' : r = fs_B ; break ; case 'A' : r = fs_A ; break ; } c = *(++modif) ; if ((c!=' ')&&(c!=EOL)&&(c!='\t')) r = 0 ; return (r) ; } void regtest(ad, modif) struct mnemo_desc *ad ; uchar *modif ; { int r ; if (r=field_select(modif) ) { if (r==fs_A) { gen_code[1] = hex (r + ad->m_a) ; } else { gen_code[0] = '9' ; gen_code[1] = hex ((ad->m_a==2) ? r+7 : r-1) ; } } else error (WRNIWS, "") ; } void regarith (ad, modif) struct mnemo_desc *ad ; uchar *modif ; { int r ; if (r=field_select(modif)) { /* gen_len is 3 by default */ if (r==fs_A) gen_len = 2 ; if (passnb==2) { if (r==fs_A) { gen_code[0] = hex (ad->m_a + 11) ; gen_code[1] = gen_code[2] ; gen_code[2] = EOL ; } else { gen_code[0] = hex(((ad->m_a==ar_C)||(ad->m_a==ar_D))?10:11) ; gen_code[1] = hex(((ad->m_a==ar_C)||(ad->m_a==ar_E))?r-1:r+7) ; } } } else error (WRNIWS, "") ; } void reglogic (modif) uchar *modif ; { int r ; if (r=field_select(modif)) gen_code[2] = (r==fs_A) ? 'F' : hex(r-1) ; else error (WRNIWS, "") ; } int range (org, dest, nibs, offset) saddr org, dest, *offset ; int nibs ; { saddr Sixtine, Fiftine ; int r ; Sixtine = ((saddr) 1) << (nibs*4) ; Fiftine = Sixtine >> 1 ; *offset = dest - org ; r = ((*offset >= -Fiftine) && (*offset < Fiftine)) ; if (*offset<0) (*offset) += Sixtine ; /* -128 = 128 ; -1 = 255 */ return (r) ; } void branches (ad, modif) struct mnemo_desc *ad ; uchar *modif ; { saddr val, offset, pc_bis ; int fits, i, j ; uchar hex_var[MAXLEN+1] ; if ((ad->m_flag & F_GOYS) && (!(prev_test))) error (WRNTST, "") ; /* needs previous test instruction */ else { val = calc_expression (modif) ; if (val >= 0L) { if (ad->m_flag & F_ABSL) { fits = 1 ; offset = val ; } else { if (ad->m_flag & F_GSUB) pc_bis = pc + (long int) gen_len ; else pc_bis = pc + (long int) (ad->m_a) - 1L ; fits = range (pc_bis, val, ad->m_b, &offset) ; } if (!(fits)) { offset = 0L ; error (WRNJVL, "") ; /* Jump or value too large */ } hex6 (hex_var, offset) ; for (i=1, j=5; i<=ad->m_b; i++, j--) { gen_code[ad->m_a + i - 2] = hex_var[j] ; } gen_code[gen_len] = EOL ; } else /* EXP_ERR or EXP_EXT */ { if (val == EXP_EXT) { switch (ad->m_flag & (F_GSUB | F_ABSL)) { case F_GSUB : i = XRGSB ; break ; case F_ABSL : case F_ABSL | F_GSUB : i = XABSL ; break ; default : i = XRGTO ; break ; } add_xused (i, pc + (long int) ad->m_a - 1L, ad->m_b, extexp) ; } for (i=0; i<ad->m_b; i++) gen_code [ad->m_a - 1 + i] = '0' ; gen_code [gen_len] = EOL ; } } } void rtnyes() { if (!(prev_test)) error (WRNTST, "") ; /* needs previous test instr. */ } void ptrtest (modif) uchar *modif ; { saddr val ; val = calc_expression (modif) ; if (val == EXP_EXT) { add_xused (XABSL, pc + 2L, 1, extexp) ; val = (saddr) 0 ; /* FALLS INTO FOLLOWING */ } if (val == EXP_ERR) val = (saddr) 0 ; /* FALLS INTO FOLLOWING */ if (val>15L) error (WRNIPP, "") ; /* illegal pointer position */ else gen_code[2] = hex ((int) val) ; } void stattest (modif) uchar *modif ; { saddr val ; val = calc_expression (modif) ; if (val == EXP_EXT) { add_xused (XABSL, pc + 2L, 1, extexp) ; val = (saddr) 0 ; /* FALLS INTO FOLLOWING */ } if (val == EXP_ERR) val = (saddr) 0 ; /* FALLS INTO FOLLOWING */ if (val>15L) error (WRNISB, "") ; /* illegal status bit */ else gen_code[2] = hex ((int) val) ; } void setptr (modif) uchar *modif ; { saddr val ; val = calc_expression (modif) ; if (val == EXP_EXT) { add_xused (XABSL, pc + (long int) gen_len - 1L, 1, extexp) ; val = (saddr) 0 ; } /* FALLS INTO FOLLOWING */ if (val == EXP_ERR) val = (saddr) 0 ; /* FALLS INTO FOLLOWING */ if (val>15L) error (WRNIPP, "") ; /* illegal pointer position */ else gen_code[gen_len-1] = hex ((int) val) ; } void setstat (modif) uchar *modif ; { saddr val ; val = calc_expression (modif) ; if (val == EXP_EXT) { add_xused (XABSL, pc + 2L, 1, extexp) ; val = (saddr) 0 ; } /* FALLS INTO FOLLOWING */ if (val == EXP_ERR) val = (saddr) 0 ; /* FALLS INTO FOLLOWING */ if (val>15L) error (WRNISB, "") ; /* illegal status bit */ else gen_code[2] = hex ((int) val) ; } void dparith (modif) uchar *modif ; { saddr val ; val = calc_expression (modif) ; if (val >= 0L) { if ((val<1L)||(val>16L)) error (WRNIDP, "") ; /* illegal dp arithmetic value */ else gen_code[2] = hex (val - 1L) ; } else if (val == EXP_EXT) { add_xused (XABSO, pc + 2L, 1, extexp) ; val = (saddr) 1 ; } else /* (val == EXP_ERR) */ { val = (saddr) 1 ; } } void datatrans (modif) uchar *modif ; { saddr val ; int r ; r=field_select (modif) ; if ((r==fs_A)||(r==fs_B)) gen_len = 3 ; if (passnb == 2) { switch (r) { case 0 : /* expression instead of field selector */ val = calc_expression (modif) ; if (val >= 0L) { if ((val<1L)||(val>16)) error (WRNTFR, "") ; /* illegal transfer value */ else { gen_code[2] = hex (dec(gen_code[2])+8) ; gen_code[3] = hex ((int) val - 1L) ; } } else if (val == EXP_EXT) { add_xused (XABSO, pc + 3L, 1, extexp) ; gen_code[2] = hex (dec(gen_code[2])+8) ; /* ajout */ val = 1L ; } else /* (val == EXP_EXT) */ { val = 1L ; } break ; case fs_A : gen_len = 3 ; gen_code[1] = '4' ; gen_code[3] = EOL ; break ; case fs_B : gen_len = 3 ; gen_code[1] = '4' ; gen_code[2] = hex ( dec(gen_code[2]) + 8) ; gen_code[3] = EOL ; break ; default : gen_code[3] = hex (r-1) ; break ; } } } int hex_len (modif) /* aCLCHX : AS5 : ED094 */ uchar *modif ; { int i = 0 ; if (*modif=='#') modif++ ; while (((*modif>='0')&&(*modif<='9'))|| ((*modif>='A')&&(*modif<='F'))|| ((*modif>='a')&&(*modif<='f'))) { modif++ ; i++ ; } return ((i>16) ? 16 : i) ; } void check_last_hex (digit) uchar digit ; { if ((digit!=EOL)&&(digit!='\t')&&(digit!=' ')) { if ((digit<'0')|| ((digit>'9')&&(digit<'A'))|| ((digit>'F')&&(digit<'a'))|| (digit>'f')) error (WRNTMH, "") ; /* too many hex digit present */ else error (WRNNHX, "") ; /* non hexadecimal digit present */ } } void nibhex (modif) uchar *modif ; { int i ; gen_len = hex_len (modif) ; if (passnb==2) { if (*modif=='#') modif++ ; for (i=0; i<gen_len; i++) { if (modif[i]>='a') gen_code[i] = modif[i] - 32 ; else gen_code[i] = modif[i] ; } gen_code[gen_len] = EOL ; check_last_hex (modif[gen_len]) ; } } void lchex (modif) uchar *modif ; { int i, j ; gen_len = hex_len (modif) ; if (passnb==2) { if (*modif=='#') modif++ ; if (gen_len) { gen_code[1] = hex (gen_len - 1) ; for (i=0, j=gen_len-1; i<gen_len; i++, j--) { if (modif[j]>='a') gen_code[2+i] = modif[j] - 32 ; else gen_code[2+i] = modif[j] ; } gen_code[gen_len + 2] = EOL ; check_last_hex (modif[gen_len]) ; } else { gen_code[0] = EOL ; error (WRNNHX, "") ; /* non hex present (in fact, there is no) */ } } gen_len = (gen_len) ? gen_len+2 : 0 ; } void dxhex (modif) uchar *modif ; { int i, j, r ; r = hex_len (modif) ; if (passnb==2) { if ((r!=2)&&(r!=4)&&(r!=5)) error (WRNIHX, "") ; /* illegal hex const (number of digits) */ else { if (*modif=='#') modif++ ; /* if 2, no change to the opcode */ /* if 4, add 1, if 5 add two */ if (r!=2) gen_code[1] = hex (dec(gen_code[1]) + r - 3) ; for (i=0, j=r-1; i<r; i++, j--) { if (modif[j]>='a') gen_code[2+i] = modif[j] - 32 ; else gen_code[2+i] = modif[j] ; } gen_code[r+2] = EOL ; check_last_hex (modif[r]) ; } } gen_len = ((r==4)||(r==5)) ? r+2 : 4 ; } int ascii_len (modif) uchar *modif ; { uchar limit ; int i = 0 ; switch (*modif) { case '\'' : case '\\' : limit = *modif++ ; while ((*modif!=limit)&&(*modif)) { modif++ ; i++ ; } break ; } return ((i>8) ? 8 : i) ; } void nibasc (modif) uchar *modif ; { uchar limit ; int i ; gen_len = ascii_len (modif) ; if (passnb==2) { limit = *modif ; for (i=1; i<=gen_len; i++) { gen_code[2*(i-1)] = hex (((int) modif[i]) % 16) ; gen_code[2*i-1] = hex (((int) modif[i]) / 16) ; } gen_code[2*gen_len] = EOL ; switch (modif[gen_len + 1]) { case '\'' : case '\\' : if (modif[gen_len + 1]!=limit) error (WRNTMA, "") ; /* too many ascii chars present */ break ; case EOL : error (WRNASC, "") ; /* illegal ascii constant */ break ; default : error (WRNTMA, "") ; /* too many ascii chars present */ break ; } } gen_len *= 2 ; } void lcasc (modif) uchar *modif ; { uchar limit ; int i ; gen_len = ascii_len (modif) ; if (passnb==2) { limit = *modif ; for (i=1; i<=gen_len; i++) { gen_code[2*i] = hex (((int) modif[gen_len - i + 1]) % 16) ; gen_code[2*i+1] = hex (((int) modif[gen_len - i + 1]) / 16) ; } gen_code[2+2*gen_len] = EOL ; switch (modif[gen_len + 1]) { case '\'' : case '\\' : if (modif[gen_len + 1]!=limit) error (WRNTMA, "") ; /* too many ascii chars present */ break ; case EOL : error (WRNASC, "") ; /* illegal ascii constant */ break ; default : error (WRNTMA, "") ; /* too many ascii chars present */ break ; } gen_code[1] = hex (2*gen_len - 1) ; } gen_len = (gen_len) ? 2+2*gen_len : 0 ; } @EOF set `wc -lwc <areuh/assembler/aopc1.c` if test $1$2$3 != 630196812298 then echo ERROR: wc results of areuh/assembler/aopc1.c are $* should be 630 1968 12298 fi chmod 644 areuh/assembler/aopc1.c exit 0
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:33:05 1990 # # This archive contains: # areuh/assembler/aopc2.c areuh/assembler/apass.c # areuh/assembler/areport.c areuh/assembler/autil.c # areuh/assembler/common.h areuh/assembler/err.h # areuh/assembler/exp.c areuh/assembler/flag.h # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - areuh/assembler/aopc2.c cat >areuh/assembler/aopc2.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER OPCODE PROCESSING (PART 2) ******************************************************************************/ #include "aglobal.h" #include "agen.h" extern void l_new_page(), l_print (), ps_line () ; extern int ascii_len () ; extern saddr calc_expression () ; int ltok = 255 ; /* lowest token */ int htok = 0 ; /* highest token */ int ctok = 0 ; /* current token */ int ckey = 0 ; /* current key macro-op */ /****************************************************************************** FILE_HEADER synopsis : file_header (modif, type) uchar *modif, *line description : expand a macro-op (LEX or BIN) ******************************************************************************/ file_header (modif, type) uchar *modif, *type ; { uchar line [MAXLEN+1], *pline, limit, c ; int i = 0, later = 0 ; uprc (modif) ; strcpy (line, " NIBASC ") ; pline = line + 9 ; limit = *modif ; if ((limit!='\'')&&(limit!='\\')) error (ERRIFL, "") ; /* inv. file name */ *pline = limit ; pline++ ; modif++ ; while ((i<=8)&&((c = *modif)!=limit)&&(c)) { i++ ; if (!( ((c>='A')&&(c<='Z')) || ((later)&&(c>='0')&&(c<='9')) ) ) error (ERRIFL, "") ; /* invalid file name */ later++ ; *pline = c ; modif++ ; pline++ ; } if ((i==0)||(i==9)) error (ERRIFL, "") ; while (i<8) { *pline = ' ' ; pline++ ; i++ ; } *pline = limit ; *(pline+1) = EOL ; ps_line (line) ; strcpy (line, " NIBHEX ") ; strcat (line, type) ; ps_line (line) ; ps_line (" CON(2) 0") ; /* copy code / secure code */ for (i=1; i<=5; i++) ps_line (" CON(2) #00") ; /* time */ ps_line (" REL(5) FiLeNd") ; ctok = ckey = 0 ; } /****************************************************************************** BSS synopsis : void bss (modif) char *modif description : areuh ******************************************************************************/ void bss (modif) uchar *modif ; { saddr val ; int i, m ; val = calc_expression (modif) ; if (val < 0L) error (ERRVMD, "BSS") ; /* fatal error */ gen_len = (int) val ; if (passnb==2) { m = (gen_len>18) ? 18 : gen_len ; for (i=0; i<m; i++) gen_code[i] = '0' ; gen_code[m] = EOL ; } } void eject () { l_new_page (1) ; print_this_line = 0 ; } void endx () { running = 0 ; } void list (modif) uchar *modif ; { int r = 0 ; uchar c ; uprc (modif) ; c = *modif++ ; if (c=='O') { c = *modif++ ; switch (c) { case 'N' : r = 1 ; break ; case 'F' : c = *modif++ ; if (c=='F') r = 0 ; else r = -1 ; break ; default : r = -1 ; break ; } } else r = -1 ; c = *modif ; if ((r==-1)||((c!=' ')&&(c!=EOL)&&(c!='\t'))) error (WRNLST, "") ; /* invalid LIST argument */ else cntlist = r * cntlist_ref ; } void title (modif) uchar *modif ; { if (*l_title==EOL) strcpy (l_title, modif) ; } void stitle (modif) uchar *modif ; { strcpy (l_stitle, modif) ; eject () ; } void lex (modif, line) uchar *modif, *line ; { switch (passnb) { case 1 : if (linenb!=1) error (ERRLEX, "") ; /* invalid macro LEX or BIN */ modular = 0 ; gen_len = 37 ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; file_header (modif, "802E") ; print_this_line = 0 ; gen_len = 0 ; break ; } } void id (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "ID") ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; sprintf (tmp, " CON(2) %s", modif) ; ps_line (tmp) ; sprintf (tmp, " CON(2) %03d", ltok) ; ps_line (tmp) ; sprintf (tmp, " CON(2) %03d", htok) ; ps_line (tmp) ; ps_line (" CON(5) 0") ; ps_line (" NIBHEX F") ; ps_line (" REL(4) 1+TxTbSt") ; print_this_line = gen_len = 0 ; break ; } /* du switch */ } void msg (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; saddr val ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "MSG") ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; if (((val = calc_expression (modif)) == 0L) || (val == EXP_ERR)) ps_line (" CON(4) 0") ; else { sprintf (tmp, " REL(4) %s", modif) ; ps_line (tmp) ; } print_this_line = gen_len = 0 ; } /* du switch */ } void poll (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; saddr val ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "POLL") ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; if (((val = calc_expression (modif)) == 0L) || (val == EXP_ERR)) ps_line (" CON(5) 0") ; else { sprintf (tmp, " REL(5) %s", modif) ; ps_line (tmp) ; } print_this_line = gen_len = 0 ; } /* du switch */ } void entryx (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "ENTRY") ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; if (!ctok) ps_line (" * * * M A I N T A B L E * * *") ; sprintf (tmp, " CON(3) (TxEn%02d)-(TxTbSt)", ++ctok) ; ps_line (tmp) ; sprintf (tmp, " REL(5) %s", modif) ; ps_line (tmp) ; print_this_line = gen_len = 0 ; break ; } /* du switch */ } void charx (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "CHAR") ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; sprintf (tmp, " CON(1) %s", modif) ; ps_line (tmp) ; print_this_line = gen_len = 0 ; break ; } } void key (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "KEY") ; if (!ckey) ps_line (" TxTbSt") ; sprintf (tmp, " TxEn%02d", ++ckey) ; ps_line (tmp) ; gen_len = ((ascii_len(modif))*2) + 1 ; break ; case 2 : uprc (modif) ; if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; if (!ckey) { ps_line (" * * * T E X T T A B L E * * *") ; ps_line (" TxTbSt") ; } sprintf (tmp, " TxEn%02d", ++ckey) ; ps_line (tmp) ; sprintf (tmp, " CON(1) %02d", ((ascii_len(modif))*2) - 1) ; ps_line (tmp) ; sprintf (tmp, " NIBASC %s", modif) ; ps_line (tmp) ; print_this_line = gen_len = 0 ; break ; } /* du switch */ } void token (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; saddr tok ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "TOKEN") ; tok = calc_expression (modif) ; if (tok<ltok) ltok = tok ; if (tok>htok) htok = tok ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; sprintf (tmp, " CON(2) %s", modif) ; ps_line (tmp) ; print_this_line = gen_len = 0 ; break ; } /* du switch */ } void bin (modif, line) uchar *modif, *line ; { switch (passnb) { case 1 : if (linenb!=1) error (ERRLEX, "") ; /* invalid macro LEX or BIN */ modular = 0 ; gen_len = 37 ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; file_header (modif, "402E") ; print_this_line = 0 ; gen_len = 0 ; break ; } } void chain (modif, line) uchar *modif, *line ; { uchar tmp [MAXLEN+1] ; switch (passnb) { case 1 : if (modular) error (ERRIMO, "CHAIN") ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; if (calc_expression (modif) == EXP_ERR) ps_line (" CON(5) -1") ; else { sprintf (tmp, " REL(5) %s", modif) ; ps_line (tmp) ; } ps_line (" CON(5) -1") ; ps_line (" NIBHEX 20") ; print_this_line = gen_len = 0 ; break ; } } void endtxt (line) uchar *line ; { switch (passnb) { case 1 : if (modular) error (ERRIMO, "ENDTXT") ; if (!ckey) ps_line (" TxTbSt") ; /* if (!ckey) add_label (" TxTbSt", pc, "", LREL, 0) ; */ gen_len = 3 ; break ; case 2 : if (cntlist) l_print (pc, gen_code, line, F_PC+F_LN+F_TL) ; if (!ckey) ps_line (" TxTbSt") ; ps_line (" NIBHEX 1FF") ; print_this_line = gen_len = 0 ; break ; } /* du switch */ } void endifx () { if (!(in_if || in_else)) error (WRNIIF, "") ; /* Invalid conditional structure */ in_if = in_else = 0 ; exec = 1 ; } void absx (modif) /* FUTURE USE... */ uchar *modif ; { } void rdsymb (modif) uchar *modif ; { uchar *pmodif ; if (passnb==1) { pmodif = modif ; while ((*pmodif!=EOL)&&(*pmodif!='\t')&&(*pmodif!=' ')) pmodif++ ; *pmodif = EOL ; load_file (modif) ; } } void elsex () { if (!in_if) { error (WRNIIF, "") ; /* Invalid conditional structure */ in_if = in_else = 0 ; exec = 1 ; } else { in_if = 0 ; in_else = 1 ; exec = ! exec ; } } void ifx (modif) uchar *modif ; { saddr val ; if (in_if || in_else) { error (WRNIIF, "") ; /* Invalid conditional structure */ in_if = in_else = 0 ; exec = 1 ; } else { val = calc_expression (modif) ; if (val==EXP_EXT) error (WRNEXP, "") ; /* Illegal expression */ in_if = 1 ; in_else = 0 ; exec = (int) val ; } } @EOF set `wc -lwc <areuh/assembler/aopc2.c` if test $1$2$3 != 513162210067 then echo ERROR: wc results of areuh/assembler/aopc2.c are $* should be 513 1622 10067 fi chmod 644 areuh/assembler/aopc2.c echo x - areuh/assembler/apass.c cat >areuh/assembler/apass.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER PASS PROCESSING pass ******************************************************************************/ #include "aglobal.h" #include "agen.h" extern struct mnemo_desc *find_mnemo() ; extern int read_line(); extern void parse_line(), ps_label(), process_mnemo(), l_new_page(), l_print(), o_print() ; extern struct symbol *add_label() ; void ps_line() ; /****************************************************************************** PASS synopsis : void pass() description : ******************************************************************************/ void pass() { uchar line[MAXLEN+1]; int c; pc = 0 ; prev_test = 0 ; running = 1 ; exec = 1 ; in_if = in_else = 0 ; while (running) { c = read_line (fd_s, line) ; error_this_line = 0 ; if (c) running = 0 ; else ps_line (line) ; } if (passnb==1) { add_label("FiLeNd", pc, "", LREL, 0) ; } } /****************************************************************************** PS_LINE synopsis : void ps_line (line) uchar *line description : parses the line read from the input (breaks the line into three components), processes the label if necessary, processes the mnemonic if necessary, and does the listing and object file actualization, if pass one. ******************************************************************************/ void ps_line (line) uchar *line ; { uchar label[LBLLEN+2], mnemo[7], modif[MAXLEN+1] ; struct mnemo_desc *ad ; parse_line (line, label, mnemo, modif) ; if (!exec) { if ( (strcmp(mnemo, "IF"))&& (strcmp(mnemo, "ELSE"))&& (strcmp(mnemo, "ENDIF"))&& (strcmp(mnemo, "END")) ) return ; /* Neither IF nor ELSE nor ENDIF */ } if (*label) ps_label (label, mnemo, modif) ; *gen_code = EOL ; gen_len = 0 ; if (*mnemo) { ad = find_mnemo (mnemo) ; if (ad) { gen_len = ad->m_len ; switch (passnb) { case 1 : if (!((ad->m_flag)&F_LSET)) ps_mnemo (line, modif, ad) ; break ; case 2 : strcpy (gen_code, ad->m_code) ; ps_mnemo (line, modif, ad) ; if ((prev_test)&&(!(ad->m_flag & F_GOYS))) error (WRNYES, "") ; /* GOYES or RTNYES required */ break ; } } else { error (WRNOPC, "") ; /* unknown oopcode */ if (prev_test) error (WRNYES, "") ; /* GOYES or RTNYES required */ } } else ad = (struct mnemo_desc *) NULL ; if (passnb==2) { if ((cntlist)&&(print_this_line++)) l_print (pc, gen_code, line, F_PC+F_LN+F_GC+F_TL) ; o_print (gen_code, gen_len) ; if (ad) prev_test = ((ad->m_flag)&F_RETY) ? 1 : 0 ; } pc += gen_len ; } @EOF set `wc -lwc <areuh/assembler/apass.c` if test $1$2$3 != 1443803049 then echo ERROR: wc results of areuh/assembler/apass.c are $* should be 144 380 3049 fi chmod 644 areuh/assembler/apass.c echo x - areuh/assembler/areport.c cat >areuh/assembler/areport.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER END OF ASSEMBLY REPORT print_ref, print_status, print_label, print_xref ******************************************************************************/ #include "aglobal.h" extern void l_print (), l_new_page () ; uchar format [15], formateq [16], xformat [MAXLEN], xf[15] ; void print_status (), print_label (), print_xref () ; /****************************************************************************** PRINT_REF synopsis : void print_ref () description : at the end of assembly (end of second pass), programmer want some informations on the program. This includes : - list of labels with their value, and cross reference - error count - time and date - that's all folks ******************************************************************************/ void print_ref () { sprintf (format, " %%-%ds %%s", LBLLEN) ; sprintf (formateq, "%%-%ds %%s", LBLLEN+1) ; sprintf (xf, "%%%ds+ ", LBLLEN+18) ; sprintf (xformat, xf, "") ; if ((cntlist) || (xref)) print_label() ; if (cntlist) print_status() ; else { if (errcnt) printf ("aas: %d errors in file %s\n", errcnt, fsource) ; } } /****************************************************************************** PRINT_STATUS synopsis : void print_status () description : reports some status lines after the assembly ******************************************************************************/ void print_status() { uchar line[MAXLEN+1], tmp[MAXLEN+1] ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "", F_TL) ; sprintf (line, "Source : %s", fsource) ; l_print (0L, "", line, F_TL) ; l_print (0L, "", "", F_TL) ; sprintf (line, "Object : %s", fobject) ; l_print (0L, "", line, F_TL) ; l_print (0L, "", "", F_TL) ; strcpy (line, "Listing : ") ; if (cntlist == 1) strcat (line, "stdout") ; else strcat (line, flisting) ; l_print (0L, "", line, F_TL) ; l_print (0L, "", "", F_TL) ; format_time (tmp) ; sprintf (line, "Date : %s", tmp) ; l_print (0L, "", line, F_TL) ; l_print (0L, "", "", F_TL) ; sprintf (line, "Errors : %03d", errcnt) ; l_print (0L, "", line, F_TL) ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "", F_TL) ; l_print (0L, "", "Areuh Assembler/Linker V2.4, (c) P. David & J. Taillandier 1986 Paris, France", F_TL) ; } /****************************************************************************** PRINT_LABEL synopsis : void print_label() description : prints a complete list of labels encoutered in the assembly. ******************************************************************************/ void print_label () { struct symbol *t ; struct xtable *x ; uchar line[MAXLEN+1], tmp[MAXLEN+1] ; int i ; strcpy (l_stitle, "**** SYMBOL TABLE ****") ; l_new_page (1) ; for (i=0; i<256; i++) { t = h_label[i]->s_next ; while (t) { if (!t->s_os) { if (t->s_value >= (saddr) 0) { hex5 (tmp, t->s_value) ; } else if (t->s_value == LBL_UDF) { strcpy (tmp, "Undef") ; } else if (t->s_value == LBL_EXT) { strcpy (tmp, "Extrn") ; } else /* (t->s_value == LBL_SEQ) || (t->s_value == LBL_XEQ) */ { strcpy (tmp, "Unkwn") ; } if (*(t->s_name)=='=') sprintf (line, formateq, t->s_name, tmp) ; else sprintf (line, format, t->s_name, tmp) ; if (xref) { switch (t->s_type) { case LUDF : strcat (line, " Ukn") ; break ; case LABS : strcat (line, " Abs") ; break ; case LREL : strcat (line, " Rel") ; break ; } if ((t->s_value!=LBL_UDF)&&(t->s_value!=LBL_EXT)) sprintf (tmp, "%s %04d - ", line, t->s_decl) ; else sprintf (tmp, "%s - ", line, t->s_decl) ; x = t->s_xref ; if (x) { while (x->x_next) x = x->x_next ; print_xref (x, tmp) ; } else { if (cntlist) l_print (0L, "", tmp, F_TL) ; else printf ("%s\n", tmp) ; } } else l_print (0L, "", line, F_TL) ; } /* if not (O.S. entry point not used) */ t = t->s_next ; } /* while */ } /* for */ } /****************************************************************************** PRINT_XREF synopsis : void print_xref (x, line) struct xtable *x uchar *line description : prints the complete cross-reference list backward from the end. x is the end of xref list, line is the line to be printed first. ******************************************************************************/ void print_xref (x, line) struct xtable *x ; uchar *line ; { int col = LBLLEN+21 ; /* column number */ uchar tmp[MAXLEN+1], strnum[MAXLEN+1] ; strcpy (tmp, line) ; while (x) { if (col>75) { if (cntlist) l_print (0L, "", tmp, F_TL) ; else printf ("%s\n", tmp) ; col = LBLLEN+21 ; strcpy (tmp, xformat) ; } sprintf (strnum, " %04d", x->x_line) ; strcat (tmp, strnum) ; col += 5 ; x = x->x_prev ; } if (cntlist) l_print (0L, "", tmp, F_TL) ; else printf ("%s\n", tmp) ; } @EOF set `wc -lwc <areuh/assembler/areport.c` if test $1$2$3 != 2297616584 then echo ERROR: wc results of areuh/assembler/areport.c are $* should be 229 761 6584 fi chmod 644 areuh/assembler/areport.c echo x - areuh/assembler/autil.c cat >areuh/assembler/autil.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** TITAN ASSEMBLER GENERAL UTILITIES hard_init, soft_init, between, term, memoire ******************************************************************************/ #include "aglobal.h" void free_mem () ; extern void o_init() ; extern void dump_linker_infos () ; extern void l_init(), l_flush() ; extern void s_init() ; extern void i_tab0(), i_tab1(), i_tab2(), i_tab3(), i_tab4(), i_tab5() ; extern void print_ref() ; extern char *malloc () ; /****************************************************************************** INIT synopsis : void init() description : initiates the pass one. Opens source file, initializes the symbol list. Called for each file assembled. ******************************************************************************/ void init () { uchar file [MAXLEN+1], *psource, *pfile ; if (!try_source (fsource)) /* if can't open succesfully */ { pfile = file ; psource = fsource ; while ((*pfile = *psource) && (*pfile != '.')) { pfile++ ; psource++ ; } if (*pfile == EOL) { strcpy (pfile, ".as") ; if (try_source (file)) strcpy (fsource, file) ; } } if (fd_s==NULL) error (ERROPN, fsource) ; s_init() ; /* symbol table init */ passnb = 1 ; linenb = 0 ; cntlist = 0 ; modular = 1 ; *l_title = *l_stitle = EOL ; } /****************************************************************************** BETWEEN synopsis : void between() description : terminates the passe one, and prepares pass two. Restore file source pointer, opens object file. ******************************************************************************/ void between() { int r ; r = fseek (fd_s,0L,0); if (r) error (ERRREW, fsource) ; o_init() ; cntlist = cntlist_ref ; l_init() ; linenb = 0 ; passnb = 2 ; print_this_line = 1 ; errcnt = 0 ; headxu = (struct xused *) NULL ; } /****************************************************************************** TERM synopsis : void term () description : ends the pass two, and thus the assembly. Closes source file, and flushes object files. ******************************************************************************/ void term () { if (fclose (fd_s)) error (ERRCLO, fsource) ; if (modular) dump_linker_infos () ; if (fclose (fd_o)) error (ERRCLO, fobject) ; print_ref () ; l_flush () ; free_mem () ; } int try_source (file) uchar *file ; { long int magic ; fd_s = fopen (file, "r") ; if (fd_s) { fread (&magic, sizeof (long int), 1, fd_s) ; if (((magic>=ALF_MAGIC)&&(magic<=AL_MAGIC))|| ((magic>=AOF_MAGIC)&&(magic<=AO_MAGIC))) { fclose (fd_s) ; fd_s = (FILE *) NULL ; } else fseek (fd_s, 0L, 0) ; } return ((int) fd_s) ; } /****************************************************************************** MEMOIRE synopsis : uchar *memoire (size) int size description : get memory from heap using malloc. It is just a layer above malloc, including a test. ******************************************************************************/ uchar *memoire (size) int size ; { uchar *x ; if ((x = (uchar *) malloc (size)) == NULL) error (ERRMEM, "") ; return (x) ; } /****************************************************************************** UPRC synopsis : void uprc (str) uchar *str description : uppercase a string ******************************************************************************/ void uprc (str) uchar *str ; { while (*str) { if ((*str >= 'a') && (*str <= 'z')) *str -= 32 ; str++ ; } } /****************************************************************************** FORMAT_HEX synopsis : void format_hex (str, val, dig) uchar *str saddr val int dig description : stores into str the hexadecimal string representing the dig low order hex digits of val. ******************************************************************************/ void format_hex (str, val, dig) uchar *str ; saddr val ; int dig ; { register int i, h ; for (i=dig-1; i>=0; i--) { h = (int) (val & ((saddr) 0xf)) ; str [i] = h + ((h < 10) ? '0' : 'A' - 10) ; val >>= 4 ; } str [dig] = EOL ; } /****************************************************************************** FREE_MEM synopsis : void free_mem () description : frees all dynamically allocated memory during both passes. ******************************************************************************/ void free_mem () { struct xused *u ; struct symbol *s1, *s2 ; struct xtable *x1, *x2 ; int i ; for (i=0; i<=255; i++) { s1 = h_label[i]->s_next ; while (s1) { if (xref) { x1 = s1->s_xref ; while (x1) { x2 = x1->x_next ; free ((char *) x1) ; x1 = x2 ; } } if (s1->s_def) free ((char *) s1->s_def) ; s2 = s1->s_next ; free ((char *) s1) ; s1 = s2 ; } } free ((char *) h_label [0]) ; } @EOF set `wc -lwc <areuh/assembler/autil.c` if test $1$2$3 != 2656915648 then echo ERROR: wc results of areuh/assembler/autil.c are $* should be 265 691 5648 fi chmod 644 areuh/assembler/autil.c echo x - areuh/assembler/common.h cat >areuh/assembler/common.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include <stdio.h> #define MAXLEN 256 #define EOL '\0' #define LBLLEN 12 /****************************************************************************** TYPE DEFINITIONS ******************************************************************************/ typedef long int saddr ; /* Saturne address. At least 32 bits */ typedef unsigned char uchar ; /* unsigned characters, for accents */ typedef short int sint ; /* 16 bits */ /****************************************************************************** MAGIC NUMBERS ******************************************************************************/ #define AL_MAGIC 0x1b080100 /* ... areuh_lex */ #define AO_MAGIC 0x1b0d0100 /* ... areuh_output of assembler */ #define ALF_MAGIC 0x1b080100 /* first version of object file format */ #define AOF_MAGIC 0x1b0d0100 /* first version of object file format */ /****************************************************************************** USAGE TYPES IN .ao FILES ******************************************************************************/ #define XABSL 0x10 /* absolute reference */ #define XABSO 0x20 /* absolute reference, with one bias */ #define XRGTO 0x40 /* relative reference, goto type */ #define XRGSB 0x80 /* relative reference, gosub type */ /****************************************************************************** LABEL VALUES IN .ao FILES ******************************************************************************/ #define LBL_UDF -1L /* label not declared (implicit or explicit) <=> only used */ #define LBL_IVL -2L /* invalid label (invalid expression for an EQU during pass one) */ #define LBL_EXT -3L /* external label not defined here (or yet) */ #define LBL_XEQ -4L /* global label which is defined here, with an external reference */ #define LBL_SEQ -5L /* local label which is defined with an external reference */ /****************************************************************************** LABEL TYPES IN .ao FILES ******************************************************************************/ #define LUDF 0 /* undefined type (external label) */ #define LABS 1 /* absolute local label (declared explicitly, with constants) */ #define LREL 2 /* relative local label (declared implicitly, or explicitly with at least one relative) */ /****************************************************************************** VALUES RETURNED BY EXPRESSION EVALUATOR ******************************************************************************/ #define EXP_ERR -1L #define EXP_EXT -2L extern int relabs ; extern uchar extexp[] ; #include "err.h" extern void error () ; #define hex5(str,val) format_hex (str, val, 5) ; #define hex6(str,val) format_hex (str, val, 6) ; /****************************************************************************** MACHINE DEPENDANCIES ******************************************************************************/ #define HPUX 1 #define ATARI_LATTICE 0 #define PC_MSC 0 /* PC (beuark, Microsoft C) */ #if HPUX extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "r" #define WAO_MODE "w" #define skip(fp) #endif #if ATARI_LATTICE extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "rb" #define WAO_MODE "wb" extern char skipvar ; #define skip(fp) fread(&skipvar,1,1,fp) ; #endif #if PC_MSC extern void format_time(), load_file() ; #define HP71EP "hp71.ep" #define RAO_MODE "rb" #define WAO_MODE "wb" extern char skipvar ; #define skip(fp) fread(&skipvar,1,1,fp) ; #endif @EOF set `wc -lwc <areuh/assembler/common.h` if test $1$2$3 != 1244243878 then echo ERROR: wc results of areuh/assembler/common.h are $* should be 124 424 3878 fi chmod 644 areuh/assembler/common.h echo x - areuh/assembler/err.h cat >areuh/assembler/err.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** AREUH ASSEMBLER / LINKER ERROR NUMBERS DECLARATIONS ******************************************************************************/ /* FATAL ERRORS */ #define ERROPN -1 /* A L */ /* system error opening file */ #define ERRCLO -2 /* A L */ /* system error closing file */ #define ERRREW -3 /* A */ /* system error on file at start of pass two */ #define ERRWRT -4 /* A L */ /* system error writing file */ #define ERRRD -5 /* A L */ /* system error reading file */ #define ERRMEM -6 /* A L */ /* not enough memory */ #define ERRLEX -10 /* A */ /* invalid macro pseudo-op LEX or BIN */ #define ERRPGS -11 /* A */ /* invalid page size */ #define ERRFLN -12 /* A */ /* restricted label FiLeNd exists */ #define ERRIFL -13 /* A L */ /* invalid file name */ #define ERRIMO -14 /* A */ /* invalid macro-op xx in modular assembling */ #define ERRVMD -15 /* A */ /* value must be defined for xx */ #define ERRUSA -20 /* A L */ /* usage: ass [ [-l] source_file ] */ /* usage: ald ... */ #define ERRNOA -30 /* L */ /* file not output from aas */ #define ERRICV -31 /* L */ /* incompatible version */ /* NON FATAL ERRORS */ #define WRNEQU 10 /* A */ /* cannot resolve equate */ #define WRNDUP 11 /* A L */ /* duplicate label */ #define WRNLBL 12 /* A */ /* illegal label */ #define WRNULB 13 /* A */ /* unrecognized label */ #define WRNURF 14 /* L */ /* unresolved reference */ #define WRNURL 15 /* L */ /* unresolved label */ #define WRNEXP 20 /* A */ /* illegal expression */ #define WRNASC 21 /* A */ /* illegal ascii constant */ #define WRNPAR 22 /* A */ /* mismatched parenthesis */ #define WRNIHX 23 /* A */ /* illegal hexadecimal constant */ #define WRNNUL 24 /* A */ /* null divisor */ #define WRNIXP 25 /* A */ /* illegal exponentiation */ #define WRNIBC 26 /* A */ /* illegal binary constant */ #define WRNENA 27 /* A */ /* external references not allowed */ #define WRNYES 30 /* A */ /* GOYES or RTNYES required */ #define WRNIDP 31 /* A */ /* illegal dp arithmetic value */ #define WRNIPP 32 /* A */ /* illegal pointer position */ #define WRNISB 33 /* A */ /* illegal status bit */ #define WRNTFR 34 /* A */ /* illegal transfer value */ #define WRNIWS 35 /* A */ /* illegal word select */ #define WRNLST 36 /* A */ /* invalid LIST argument */ #define WRNJVL 37 /* A L */ /* jump or value too large */ #define WRNMLB 38 /* A */ /* missing label */ #define WRNTST 39 /* A */ /* needs previous test instruction */ #define WRNNHX 40 /* A */ /* non hexadecimal digits present */ #define WRNTMA 41 /* A */ /* too many ascii characters present */ #define WRNTMH 42 /* A */ /* too many hexadecimal digits present */ #define WRNOPC 43 /* A */ /* unknown opcode */ #define WRNIIF 50 /* A */ /* invalid conditional structure */ extern void error() ; @EOF set `wc -lwc <areuh/assembler/err.h` if test $1$2$3 != 1275845010 then echo ERROR: wc results of areuh/assembler/err.h are $* should be 127 584 5010 fi chmod 644 areuh/assembler/err.h echo x - areuh/assembler/exp.c cat >areuh/assembler/exp.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** TITAN ASSEMBLER EXPRESSION EVALUATION calc_expression, reduce_E, reduce_T, reduce_F, reduce_B, reduce_X, reduce_P, dec_value, hex_value, bin_value, ascii_value, label_value, apply, trunc, next_char, append_extexp ******************************************************************************/ #include "flag.h" #if ASSEMBLER #include "aglobal.h" #else #include "lglobal.h" #endif uchar extexp [4*MAXLEN] ; uchar *pexp, *pextexp ; uchar *xlabel ; int relabs ; extern saddr symbol_value() ; saddr reduce_E(), reduce_T(), reduce_F(), reduce_B(), reduce_X(), reduce_P(), dec_value(), hex_value(), bin_value(), ascii_value(), label_value(), apply(), trunc() ; void next_char(), append_extexp() ; /****************************************************************************** CALC_EXPRESSION synopsis : saddr calc_expression (exp) uchar *exp description : That's the expression evaluator. Productions used are : E -> T { {+|-} T }* T -> F { {*|/} F }* F -> B { {&|!} B }* B -> X | -X | `X (two's and one's complement) X -> N { {~|^} N }* P -> D | #<hex> | %<bin> | '<ascii>' | \<ascii>\ | <label> | * | (E) D -> <dec> if expression evaluated by ASSSEMBLER D -> <dec> | <dec> r if expression evaluated by LINKER where E : expression T : term F : factor B : boolean X : exponentiation P : primary D : decimal number warning : with this grammar, 5--5 is valid (5 minus -5), but 5---5 is not. This can be modified by : B -> -B | P . The code is more complex, and I'm not sure that it's a real improvement. note : Algorithm used is recursive descent (Mr Vermeulen would be horrified !) like Forth/Assembler rom based assembler, but is quietly different... ******************************************************************************/ saddr calc_expression (exp) uchar *exp; { saddr val; pextexp = extexp ; pexp = exp ; val = reduce_E() ; if (((val>=0L)||(val==EXP_EXT))&&(*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t')) { error(WRNEXP, "") ; /* illegal expression */ val = EXP_ERR ; } *pextexp = EOL ; return (val) ; } /****************************************************************************** REDUCE_E synopsis : saddr reduce_E() description : This function reduces a given expression starting at pexp. ******************************************************************************/ saddr reduce_E() { saddr val1, val2; uchar op, lrelabs; val1 = reduce_T () ; while ((((op = *pexp)=='+')||(op=='-'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_T () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_T synopsis : saddr reduce_T () description : same as above, for T-production ******************************************************************************/ saddr reduce_T () { saddr val1, val2 ; uchar op, lrelabs ; val1 = reduce_F () ; while ((((op = *pexp)=='*')||(op=='/'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_F () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_F synopsis : saddr reduce_F () description : same as reduce_E ******************************************************************************/ saddr reduce_F () { saddr val1, val2; uchar op, lrelabs ; val1 = reduce_B () ; while ((((op = *pexp)=='&')||(op=='!'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_B () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_B synopsis : saddr reduce_B () description : reduces a boolean factor. This must be done by reduction of minus sign eventually. ******************************************************************************/ saddr reduce_B () { saddr val; uchar op ; op = *pexp ; if ((op=='-')||(op=='\`')) next_char () ; val = reduce_X () ; if (val<0L) return(val) ; switch (op) { case '-' : return (trunc (-val)) ; case '\`' : return (trunc (~val)) ; default : return (val) ; } } /****************************************************************************** REDUCE_X synopsis : saddr reduce_X () description : same as reduce_E ******************************************************************************/ saddr reduce_X () { saddr val1, val2; uchar op, lrelabs; val1 = reduce_P () ; while ((((op = *pexp)=='~')||(op=='^'))&&(val1!=EXP_ERR)) { lrelabs = relabs ; next_char () ; val2 = reduce_P () ; val1 = apply (val1, op, val2, lrelabs, relabs) ; } return (val1) ; } /****************************************************************************** REDUCE_P synopsis : saddr reduce_P () description : these are the terminal rules. note : rule P -> D is implemented "in line" in this code (not as a separate function). ******************************************************************************/ saddr reduce_P () { saddr val ; uchar limit, line[MAXLEN] ; switch (*pexp) { case '#' : next_char () ; if (((*pexp>='0')&&(*pexp<='9')) || ((*pexp>='A')&&(*pexp<='F')) || ((*pexp>='a')&&(*pexp<='f'))) val = hex_value () ; else { error (WRNIHX,""); /* illegal hexadecimal constant */ val = EXP_ERR ; } relabs = LABS ; break ; case '%' : next_char () ; if ((*pexp=='0')||(*pexp=='1')) val = bin_value () ; else { error (WRNIBC, "") ; /* illegal binary constant */ val = EXP_ERR ; } relabs = LABS ; break ; case '\'' : case '\\' : limit = *pexp ; next_char () ; val = ascii_value (limit) ; if (*pexp!=limit) { error (WRNASC,""); /* illegal ascii constant */ val = EXP_ERR ; } next_char () ; relabs = LABS ; break ; case '*' : val = pc ; pexp++ ; sprintf (line, "%ldr", pc) ; relabs = LREL ; append_extexp (line) ; break ; case '(' : next_char () ; val = reduce_E () ; if ((*pexp!=')')&&(val>=0)) { error (WRNPAR, "") ; /* mismatched parenthesis */ val = EXP_ERR ; } next_char () ; break ; case EOL : error (WRNEXP,"") ; /* illegal expression */ val = EXP_ERR ; break ; default : if ((*pexp>='0')&&(*pexp<='9')) { val = dec_value () ; relabs = LABS ; #if LINKER if (*pexp=='r') { next_char() ; relabs = LREL ; val += tmodule[file].m_ad ; } #endif } else val = label_value () ; break ; } return (val) ; } /****************************************************************************** DEC_VALUE synopsis : saddr dec_value () descrption : This function returns the decimal value of a constant. The search is stopped when a non numeric digit is reached. (this can be ),+,-,*,/,&,!). Finally, the founded value is returned. note : this function doesn't check overflow. If there is, numbers are treated as 20 bits words, and overflow doesn't propagate on 32 bits of an integer (-1 is never reached when calculus). ******************************************************************************/ saddr dec_value () { saddr val=0L ; do { val = trunc (val * 10L + (saddr) (*pexp-'0') ) ; next_char () ; } while ((*pexp>='0')&&(*pexp<='9')) ; return (val); } /****************************************************************************** HEX_VALUE synopsis : saddr hex_value () description : same as above for hexadecimal constants ******************************************************************************/ saddr hex_value () { saddr i, val = 0L ; while ( ((*pexp>='0')&&(*pexp<='9')) || ((*pexp>='A')&&(*pexp<='F')) || ((*pexp>='a')&&(*pexp<='f')) ) { if (*pexp<='9') i = (long int) ((*pexp) - '0') ; else if (*pexp<='F') i = (long int) ((*pexp) - 'A' + 10) ; else i = (long int) ((*pexp) - 'a' + 10) ; val = trunc (val*16L + i) ; next_char () ; } return (val) ; } /****************************************************************************** BIN_VALUE synopsis : saddr bin_value () description : same as above for binary constants ******************************************************************************/ saddr bin_value () { saddr val = 0L ; while ((*pexp=='0')||(*pexp=='1')) { val = trunc (val*2L + ((saddr) ((*pexp) - '0'))) ; next_char () ; } return (val) ; } /****************************************************************************** ASCII_VALUE synopsis : saddr ascii_value () description : same as above, but the search is stopped when encoutered a '. The pointer *pexp stands on this character. ******************************************************************************/ saddr ascii_value (limit) uchar limit ; { saddr val = 0 ; while ((*pexp!=EOL)&&(*pexp!=limit)) { val = trunc (val*256L + ((saddr) *pexp)) ; next_char () ; } return (val) ; } /****************************************************************************** LABEL_VALUE synopsis : saddr label_value () description : parses the symbol, then tries to return the value founded in the symbol list. ******************************************************************************/ saddr label_value () { uchar label[LBLLEN+2], *plabel ; int mx, need_par = 0, j = 0 ; saddr val ; mx = LBLLEN + ((*pexp=='=') ? 1 : 0) ; while ((*pexp!=EOL)&&(*pexp!=' ')&&(*pexp!='\t')&& (*pexp!=')')&&(*pexp!='\\')) { if (j<mx) label[j++] = *pexp ; pexp++ ; } label[j] = EOL ; plabel = label ; if ((val = symbol_value (label)) >= (saddr) 0) { /* found, copy value */ if (relabs==LREL) sprintf (label, "%ldr", val) ; else sprintf (label, "%ld", val) ; } else if ((val == LBL_UDF) || (val == LBL_IVL)) { /* UDF : label not (yet) declared, IVl : invalid label */ *plabel = EOL ; /* incoherent value */ val = EXP_ERR ; } else if ((val == LBL_EXT) || (val == LBL_XEQ)) { /* LBL_EXT: ext. label not known, LBL_XEQ: global defined with ext. */ val = EXP_EXT ; /* keep label name */ } else /* (val == LBL_SEQ) */ { /* LBL_SEQ : synonym, expandable */ plabel = xlabel ; /* get definition of label */ need_par = 1 ; /* enclose label with (...) */ val = EXP_EXT ; /* and store it into extep */ } if (need_par) append_extexp ("(") ; append_extexp (plabel) ; if (need_par) append_extexp (")") ; return (val) ; } /****************************************************************************** APPLY synopsis : saddr apply (val1, op, val2, relabs1, relabs2) saddr val1, val2 uchar op, relabs1, relabs2 description : calculate the value of binary operator op applied to operands val1 & val2. note : under overflow condition, numbers are truncated to 20 bits. ******************************************************************************/ saddr apply (val1, op, val2, relabs1, relabs2) uchar op, relabs1, relabs2 ; saddr val1, val2 ; { saddr val ; if (val2==EXP_ERR) return (EXP_ERR) ; if ((val1==EXP_EXT)||(val2==EXP_EXT)) return (EXP_EXT) ; switch (op) { case '+' : val = trunc (val1 + val2) ; break ; case '-' : val = trunc (val1 - val2 ) ; break ; case '*' : val = trunc (val1 * val2 ) ; break ; case '/' : #if ASSEMBLER val = (val2 ? val1 / val2 : EXP_ERR ) ; #else val = (val2 ? val1 / val2 : EXP_EXT ) ; #endif if (val2==0L) error (WRNNUL, "") ; /* null divisor */ break ; case '&' : val = val1 & val2 ; break ; case '!' : val = val1 | val2 ; break ; case '~' : val = trunc (val1*256 + val2) ; break ; case '^' : if ((val1<0)||(val2<0)||((val1==0)&&(val2==0))) { error (WRNIXP, "") ; /* Illegal exponentiation */ #if ASSEMLER val = EXP_ERR ; #else val = EXP_EXT ; #endif } else { val = 1 ; for (;val2>0 ; val2--) val *= val1 ; val = trunc (val) ; } break ; } if ((relabs1==LUDF)||(relabs2==LUDF)) relabs = LUDF ; else if ((relabs1==LREL)||(relabs2==LREL)) relabs = LREL ; else relabs = LABS ; return (val) ; } /****************************************************************************** TRUNC synopsis : saddr trunc (val) saddr val description : truncates 32 bits integer to 24 bits. ******************************************************************************/ saddr trunc (val) saddr val ; { return (val & 0xffffff) ; } /****************************************************************************** NEXT_CHAR synopsis : void next_char () description : stores the current character in extexp variable, and moves the expression pointer (pexp) forward one position. ******************************************************************************/ void next_char () { *pextexp = *pexp ; pextexp++ ; pexp++ ; } /****************************************************************************** APPEND_EXTEXP synopsis : void append_extexp (line) uchar *line ; description : append line to extexp string. ******************************************************************************/ void append_extexp (line) uchar *line ; { while (*line) { *pextexp = *line ; pextexp++ ; line++ ; } } @EOF set `wc -lwc <areuh/assembler/exp.c` if test $1$2$3 != 634182916414 then echo ERROR: wc results of areuh/assembler/exp.c are $* should be 634 1829 16414 fi chmod 644 areuh/assembler/exp.c echo x - areuh/assembler/flag.h cat >areuh/assembler/flag.h <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************/ /* !!! CONTENTS OF THIS FILE MUST BE DIFFERENT FOR ASSEMBLER AND LINKER !!! */ /****************************************************************************/ #define ASSEMBLER 1 #define LINKER 0 @EOF set `wc -lwc <areuh/assembler/flag.h` if test $1$2$3 != 1663507 then echo ERROR: wc results of areuh/assembler/flag.h are $* should be 16 63 507 fi chmod 644 areuh/assembler/flag.h exit 0
pda@litp.ibp.fr (Pierre DAVID) (07/05/90)
#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Pierre David <pda@janick> on Sun Jul 1 12:33:08 1990 # # This archive contains: # areuh/assembler/mdep.c areuh/assembler/tabgrp.c # areuh/assembler/tabopc.c areuh/assembler/Makefile # areuh/assembler/aas.1 areuh/README # # Error checking via wc(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - areuh/assembler/mdep.c cat >areuh/assembler/mdep.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ /****************************************************************************** M A C H I N E D E P E N D E N C I E S ******************************************************************************/ #include "flag.h" #if ASSEMBLER #include "aglobal.h" #else #include "lglobal.h" #endif extern struct symbol *add_label() ; #if HPUX void format_time (str) uchar *str ; { long int l ; extern long int time () ; extern char *ctime () ; l = time (0L) ; strcpy (str, ctime (&l)) ; str [strlen (str) - 1] = EOL ; } char *tab[] = { "", "/usr/lib/", "/usr/local/lib/", "/lib/", "/hp71/lib/", "/local/lib/", 0 } ; void load_file (file) uchar *file ; { int i = 0 ; uchar name [MAXLEN+1] ; saddr val ; FILE *fp ; fp = (FILE *) NULL ; while ((tab[i])&&(!fp)) { sprintf (name, "%s%s", tab[i++], file) ; fp = fopen (name, "r") ; } if (!fp) error (ERROPN, file) ; #if LINKER file = 0 ; #endif while (fscanf (fp, "%s\n%X\n", name, &val) != EOF) { #if ASSEMBLER add_label (name, val, "", LABS, 1) ; #else add_label (name, val, 1) ; #endif } if (ferror (fp)) error (ERRWRT, file) ; if (fclose (fp)) error (ERRCLO, file) ; } #include <sys/types.h> #include <sys/stat.h> /* look for object file (object code or listing file) * if non existent, ok * if exists and not directory, ok * if exists and directory, then append "<dir>/<default>" */ look_obj (fname, dfl) uchar *fname, *dfl ; { struct stat buf ; if (*fname == EOL) /* if fname == "" then default it */ strcpy (fname, dfl) ; if (!stat (fname, &buf)) /* file exists. Is it a directory ? */ { if ((buf.st_mode & S_IFMT) == S_IFDIR) sprintf (fname, "%s/%s", fname, dfl) ; } } /* build a default file name, based on "source" basename and a given * default extension. */ dfl_extension (object, source, extension) uchar *object, *source, *extension ; { uchar *pname ; strcpy (object, source) ; pname = object ; while ((*pname)&&(*pname!='.')) pname++ ; if (*pname==EOL) *pname = '.' ; strcpy (pname+1, extension) ; } #endif /* HPUX */ #if ATARI_LATTICE char skipvar ; void format_time (str) uchar *str ; { strcpy (str, "Areuh Tagada Bouzouh bouzouh areuh areuh... et toc !") ; } char *optarg ; int optind = 0, opterr = 0 ; int getopt (argc, argv, optstr) int argc ; char *argv[], *optstr ; { char *o, car ; static char *index = 0 ; extern char *strchr () ; if ((index==(char *)0)||(*(index+1)==0)) { if (++optind>argc-1) return (EOF) ; index = argv[optind] ; if (*index!='-') return (EOF) ; } car = *(++index) ; /* state 6 */ if (!(o = strchr (optstr, car))) return ('?') ; if (*(o+1)!=':') return ((int) car) ; if (*(index+1)) optarg = index+1 ; else { if (++optind>argc-1) return (EOF) ; else optarg = argv[optind] ; } index = (char *) 0 ; return ((int) car) ; } uchar *tab[] = { "", "A:", "A:\\TABLE\\", 0 } ; void load_file (file) uchar *file ; { int i = 0 ; uchar name [MAXLEN+1] ; saddr val ; FILE *fp ; fp = (FILE *) NULL ; while ((tab[i])&&(!fp)) { sprintf (name, "%s%s", tab[i++], file) ; fp = fopen (name, "r") ; } if (!fp) error (ERROPN, file) ; #if LINKER file = 0 ; #endif while (fscanf (fp, "%s\n%x\n", name, &val) != EOF) { #if ASSEMBLER add_label (name, val, "", LABS, 1) ; #else add_label (name, val, 1) ; #endif } if (fclose (fp)) error (ERRCLO, file) ; } #endif /* ATARI_LATTICE */ #if PC_MSC char skipvar ; void format_time (str) uchar *str ; { long int l ; extern long int time () ; extern char *ctime () ; time (&l) ; strcpy (str, ctime (&l)) ; str [strlen (str) - 1] = EOL ; } char *optarg ; int optind = 0, opterr = 0 ; int getopt (argc, argv, optstr) int argc ; char *argv[], *optstr ; { char *o, car ; static char *index = 0 ; extern char *strchr () ; if ((index==(char *)0)||(*(index+1)==0)) { if (++optind>argc-1) return (EOF) ; index = argv[optind] ; if (*index!='-') return (EOF) ; } car = *(++index) ; /* state 6 */ if (!(o = strchr (optstr, car))) return ('?') ; if (*(o+1)!=':') return ((int) car) ; if (*(index+1)) optarg = index+1 ; else { if (++optind>argc-1) return (EOF) ; else optarg = argv[optind] ; } index = (char *) 0 ; return ((int) car) ; } uchar *tab[] = { "", "c:", "c:\\hp71\\", "c:\\lib\\hp71\\", "c:\\lib\\", "c:\\areuh\\lib\\", 0 } ; void load_file (file) uchar *file ; { int i = 0 ; uchar name [MAXLEN+1] ; saddr val ; FILE *fp ; fp = (FILE *) NULL ; while ((tab[i])&&(!fp)) { sprintf (name, "%s%s", tab[i++], file) ; fp = fopen (name, "r") ; } if (!fp) error (ERROPN, file) ; #if LINKER file = 0 ; #endif while (fscanf (fp, "%s\n%X\n", name, &val) != EOF) { #if ASSEMBLER add_label (name, val, "", LABS, 1) ; #else add_label (name, val, 1) ; #endif } if (fclose (fp)) error (ERRCLO, file) ; } #include <sys\types.h> #include <sys\stat.h> /* look for object file (object code or listing file) * if non existent, ok * if exists and not directory, ok * if exists and directory, then append "<dir>/<default>" */ look_obj (fname, dfl) uchar *fname, *dfl ; { struct stat buf ; if (*fname == EOL) /* if fname == "" then default it */ strcpy (fname, dfl) ; if (!stat (fname, &buf)) /* file exists. Is it a directory ? */ { if ((buf.st_mode & S_IFMT) == S_IFDIR) sprintf (fname, "%s\\%s", fname, dfl) ; } } /* build a default file name, based on "source" basename and a given * default extension. */ dfl_extension (object, source, extension) uchar *object, *source, *extension ; { uchar *pname ; strcpy (object, source) ; pname = object ; while ((*pname)&&(*pname!='.')) pname++ ; if (*pname==EOL) *pname = '.' ; strcpy (pname+1, extension) ; } #endif /* PC_MSC */ @EOF set `wc -lwc <areuh/assembler/mdep.c` if test $1$2$3 != 32610286303 then echo ERROR: wc results of areuh/assembler/mdep.c are $* should be 326 1028 6303 fi chmod 644 areuh/assembler/mdep.c echo x - areuh/assembler/tabgrp.c cat >areuh/assembler/tabgrp.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "aglobal.h" int h_opcode [] = { /* 00 */ 0, /* 01 */ 9, /* 02 */ 24, /* 03 */ 33, /* 04 */ 40, /* 05 */ 53, /* 06 */ 64, /* 07 */ 72, /* 08 */ 79, /* 09 */ 93, /* 10 */ 100, /* 11 */ 107, /* 12 */ 114, /* 13 */ 125, /* 14 */ 134, /* 15 */ 140, /* 16 */ 152, /* 17 */ 162, /* 18 */ 168, /* 19 */ 174, /* 20 */ 180, /* 21 */ 185, /* 22 */ 191, /* 23 */ 200, /* 24 */ 207, /* 25 */ 212, /* 26 */ 224, /* 27 */ 230, /* 28 */ 239, /* 29 */ 244, /* 30 */ 250, /* 31 */ 257, /* 32 */ 267, /* 33 */ 275, /* 34 */ 287, /* 35 */ 295, /* 36 */ 305, /* 37 */ 312, /* 38 */ 318, /* 39 */ 328, /* 40 */ 337, /* 41 */ 342, /* 42 */ 351, /* 43 */ 356, } ; @EOF set `wc -lwc <areuh/assembler/tabgrp.c` if test $1$2$3 != 59225883 then echo ERROR: wc results of areuh/assembler/tabgrp.c are $* should be 59 225 883 fi chmod 644 areuh/assembler/tabgrp.c echo x - areuh/assembler/tabopc.c cat >areuh/assembler/tabopc.c <<'@EOF' /* * Authors : * Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) * Janick TAILLANDIER * * This program can be freely used or distributed as long as this * note is kept. * * This program is provided "as is". */ #include "aglobal.h" struct mnemo_desc mnemo_table [] = { /* 000 */ {1, "?A>B", 3, 3, "800", 2, 0}, /* 001 */ {5, "CR1EX", 5, 3, "129", 0, 0}, /* 002 */ {5, "AR0EX", 5, 3, "120", 0, 0}, /* 003 */ {10, "P=C", 33, 4, "80D0", 0, 0}, /* 004 */ {5, "SETDEC", 5, 2, "05", 0, 0}, /* 005 */ {3, "C=C!B", 1, 4, "0E0D", 0, 0}, /* 006 */ {5, "CSLC", 1, 3, "812", 0, 0}, /* 007 */ {5, "D1=CS", 5, 3, "13D", 0, 0}, /* 008 */ {40, "ENDIF", 0, 0, "", 0, 0}, /* 009 */ {4, "GOYES", 41, 2, "00", 1, 2}, /* 010 */ {4, "GOSBVL", 53, 7, "8F000", 3, 5}, /* 011 */ {13, "DAT0=A", 32, 4, "1500", 0, 0}, /* 012 */ {4, "GONC", 33, 3, "500", 2, 2}, /* 013 */ {22, "EQU", 36, 0, "", 0, 0}, /* 014 */ {1, "?C>A", 3, 3, "802", 2, 0}, /* 015 */ {1, "?A>=C", 3, 3, "80E", 2, 0}, /* 016 */ {1, "?B#C", 7, 3, "805", 1, 0}, /* 017 */ {1, "?A<=B", 7, 3, "80C", 2, 0}, /* 018 */ {2, "B=B+B", 4, 3, "005", 1, 0}, /* 019 */ {5, "RTNC", 5, 3, "400", 0, 0}, /* 020 */ {33, "CHAR", 32, 1, "0", 0, 0}, /* 021 */ {5, "D1=AS", 5, 3, "138", 0, 0}, /* 022 */ {5, "NOP4", 5, 4, "6300", 0, 0}, /* 023 */ {5, "RTI", 1, 2, "0F", 0, 0}, /* 024 */ {2, "A=C", 4, 3, "00A", 2, 0}, /* 025 */ {7, "RTNYES", 13, 2, "00", 0, 0}, /* 026 */ {2, "A=A-B", 0, 3, "000", 3, 0}, /* 027 */ {1, "?B#A", 7, 3, "804", 1, 0}, /* 028 */ {5, "RTNNC", 1, 3, "500", 0, 0}, /* 029 */ {2, "C=D", 0, 3, "00B", 2, 0}, /* 030 */ {5, "DSLC", 5, 3, "813", 0, 0}, /* 031 */ {8, "?P#", 39, 3, "880", 0, 0}, /* 032 */ {6, "?MP=0", 3, 3, "838", 0, 0}, /* 033 */ {13, "DAT0=C", 32, 4, "1540", 0, 0}, /* 034 */ {2, "A=A+B", 0, 3, "000", 1, 0}, /* 035 */ {2, "C=D+C", 4, 3, "00B", 1, 0}, /* 036 */ {1, "?D#0", 7, 3, "80F", 1, 0}, /* 037 */ {29, "ID", 36, 16, "", 0, 0}, /* 038 */ {27, "WORDI", 32, 0, "", 0, 0}, /* 039 */ {4, "LC(6)", 177, 8, "35000", 3, 6}, /* 040 */ {2, "B=C", 4, 3, "005", 2, 0}, /* 041 */ {5, "R0=C", 5, 3, "108", 0, 0}, /* 042 */ {5, "CR0EX", 1, 3, "128", 0, 0}, /* 043 */ {1, "?A=B", 7, 3, "800", 1, 0}, /* 044 */ {2, "ABEX", 4, 3, "00C", 2, 0}, /* 045 */ {1, "?B<=A", 3, 3, "808", 2, 0}, /* 046 */ {2, "D=D-C", 4, 3, "003", 3, 0}, /* 047 */ {3, "C=D!C", 1, 4, "0E0F", 0, 0}, /* 048 */ {3, "A=A!B", 5, 4, "0E08", 0, 0}, /* 049 */ {5, "ASRC", 1, 3, "814", 0, 0}, /* 050 */ {4, "LC(4)", 177, 6, "33000", 3, 4}, /* 051 */ {5, "C=ST", 5, 2, "09", 0, 0}, /* 052 */ {5, "A=R4", 1, 3, "114", 0, 0}, /* 053 */ {1, "?C=A", 3, 3, "802", 1, 0}, /* 054 */ {1, "?A=0", 7, 3, "808", 1, 0}, /* 055 */ {5, "R0=A", 1, 3, "100", 0, 0}, /* 056 */ {2, "B=A+B", 0, 3, "008", 1, 0}, /* 057 */ {4, "LC(2)", 177, 4, "3100", 3, 2}, /* 058 */ {5, "A=R2", 5, 3, "112", 0, 0}, /* 059 */ {23, "LIST", 5, 0, "", 0, 0}, /* 060 */ {2, "D=D+C", 4, 3, "003", 1, 0}, /* 061 */ {4, "D0=(2)", 177, 4, "1900", 3, 2}, /* 062 */ {5, "R4=C", 5, 3, "10C", 0, 0}, /* 063 */ {5, "BUSCC", 5, 3, "80B", 0, 0}, /* 064 */ {5, "A=R0", 1, 3, "110", 0, 0}, /* 065 */ {2, "A=B", 4, 3, "004", 2, 0}, /* 066 */ {4, "CON(4)", 49, 4, "0000", 1, 4}, /* 067 */ {3, "B=A!B", 1, 4, "0E0C", 0, 0}, /* 068 */ {5, "RTNSXM", 5, 2, "00", 0, 0}, /* 069 */ {3, "D=D!C", 5, 4, "0E0B", 0, 0}, /* 070 */ {5, "BSRC", 5, 3, "815", 0, 0}, /* 071 */ {5, "R4=A", 1, 3, "104", 0, 0}, /* 072 */ {4, "GOTO", 33, 4, "6000", 2, 3}, /* 073 */ {1, "?C>=A", 7, 3, "80A", 2, 0}, /* 074 */ {2, "C=C+C", 4, 3, "006", 1, 0}, /* 075 */ {9, "?ST=0", 35, 3, "860", 0, 0}, /* 076 */ {3, "A=C&A", 5, 4, "0E06", 0, 0}, /* 077 */ {5, "ST=C", 5, 2, "0A", 0, 0}, /* 078 */ {5, "A=IN", 1, 3, "802", 0, 0}, /* 079 */ {13, "A=DAT0", 36, 4, "1520", 0, 0}, /* 080 */ {5, "D0=C", 5, 3, "134", 0, 0}, /* 081 */ {12, "D1=D1+", 33, 3, "170", 0, 0}, /* 082 */ {5, "CSRC", 1, 3, "816", 0, 0}, /* 083 */ {1, "?A<B", 7, 3, "804", 2, 0}, /* 084 */ {9, "?ST#0", 35, 3, "870", 0, 0}, /* 085 */ {11, "ST=1", 33, 3, "850", 0, 0}, /* 086 */ {2, "CBEX", 0, 3, "00D", 2, 0}, /* 087 */ {2, "B=B-C", 0, 3, "001", 3, 0}, /* 088 */ {2, "D=C", 4, 3, "007", 2, 0}, /* 089 */ {5, "CLRST", 5, 2, "08", 0, 0}, /* 090 */ {5, "SB=0", 1, 3, "822", 0, 0}, /* 091 */ {5, "C=R4", 5, 3, "11C", 0, 0}, /* 092 */ {5, "SR=0", 5, 3, "824", 0, 0}, /* 093 */ {13, "A=DAT1", 36, 4, "1530", 0, 0}, /* 094 */ {5, "D0=A", 1, 3, "130", 0, 0}, /* 095 */ {1, "?A<=C", 7, 3, "80A", 2, 0}, /* 096 */ {1, "?C<A", 3, 3, "806", 2, 0}, /* 097 */ {2, "B=B+C", 0, 3, "001", 1, 0}, /* 098 */ {5, "C=R2", 5, 3, "11A", 0, 0}, /* 099 */ {4, "REL(1)", 37, 1, "0", 1, 1}, /* 100 */ {12, "D1=D1-", 37, 3, "1C0", 0, 0}, /* 101 */ {2, "C=B", 4, 3, "009", 2, 0}, /* 102 */ {5, "C=R0", 1, 3, "118", 0, 0}, /* 103 */ {2, "A=A-C", 4, 3, "00A", 3, 0}, /* 104 */ {3, "B=B!C", 1, 4, "0E09", 0, 0}, /* 105 */ {5, "DSRC", 1, 3, "817", 0, 0}, /* 106 */ {5, "OUT=C", 5, 3, "801", 0, 0}, /* 107 */ {2, "A=A+C", 0, 3, "00A", 1, 0}, /* 108 */ {2, "C=B+C", 0, 3, "009", 1, 0}, /* 109 */ {3, "C=C&A", 5, 4, "0E02", 0, 0}, /* 110 */ {3, "A=B&A", 5, 4, "0E00", 0, 0}, /* 111 */ {1, "?D>C", 7, 3, "803", 2, 0}, /* 112 */ {35, "TOKEN", 36, 2, "00", 0, 0}, /* 113 */ {5, "C=IN", 1, 3, "803", 0, 0}, /* 114 */ {13, "C=DAT0", 32, 4, "1560", 0, 0}, /* 115 */ {14, "NIBHEX", 4, 0, "", 1, 14}, /* 116 */ {10, "P=", 33, 2, "20", 0, 0}, /* 117 */ {2, "B=A", 0, 3, "008", 2, 0}, /* 118 */ {1, "?A#B", 7, 3, "804", 1, 0}, /* 119 */ {1, "?B>=C", 3, 3, "809", 2, 0}, /* 120 */ {3, "A=A!C", 5, 4, "0E0E", 0, 0}, /* 121 */ {3, "C=B!C", 5, 4, "0E0D", 0, 0}, /* 122 */ {5, "C=ID", 1, 3, "806", 0, 0}, /* 123 */ {5, "RESET", 5, 3, "80A", 0, 0}, /* 124 */ {41, "ABS", 0, 0, "", 0, 0}, /* 125 */ {13, "C=DAT1", 36, 4, "1570", 0, 0}, /* 126 */ {1, "?C#A", 3, 3, "806", 1, 0}, /* 127 */ {1, "?A#0", 7, 3, "80C", 1, 0}, /* 128 */ {2, "D=D+D", 0, 3, "007", 1, 0}, /* 129 */ {3, "B=B&A", 1, 4, "0E04", 0, 0}, /* 130 */ {6, "?XM=0", 3, 3, "831", 0, 0}, /* 131 */ {2, "A=-A-1", 4, 3, "00C", 4, 0}, /* 132 */ {5, "OUT=CS", 5, 3, "800", 0, 0}, /* 133 */ {42, "RDSYMB", 0, 0, "", 0, 0}, /* 134 */ {2, "C=A", 0, 3, "006", 2, 0}, /* 135 */ {2, "A=0", 4, 3, "000", 2, 0}, /* 136 */ {2, "C=A-C", 4, 3, "00E", 3, 0}, /* 137 */ {4, "CON(5)", 53, 5, "00000", 1, 5}, /* 138 */ {34, "KEY", 32, 0, "", 0, 0}, /* 139 */ {2, "C=C-D", 0, 3, "00B", 3, 0}, /* 140 */ {2, "C=A+C", 4, 3, "002", 1, 0}, /* 141 */ {5, "R1=C", 5, 3, "109", 0, 0}, /* 142 */ {2, "ACEX", 0, 3, "00E", 2, 0}, /* 143 */ {1, "?C<=A", 7, 3, "80E", 2, 0}, /* 144 */ {1, "?C>=B", 3, 3, "80D", 2, 0}, /* 145 */ {1, "?D=C", 7, 3, "803", 1, 0}, /* 146 */ {2, "C=C+D", 0, 3, "00B", 1, 0}, /* 147 */ {9, "?ST=1", 35, 3, "870", 0, 0}, /* 148 */ {2, "A=-A", 4, 3, "008", 4, 0}, /* 149 */ {30, "MSG", 32, 4, "0000", 0, 0}, /* 150 */ {6, "?SB=0", 3, 3, "832", 0, 0}, /* 151 */ {6, "?SR=0", 7, 3, "834", 0, 0}, /* 152 */ {5, "R1=A", 5, 3, "101", 0, 0}, /* 153 */ {2, "B=0", 4, 3, "001", 2, 0}, /* 154 */ {9, "?ST#1", 35, 3, "860", 0, 0}, /* 155 */ {1, "?B=0", 7, 3, "809", 1, 0}, /* 156 */ {4, "D1=(2)", 177, 4, "1D00", 3, 2}, /* 157 */ {2, "D=C-D", 4, 3, "00F", 3, 0}, /* 158 */ {3, "C=A!C", 5, 4, "0E0A", 0, 0}, /* 159 */ {2, "C=-C-1", 0, 3, "00E", 4, 0}, /* 160 */ {3, "C=C!D", 1, 4, "0E0F", 0, 0}, /* 161 */ {31, "POLL", 32, 5, "00000", 0, 0}, /* 162 */ {15, "LCHEX", 4, 2, "30", 3, 2}, /* 163 */ {2, "D=C+D", 4, 3, "003", 1, 0}, /* 164 */ {2, "BCEX", 0, 3, "00D", 2, 0}, /* 165 */ {3, "B=C&B", 5, 4, "0E01", 0, 0}, /* 166 */ {4, "REL(2)", 33, 2, "00", 1, 2}, /* 167 */ {21, "END", 0, 0, "", 0, 0}, /* 168 */ {2, "C=0", 4, 3, "002", 2, 0}, /* 169 */ {5, "AD1EX", 5, 3, "133", 0, 0}, /* 170 */ {10, "C=P", 33, 4, "80C0", 0, 0}, /* 171 */ {2, "C=-C", 0, 3, "00A", 4, 0}, /* 172 */ {3, "D=C!D", 5, 4, "0E0B", 0, 0}, /* 173 */ {43, "ELSE", 0, 0, "", 0, 0}, /* 174 */ {4, "GOLONG", 33, 6, "8C000", 3, 4}, /* 175 */ {5, "D1=C", 1, 3, "135", 0, 0}, /* 176 */ {1, "?D<C", 7, 3, "807", 2, 0}, /* 177 */ {3, "C=C&B", 5, 4, "0E05", 0, 0}, /* 178 */ {2, "ASL", 0, 3, "000", 4, 0}, /* 179 */ {39, "ENDTXT", 4, 3, "", 0, 0}, /* 180 */ {5, "D1=A", 1, 3, "131", 0, 0}, /* 181 */ {17, "NIBASC", 36, 0, "", 1, 14}, /* 182 */ {1, "?B<=C", 7, 3, "80D", 2, 0}, /* 183 */ {2, "D=0", 4, 3, "003", 2, 0}, /* 184 */ {28, "LEX", 32, 0, "", 0, 0}, /* 185 */ {1, "?A>C", 7, 3, "806", 2, 0}, /* 186 */ {4, "D0=(4)", 177, 6, "1A000", 3, 4}, /* 187 */ {2, "DCEX", 4, 3, "00F", 2, 0}, /* 188 */ {1, "?C>D", 3, 3, "807", 2, 0}, /* 189 */ {20, "EJECT", 1, 0, "", 0, 0}, /* 190 */ {2, "BSL", 4, 3, "001", 4, 0}, /* 191 */ {13, "DAT1=A", 36, 4, "1510", 0, 0}, /* 192 */ {5, "C=RSTK", 5, 2, "07", 0, 0}, /* 193 */ {5, "CD1EX", 1, 3, "137", 0, 0}, /* 194 */ {5, "AD0EX", 1, 3, "132", 0, 0}, /* 195 */ {1, "?C>B", 7, 3, "805", 2, 0}, /* 196 */ {5, "NOP5", 1, 5, "64000", 0, 0}, /* 197 */ {5, "SHUTDN", 5, 3, "807", 0, 0}, /* 198 */ {4, "CON(6)", 53, 6, "00000", 1, 6}, /* 199 */ {5, "PC=(A)", 1, 4, "808C", 0, 0}, /* 200 */ {1, "?C<=B", 7, 3, "809", 2, 0}, /* 201 */ {3, "A=A&B", 5, 4, "0E00", 0, 0}, /* 202 */ {3, "C=D&C", 5, 4, "0E07", 0, 0}, /* 203 */ {1, "?D#C", 3, 3, "807", 1, 0}, /* 204 */ {2, "CSL", 0, 3, "002", 4, 0}, /* 205 */ {5, "NOP3", 5, 3, "420", 0, 0}, /* 206 */ {5, "AD1XS", 1, 3, "13B", 0, 0}, /* 207 */ {5, "RTN", 5, 2, "01", 0, 0}, /* 208 */ {13, "DAT1=C", 36, 4, "1550", 0, 0}, /* 209 */ {1, "?B#0", 7, 3, "80D", 1, 0}, /* 210 */ {32, "ENTRY", 32, 8, "00000", 0, 0}, /* 211 */ {5, "C+P+1", 1, 3, "809", 0, 0}, /* 212 */ {1, "?A=C", 7, 3, "802", 1, 0}, /* 213 */ {5, "RTNCC", 1, 2, "03", 0, 0}, /* 214 */ {5, "RTNSC", 5, 2, "02", 0, 0}, /* 215 */ {4, "REL(3)", 37, 3, "000", 1, 3}, /* 216 */ {4, "LC(5)", 177, 7, "34000", 3, 5}, /* 217 */ {1, "?C=D", 3, 3, "803", 1, 0}, /* 218 */ {3, "B=A&B", 5, 4, "0E04", 0, 0}, /* 219 */ {3, "D=D&C", 1, 4, "0E03", 0, 0}, /* 220 */ {19, "BSS", 32, 0, "", 0, 0}, /* 221 */ {2, "DSL", 4, 3, "003", 4, 0}, /* 222 */ {4, "CON(1)", 53, 1, "0", 1, 1}, /* 223 */ {44, "IF", 0, 0, "", 0, 0}, /* 224 */ {5, "CD0EX", 1, 3, "136", 0, 0}, /* 225 */ {5, "R2=C", 1, 3, "10A", 0, 0}, /* 226 */ {5, "A=R3", 1, 3, "113", 0, 0}, /* 227 */ {1, "?C=B", 7, 3, "801", 1, 0}, /* 228 */ {5, "ASRB", 5, 3, "81C", 0, 0}, /* 229 */ {4, "LC(3)", 181, 5, "32000", 3, 3}, /* 230 */ {1, "?C=0", 7, 3, "80A", 1, 0}, /* 231 */ {5, "A=R1", 1, 3, "111", 0, 0}, /* 232 */ {5, "R2=A", 5, 3, "102", 0, 0}, /* 233 */ {4, "LC(1)", 177, 3, "300", 3, 1}, /* 234 */ {2, "ASR", 4, 3, "004", 4, 0}, /* 235 */ {5, "AR4EX", 1, 3, "124", 0, 0}, /* 236 */ {5, "CD1XS", 1, 3, "13F", 0, 0}, /* 237 */ {5, "AD0XS", 5, 3, "13A", 0, 0}, /* 238 */ {5, "CLRHST", 5, 3, "82F", 0, 0}, /* 239 */ {4, "GOSUB", 101, 4, "7000", 2, 3}, /* 240 */ {5, "BSRB", 5, 3, "81D", 0, 0}, /* 241 */ {16, "D0=HEX", 0, 4, "1900", 3, 2}, /* 242 */ {38, "CHAIN", 32, 12, "00000", 0, 0}, /* 243 */ {5, "CONFIG", 5, 3, "805", 0, 0}, /* 244 */ {4, "D0=(5)", 177, 7, "1B000", 3, 5}, /* 245 */ {1, "?A<C", 7, 3, "802", 2, 0}, /* 246 */ {1, "?C<D", 3, 3, "803", 2, 0}, /* 247 */ {10, "CPEX", 37, 4, "80F0", 0, 0}, /* 248 */ {3, "B=B&C", 5, 4, "0E01", 0, 0}, /* 249 */ {2, "BSR", 0, 3, "005", 4, 0}, /* 250 */ {2, "A=C+A", 0, 3, "00A", 1, 0}, /* 251 */ {2, "CDEX", 0, 3, "00F", 2, 0}, /* 252 */ {5, "CSRB", 5, 3, "81E", 0, 0}, /* 253 */ {5, "C=R3", 5, 3, "11B", 0, 0}, /* 254 */ {11, "ST=0", 33, 3, "840", 0, 0}, /* 255 */ {1, "?C<B", 7, 3, "801", 2, 0}, /* 256 */ {5, "UNCNFG", 5, 3, "804", 0, 0}, /* 257 */ {5, "C=R1", 1, 3, "119", 0, 0}, /* 258 */ {5, "AR3EX", 1, 3, "123", 0, 0}, /* 259 */ {3, "A=A&C", 1, 4, "0E06", 0, 0}, /* 260 */ {3, "A=C!A", 5, 4, "0E0E", 0, 0}, /* 261 */ {2, "D=D-1", 4, 3, "00F", 1, 0}, /* 262 */ {1, "?C>=D", 7, 3, "80F", 2, 0}, /* 263 */ {2, "CSR", 0, 3, "006", 4, 0}, /* 264 */ {3, "C=B&C", 5, 4, "0E05", 0, 0}, /* 265 */ {5, "CR4EX", 5, 3, "12C", 0, 0}, /* 266 */ {5, "CD0XS", 1, 3, "13E", 0, 0}, /* 267 */ {4, "GOSUBL", 97, 6, "8E000", 3, 4}, /* 268 */ {12, "D0=D0+", 33, 3, "160", 0, 0}, /* 269 */ {2, "D=D+1", 0, 3, "007", 3, 0}, /* 270 */ {4, "D1=(4)", 181, 6, "1E000", 3, 4}, /* 271 */ {1, "?B>C", 7, 3, "801", 2, 0}, /* 272 */ {5, "DSRB", 5, 3, "81F", 0, 0}, /* 273 */ {5, "D0=CS", 1, 3, "13C", 0, 0}, /* 274 */ {5, "INTON", 5, 4, "8080", 0, 0}, /* 275 */ {1, "?A#C", 7, 3, "806", 1, 0}, /* 276 */ {2, "C=C-A", 0, 3, "002", 3, 0}, /* 277 */ {2, "C=C-1", 4, 3, "00E", 1, 0}, /* 278 */ {2, "A=B-A", 0, 3, "00C", 3, 0}, /* 279 */ {1, "?C#D", 7, 3, "807", 1, 0}, /* 280 */ {1, "?B>A", 3, 3, "804", 2, 0}, /* 281 */ {4, "CON(2)", 53, 2, "00", 1, 2}, /* 282 */ {4, "REL(4)", 37, 4, "0000", 1, 4}, /* 283 */ {2, "DSR", 4, 3, "007", 4, 0}, /* 284 */ {5, "D0=AS", 1, 3, "138", 0, 0}, /* 285 */ {5, "MP=0", 1, 3, "828", 0, 0}, /* 286 */ {5, "RSI", 1, 5, "80810", 0, 0}, /* 287 */ {4, "GOVLNG", 53, 7, "8D000", 3, 5}, /* 288 */ {2, "C=C+1", 0, 3, "006", 3, 0}, /* 289 */ {2, "C=C+A", 4, 3, "002", 1, 0}, /* 290 */ {12, "D0=D0-", 33, 3, "180", 0, 0}, /* 291 */ {2, "A=B+A", 0, 3, "000", 1, 0}, /* 292 */ {1, "?C#B", 7, 3, "805", 1, 0}, /* 293 */ {1, "?D>=C", 3, 3, "80B", 2, 0}, /* 294 */ {36, "BIN", 36, 0, "", 0, 0}, /* 295 */ {1, "?C#0", 7, 3, "80E", 1, 0}, /* 296 */ {2, "B=B-1", 0, 3, "00D", 1, 0}, /* 297 */ {2, "B=B-A", 4, 3, "008", 3, 0}, /* 298 */ {5, "AR2EX", 5, 3, "122", 0, 0}, /* 299 */ {5, "CR3EX", 1, 3, "12B", 0, 0}, /* 300 */ {3, "C=C!A", 1, 4, "0E0A", 0, 0}, /* 301 */ {3, "A=B!A", 1, 4, "0E08", 0, 0}, /* 302 */ {3, "C=A&C", 1, 4, "0E02", 0, 0}, /* 303 */ {3, "C=C&D", 5, 4, "0E07", 0, 0}, /* 304 */ {5, "XM=0", 5, 3, "821", 0, 0}, /* 305 */ {4, "GOC", 37, 3, "400", 2, 2}, /* 306 */ {2, "B=B+A", 4, 3, "008", 1, 0}, /* 307 */ {1, "?B=C", 3, 3, "801", 1, 0}, /* 308 */ {2, "B=B+1", 0, 3, "005", 3, 0}, /* 309 */ {1, "?A>=B", 7, 3, "808", 2, 0}, /* 310 */ {2, "B=-B-1", 4, 3, "00D", 4, 0}, /* 311 */ {37, "FORTH", 0, 0, "", 0, 0}, /* 312 */ {2, "A=A-1", 4, 3, "00C", 1, 0}, /* 313 */ {8, "?P=", 35, 3, "890", 0, 0}, /* 314 */ {5, "R3=C", 1, 3, "10B", 0, 0}, /* 315 */ {1, "?B=A", 7, 3, "800", 1, 0}, /* 316 */ {3, "B=B!A", 1, 4, "0E0C", 0, 0}, /* 317 */ {3, "D=C&D", 5, 4, "0E03", 0, 0}, /* 318 */ {2, "A=A+1", 0, 3, "004", 3, 0}, /* 319 */ {18, "LCASC", 32, 2, "30", 3, 2}, /* 320 */ {1, "?D=0", 7, 3, "80B", 1, 0}, /* 321 */ {5, "R3=A", 5, 3, "103", 0, 0}, /* 322 */ {25, "STITLE", 1, 0, "", 0, 0}, /* 323 */ {2, "A=A+A", 4, 3, "004", 1, 0}, /* 324 */ {2, "B=-B", 0, 3, "009", 4, 0}, /* 325 */ {2, "BAEX", 4, 3, "00C", 2, 0}, /* 326 */ {5, "INTOFF", 1, 4, "808F", 0, 0}, /* 327 */ {26, "WORD", 36, 0, "", 0, 0}, /* 328 */ {5, "P=P-1", 5, 2, "0D", 0, 0}, /* 329 */ {2, "B=C-B", 4, 3, "00D", 3, 0}, /* 330 */ {5, "AR1EX", 5, 3, "121", 0, 0}, /* 331 */ {5, "CR2EX", 1, 3, "12A", 0, 0}, /* 332 */ {1, "?B>=A", 7, 3, "80C", 2, 0}, /* 333 */ {1, "?C<=D", 3, 3, "80B", 2, 0}, /* 334 */ {5, "ASLC", 1, 3, "810", 0, 0}, /* 335 */ {16, "D1=HEX", 4, 4, "1D00", 3, 2}, /* 336 */ {2, "D=-D-1", 0, 3, "00F", 4, 0}, /* 337 */ {4, "D1=(5)", 177, 7, "1F000", 3, 5}, /* 338 */ {5, "P=P+1", 5, 2, "0C", 0, 0}, /* 339 */ {2, "B=C+B", 0, 3, "001", 1, 0}, /* 340 */ {1, "?B<C", 7, 3, "805", 2, 0}, /* 341 */ {2, "CAEX", 4, 3, "00E", 2, 0}, /* 342 */ {5, "RSTK=C", 1, 2, "06", 0, 0}, /* 343 */ {2, "C=C-B", 0, 3, "009", 3, 0}, /* 344 */ {1, "?B<A", 7, 3, "800", 2, 0}, /* 345 */ {4, "REL(5)", 37, 5, "00000", 1, 5}, /* 346 */ {4, "CON(3)", 53, 3, "000", 1, 3}, /* 347 */ {5, "BSLC", 5, 3, "811", 0, 0}, /* 348 */ {3, "B=C!B", 1, 4, "0E09", 0, 0}, /* 349 */ {2, "D=-D", 0, 3, "00B", 4, 0}, /* 350 */ {24, "TITLE", 4, 0, "", 0, 0}, /* 351 */ {2, "C=C+B", 0, 3, "009", 1, 0}, /* 352 */ {5, "SETHEX", 1, 2, "04", 0, 0}, /* 353 */ {1, "?D<=C", 7, 3, "80F", 2, 0}, /* 354 */ {5, "CSTEX", 5, 2, "0B", 0, 0}, /* 355 */ {5, "SREQ?", 5, 3, "80E", 0, 0}, } ; @EOF set `wc -lwc <areuh/assembler/tabopc.c` if test $1$2$3 != 373361015611 then echo ERROR: wc results of areuh/assembler/tabopc.c are $* should be 373 3610 15611 fi chmod 644 areuh/assembler/tabopc.c echo x - areuh/assembler/Makefile cat >areuh/assembler/Makefile <<'@EOF' # # Makefile genere automatiquement par mkmf (le masque par defaut a ete adapte) # CFLAGS = -O LDFLAGS = LIBS = SYSLIBS = BINDEST = /usr/local/bin # # S'il y a plus d'un programme, il faut aussi remplacer la cible # $(PROGRAM) par autant de cibles que necessaire. # PROGRAM = aas SRCS = aerror.c \ ainput.c \ alabel.c \ alist.c \ amain.c \ amnemo.c \ aobj.c \ aopc1.c \ aopc2.c \ apass.c \ areport.c \ autil.c \ exp.c \ mdep.c \ tabgrp.c \ tabopc.c HDRS = agen.h \ aglobal.h \ common.h \ err.h \ flag.h EXTHDRS = /usr/include/stdio.h \ /usr/include/sys/stat.h \ /usr/include/sys/types.h OBJS = aerror.o \ ainput.o \ alabel.o \ alist.o \ amain.o \ amnemo.o \ aobj.o \ aopc1.o \ aopc2.o \ apass.o \ areport.o \ autil.o \ exp.o \ mdep.o \ tabgrp.o \ tabopc.o MANDEST = /usr/local/man/man1.Z MANPAGES = aas.1 # # Les cibles : # all : compiler tout # clean : effacer les .o et les core # clobber : effacer tout ce qui peut etre regenere # depend : recalculer toutes les dependances et les inserer ici # install : installe le programme dans l'aborescence # tags : cree les tags # all: $(PROGRAM) $(PROGRAM): $(OBJS) $(LIBS) cc $(LDFLAGS) $(OBJS) $(LIBS) $(SYSLIBS) -o $(PROGRAM) clean:; rm -f $(OBJS) core clobber:; rm -f $(OBJS) $(PROGRAM) core tags depend:; mkmf ROOT=$(ROOT) install: $(PROGRAM) -strip $(PROGRAM) if [ $(BINDEST) != . ] ; \ then \ (cd $(BINDEST) ; rm -f $(PROGRAM)) ; \ cp $(PROGRAM) $(BINDEST) ; \ if [ "$(MANPAGES)" != none ] ; \ then \ (cd $(MANDEST) ; rm -f $(MANPAGES)) ; \ for i in $(MANPAGES) ; \ do \ compress < $$i > $(MANDEST)/$$i ; \ done ; \ fi ; \ fi tags: $(HDRS) $(SRCS) ctags $(HDRS) $(SRCS) # # Dependances calculees automatiquement par mkmf. # Ne rien changer apres cette ligne ! # ### aerror.o: aglobal.h common.h /usr/include/stdio.h err.h ainput.o: aglobal.h common.h /usr/include/stdio.h err.h alabel.o: aglobal.h common.h /usr/include/stdio.h err.h alist.o: aglobal.h common.h /usr/include/stdio.h err.h amain.o: aglobal.h common.h /usr/include/stdio.h err.h amnemo.o: aglobal.h common.h /usr/include/stdio.h err.h aobj.o: aglobal.h common.h /usr/include/stdio.h err.h aopc1.o: aglobal.h common.h /usr/include/stdio.h err.h agen.h aopc2.o: aglobal.h common.h /usr/include/stdio.h err.h agen.h apass.o: aglobal.h common.h /usr/include/stdio.h err.h agen.h areport.o: aglobal.h common.h /usr/include/stdio.h err.h autil.o: aglobal.h common.h /usr/include/stdio.h err.h exp.o: flag.h aglobal.h common.h /usr/include/stdio.h err.h mdep.o: flag.h aglobal.h common.h /usr/include/stdio.h err.h \ /usr/include/sys/types.h /usr/include/sys/stat.h tabgrp.o: aglobal.h common.h /usr/include/stdio.h err.h tabopc.o: aglobal.h common.h /usr/include/stdio.h err.h @EOF set `wc -lwc <areuh/assembler/Makefile` if test $1$2$3 != 1274032926 then echo ERROR: wc results of areuh/assembler/Makefile are $* should be 127 403 2926 fi chmod 644 areuh/assembler/Makefile echo x - areuh/assembler/aas.1 cat >areuh/assembler/aas.1 <<'@EOF' .TH AAS 1L .SH NAME aas \- areuh assembler .SH SYNOPSIS .B aas [ .B -p ] [ .B -l .I page length ] [ .B -A ] [ .B -a .I listing file ] [ .B -x ] [ .B -o .I object file ] [ file1 ... filen ] .SH DESCRIPTION .I Aas est le cross-assembleur pour le HP-71, qui prend un ou des fichiers sources, les assemble et place dans le fichier objet soit un Lex ou Bin complet, soit un fichier intermediaire pour edition de liens ulterieure (voir .IR ald (1L)). .PP Les options sont : .TP 17 .B -p Utilisation interactive : demande les noms des fichiers au clavier. Option par defaut lorsqu'il n'y a aucun parametre. .TP .BI -l " page length" La longueur des pages du .I listing file est fixee a .I page length lignes (72 par defaut). .TP .B -A Genere un listing d'assemblage avec offset, codes hexadecimaux, et texte source. Le listing est envoye sur la sortie standard. .TP .BI -a " listing file" Genere un listing d'assemblage dans le fichier .IR "listing file" . .TP .I -x Genere dans le .I listing file une table des references croisees, indiquant pour chaque symbole sa valeur et les numeros des lignes y faisant reference. .TP .BI -o " object file" Place le code objet dans le fichier specifie. Par defaut, le nom est celui du fichier source avec le suffixe .IR .as , remplace par .I .ao en cas d'assemblage separe, ou .B lex en assemblage complet. Si .I object file est un repertoire, le fichier est place dans le repertoire indique avec les regles de renommage ci-dessus (note : c'est l'utilisation la plus simple lorsque plusieurs sources sont donnes sur la ligne de commandes). .SH AUTHORS Pierre David Janick Taillandier .SH SEE ALSO ald(1L), adp(1L), amg(1L), cp71(1L). .br .I "IDS vol I" for HP-71. @EOF set `wc -lwc <areuh/assembler/aas.1` if test $1$2$3 != 823141696 then echo ERROR: wc results of areuh/assembler/aas.1 are $* should be 82 314 1696 fi chmod 644 areuh/assembler/aas.1 echo x - areuh/README cat >areuh/README <<'@EOF' AUTHORS ------- Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet) Janick TAILLANDIER You are free to use or distribute these programs as long as you keep this note These programs are provided as is. They are in no way supported by us. PRESENTATION ------------ These programs provide you with a complete development system for the Saturn processor (used on the HP-71, HP-28, HP-48 among others). It includes an assembler, a linker for separate assembly, and various utilities to generate message tables for the HP-71 as well as download programs to the HP-71 via HP-IL or RS-232. HISTORY ------- It was developped for the HP-71 in order for us to produce more easily the JPC Rom (PPC Paris Rom) for the HP-71. The final Rom module was 45 KB (executable) for a total of 1.5 MB source files. The speed was one of the main design objectives. These programs were written in C for the HP Integral PC (under HP-UX) in 1986 and have been adaptated for PC compatibles (Microsoft C 4.0 in 1987). It was also used as the final stage of a simple C compiler for the HP-71. HP-71 DEPENDENCIES ------------------ This development system is fully compatible with the assembler described in the HP-71 Internal Design Specifications (Volumes I or IV). The opcode syntax is the one used by HP : it seems crazy to invent a new one, just to confuse everyone! Some macros (LEX, BIN, FORTH, TOKEN...) are specific to the HP-71, but you are free not to use them. You may also want to write specific HP-48 macros to generate specific objects (it would be nice if HP give us the syntax they use). Some opcodes used in newer machines (28, 48...) are not present in the HP-71. Those opcodes (but PC=(A) and RSI) are not in our opcode table, but could be easily added if they are known. The linker preloads a special file (/usr/local/lib/hp71.ep) containing all HP-71 operating system entry points. Do not use any name contained in this file, or remove the loading of this file. In summary, HP-71 dependencies should not be a problem. However if you want to use new opcodes, you will have to add them. Please, post your modifications. CONTENTS -------- Makefile The global Makefile (HP-UX) to generate all programs. assembler Source code for aas (the assembler). Some files are shared between assembler, linker and dump (common.h, err.h), some are shared between assembler and linker (exp.c, mdep.c). Contains a manual page in French. linker Source code for ald (the linker). Contains a manual page in French. dump Source code for adp (the file dumper, used for debugging). Contains a manual page in French. cpy Source code for downloading files from a PC to an HP-71 using HP-IL Link card or RS-232. This should now superseded for HP-48 by Kermit. load Source code for acp, utility for copying an executable file generated by the linker to a LIF disk (to be read by an HP-71 with HP-9114). equ Source for all HP-71 operating system entry points. jmpdoc Some thoughts about adding a new generic branch macro. In French. Garbage. msg Source code for amg (HP-71 message table generator). Contains a manual page in French. doc Various documentations. PORTING ------- If you are using HP-UX, just type make, then make install. If you are using another flavor of Unix, the Makefile should work. We think there are no special system dependencies (it was successfully compiled on Suns 3 and 4 with SunOS 4 and a Vax under BSD 4.3). If you are using PC compatibles, we cannot do anything for you. The Makefiles will probably be difficult to use... If you are using an Amiga, a Mac or anything else, good work ! Have fun ! Pierre DAVID & Janick TAILLANDIER (July 1st, 1990) @EOF set `wc -lwc <areuh/README` if test $1$2$3 != 1406303718 then echo ERROR: wc results of areuh/README are $* should be 140 630 3718 fi chmod 644 areuh/README exit 0
akcs.scotty@hpcvbbs.UUCP (SCOTTY THOMPSON) (11/20/90)
I DON'T BELIEVE THIS!!! THINKING THAT THERE MAY BE FURTHER ADDENDUMS (I.E., 1/8, 2/8, 3/8 [WHICH I know I'VE SEEN HERE SOMEWHERE...]), I SEARCHED THE entire! COMP.SYS.HANDHELDS AND ENDED-UP WITH ZILTCH?! GOD AM I IRKED (RATHER, PO'ED, ACTUALLY). WILL SOMEONE PLEASE POST SOMETHING HERE SO THAT I, TOO, CAN "HAVE FUN!" AS A PRESUMEDLY SADISTIC AUTHOR ONCE WROTE. THIS RUN ON THE BBS WAS STRICTLY TO GET SATURN MATERIAL/ASSEMBLER/ETC. BOY, AM I DISSAPOINTED NOW. PLEASE CALL AND ADVISE WHEN SOMETHING'S ACTUALLY POSTED. SCOTT (213) 539-3611 (WK) 9780 (Hm)
akcs.hpjr@hpcvbbs.UUCP (Jerry Raia) (11/27/90)
drop me a line and we'll work something out. It's too big to try and post and would take longer than I want to spend on it.