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

📄 isp8asm.c

📁 Lattice 超精简8位软核CPU--Mico8
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

//
// ====================================================================
//
// Lattice Semiconductor Corporation
// 5555 NE Moore Court
// Hillsboro, OR 97124
// U.S.A
//
// TEL: 1-800-Lattice (USA and Canada)
// 408-826-6000 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// ====================================================================
// File Details         
// ====================================================================
// Project     : ISP 8 bit Microcontroller
// File        : isp8asm.c
// Title       : Assembler for Lattice 8 bit microcontroller
// 
// Description : This program is the assembler for Lattice 8 bit
//		 Microcontroller. Input is an assembler file output
//		 EBR initialization file.
//                    
// Additional info. :
//
// ====================================================================
// Revision History     
// ====================================================================
// Ver  | Author(s)        | Mod. Date| Changes Made
// --------------------------------------------------------------------
// 1.0  | Sandeep Dutta    | 04/27/05 | Initial Creation
// $Revision: 1.2 $

#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

/* ==================================================== */
/* 			defines 			*/
/* ==================================================== */
#define COMMENT_CHAR	'#'
#define MAX_LINE_SIZE	1024
#define MAX_TOKEN_SIZE	100
#define MAX_REG		32
#define GETC() (*lbp ? *lbp++ : *lbp)
#define UNGETC()  lbp--
#define ABS(x) (x < 0 ? -x : x)

/* ==================================================== */
/* 		types & data structures 		*/
/* ==================================================== */
typedef unsigned int uint32;

enum otype {
	OHEX = 0,
	OBIN,
	OVER,
	OVHD
};

enum optype {
	OP_NONE,  OP_REGD, 
	OP_REGB,  OP_LABEL, 
	OP_CONST, OP_PORT
};

enum codeflags {
	CODE_ISDATA = 1,
	CODE_ISLDEF = CODE_ISDATA*2
};

typedef struct instr_tab {
	char   *opname;	
	int	opcode;		
	int	nops;
	int	optypes[2];
} itab ;


typedef enum dirs {
	D_ORG, D_INCLUDE, D_EQU
} dirs;

typedef struct code {
	itab   *itabp;
	uint32	opcode;
	uint32	rd, rb, konst;
	uint32	flags;
	struct	stab   *label_ref;
	struct	stab   *label_def;
	struct	code   *next;
	int     loc_counter;
	int	line_no;
	uint32  port;
} code;

typedef enum sym_types {
	SYM_LABEL = 1,
	SYM_EQU	  = SYM_LABEL*2
} stypes;

typedef struct stab {
	char	    *name;
	stypes	     stype;
	int	     value;
	int	     loc_counter;
	code	    *codep;
	struct stab *next;
} stab;


typedef struct directs {
	char *dname;
	void (*dparse_func)();
} directs; 


/* ==================================================== */
/* 		function forward declarations 		*/
/* ==================================================== */
static uint32 parse_const();
static void   dparse_equ();
static void   dparse_org();
static void   dparse_data();

/* ==================================================== */
/* 			global variables 		*/
/* ==================================================== */
static code *croot = NULL;
static code *ccurr = NULL;
static stab *sroot = NULL;
static uint32 loc_counter = 0;
static FILE *infile = NULL;
static FILE *ofile = NULL;
static FILE *lfile = NULL;
static FILE *eifile = NULL;
static FILE *eofile = NULL;
static char *ifilename = NULL;
static char *ofilename = NULL;
static char *lfilename = NULL;
static int  line_no = 0;
static char line_buffer[MAX_LINE_SIZE];
static char *lbp;
static char token[MAX_TOKEN_SIZE];
static int omode = 0 ;
static int lgen  = 0 ;
static int prom_size = 512;
static int *vmstack;
static int  vmsp = 0;
static directs dirtab_array[] = {
	{"org", dparse_org},
	{"equ", dparse_equ},
	{"data",dparse_data}
};

#define DIRTAB_SIZE sizeof(dirtab_array)/sizeof(directs)

static itab itab_array [] = {
	{"sub",		((0x0 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"subi",	((0x0 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"subc",	((0x1 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"subic",	((0x1 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"add",		((0x2 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"addi",	((0x2 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"addc",	((0x3 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"addic",	((0x3 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"mov",		((0x4 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"movi",	((0x4 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"and",		((0x5 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"andi",	((0x5 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"or",		((0x6 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"ori",		((0x6 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"xor",		((0x7 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"xori",	((0x7 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"cmp",		((0x8 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"cmpi",	((0x8 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"test",	((0x9 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"testi",	((0x9 << 14)|(0 << 10)|0), 2, {OP_REGD, OP_CONST}},
	{"ror",		((0xa << 14)|(0 << 10)|0), 2, {OP_REGD, OP_REGB}},
	{"rorc",	((0xa << 14)|(0 << 10)|2), 2, {OP_REGD, OP_REGB}},
	{"rol",		((0xa << 14)|(0 << 10)|1), 2, {OP_REGD, OP_REGB}},
	{"rolc",	((0xa << 14)|(0 << 10)|3), 2, {OP_REGD, OP_REGB}},
	{"clrc",	((0xb << 14)|(0 << 10)|0), 0, {OP_NONE, OP_NONE}},
	{"setc",	((0xb << 14)|(0 << 10)|1), 0, {OP_NONE, OP_NONE}},
	{"clrz",	((0xb << 14)|(0 << 10)|2), 0, {OP_NONE, OP_NONE}},
	{"setz",	((0xb << 14)|(0 << 10)|3), 0, {OP_NONE, OP_NONE}},
	{"clri",	((0xb << 14)|(0 << 10)|4), 0, {OP_NONE, OP_NONE}},
	{"seti",	((0xb << 14)|(0 << 10)|5), 0, {OP_NONE, OP_NONE}},
	{"bz",		((0xc << 14)|(0 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"bnz",		((0xc << 14)|(1 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"bc",		((0xc << 14)|(2 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"bnc",		((0xc << 14)|(3 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"b",		((0xc << 14)|(4 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"callz",	((0xd << 14)|(0 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"callnz",	((0xd << 14)|(1 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"callc",	((0xd << 14)|(2 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"callnc",	((0xd << 14)|(3 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"call",	((0xd << 14)|(4 << 10)|0), 1, {OP_LABEL,OP_NONE}},
	{"ret",		((0xe << 14)|(0 << 10)|0), 0, {OP_NONE, OP_NONE}},
	{"iret",	((0xe << 14)|(4 << 10)|0), 0, {OP_NONE, OP_NONE}},
	{"importi",	((0xf << 14)|(0 << 10)|3), 2, {OP_REGD, OP_REGB}},
	{"inpi",	((0xf << 14)|(0 << 10)|3), 2, {OP_REGD, OP_REGB}},
	{"exporti",	((0xf << 14)|(0 << 10)|2), 2, {OP_REGD, OP_REGB}},
	{"outpi",	((0xf << 14)|(0 << 10)|2), 2, {OP_REGD, OP_REGB}},
	{"import",	((0xf << 14)|(0 << 10)|1), 2, {OP_REGD, OP_PORT}},
	{"inp",		((0xf << 14)|(0 << 10)|1), 2, {OP_REGD, OP_PORT}},
	{"export",	((0xf << 14)|(0 << 10)|0), 2, {OP_REGD, OP_PORT}},
	{"outp",	((0xf << 14)|(0 << 10)|0), 2, {OP_REGD, OP_PORT}},
	{"lspi",	((0xf << 14)|(0 << 10)|7), 2, {OP_REGD, OP_REGB}},
	{"sspi",	((0xf << 14)|(0 << 10)|6), 2, {OP_REGD, OP_REGB}},
	{"lsp",		((0xf << 14)|(0 << 10)|5), 2, {OP_REGD, OP_PORT}},
	{"ssp",		((0xf << 14)|(0 << 10)|4), 2, {OP_REGD, OP_PORT}},	
	{"nop",		((0x4 << 14)|(0 << 10)|0), 0, {OP_NONE, OP_NONE}}
};

#define ITAB_SIZE sizeof(itab_array)/sizeof(itab)

#if !defined(stricmp)
/* case independent string compare */
int stricmp(const char *s1, const char *s2)
{
	while (*s1 && *s2) {
		if (toupper(*s1) != toupper(*s2)) break;
		s1++; s2++;
	}
	return *s1 - *s2;
}
#endif

/* find a symbol a given type & name */
static stab *sym_find(char *name, stypes stype)
{
	stab *curr = sroot;
	
	while (curr) {
		if (!strcmp(curr->name,name) && 
		    curr->stype == stype) {
			return curr;
		}
		curr = curr->next;
	}
	return NULL;
}

/* add a symbol into the table */
static stab *sym_insert(char *name, int loc, stypes stype)
{
	stab *snew = (stab *) malloc(sizeof(stab));
	
	snew->name = (char *) strdup(name);
	snew->loc_counter = loc;
	snew->codep = NULL;
	snew->stype = stype;
	snew->next  = NULL;
	if (!sroot) {
		sroot = snew;
	} else {
		snew->next = sroot;
		sroot = snew;
	}
	return snew;
}

static code *code_insert(itab *itabp, uint32 opcode, 
			 uint32 rd,   uint32 rb, 
			 uint32 konst,stab  *label_r, 
			 stab  *label_d, int port, uint32 flags)
{
	code *cnew = (code *) malloc(sizeof(code));
	
	cnew->itabp  = itabp;
	cnew->opcode = opcode;
	cnew->rd     = rd;
	cnew->rb     = rb;
	cnew->konst  = konst;
	cnew->label_ref  = label_r;
	cnew->label_def  = label_d;
	cnew->loc_counter= (flags & CODE_ISLDEF ? loc_counter : loc_counter++);
	cnew->port   = port;
	cnew->line_no = line_no;
	cnew->next   = NULL;
	cnew->flags  = flags;

	if (croot == NULL) {
		croot = cnew;
		ccurr = croot;
	} else {
		ccurr->next = cnew;
		ccurr = cnew;
	}
	return cnew;
}
 
static itab *itab_find(char *iname)
{
	int i = 0 ;

	for (i = 0 ; i < ITAB_SIZE ; i++ ) {
		if (!stricmp(iname,itab_array[i].opname))
			return &itab_array[i];
	}
	return NULL;
}

void error_exit(char *err_txt,...)
{
	va_list ap;
	
	va_start(ap,err_txt);
	fprintf(stderr,"%s (%d) ",ifilename,line_no);
	vfprintf(stderr,err_txt,ap);
	fprintf(stderr,"\n\n");
	va_end(ap);

	exit(0);
}

static int get_token(char *buff, char *delims)
{
	char nc = GETC();
	do {
		*buff++ = nc;
		nc = GETC();
	} while (!isspace(nc) && !strchr(delims,nc) && nc);
	*buff = '\0';	
	return nc;
}

static int skip_space()
{
	char nc ;

	do {
		nc = GETC();
	} while (isspace(nc) && nc && nc != '\n');
	UNGETC();
	return nc;
}

static char *get_line()
{
	if (feof(infile)) return NULL;
	lbp = line_buffer;
	line_no++;
	return fgets(line_buffer,MAX_LINE_SIZE,infile);
}

/* parse .data directive format is
   .data <constant> */
static void dparse_data()
{
	char nc = skip_space();
	uint32 val;
	code *codep;

	val = parse_const();
	if (val & ~0x3FFFF) {
		error_exit(".data value cannot exceed 0x3ffff, value is 0x%X",val);
	}
	codep = code_insert( NULL, val, 0, 0, 0, NULL, NULL, 0, CODE_ISDATA);
}

/* parse .equ directive. the format is
         .equ <name>,<value> */
static void dparse_equ()
{
	char nc = skip_space();
	int value ;
	stab *sym;

	nc = get_token(token,",");
	UNGETC();
	nc = skip_space();
	if (nc != ',') {
		error_exit("invalid syntax for equate. expecting ','");
	}
	GETC(); /* skip the , */
	skip_space();
	value = parse_const();
	if ((sym = sym_find(token,SYM_EQU))) {
		error_exit("redifinition of .equ symbol %s",token);
	}
	sym = sym_insert(token,-1,SYM_EQU);
	sym->value = value;
}

/* parse .org directive : followed by a number */
static void dparse_org()
{
	char nc = skip_space();
	uint32 new_loc = parse_const();
	
	if (new_loc < loc_counter) {
		error_exit(".org overlays previous code; curr pc %d , new pc %d",
			   loc_counter, new_loc);
	}
	loc_counter = new_loc;
}

/* parse assembler directives */
static void parse_direct()
{
	int i;
	get_token(token,"\n,");

	for (i = 0; i < DIRTAB_SIZE; i++) {
		if (!stricmp(dirtab_array[i].dname,token)) {
			(*dirtab_array[i].dparse_func)();
			return ;
		}
	}
	error_exit("unrecognized directive %s",token);
}

/* parse label definition */
static stab *parse_label_def(char *label)
{
	stab *stabp;

	if (!(stabp = sym_find(label,SYM_LABEL))) {
		stabp = sym_insert(label, loc_counter, SYM_LABEL);
	} else if (stabp->loc_counter != -1) {
		error_exit("multiple definition of label %s",label);
	}
	stabp->loc_counter = loc_counter;
	code_insert( NULL, 0, 0, 0, 0, NULL, stabp, 0, CODE_ISLDEF);
	return stabp;
}

/* parse label reference */
static stab *parse_label_ref()
{
	char nc = skip_space();	
	stab *stabp;
	
	get_token(token,"\n");

	/* if !already exists then insert it*/
	if (!(stabp = sym_find(token, SYM_LABEL))) {
		stabp = sym_insert(token, -1, SYM_LABEL);
	}
	return stabp;
}

/* parse a number */
static uint32 parse_num()
{
	char nc = GETC();
	int sign = 0;
	int base = 10;
	int rval = 0;

	if (nc == '+') nc = GETC();
	if (nc == '-') {
		sign = 1;
		nc = GETC();
	}
	if (nc == '0') {
		/* octal */
		base = 8;
		nc = GETC();
		if (toupper(nc) == 'X') {
			/* nope .. hex */
			base = 16;
			nc = GETC();
		} 
	}
	while (isdigit(nc) || isxdigit(toupper(nc))) {
		rval *= base;
		switch (base) {
		case 8:
		case 10:
			rval += (nc - '0');
			break;
		case 16:
			if (toupper(nc) >= 'A') {
				rval += (10 + (toupper(nc) - 'A'));
			} else { 
				rval += nc - '0';
			}
			break;
		}
		nc = GETC();
	} while (isdigit(nc) || isxdigit(nc));

	if (nc != -1) {
		UNGETC();
	}
	if (sign) rval = -rval;
	return rval;
}

/* parse a character constant of the form '<char>' */
static uint32 parse_char()
{
	char nc = GETC();
	assert(nc == '\'');
	
	nc = GETC();
	/* escape character */
	if (nc == '\\') {
		nc = GETC();
		switch (nc) {
		case 'n':
			nc = '\n';
			break;
		case 'r':
			nc = '\r';
			break;

⌨️ 快捷键说明

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