klotz@aicchi.UUCP (Klotzbach) (08/30/85)
# This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # asm.h as81.c as82.c as83.c as85.c asmain.c echo x - asm.h cat | sed -e "s/^X//" > "asm.h" << '//E*O*F asm.h//' X X/* X * @(#)asm.h 1.3 X * Header. X * X * General assembler header. With this structure you X * can define the majority of the simple assembler X * dependent variables. X * X * David A Klotzbach X * X * Sizes of tables. X */ X X#define NCPS 16 /* Characters per symbol */ X#define CLMAX 256 /* Code bytes, line */ X#define CBMAX 16 /* Code bytes, object */ X#define USERMAX 2 /* User names */ X#define SRCMAX 128 /* Source line length */ X#define ERRMAX 5 /* Maximum errors per line +1 */ X#define FALSE 0 /* not true */ X#define TRUE 1 /* You should be able to guess */ X#define mxline 55 /* maximum lines per page*/ X X#define dot (&ust[0]) /* Location counter */ X#define CDOT '$' /* Character that means current PC */ X#define BSWAP 0 /* 1 = High first; 0 = Low first */ X#define MICRO "8080" X#define TASK "ASM80" /* The task that is to be run */ X#define HASH 28 X X/* X * Listing control modes. X * Go in `listmode'. X */ X#define NLIST 0 /* No list */ X#define SLIST 1 /* Source only list */ X#define ALIST 2 /* Just address */ X#define CLIST 3 /* Address and code */ X X/* X * Symbol table structure. X * Used in both the user symbol table and X * the opcode table. X */ Xstruct hu{ X struct hu *next; /* Next usage */ X int line; /* Line used */ X char how; /* How it was used */ X }; X X#define U_DEFINE 'd' /* Defined */ X#define U_EXPR 'e' /* used in expres */ X#define U_EQU '=' /* EQU or SET */ X Xstruct sym { X char s_name[NCPS]; /* Name */ X struct sym *left; /* left member */ X struct sym *right; /* right member */ X char s_type; /* Type */ X char s_flag; /* Some flags */ X int s_value; /* Value */ X struct hu *howused; /* First entry in */ X}; X Xstruct sym *hashtbl[ ]; /* Hash buckets for symbol table */ Xstruct sym *lookup(); /* define lookup as a function returning */ X X#define B 0 X#define C 1 X#define D 2 X#define E 3 X#define H 4 X#define L 5 X#define M 6 X#define A 7 X#define PSW 6 X#define SP 7 X#define INR 4 X#define DCR 5 X X X/* X * Types. X */ X#define S_UND 0 /* Undefined */ X#define S_ABS 1 /* Absolute */ X#define S_REG 2 /* Register */ X#define S_REGP 3 /* Register pair */ X#define S_ENTRY 4 /* .entry */ X#define S_BYTE 5 /* .byte */ X#define S_WORD 6 /* .word */ X#define S_ASCII 7 /* .ascii */ X#define S_ASCIZ 8 /* .asciz */ X#define S_BLKB 9 /* .blkb */ X#define S_OP1 10 /* Opcode */ X#define S_OP2 11 /* Accumulator and Memory */ X#define S_OP3 12 /* Index Register and stack */ X#define S_OP4 13 /* Branch */ X#define S_OP5 14 /* Jump */ X#define S_OP6 15 /* Condition codes */ X#define S_OP7 16 /* limitted to extnd and indexed */ X#define S_OP8 17 /* limitted to direct,extnd and indx */ X#define S_OP9 18 /* */ X#define S_OP10 19 /* */ X#define S_OP11 20 /* */ X#define S_EQU 21 /* */ X#define S_SET 22 /* */ X#define S_NAME 23 /* Name the program listing */ X#define S_ORG 24 /* Program section origin statement */ X#define S_IF 100 /* IF directive */ X#define S_ENDIF 102 /* ENDIF directive */ X#define S_MACRO 200 /* Define a macro */ X#define S_ENDM 202 /* Define macro end */ X X/* X * Flags. X */ X#define SF_MDF 01 /* Multiply defined */ X#define SF_ASG 02 /* Defined by assignment */ X#define SF_MAC 04 /* is a MACRO definition */ X X/* X * Variables. X */ X#define TITLE_LN 40 /* Length of the title */ Xextern struct sym pst[]; /* Opcode table */ Xextern struct sym ust[]; /* User symbols */ Xextern int page ; /* Current page number */ Xextern int pline ; /* Lines on the current page */ Xextern int listmode; /* Listing control */ Xextern int listaddr; /* Listing control */ Xextern int entaddr; /* .entry address */ Xextern FILE *src; /* Source */ Xextern FILE *lst; /* Listing */ Xextern FILE *obj; /* Object */ Xextern int lflag; /* -l flag */ Xextern int nflag; /* -n flag */ Xextern int sflag; /* -s flag */ Xextern int pass; /* Which pass? */ Xextern int skip; /* Skipping code lines */ Xextern int inif; /* in an if block of inif */ Xextern int lineno; /* Line number */ Xextern char *sptr; /* Source pointer */ Xextern char sbuf[]; /* Source buffer */ Xextern char *cptr; /* Listing code pointer */ Xextern char cbuf[]; /* Listing code buffer */ Xextern char *eptr; /* Error pointer */ Xextern char ebuf[]; /* Error buffer */ Xextern int cadr; /* Object address */ Xextern int crec; /* Object index */ Xextern char crbf[]; /* Object buffer */ Xextern struct sym *pptr; /* End of pst */ Xextern struct sym *uptr; /* End of ust */ Xextern char title[]; /* Title buffer */ Xextern int errcnt; /* number of errors encounterd */ Xextern int optype; /* Type of current operand */ X X/* X * Functions. Xextern struct sym *lookup(); /* Search */ X X X //E*O*F asm.h// echo x - as81.c cat | sed -e "s/^X//" > "as81.c" << '//E*O*F as81.c//' X/* X * as81.c X * Assemble a line. X */ X#include <stdio.h> X#include "asm.h" X Xstatic char *as81="@(#)as81.c 1.3"; X X/* X * Assemble a line. X */ Xasmline() X{ X register struct sym *sp,*lsp; X register int rs, rd; X char *ptr; X int n; X int a, c, opcode; X char id[NCPS]; X X listaddr = dot->s_value; X listmode = skip ? NLIST : SLIST; /* if skiping then no list */ X lsp = NULL; X c = getnb(); X X do{ X if(c=='\0' || c==';' || c=='\n') X break; X if( c == '!' ) X c = getnb(); X if(!alpha(c)) { X if( !skip ) X err('L'); X break; X } X getid(c, id); X X if(( c = getnb()) == ':' ) { X if( skip ) X break; X sp=lookup(id, ust ,'d'); X if(pass==0) { X if(sp->s_type!=S_UND && X (sp->s_flag&SF_ASG)==0) X sp->s_flag |= SF_MDF; X sp->s_type = S_ABS; X sp->s_value = dot->s_value; X } X else { X if((sp->s_flag&SF_MDF)!=0) X err('L'); X if(sp->s_type!=S_ABS || X sp->s_value!=dot->s_value) X err('L'); X } X listmode = ALIST; X continue; X } X else X putback(c); X if((sp=lookup(id, pst)) == NULL){ X if( !skip ){ X lsp = lookup( id, ust ,'=' ); X c = getnb(); X getid( c , id ); X if((sp = lookup( id, pst )) == NULL){ X err('O'); X break; X } X } X else X return; X } X else if (skip &&(sp->s_type != S_ENDIF)) X return; X else if((skip || inif)&&(sp->s_type == S_ENDIF)) { X skip = 0; X if(!(--inif)) X inif=0; X listmode = NLIST; X return; X } X listmode = CLIST; X if( lsp != NULL ){ X switch( sp->s_type){ X case S_EQU: X case S_SET: X if( lsp->s_type != S_UND && X ( lsp->s_flag&SF_ASG) == 0) X err('L'); X lsp->s_type = S_ABS; X lsp->s_flag |= SF_ASG; X lsp->s_value = listaddr = expr(); X listmode = ALIST; X lsp = NULL; X break; X case S_MACRO: X lsp = NULL; X err('M'); X break; X } X } X if( lsp != NULL ){ X if(pass==0) { X if(lsp->s_type!=S_UND && X (lsp->s_flag&SF_ASG)==0) X lsp->s_flag |= SF_MDF; X lsp->s_type = S_ABS; X lsp->s_value = dot->s_value; X } X else { X if((lsp->s_flag&SF_MDF)!=0) X err('L'); X if(lsp->s_type!=S_ABS || X lsp->s_value!=dot->s_value) X err('p'); X } X lsp = NULL; X } X listmode = CLIST; X opcode = sp->s_value; X switch(sp->s_type) { X X case S_EQU: X case S_SET: X case S_MACRO: X break; X X case S_IF: X inif += 1; X skip = (expr()==0); X listmode = NLIST; X return; X X case S_NAME: X n = TITLE_LN; X c=getnb(); X ptr = title; X while((*ptr++ = getraw())!=c && --n>0); X *(--ptr) = '\0'; X return; X X case S_ORG: X listaddr = dot->s_value = expr(); X break; X X case S_ENTRY: X entaddr = expr(); X return; X X case S_BYTE: X do { X if ( (c=getnb())=='\'') X ascii(c); X else{ X putback( c ); X a = expr(); X byte(a); X codeb(a); X } X } X while((c=getnb()) == ','); X putback(c); X break; X X case S_WORD: X do { X codew(expr()); X } X while((c=getnb()) == ','); X putback(c); X break; X X case S_BLKB: X a = expr(); X while(a--) X codeb(0); X listmode = ALIST; X break; X X case S_OP1: X codeb(opcode); X break; X X case S_OP2: X a = expr(); X byte(a); X codeb(opcode); X codeb(a); X break; X X case S_OP3: X rd = getreg(S_REG); X comma(); X a = expr(); X byte(a); X code3(opcode, rd); X codeb(a); X break; X X case S_OP4: X rd = getreg(S_REG); X comma(); X rs = getreg(S_REG); X codeb(opcode | rd<<3 | rs); X break; X X case S_OP5: X if((rd=getreg(S_REG))!=B && rd!=D) X err('a'); X code4(opcode, rd); X break; X X case S_OP6: X if((rd=getreg(S_REG)) == PSW){ X err('R'); X } X code4(opcode, rd); X break; X X case S_OP7: X if((rd=getreg(S_REG)) == SP) X err('a'); X code4(opcode, rd); X break; X X case S_OP8: X a = expr(); X if(a<0 || a>7) X err('t'); X code3(opcode, a&07); X break; X X case S_OP9: X rs = getreg(S_REG); X if(opcode==INR || opcode==DCR) X code3(opcode, rs); X else X codeb(opcode | rs); X break; X X case S_OP10: X if((rd=getreg(S_REG)) == PSW) X err('a'); X comma(); X a = expr(); X code4(opcode, rd); X codew(a); X break; X X case S_OP11: X a = expr(); X codeb(opcode); X codew(a); X break; X X default: X err('C'); X } /* end of case statement */ X } X while( ( c = getnb()) != '\0' && c != ';' ); X} X X/* X * Process the body of .ascii X * and .asciz pseudo ops. X * The z flag is true for a X * .asciz X */ Xascii(delim) Xchar delim; X{ X register int c; X X while((c=getmap())!='\0' && c!=delim) X codeb(c); X if(c == '\0') X err('S'); X} X X/* X * Get a register. X * Type is either S_REG or S_REGP. X */ Xgetreg(type) X{ X register struct sym *sp; X register int c; X char id[NCPS]; X X if(!alpha(c=getnb())) { X err('R'); X putback(c); X return(0); X } X getid(c, id); X if((sp=lookup(id, pst))==NULL || type != sp->s_type) { X err('R'); X return(0); X } X return(sp->s_value); X} X X/* X * Insure that the value of X * an expression is a legal X * byte value. X * Error if not. X */ Xbyte(b) X{ X if((b&0200)!=0) X b |= ~0377; X if(b>127 || b<-128) X err('R'); X} X X/* X * Check for `,'. X */ Xcomma() X{ X if(getnb() != ',') X err('a'); X} X X/* X * Build instructions of the X * general form xxrrrxxx. X */ Xcode3(x, r) X{ X codeb(x | r<<3); X} X X/* X * Build instructions of the X * general form xxrrxxxx. X */ Xcode4(x, r) X{ X codeb(x | (r&6)<<3); X} //E*O*F as81.c// echo x - as82.c cat | sed -e "s/^X//" > "as82.c" << '//E*O*F as82.c//' X/* X * as82.c X * Expressions. X */ X#include <stdio.h> X#include "asm.h" Xstatic char *as82="@(#)as82.c 1.2"; X X X/* X * Read an expression. X * Return its value. X * All expressions are evaluated X * left to right; parentheses X * may be used to alter the order X * of evaluation. X */ Xint Xexpr() X{ X register int c; X int l, r; X X if(!term(&l)) X return(0); X while(validop(c=getopr())) { X if(!term(&r)) { X err('e'); X return(l); X } X switch(c) { X X case '+': X l += r; X break; X X case '-': X l -= r; X break; X X case '*': X l *= r; X break; X X case '/': X l /= r; X break; X X case '&': X l &= r; X break; X X case '|': X l |= r; X break; X case '^': X l ^= r; X break; X case '%': X l %= r; X break; X case '<': X l <<= r; X break; X case '>': X l >>= r; X break; X } X } X putback(c); X return(l); X} X X/* X * Check for valid arithmetic X * operators. X */ Xvalidop(c) X{ X return( instr( c,"+-*/%&|<>^") >= 0); X} X X/* X * Get a term. X * Store its value in the X * indicated place. X * Return true if a term is X * found. X * If no term is found no X * characters are read and X * false is returned. X */ Xint Xterm(vp) Xint *vp; X{ X register struct sym *sp; X register int c; X char id[NCPS]; X X /* X * Number. X */ X if((c=getnb())>='0' && c<='9') { X *vp = getnum(c); X return(1); X /* X * Id. X */ X } else if(alpha(c)) { X getid(c, id); X if( strcmp(id,"not")== 0){ /* if the id is 'not' */ X term(vp); X *vp = ~*vp; X }else { X sp = lookup(id, ust, 'e'); X if(sp == NULL ) X err( 'U'); X else if(sp->s_type == S_UND) X err('u'); X *vp = sp->s_value; X } X return(1); X X /* X * Unary ops. X */ X } else if(c=='-') { X if(!term(vp)) { X err('e'); X return(0); X } X *vp = -*vp; X /* X * Parentheses. X */ X } else if(c == '(') { X *vp = expr(); X if(getnb() != ')') X err('('); X return(1); X X /* X * Character constant. X */ X } else if(c == '\'') { X *vp = getmap(); X if(getnb() != '\'') X { X putback(c); X *vp = *vp+(getmap()<<8); X if(getnb() != '\'') X err('\''); X } X return(1); X X /* X * The current value of DOT X */ X X } else if ( c == CDOT ){ X *vp = dot->s_value; X return(1); X X /* X * None. X */ X } else { X putback(c); X return(0); X } X} X X/* X * getopr() X * X * Get a valid operator. X * X * Finds non-unix type operators and returns them as valid X * Unix operators. X * X */ Xgetopr() X{ X char ch; X char id[ NCPS ]; X int index; X X if( validop(ch=getnb()) ) X return(ch); X if( alpha(ch)) X getid( ch, id); X else X return(ch); X if( strcmp( id , "and") == 0) X return('&'); X else if( strcmp( id, "or") == 0) X return('|'); X else if( strcmp( id, "xor") == 0) X return('^'); X else if( strcmp( id, "mod") == 0) X return('%'); X else if( strcmp( id, "shr") == 0) X return('>'); X else if( strcmp( id, "shl") == 0) X return('<'); X else X for( index = strlen(id); index==1 ;index--) X putback( id[ index] ); X return( id[ 0 ]); X} //E*O*F as82.c// echo x - as83.c cat | sed -e "s/^X//" > "as83.c" << '//E*O*F as83.c//' X/* X * Lex. X */ X#include <stdio.h> X#include "asm.h" Xstatic char *sccsid="@(#)as83.c 1.2"; X X X/* X * Get the next non white X * character. X */ Xgetnb() X{ X register int c; X X while((c=getraw())==' ' || c=='\t'); X return(c); X} X X/* X * Get next character from X * the input. X * Apply string mappings. X */ Xgetmap() X{ X register int n, c, v; X X if((c=getraw()) == '\\') X switch(c = getraw()) { X X case 'n': X c = '\n'; X break; X X case 'r': X c = '\r'; X break; X X case 't': X c = '\t'; X break; X X case 'b': X c = '\b'; X break; X X case '0': X case '1': X case '2': X case '3': X case '4': X case '5': X case '6': X case '7': X v = n = 0; X while(++n<=3 && c>='0' && c<='7') { X v = 8*v + c - '0'; X c = getraw(); X } X putback(c); X c = v; X break; X X default: X putback(c); X c = '\\'; X } X return(c); X} X X/* X * Get next character. X * Basic routine. X * Don't screw up on end of X * line. X */ Xgetraw() X{ X register int c; X X if((c = *sptr) != '\0') X ++sptr; X return(c); X} X X/* X * Check for alpha. X */ Xalpha(c) Xregister int c; X{ X return(c=='?'|| (c>='a' && c<='z') || (c>='A' && c<='Z')); X} X X/* X * Put a character back. X * A line at a time version X * of ungetc. X * Die if too many characters X * are put back. X */ Xputback(c) X{ X if(c != '\0') X if(--sptr < sbuf) X abort(); X} X X/* X * Read in an indentifier. X * Store it (padded with nulls) into the X * supplied buffer. X */ Xgetid(c, id) Xregister int c; Xchar *id; X{ X register char *p; X X p = id; X while(alpha(c) || c== '$' || (c>='0' && c<='9')) { X if(p < &id[NCPS]){ X if ( c>='A' && c<='Z' ) X c |=' '; X if( c != '$' ) X *p++ = c; X } X c = getraw(); X } X while(p < &id[NCPS]) X *p++ = '\0'; X putback(c); X} X X/* X * instr( c,str) X * X * returns the index to locate c in str if c is in str. X * if c is not in str then returns -1. X */ X Xint Xinstr( c, str ) Xchar c; Xchar *str; X{ X register char *lp; X lp = str; X while( *lp != '\0' ) X if( *lp++ == c ) X return( lp-str-1 ); X return( -1 ); X} Xchar Xucase( c ) Xchar c; X{ X if( c >= 'a' && c <= 'z') X c = ( c - ( 'a' - 'A' )); X return( c ); X} X X/* X * get a number; X * X */ Xstatic char *hexstr = "0123456789ABCDEF"; Xint Xgetnum(c) Xchar c; X{ X static char *radix = "BDHOQ"; X static int radv[]={ 10,2,10,16,8,8}; X int value; X X char numbstr[ 16 ]; X char *np; X X np = numbstr; X while( instr( ucase( c ), hexstr) >= 0 ){ X *np++=ucase( c ); X c = getraw(); X } X *np-- = '\0'; X if( instr( ucase( c ), radix ) < 0 ){ X putback(c ); /* if terminal not right */ X c = *np; /* then the previous is */ X if( instr( ucase( c ), radix ) >= 0 ) X *np = '\0'; X } X /* X * The following code uses the index into the radix array to X * calculate the correct index into radix value table and X * use the value found to determine the correct conversion X * routine. X * X * Think carefully before changing the following code. X * X */ X return( scnnumb( numbstr, radv[ 1 + instr( ucase( c ), radix )])); X} X Xint Xscnnumb( str ,radix ) Xchar *str; Xint radix; X{ X int v ,d; X v = 0; X while( *str ) X if( (d=instr( *str++, hexstr)) >= 0 && d < radix ) X v = v*radix + d; X else X return( err( 'N' ), 0 ); X return( v ); X} //E*O*F as83.c// echo x - as85.c cat | sed -e "s/^X//" > "as85.c" << '//E*O*F as85.c//' X/* X * as85.c X * Tables. X */ X#include <stdio.h> X#include "asm.h" X X/* X * Assorted variables. X */ Xstatic char *as85="@(#)as85.c 1.2"; X Xint listmode; /* Listing control */ Xint listaddr; /* Listing control */ Xint entaddr; /* Entry address */ XFILE *src; /* Source */ XFILE *lst; /* Listing */ XFILE *obj; /* Object */ Xint lflag; /* -l flag */ Xint nflag; /* -n flag */ Xint sflag; /* -s flag */ Xint pass; /* Which pass? */ Xint skip; /* skipping code */ Xint inif; /* in an if block */ Xint lineno; /* Line number */ Xchar *sptr; /* Source pointer */ Xchar sbuf[SRCMAX]; /* Source buffer */ Xchar *cptr; /* Listing code pointer */ Xchar cbuf[CLMAX]; /* Listing code buffer */ Xchar *eptr; /* Error pointer */ Xchar ebuf[ERRMAX]; /* Error buffer */ Xint cadr; /* Object address */ Xint crec; /* Object index */ Xchar crbf[CBMAX]; /* Object buffer */ Xint errcnt; /* error count */ Xint page; /* current page number */ Xint pline; /* lines on the current page */ Xchar title[TITLE_LN+1]; /* program listing title*/ Xstruct sym *hashtbl[ HASH ]; /* symbol table hashbuckets */ X X/* X * User symbol table. X * The first item must be '$'. X */ Xstruct sym ust[USERMAX] = { X "$", NULL,NULL, S_ABS, SF_ASG, 0 X}; X X/* X * Opcode table. X * Also contains pseudo operations and X * registers. X */ Xstruct sym pst[] = { X "b",NULL,NULL, S_REG, 0, 0, NULL, X "c",NULL,NULL, S_REG, 0, 1, NULL, X "d",NULL,NULL, S_REG, 0, 2, NULL, X "e",NULL,NULL, S_REG, 0, 3, NULL, X "h",NULL,NULL, S_REG, 0, 4, NULL, X "l",NULL,NULL, S_REG, 0, 5, NULL, X "m",NULL,NULL, S_REG, 0, 6, NULL, X "a",NULL,NULL, S_REG, 0, 7, NULL, X "sp",NULL,NULL, S_REG, 0, SP, NULL, X "psw",NULL,NULL, S_REG, 0, PSW, NULL, X "org",NULL,NULL, S_ORG, 0, 0, NULL, X "end",NULL,NULL, S_ENTRY, 0, 0, NULL, X "db",NULL,NULL, S_BYTE, 0, 0, NULL, X "dw",NULL,NULL, S_WORD, 0, 0, NULL, X "ds",NULL,NULL, S_BLKB, 0, 0, NULL, X "set",NULL,NULL, S_SET, 0, 0, NULL, X "equ",NULL,NULL, S_EQU, 0, 0, NULL, X "if",NULL,NULL, S_IF, 0, 0, NULL, X "endif",NULL,NULL, S_ENDIF, 0, 0, NULL, X "macro",NULL,NULL, S_MACRO, 0, 0, NULL, X "endm",NULL,NULL, S_ENDM, 0, 0, NULL, X "title",NULL,NULL, S_NAME, 0, 0, NULL, X "pchl",NULL,NULL, S_OP1, 0, 0351, NULL, X "ret",NULL,NULL, S_OP1, 0, 0311, NULL, X "rc",NULL,NULL, S_OP1, 0, 0330, NULL, X "rnc",NULL,NULL, S_OP1, 0, 0320, NULL, X "rz",NULL,NULL, S_OP1, 0, 0310, NULL, X "rnz",NULL,NULL, S_OP1, 0, 0300, NULL, X "rm",NULL,NULL, S_OP1, 0, 0370, NULL, X "rp",NULL,NULL, S_OP1, 0, 0360, NULL, X "rpe",NULL,NULL, S_OP1, 0, 0350, NULL, X "rpo",NULL,NULL, S_OP1, 0, 0340, NULL, X "xchg",NULL,NULL, S_OP1, 0, 0353, NULL, X "sphl",NULL,NULL, S_OP1, 0, 0371, NULL, X "cma",NULL,NULL, S_OP1, 0, 0057, NULL, X "cmc",NULL,NULL, S_OP1, 0, 0077, NULL, X "daa",NULL,NULL, S_OP1, 0, 0047, NULL, X "rlc",NULL,NULL, S_OP1, 0, 0007, NULL, X "rrc",NULL,NULL, S_OP1, 0, 0017, NULL, X "ral",NULL,NULL, S_OP1, 0, 0027, NULL, X "rar",NULL,NULL, S_OP1, 0, 0037, NULL, X "xthl",NULL,NULL, S_OP1, 0, 0343, NULL, X "ei",NULL,NULL, S_OP1, 0, 0373, NULL, X "di",NULL,NULL, S_OP1, 0, 0363, NULL, X "stc",NULL,NULL, S_OP1, 0, 0067, NULL, X "nop",NULL,NULL, S_OP1, 0, 0000, NULL, X "hlt",NULL,NULL, S_OP1, 0, 0166, NULL, X "in",NULL,NULL, S_OP2, 0, 0333, NULL, X "out",NULL,NULL, S_OP2, 0, 0323, NULL, X "adi",NULL,NULL, S_OP2, 0, 0306, NULL, X "aci",NULL,NULL, S_OP2, 0, 0316, NULL, X "sui",NULL,NULL, S_OP2, 0, 0326, NULL, X "sbi",NULL,NULL, S_OP2, 0, 0336, NULL, X "ani",NULL,NULL, S_OP2, 0, 0346, NULL, X "xri",NULL,NULL, S_OP2, 0, 0356, NULL, X "ori",NULL,NULL, S_OP2, 0, 0366, NULL, X "cpi",NULL,NULL, S_OP2, 0, 0376, NULL, X "mvi",NULL,NULL, S_OP3, 0, 0006, NULL, X "mov",NULL,NULL, S_OP4, 0, 0100, NULL, X "ldax",NULL,NULL, S_OP5, 0, 0012, NULL, X "stax",NULL,NULL, S_OP5, 0, 0002, NULL, X "dad",NULL,NULL, S_OP6, 0, 0011, NULL, X "inx",NULL,NULL, S_OP6, 0, 0003, NULL, X "dcx",NULL,NULL, S_OP6, 0, 0013, NULL, X "push",NULL,NULL, S_OP7, 0, 0305, NULL, X "pop",NULL,NULL, S_OP7, 0, 0301, NULL, X "rst",NULL,NULL, S_OP8, 0, 0307, NULL, X "add",NULL,NULL, S_OP9, 0, 0200, NULL, X "sub",NULL,NULL, S_OP9, 0, 0220, NULL, X "adc",NULL,NULL, S_OP9, 0, 0210, NULL, X "sbb",NULL,NULL, S_OP9, 0, 0230, NULL, X "ana",NULL,NULL, S_OP9, 0, 0240, NULL, X "xra",NULL,NULL, S_OP9, 0, 0250, NULL, X "ora",NULL,NULL, S_OP9, 0, 0260, NULL, X "cmp",NULL,NULL, S_OP9, 0, 0270, NULL, X "inr",NULL,NULL, S_OP9, 0, 0004, NULL, X "dcr",NULL,NULL, S_OP9, 0, 0005, NULL, X "lxi",NULL,NULL, S_OP10, 0, 0001, NULL, X "jpo",NULL,NULL, S_OP11, 0, 0342, NULL, X "jpe",NULL,NULL, S_OP11, 0, 0352, NULL, X "jm",NULL,NULL, S_OP11, 0, 0372, NULL, X "jp",NULL,NULL, S_OP11, 0, 0362, NULL, X "jnz",NULL,NULL, S_OP11, 0, 0302, NULL, X "jz",NULL,NULL, S_OP11, 0, 0312, NULL, X "jnc",NULL,NULL, S_OP11, 0, 0322, NULL, X "jc",NULL,NULL, S_OP11, 0, 0332, NULL, X "cpo",NULL,NULL, S_OP11, 0, 0344, NULL, X "cpe",NULL,NULL, S_OP11, 0, 0354, NULL, X "cm",NULL,NULL, S_OP11, 0, 0374, NULL, X "cp",NULL,NULL, S_OP11, 0, 0364, NULL, X "cnz",NULL,NULL, S_OP11, 0, 0304, NULL, X "cz",NULL,NULL, S_OP11, 0, 0314, NULL, X "cnc",NULL,NULL, S_OP11, 0, 0324, NULL, X "cc",NULL,NULL, S_OP11, 0, 0334, NULL, X "call",NULL,NULL, S_OP11, 0, 0315, NULL, X "jmp",NULL,NULL, S_OP11, 0, 0303, NULL, X "lda",NULL,NULL, S_OP11, 0, 0072, NULL, X "sta",NULL,NULL, S_OP11, 0, 0062, NULL, X "lhld",NULL,NULL, S_OP11, 0, 0052, NULL, X "shld",NULL,NULL, S_OP11, 0, 0042, NULL, X}; X X/* X * Pointers to the end of the X * tables. X * Must be here! X */ Xstruct sym *pptr = &pst[sizeof(pst)/sizeof(pst[0])]; /* Ditto */ Xstruct sym *uptr = &ust[1]; /* Pointer to end of ust */ X //E*O*F as85.c// echo x - asmain.c cat | sed -e "s/^X//" > "asmain.c" << '//E*O*F asmain.c//' X X/* X * asm.c X * Mainline. X * X */ X#include <stdio.h> X#include "asm.h" Xstatic char *ident="@(#)asmain.c 1.4"; X X/* X * This is the mainline. X * It scans the command line, X * collects up a source file, X * sets option flags and calls X * the assembler proper. X */ Xstatic int cflag = 0; /* cross reference on flag */ X Xmain(argc, argv) Xchar *argv[]; X{ X register int i, c; X register char *p; X char *file; X X file = NULL; X for(i=1; i<argc; ++i) { X p = argv[i]; X if(*p++ == '-') { X while(c = *p++) X switch(c) { X X case 'l': X case 'L': X ++lflag; X break; X case 'c': X case 'C': X ++lflag; X ++cflag; X break; X X case 'n': X case 'N': X ++nflag; X break; X X case 's': X case 'S': X ++lflag; X ++sflag; X break; X default: X usage(); X } X } X else X { X file = argv[i]; X if(file == NULL) X usage(); X assemble(file); X } X } X} X X/* X * Assemble a file. X */ X Xassemble(file) Xchar *file; X{ X char fn[40]; X int index; X X strncpy(title,file,20); X for ( index = 0 ; index < HASH ; index ++) X hashtbl[ index ] = NULL; X name(fn, file, "asm", 0); X if((src=fopen(fn, "r")) == NULL) { X fprintf(stderr, "%s: cannot open\n", fn); X exit(1); X } X if(lflag) { X name(fn, file, "lst", 1); X if((lst=fopen(fn, "w")) == NULL) { X fprintf(stderr, "%s: cannot create\n", fn); X exit(1); X } X } X if(!nflag) { X name(fn, file, "hex", 1); X if((obj=fopen(fn, "w")) == NULL) { X fprintf(stderr, "%s: cannot create\n", fn); X exit(1); X } X fprintf(obj, "\n"); X } X page = 1; X for(pass=0; pass<2; ++pass) { X skip = 0; /* not currently skipping*/ X rewind(src); X errcnt = 0; X lineno = 0; X dot->s_type = S_ABS; X dot->s_flag = SF_ASG; X dot->s_value = 0; X if(pass && lflag ) X top(0); X X while(fgets(sbuf, SRCMAX , src) != NULL) { X ++lineno; X sptr = sbuf; X cptr = cbuf; X eptr = ebuf; X asmline(); X if(pass) { X outerrors(); X if(lflag) X outlisting(); X } X } X } X if(errcnt) X printf(" Total errors = %5d\n",errcnt); X if(lflag){ X if(errcnt){ X fprintf(lst,"\n Total number of errors = %5d \n",errcnt) X ; X } X table(); X fclose(lst); X } X if(!nflag){ X cflush(1); X fclose(obj); X } X printf(" Total bytes assembled = %04X\n",dot->s_value); X fclose(src); X} X X/* X * If the user screws up, put out X * a usage message. X * Then quit. X * Not much sense staying around. X */ Xusage() X{ X fprintf(stderr, "Usage:%4s [-ln] file file ...\n",TASK); X fprintf(stderr, "where: \n"); X fprintf(stderr, " l = make a listing \n"); X fprintf(stderr, " and n = don't make an object file\n"); X exit(1); X} X X/* X * Build RSX file names. X * The mode argument is either 0 X * which means default, or 1 which X * means replace with. X */ Xname(fn, file, type, mode) Xchar *fn, *file, *type; X{ X register char *p1, *p2; X register int c; X X p1 = fn; X p2 = file; X while((c = *p2++) && c!='.') X *p1++ = c; X if(mode == 0) { X if(c == '.') { X do { X *p1++ = c; X } X while(c = *p2++); X } X else { X *p1++ = '.'; X p2 = type; X while(c = *p2++) X *p1++ = c; X } X } X else { X *p1++ = '.'; X p2 = type; X while(c = *p2++) X *p1++ = c; X } X *p1 = '\0'; X} X X/* X * Output code byte. X * Save it in the per line X * buffer for outlisting. X * Update dot. X */ Xcodeb(b) X{ X b &= 0377; X if(cptr < &cbuf[CLMAX]) X *cptr++ = b; X if(pass && !nflag) { X if(crec>=CBMAX || cadr+crec!=dot->s_value) { X cflush(0); X cadr = dot->s_value; X } X crbf[crec++] = b; X } X ++dot->s_value; X} X X/* X * Output a word. X * Low then high. X */ Xcodew(w) X{ X if(BSWAP)codeb(w>>8); X codeb(w); X if(!BSWAP)codeb(w>>8); X} X X/* X * Signal error. X * Add it to the error buffer X * if not already there. X */ Xerr(c) X{ X register char *p; X X errcnt+=1; X p = ebuf; X if(eptr == &ebuf[ERRMAX-1]) c ='*'; X while(p < eptr) X if(*p++ == c) X return; X *p++ = c; X if ( p> &ebuf[ERRMAX]) X --p; X eptr = p; X} X X/* X * Format a line for the X * listing. X * More work than you would X * think. X * Only called if -l. X */ Xoutlisting() X{ X register int nbytes; X register char *cp; X int w1, w2, w3, w4; X X if(listmode == NLIST) X return; X for(cp = eptr; cp < &ebuf[ERRMAX-1]; *cp++ = ' '); X *cp='\0'; X if(!(--pline )) X top(1); X if(listmode == SLIST) X fprintf(lst, "%.6s ", ebuf); X else X fprintf(lst, "%.6s %04X ", ebuf, listaddr); X if(listmode == ALIST) X fprintf(lst, "%9s%4d %s", "", lineno, sbuf); X else { X nbytes = cptr-cbuf; X w1 = cbuf[0]&0377; X w2 = cbuf[1]&0377; X w3 = cbuf[2]&0377; X w4 = cbuf[3]&0377; X switch(nbytes) { X case 0: X fprintf(lst, "%9s", ""); X break; X case 1: X fprintf(lst, "%02X%7s", w1, ""); X break; X case 2: X fprintf(lst, "%02X%02X%5s", w1, w2, ""); X break; X case 3: X fprintf(lst, "%02X%02X%02X%3s", w1, w2, w3,""); X break; X default: X fprintf(lst, "%02X%02X%02X%02X%1s", w1, w2, w3,w4,""); X } X fprintf(lst, "%4d\t%s", lineno, sbuf); X cp = &cbuf[4]; X while((nbytes -= 4) > 0) { X if( --pline < 0 ) X top(1); X listaddr += 4; X fprintf(lst, "%5s%04X ", "",listaddr ); X switch(nbytes) { X case 0: X break; X case 1: X w1 = cp[0]&0377; X fprintf(lst, "%02X\n", w1); X break; X case 2: X w1 = cp[0]&0377; X w2 = cp[1]&0377; X fprintf(lst, "%02X%02X\n", w1, w2); X break; X case 3: X w1 = cp[0]&0377; X w2 = cp[1]&0377; X w3 = cp[2]&0377; X fprintf(lst, "%02X%02X%02X\n", w1, w2, w3); X break; X default: X w1 = cp[0]&0377; X w2 = cp[1]&0377; X w3 = cp[2]&0377; X w4 = cp[3]&0377; X fprintf(lst, "%02X%02X%02X%02X\n", w1, w2, w3,w4); X } X cp += 4; X } X } X} X X/* X * Write errors to the tty. X */ Xouterrors() X{ X register char *p; X if( lflag ) X return; X X if( eptr > ebuf ){ X *eptr='\0'; X printf("%s\t%04d\t%s", ebuf, lineno, sbuf); X } X} X X/* X * Flush the binary code X * buffer. X */ X Xcflush(lf) Xint lf; X{ X int chksum; /* checksum for hex file format */ X register int i; X X if(crec == 0) X return; X fprintf( obj, ":%02X%04X00",crec,cadr ); X chksum = 0; X chksum += crec; X chksum += (( cadr >> 8)& 0xFF); X chksum += ( cadr & 0xFF); X for(i=0; i<crec; ++i){ X fprintf( obj,"%02X", crbf[ i ]&0xFF ); X chksum += crbf[ i ]&0xFF; X } X fprintf( obj,"%02X\n" , ( 00 -( chksum &0xFF))&0xFF ); X crec = 0; X if(lf) X fprintf(obj,":00000000\n"); X} X/* X * Print out the user symbol table X */ Xtable() X{ X register struct sym *mine ; X register struct hu *howu; X int line,indx,count; X X count =line = 0; X page = 1; X fprintf(lst,"\f\n%-40s Symbol table dump \t\t Page %3d\n\n\n", X title,page++) ; X for( indx = 0 ; indx < HASH ; indx++){ X for(mine = hashtbl[ indx ]; mine != NULL; mine = mine->right ){ X if( line >= mxline ){ X fprintf(lst, X "\f\n Symbol table dump page %3d\n\n\n" X ,page++); X line = 0; X } X fprintf(lst,"%10s = %04X ",mine->s_name,mine->s_value); X if( cflag ){ X for( howu = mine->howused; howu != NULL ; X howu = howu->next ){ X if( count >= 10 ){ X fprintf(lst,"\n "); X line++; X count = 0; X } X fprintf(lst,"%6d %c :", howu->line, howu->how ); X count++; X } X count = 0; X line++; X fprintf(lst,"\n"); X } X else{ X if( count >= 4 ){ X line++; X count = 0; X fprintf(lst,"\n"); X } X count++; X } X } X } X fprintf(lst,"\f\n"); X fflush(lst); X} X X/* X * X * Top - Print the label at the top of the page X * X */ X Xtop(mode) Xint mode; X{ X X if(mode)putc('\f',lst); X pline = mxline; X fprintf(lst,"\n %-40s KSE cross assembler for the %-5s",title,MICRO); X fprintf(lst," page %3d",page++); X fprintf(lst," \n\n\n"); X} X Xint Xhash( id ) Xchar *id; X{ X if( *id >= 'a' && *id <= 'z' ) X return( *id - 'a'); X else if( *id == '?' ) X return( 26 ); X else X return( 27 ); X} Xstruct sym * Xlkup( id , howu ) Xchar *id; Xchar howu; X{ X struct sym *np; X struct hu *usage; X X for( np = hashtbl[hash(id)]; np != NULL; np = np->right ){ X if( strcmp( id, np->s_name ) == 0){ X if( cflag ){ X for( usage = np->howused; X usage->line != lineno && usage->next != NULL; X usage = usage->next ) X ; X if( usage->line != lineno ){ X usage->next =(struct hu *) X malloc( sizeof( *usage)); X if( usage->next != NULL){ X usage->next->line = lineno; X usage->next->how =howu; X usage->next->next = NULL; X } X } X } X return( np ); X } X } X return(NULL ); X} Xstruct sym * Xinstall( id , howu ) Xchar *id; Xchar howu; X{ X struct sym *np,*lp; X struct sym *lkup(); X int hashval; X X if( (np = lkup( id , howu ) ) == NULL ) { X np= ( struct sym *)malloc( sizeof( *np )); X if(np == NULL ){ X fprintf(stderr,"in line %d ",lineno); X fprintf(stderr,"Symbol table overflow\n"); X return( NULL ); X } X np->right = NULL; X np->left = NULL; X np->s_type= 0; X np->s_flag= 0; X np->s_value = 0; X if( cflag ){ X np->howused = (struct hu *)malloc( sizeof( *np->howused)); X if( np->howused != NULL ){ X np->howused->how = howu; X np->howused->line = lineno; X np->howused->next = NULL; X } X } X strcpy(np->s_name,id); X hashval = hash( id ); X if( hashtbl[ hashval ] == NULL ){ X hashtbl[ hashval ] = np; X } X else if( strcmp( id , hashtbl[hashval]->s_name ) > 0 ){ X hashtbl[ hashval ]->left = np; X np->right = hashtbl[ hashval ]; X hashtbl[ hashval] = np; X } X else X for( lp = hashtbl[hashval];lp != NULL;lp = lp->right) { X if( lp->right == NULL ){ X lp->right = np; X np->left = lp; X break; X } X else if ( strcmp( id, lp->right->s_name ) < 0){ X np->right = lp->right; X lp->right->left = np; X lp->right = np; X np->left = lp; X break; X } X } X } X return( np ); X} X/* X * Lookup id. X * The table is either the pst or X * the ust. X */ Xstruct sym * Xlookup(id, stp, howu) Xchar *id; Xregister struct sym *stp; Xchar howu; X{ X if(stp == ust) X return(install( id ,howu )); X while(stp < pptr) X if(strcmp(id, stp->s_name) == 0) X break; X else X ++stp; X if( stp >= pptr ) X return( NULL); X else X return( stp ); X} //E*O*F asmain.c// exit 0