cpm xasm part 1 of 2
Klotzbach
klotz at aicchi.UUCP
Fri Aug 30 15:37:42 AEST 1985
# 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
More information about the Comp.sources.unix
mailing list