⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smal32.c

📁 极小的CPU的VHDL源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* smal32.c   language: C   copyright 1996 by Douglas W. Jones                     University of Iowa                     Iowa City, Iowa  52242                     USA   Permission is granted to make copies of this program for any purpose,   provided that the above copyright notice is preserved in the copy, and   provided that the copy is not made for direct commercial advantage.   Note: This software was developed with no outside funding.  If you find   it useful, and especially if you find it useful in a profit making   environment, please consider making a contribution to the University   of Iowa Department of Computer Science in care of:                     The University of Iowa Foundation                     Alumni Center                     University of Iowa                     Iowa City, Iowa  52242                     USA*//* Simple macro assembler and linkage editor with a 32 bit word.   Started by D. W. Jones in the fall 1980 at the University of Iowa.   rev 4/20/82 includes complete macro and conditional support.   rev 5/5/82 includes errata and extensions.   rev 2/5/84 yields 32-bit math, hex conversion.   rev 12/1/88 to remove NS32000 specific code and run on Berkeley Pascal.   rev 8/6/96 to translate to C with the aid of the PtoC translator.   rev 7/27/97 includes command arguments.   rev 6/11/98 minor bug fix in command line arguments.  Originally coded in Hull r-mode Pascal for Prime computers:    this uses 16 bit integer representations and the char type has    only 64 elements.  Works compatably in Hull v-mode Pascal for Prime computers:    this uses 32 bit integer representations and the char type uses    ASCII codes with the high bit always set to zero.  Works in Prime Pascal (v-mode) when keyword 'packed' is deleted:    this uses 32 bit integer representations and the char type uses    ASCII codes with the high bit always set to one.  Works in Berkeley Pascal, after date and time inquiry formats were    changed from Hull v-mode to make this work.  as modified by E. Wedel, requires 32-bit integers, but only    where explicitly called for by "oversized" subrange types.  as transliterated to C by D. Jones, limited to ASCII and 32 bit integers*//* As currently configured, this program takes command line arguments   to specify input, object and listing files.  The .o and .l suffixes   are used for object and listing files.  The final suffix present on   the input file name is removed before adding a .o or .l suffix;   usually the input file suffix will be .a for assembly, this is not   checked!  The -L option suppresses listing, the -D option enables   symbol table dump.*//* This assembler is written assuming that it will run on a   machine with at least 32 bit two's complement integers.   */#include <stdio.h>#include <time.h>/* boolean values */#define true 1#define false 0#define boolean int/* number of symbols allowed in symboltable */#define symsize         500/* opcodes and macro names allowed in optab */#define opcodes         200/* chars in stringpool; should be greater than the average symbol length   times symsize, plus the average opcode or macro name length times   opcodes, plus additional space for macro text storage, plus additional   space for the macro call stack, at a minimum of 8 characters per macro   nesting level, if no parameters are passed.   note: poolsize must not be increased above 32767 unless appropriate   changes are made to pushint and popint  */#define poolsize        30000/* offset of null symbol in pool */#define relsym          1/* offset for abs symbol (just below pool */#define abssym          0/* pool delimiter, an illegal character in programs, presently = control-A */#define pooldel         '\001'/* replacement for virgin occurrences of -pooldel- in input stream (ha!) */#define pdelrep         '~'/* number of files in input file stack */#define maxgetl         4/* number of macro parameters per call.   note: increasing this above 9 will require changes to   onepass.getline.getmac and to onepass.macdef.getbody; these currently use   decimal digits to encode parameter numbers, and must be changed to use   some other scheme */#define parmlim         8/* one more than length of allowed input line */#define linelen         120/* last column of listing used for object code info   note that if listcol is changed to be less than 20, the error messages   must all be shortened to keep the error markup under the right places   on the input line.     */#define listcol         24/* object code items (bytes,words) listed on a line */#define listcodes       50/* field-size allocated to title and sub-title texts */#define ttlbuflen       28/* lines per page on the listing device */#define linesper        56/* characters per textual file name */#define filelen         40/* break character in file system path names.  used for implementation of USE   in hierarchic file systems.  it is assumed in procedure insert that path   names starting with pathbrk are absolute, while those starting with other   characters are relative */#define pathbrk         '/'/* max 32-bit signed positive value 2^31-1*/#define maxposint       2147483647L#define maxposintdiv10  214748364L   /* maxposint DIV 10 (truncated) *//* symboltable types *//* reference to a location in the string pool */typedef short poolref;typedef struct value {	poolref base;   /* symbol from which offset is relocated */	long offset; /* offset from that symbol */} value;/* types of symbol-value associations */enum {	def, lab,   /* is it a label or defined value */	intdef,     /* is the value to be exported */	usedyet,    /* has value been used this pass */	setyet      /* has value been set this pass */};/* symbol-value association */typedef struct association {	/* fields known only to lookup routine */	poolref id;	/* fields known only by table users */	value val;	long use; /* a set, one bit per type */} association;/* opcode types */typedef enum {	operr,   /* error */	/* assembler directives */	opb,     /* byte (8 bit) constant */	oph,     /* half-word (16 bit) constant */	opw,     /* word (32 bit) constant */	opascii, /* string constant */	opif,    /* conditional assembly */	opelseif,	opelse,	opendif,	opint,   /* internal symbol definition */	opext,   /* external symbol declaration */	opcomon, /* common declaration */	opmac,   /* macro declaration */	opendm,	opuse,   /* use text from secondary source */	oplist,  /* listing control directive */	operror, /* directive to list this line as an error msg */	opttl,   /* title directive */	opsbttl, /* subtitle directive */	opeject, /* page eject directive */	opstart, /* starting address specification */	opend,   /* end of file */	/* macro call type */	opmcall  /* macro call */	/* add machine instruction types here */} optypes;/* all textual information stored by the assembler is in the string pool */static char strpool[poolsize - relsym + 1];/* two data structures share the string pool: permanent text grows up   from relsym, the last used location is pointed to by          */static poolref poolpos;/* transient text grows down from poolsize, organized as a stack.  the   format of each stack entry is documented in onepass.pushget           *//* when the stringpool fills up, it is indicated by:     */static boolean poolfull;/* some key-words are stored in the pool but not in any symbol table;   these are pointed to by the following (constant) variables            */static poolref funcdf, funcfw, functy, funcab, funcrl, funcle;/* the assembler symbol table for labels etc */static association symtab[symsize];typedef short symptr; /* index type into symtab *//* flag indicating symbol table is full */static boolean symfull;/* the assembler symbol table for opcodes, directives, and macro names */typedef struct _REC_optab {	poolref id;	optypes typ;	long val, subtyp;} _REC_optab;typedef int opptr; /* index type for optab */static _REC_optab optab[opcodes];/* flag indicating opcode table is full */static boolean opfull;/* textual names of input and output files */typedef char filename[filelen];static filename outfile, objfile, dumpfile;static filename infile[maxgetl];/* shallow stack of source files */static FILE *inp[maxgetl];/* listing output file */static FILE *o;/* object code file */static FILE *obj;/* object code file */static FILE *dmp;/* input line buffer types */typedef char linebuf[linelen];typedef int inbufptr; /* index into a line buffer *//* title and subtitle buffers for listing */static linebuf titlebuf, sbttlbuf;static inbufptr titlelen, sbttllen;/* used to determine when to list title */static long lineonpg;/* current page in assembly listing */static long pagenum;/* global, set in -onepass-' routines */static long errorcount;/* date and time buffers for listing -- see getdatetime for details */static char datestr[16];static char timestr[9];/* system date/time access routines */static void getdatetime(){	char *datetime;	long tloc = time(0);	datetime = ctime(&tloc);		/* fill datestr with "Mon Jan 16 1973", timestr with "12:00:00" */	memcpy(&(datestr[0]), &(datetime[0]), 11);	memcpy(&(datestr[11]), &(datetime[20]), 4);	datestr[15] = 0;	memcpy(&(timestr[0]), &(datetime[11]), 8);	timestr[8] = 0;}typedef char string[16];/* inside smal32, functions simulating 32 bit two's complement machine.   All of these avoid overflow or underflow; for efficiency, these may be   re-implemented as external assembly language routines      */static long add(i, j)long i, j;{	if (i > 0 && j > 0) {		if (i <= maxposint - j)			return (i + j);		else			return (i - maxposint + j - maxposint - 2);	} else if (i < 0 && j < 0) {		if (i >= -maxposint - j - 1)			return (i + j);		else			return (i + maxposint + j + maxposint + 2);	} else		return (i + j);}static long neg(i)long i;{	if (i == -maxposint - 1)		return (-maxposint - 1);	else		return (-i);}static long sub(i, j)long i, j;{	return (add(i, neg(j)));}static boolean ugt(i, j)long i, j;{	/* unsigned greater than */	if (i >= 0) {		if (j >= 0)			return (i > j);		else			return false;	} else {  /* i<0 */		if (j < 0)			return (i > j);		else			return true;	}}static long mod10(i)long i;{	if (i >= 0) {		return (i % 10);	} else {		return (((i + maxposint + 1) % 10 + 8) % 10);	}}static long div10(i)long i;{	if (i >= 0)		return (i / 10);	else		return ((i + maxposint + 1) / 10 + maxposintdiv10 +			(mod10(i + maxposint + 1) + 8) / 10);}static long inot(i)long i;{	return (add(neg(i), -1L));}static long iand(i, j)long i, j;{	return (i & j);}static long ior(i, j)long i, j;{	return (i | j);}static long rightshift(i)long i;{	return (i >> 1);}/* inside smal32, procedures for doing output format conversion */static void writedec(f, v, l)FILE *f;int v, l;{	/* write v as an l digit decimal number on file f */	char digits[10];	long i;	long sign = ' ';	if (v < 0) {		v = -v;		sign = '-';	}	i = 0;	do {		digits[i] = (v % 10) + '0';		v = v / 10;		i++;	} while (v > 0);	while ((--l) > i) {		putc(' ', f);	}	putc(sign, f);	do {		i--;		putc(digits[i], f);	} while (i > 0);}static void writehex(f, v, l)FILE *f;long v;int l;{	/* write v as an l digit hex number on file f */	char digits[8];	char digit;	long i;	if (l > 8) {		for (i = l - 1; i >= 8; i--)			putc(' ', f);		l = 8;	}	for (i = 0; i < l; i++) {		if (v < 0) {			v = (v + maxposint) + 1;			digit = v & 15;			v = v / 16 + 134217728L;		} else {			digit = v & 15;			v /= 16;		}		if (digit < 10)			digits[i] = digit + '0';		else			digits[i] = digit - 10 + 'A';	}	for (i = l - 1; i >= 0; i--)		putc(digits[i], f);}static void writesym(f, pos)FILE *f;poolref pos;{	/* write the symbol from the symboltable on the indicated file */	while (strpool[pos - relsym] != pooldel) {		putc(strpool[pos - relsym], f);		pos++;	}}static void genval(siz, offset, base)long siz, offset;poolref base;{	/* generate siz byte value in object file based on indicated	   symbol with the given offset from that symbol */	if (base == abssym) {		putc('#', obj);		writehex(obj, offset, siz * 2);	} else {		if (offset == 0)			putc(' ', obj);		else {			putc('#', obj);			writehex(obj, offset, siz * 2);			putc('+', obj);		}			putc('R', obj);			writesym(obj, base);	}	putc('\n', obj);}/* inside smal32, procedures for symbol table management */static void clearsym(){	/* initialize all entries in the symbol table to unused */	symptr i;	association *WITH;	/* clearsym */	symfull = false;	for (i = 0; i < symsize; i++) {		WITH = &symtab[i];		WITH->id = 0;		WITH->use = 0;	}}static void clearuse(){	/* clear symbol table flags in preparation for one pass */	symptr sym;	association *WITH;	/* clearuse */	for (sym = 0; sym < symsize; sym++) {		WITH = &symtab[sym];		WITH->use &= ~((1L << ((long)usedyet))			     | (1L << ((long)setyet)));	}}static void objsufx(){	/* generate suffix to object file which defines all internal symbols */	symptr sym;	association *WITH;	/* objsufx */	for (sym = 0; sym < symsize; sym++) {		WITH = &symtab[sym];		if (((1L << ((long)intdef)) & WITH->use) != 0) {			putc('R', obj);			writesym(obj, WITH->id);			putc('=', obj);			genval( 4L, WITH->val.offset, WITH->val.base);		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -