📄 isp8sim.c
字号:
/*
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 : isp8sim.c
// Title : Instruction Set Simulator for Lattice 8 bit microcontroller
//
// Description : This program is the Instruction Set simulator for Lattice 8 bit
// Microcontroller.
//
// Additional info. :
//
// ====================================================================
// Revision History
// ====================================================================
// Ver | Author(s) | Mod. Date| Changes Made
// --------------------------------------------------------------------
// 1.0 | Sandeep Dutta | 04/27/05 | Initial Creation
// $Revision: 1.3 $
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
enum imodes {
IMODE_HEX = 0,
IMODE_BIN ,
};
#define ABS(x) (x < 0 ? -x : x)
static FILE *promf = NULL;
static char *promfname = NULL;
static char linebuff[512];
static int line_no = 0;
static int imode = 0;
static int trace = 0;
static int disa = 0;
static int no_import_text = 0;
static int promsize = 512;
static int *prom;
static int icount = 0;
static int xcount = 0;
static int cpc = 1;
static int carry = 0, zero = 0, ie = 0;
static int carry_i=0, zero_i=0;
static int carry_o=0, zero_o=0;
static int regfile[32];
static int oregfile[32];
static int callstack[16];
static int csp = 0;
static char xsp[256];
static void error_exit(char *err_txt,...)
{
va_list ap;
va_start(ap,err_txt);
fprintf(stderr,"%s (%d) ",promfname,line_no);
vfprintf(stderr,err_txt,ap);
fprintf(stderr,"\n\n");
va_end(ap);
exit(0);
}
static unsigned int read_bin()
{
char *lbp = linebuff;
//char *nc;
unsigned int rval = 0;
while (!isdigit(*lbp) && *lbp) lbp++;
if (!*lbp) return -1;
while (isdigit(*lbp)) {
if (*lbp != '0' && *lbp != '1') {
error_exit("invalid binary character '%c'",*lbp);
}
rval <<= 1;
rval |= ('0' - *lbp);
lbp++;
}
return rval;
}
static unsigned int read_hex()
{
char *lbp = linebuff;
//char *nc;
unsigned int rval = 0;
while (!isxdigit(*lbp) && *lbp) lbp++;
if (!*lbp) return -1;
while (isxdigit(*lbp)) {
rval <<= 4;
if (*lbp <= '9')
rval += ((*lbp) - '0');
else
rval += 10 + (tolower(*lbp) - 'a');
lbp++;
}
return rval;
}
static void load_prom()
{
int ploc = 0;
if (!(prom = (int *)malloc(promsize*sizeof(int)))) {
error_exit("cannot allocate memory for prom size(%d)",promsize);
}
line_no ++;
while (fgets(linebuff,sizeof(linebuff),promf)) {
int val;
line_no ++;
if (imode == IMODE_BIN) {
val = read_bin();
} else if (imode == IMODE_HEX) {
val = read_hex();
}
if (ploc >= promsize) {
error_exit("prom full, increase promsize %d, %d",
ploc, promsize);
}
prom[ploc++] = val;
}
while (ploc < promsize)
prom[ploc++] = 0;
}
static void disass(int cpc, unsigned int instr)
{
int rd = (instr >> 8) & 0x1f;
int rb = (instr >> 3) & 0x1f;
int konst = (instr & 0xff);
int broffset = (instr & 0x3ff);
int iskonst = (instr >> 13) & 1;
int zu = 0;
int grp_code = ((instr >> 14) & 0xf);
int pushpc = 0;
if (instr == 0) return ;
fprintf(stdout,"0x%05X\t0x%05X",cpc,instr & 0x3FFFF);
switch (grp_code) {
case 0: /* sub */
case 1: /* subc */
if (iskonst) {
fprintf(stdout,"\tsubi%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\tsub%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 2: /* add */
case 3: /* addc */
if (iskonst) {
fprintf(stdout,"\taddi%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\tadd%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 4: /* mov */
if (iskonst) {
fprintf(stdout,"\tmovi%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\tmov%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 5: /* and */
if (iskonst) {
fprintf(stdout,"\tandi%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\tand%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 6: /* or */
if (iskonst) {
fprintf(stdout,"\tori%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\tor%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 7: /* xor */
if (iskonst) {
fprintf(stdout,"\txori%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\txor%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 8: /* compare */
if (iskonst) {
fprintf(stdout,"\tcmpi%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\tcmp%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 9: /* test */
if (iskonst) {
fprintf(stdout,"\ttesti%c\tR%02d,0x%02X\n",
(grp_code & 1 ? 'c' : ' '), rd, konst);
} else {
fprintf(stdout,"\ttest%c\tR%02d,R%02d\n",
(grp_code & 1 ? 'c' : ' '), rd, rb);
}
break;
case 10: { /* rotate group */
switch (instr & 0x3) {
case 0: /* ror */
fprintf(stdout,"\tror\tR%02d,R%02d\n", rd, rb);
break;
case 1: /* rol */
fprintf(stdout,"\trol\tR%02d,R%02d\n", rd, rb);
break;
case 2: /* rorc */
fprintf(stdout,"\trorc\tR%02d,R%02d\n", rd, rb);
break;
case 3: /* rolc */
fprintf(stdout,"\trolc\tR%02d,R%02d\n", rd, rb);
break;
}
break;
}
case 11: { /* flag set/clear */
switch (instr & 7) {
case 0:
case 1:
fprintf(stdout,"\t%sc\n",
(instr & 1 ? "set" : "clr"));
break;
case 2:
case 3:
fprintf(stdout,"\t%sz\n",
(instr & 1 ? "set" : "clr"));
break;
case 4:
case 5:
fprintf(stdout,"\t%si\n",
(instr & 1 ? "set" : "clr"));
break;
}
break;
}
case 13:
pushpc = 1;
/* fall thru */
case 12: { /* branch */
char *opname = (pushpc ? "call" : "b");
switch ((instr >> 10) & 0x7) {
case 0:
case 1:
case 2:
case 3:
// bz, bnz, callz, callnz, bc, bnc, callc, callnc
broffset &= 0x3ff;
break;
case 4:
// b, call
broffset &= 0xfff;
break;
default:
// cover hazard
broffset &= 0x3ff;
}
switch ((instr >> 10) & 0x7) {
case 0:
fprintf(stdout,"\t%sz\t%c%d\n",opname,
(broffset < 0 ? '-' : '+'), ABS(broffset));
break;
case 1:
fprintf(stdout,"\t%snz\t%c%d\n",opname,
(broffset < 0 ? '-' : '+'), ABS(broffset));
break;
case 2:
fprintf(stdout,"\t%sc\t%c%d\n",opname,
(broffset < 0 ? '-' : '+'), ABS(broffset));
break;
case 3:
fprintf(stdout,"\t%snc\t%c%d\n",opname,
(broffset < 0 ? '-' : '+'), ABS(broffset));
break;
case 4:
fprintf(stdout,"\t%s\t%c%d\n",opname,
(broffset < 0 ? '-' : '+'), ABS(broffset));
break;
}
break;
}
case 14: /* ret & iret */
if (instr & (4 << 10)) {
fprintf(stdout,"\tiret\n");
} else {
fprintf(stdout,"\tret\n");
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -