Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!inria!litp!pda From: pda@litp.ibp.fr (Pierre DAVID) Newsgroups: comp.sys.handhelds Subject: Saturn Assembler (Part 5/8) Message-ID: <3306@litp.ibp.fr> Date: 5 Jul 90 16:24:14 GMT Reply-To: pda@litp.ibp.fr.UUCP (Pierre DAVID) Organization: M.A.S.I., Universite P. & M. Curie, Paris, FRANCE Lines: 2144 #---------------------------------- 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 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 #include 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/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 /* 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'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=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; iareuh/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 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/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/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, "?AC", 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, "?DC", 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=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, "?Bareuh/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) 2 GOYES ! 6 GOYES xx GOTO xx ! 8 GOYES xx GOLONG xx 9 GOYES xx GONC yy xx GOTO yy 11 GOYES xx GONC yy xx GOLONG yy ------------------------------------------------------------------------------- JSR (6) GOSUB 4 GOSUBL 6 @EOF set `wc -lwc 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/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 GOYES %s 2 -128 +127 Non ! GOYES *+6 6 -2045 +2050 Oui GOTO %s ! GOYES *+8 8 -32764 +32771 Oui GOLONG %s GOYES *+5 9 -2042 +2053 Non GONC *+6 GOTO %s 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/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/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/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/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/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