📄 isp8sim.c
字号:
case 15: { /* import/export & scratch pad access */
int port = rb;
if (!(instr & 0x4)) { /* import / export */
char *opname = (instr & 1 ? "import" : "export");
if (instr & 2) { /* indirect */
fprintf(stdout,"\t%si\tR%02d,R%02d\n",opname,rd,rb);
} else {
fprintf(stdout,"\t%s\tR%02d,%d\n",opname,rd,rb);
}
} else { /* load/store from/to scratch pad */
char *opname = (instr & 1 ? "lsp" : "ssp");
if (instr & 2) { /* indirect */
fprintf(stdout,"\t%si\tR%02d,R%02d\n",opname,rd,rb);
} else {
fprintf(stdout,"\t%s\tR%02d,%d\n",opname,rd,rb);
}
}
break;
}
default:
fprintf(stderr,"unknown instruction @pc = 0x%x\n",cpc);
break;
}
}
static void disass_prom()
{
int i;
for (i = 0 ; i < promsize ; i++) {
disass(i,prom[i]);
}
}
static void exec_i()
{
unsigned int instr = prom[cpc];
int rd = (instr >> 8) & 0x1f;
int rb = (instr >> 3) & 0x1f;
int konst = (instr & 0xff);
int broffset = (instr & 0xfff);
int iskonst = (instr >> 13) & 1;
int port, zu = 0;
int grp_code = ((instr >> 14) & 0xf);
int tmp;
int cpc_ch = 0;
int pushpc = 0;
port = rb;
if (trace)
disass(cpc, instr);
switch (grp_code) {
case 0: /* sub */
case 1: /* subc */
regfile[rd] -= ((iskonst ? konst : regfile[rb]) + (grp_code & 1 ? carry : 0));
carry = ((regfile[rd] & ~0xff) ? 1 : 0);
zero = (regfile[rd] == 0 ? 1 : 0);
break;
case 2: /* add */
case 3: /* addc */
regfile[rd] += ((iskonst ? konst : regfile[rb]) + (grp_code & 1 ? carry : 0));
carry = ((regfile[rd] & ~0xff) ? 1 : 0);
zero = (regfile[rd] == 0 ? 1 : 0);
break;
case 4: /* mov */
regfile[rd] = (iskonst ? konst : regfile[rb]);
break;
case 5: /* and */
regfile[rd] &= (iskonst ? konst : regfile[rb]);
zero = (regfile[rd] == 0 ? 1 : 0);
break;
case 6: /* or */
regfile[rd] |= (iskonst ? konst : regfile[rb]);
zero = (regfile[rd] == 0 ? 1 : 0);
break;
case 7: /* xor */
regfile[rd] ^= (iskonst ? konst : regfile[rb]);
zero = (regfile[rd] == 0 ? 1 : 0);
break;
case 8: /* compare */
tmp = regfile[rd] - (iskonst ? konst : regfile[rb]);
carry = (( tmp & ~0xff) ? 1 : 0);
zero = ( tmp == 0 ? 1 : 0);
break;
case 9: /* test */
tmp = regfile[rd] & (iskonst ? konst : regfile[rb]);
zero = ( tmp == 0 ? 1 : 0);
break;
case 10: { /* rotate group */
unsigned char rval = regfile[rb] ;
unsigned int rcode = (instr & 0x3);
unsigned oval = rval;
switch (rcode) {
case 0: /* ror */
rval >>= 1;
rval |= (oval & 1 ? 0x80 : 0);
break;
case 1: /* rol */
rval <<= 1;
rval |= (oval & 0x80 ? 1 : 0);
break;
case 2: /* rorc */
rval >>= 1;
rval |= (carry ? 0x80 : 0);
carry = (oval & 1);
break;
case 3: /* rolc */
rval <<= 1;
rval |= (carry ? 1 : 0);
carry = ((oval & 0x80) ? 1 : 0);
break;
}
regfile[rd] = rval & 0xff;
zero = ((rval & 0xff) == 0 ? 1 : 0);
break;
}
case 11: { /* flag set/clear */
switch (instr & 7) {
case 0:
case 1:
carry = instr & 1;
break;
case 2:
case 3:
zero = instr & 1;
break;
case 4:
case 5:
ie = instr & 1;
break;
}
break;
}
case 13:
pushpc = 1;
/* fall thru */
case 12: { /* branch */
/* sign extend */
switch ((instr >> 10) & 0x7) {
case 0:
case 1:
case 2:
case 3:
// bz, bnz, callz, callnz, bc, bnc, callc, callnc
broffset &= 0x3ff;
broffset <<= (32 - 10);
broffset >>= (32 - 10);
break;
case 4:
// b, call
broffset <<= (32 - 12);
broffset >>= (32 - 12);
break;
default:
// cover hazard
broffset &= 0x3ff;
broffset <<= (32 - 10);
broffset >>= (32 - 10);
}
switch ((instr >> 10) & 0x7) {
case 0:
cpc_ch = zero;
break;
case 1:
cpc_ch = !zero;
break;
case 2:
cpc_ch = carry;
break;
case 3:
cpc_ch = !carry;
break;
case 4:
cpc_ch = 1;
break;
}
if (pushpc) {
callstack[csp++] = cpc + 1;
if (csp >= 16) csp = 0;
}
if (cpc_ch) cpc += broffset;
break;
}
case 14: /* ret & iret */
if (instr & (4 << 10)) {
carry = carry_i;
zero = zero_i;
}
cpc_ch = 1;
cpc = callstack[--csp];
if (csp < 0) csp = 0;
break;
case 15: { /* import/export & scratch pad access */
char buffer[32];
char *spp;
spp = xsp;
if (instr & 2) { /* indirect */
port = regfile[rb] & 0xff;
} else {
port = (instr & 0xf8) >> 3;
}
if (!(instr & 0x4)) { /* import / export */
if (instr & 1) { /* import */
if (!no_import_text) {
fprintf(stdout,"input value for port #(%d) : ",port);
fflush(stdout);
fgets(buffer,sizeof(buffer),stdin);
}
regfile[rd] = (unsigned char)strtoul(buffer, NULL, 0);
//regfile[rd] = buffer[0] & 0xff;
} else {
fprintf(stdout,"@%x %02X\n", port, regfile[rd] & 0xff);
/* write to port #0xFF means exit simulator */
if (port == 0xff) exit(0);
}
} else { /* load/store from/to scratch pad */
if (instr & 1)
regfile[rd] = spp[port] & 0xff;
else
spp[port] = regfile[rd] & 0xff;
}
break;
}
default:
fprintf(stderr,"unknown instruction @pc = 0x%x\n",cpc);
break;
}
if (trace) {
int ach = 0;
/* print flags changed */
if (carry_o != carry) {
fprintf(stdout,"\tCY=%d,",carry);
ach++;
}
if (zero_o != zero) {
fprintf(stdout,"\tZR=%d,",zero);
ach++;
}
/* print register changed */
if (oregfile[rd] != regfile[rd]) {
fprintf(stdout,"\tR%02d = 0x%02X",rd, regfile[rd] & 0xFF);
ach++;
}
if (ach) fprintf(stdout,"\n");
}
regfile[rd] &= 0xff;
oregfile[rd] = regfile[rd];
carry_o = carry;
zero_o = zero;
if (!cpc_ch)
cpc++;
}
static void print_help(char *pname)
{
fprintf(stdout,"usage %s: [options] promfilename\n",pname);
fprintf(stdout,"\t-p promsize. (default 512)\n");
fprintf(stdout,"\t-ix promfile is hex (default)\n");
fprintf(stdout,"\t-ib promfile is binary\n");
fprintf(stdout,"\t-t trace instructions\n");
fprintf(stdout,"\t-d disassemble\n");
fprintf(stdout,"\t-h this message\n");
}
static void msg_print(char *pname)
{
fprintf(stdout,"usage %s: [options] promfilename\n",pname);
fprintf(stdout,"\t-p promsize. (default 512)\n");
}
int main(int argc, char *argv[])
{
int i;
if (argc < 2) {
print_help(argv[0]);
exit(-1);
}
for (i = 1; i < argc ; i++ ) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'h':
print_help(argv[0]);
exit(-1);
case 'i':
if (argv[i][2] == 'x') {
imode = IMODE_HEX;
} else if (argv[i][2] == 'b') {
imode = IMODE_BIN;
}
break;
case 'p':
i++;
if (sscanf(argv[i],"%d",&promsize) != 1) {
fprintf(stdout,"invalid promsize %s\n",argv[i]);
exit(-1);
}
break;
case 'd':
disa = 1;
break;
case 't':
trace = 1;
break;
case 'n':
no_import_text = 1;
break;
default:
fprintf(stdout,"invalid option %s\n",argv[i]);
print_help(argv[0]);
exit(-1);
}
} else {
/* assume it is promfile name */
promfname = strdup(argv[i]);
if (!(promf = fopen(promfname,"r"))) {
error_exit("cannot open promfile %s",promfname);
}
}
}
load_prom();
memset(regfile,0,sizeof(regfile));
memset(oregfile,0,sizeof(oregfile));
if (disa) {
disass_prom();
exit(0);
}
while (1) {
exec_i();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -