Updated to support P2 FPGA v32b
This commit is contained in:
parent
56e4571636
commit
1b0c107390
|
@ -1,6 +1,6 @@
|
||||||
Spinsim 0.97
|
Spinsim 0.98
|
||||||
|
|
||||||
This version of spinsim supports most of the opcodes in the P2 v20 instruction
|
This version of spinsim supports most of the opcodes in the P2 v32a instruction
|
||||||
set. The opcodes that are not supported are as follows:
|
set. The opcodes that are not supported are as follows:
|
||||||
|
|
||||||
xzero xinit xcont clkset setdacs setxfrq getxcos getxsin
|
xzero xinit xcont clkset setdacs setxfrq getxcos getxsin
|
||||||
|
|
66
disasm2.c
66
disasm2.c
|
@ -32,9 +32,9 @@ static char *group1[] = {
|
||||||
"cmp", "cmpx", "cmps", "cmpsx", "cmpr", "cmpm", "subr", "cmpsub",
|
"cmp", "cmpx", "cmps", "cmpsx", "cmpr", "cmpm", "subr", "cmpsub",
|
||||||
"fge", "fle", "fges", "fles", "sumc", "sumnc", "sumz", "sumnz",
|
"fge", "fle", "fges", "fles", "sumc", "sumnc", "sumz", "sumnz",
|
||||||
"bitl", "bith", "bitc", "bitnc", "bitz", "bitnz", "bitrnd", "bitnot",
|
"bitl", "bith", "bitc", "bitnc", "bitz", "bitnz", "bitrnd", "bitnot",
|
||||||
"andn", "and", "or", "xor", "muxc", "muxnc", "muxz", "muxnz",
|
"and", "andn", "or", "xor", "muxc", "muxnc", "muxz", "muxnz",
|
||||||
"mov", "not", "abs", "neg", "negc", "negnc", "negz", "negnz",
|
"mov", "not", "abs", "neg", "negc", "negnc", "negz", "negnz",
|
||||||
"incmod", "decmod", "encod", "invalid", "testn", "test", "anyb", "invalid"};
|
"incmod", "decmod", "zerox", "signx", "encod", "ones", "test", "testn"};
|
||||||
|
|
||||||
static char *group2[] = {
|
static char *group2[] = {
|
||||||
"setnib", "setnib", "setnib", "setnib", "setnib", "setnib", "setnib", "setnib",
|
"setnib", "setnib", "setnib", "setnib", "setnib", "setnib", "setnib", "setnib",
|
||||||
|
@ -44,15 +44,14 @@ static char *group2[] = {
|
||||||
"rolbyte", "rolbyte", "rolbyte", "rolbyte", "setword", "setword", "getword", "getword",
|
"rolbyte", "rolbyte", "rolbyte", "rolbyte", "setword", "setword", "getword", "getword",
|
||||||
"rolword", "rolword", "altsn", "altgn", "altsb", "altgb", "altsw", "altgw",
|
"rolword", "rolword", "altsn", "altgn", "altsb", "altgb", "altsw", "altgw",
|
||||||
"altr", "altd", "alts", "altb", "alti", "setr", "setd", "sets",
|
"altr", "altd", "alts", "altb", "alti", "setr", "setd", "sets",
|
||||||
"decod", "bmask", "zerox", "signx", "muxnits", "muxnibs", "muxq", "movbyts",
|
"decod", "bmask", "crcbit", "crcnib", "muxnits", "muxnibs", "muxq", "movbyts",
|
||||||
"mul", "mul", "muls", "muls", "sclu", "sclu", "scl", "scl",
|
"mul", "mul", "muls", "muls", "sca", "sca", "scas", "scas",
|
||||||
"addpix", "mulpix", "blnpix", "mixpix", "addct1", "addct2", "addct3", "wmlong",
|
"addpix", "mulpix", "blnpix", "mixpix", "addct1", "addct2", "addct3", "wmlong",
|
||||||
"rqpin", "rdpin", "rqpin", "rdpin", "rdlut", "rdlut", "rdlut", "rdlut",
|
"rqpin", "rdpin", "rqpin", "rdpin", "rdlut", "rdlut", "rdlut", "rdlut",
|
||||||
"rdbyte", "rdbyte", "rdbyte", "rdbyte", "rdword", "rdword", "rdword", "rdword",
|
"rdbyte", "rdbyte", "rdbyte", "rdbyte", "rdword", "rdword", "rdword", "rdword",
|
||||||
"rdlong", "rdlong", "rdlong", "rdlong", "calld", "calld", "calld", "calld",
|
"rdlong", "rdlong", "rdlong", "rdlong", "calld", "calld", "calld", "calld",
|
||||||
"ijz", "ijnz", "ijs", "ijns", "djz", "djnz", "djs", "djns",
|
"callpa", "callpa", "callpb", "callpb", "djz", "djnz", "djf", "djnf",
|
||||||
"tjz", "tjnz", "tjs", "tjns", "invalid", "invalid", "invalid", "invalid",
|
"ijz", "ijnz", "tjz", "tjnz", "tjf", "tjnf", "tjs", "tjns", "tjv"};
|
||||||
"callpa", "callpa", "callpb", "callpb"};
|
|
||||||
|
|
||||||
static char *group3[] = {
|
static char *group3[] = {
|
||||||
"jint", "jct1", "jct2", "jct3", "jse1", "jse2", "jse3", "jse4",
|
"jint", "jct1", "jct2", "jct3", "jse1", "jse2", "jse3", "jse4",
|
||||||
|
@ -68,10 +67,10 @@ static char *group5[] = {
|
||||||
"qmul", "qdiv", "qfrac", "qsqrt", "qrotate", "qvector"};
|
"qmul", "qdiv", "qfrac", "qsqrt", "qrotate", "qvector"};
|
||||||
|
|
||||||
static char *group6[] = {
|
static char *group6[] = {
|
||||||
"clkset", "cogid", "invalid", "cogstop", "locknew", "lockret", "lockclr", "lockset",
|
"hubset", "cogid", "invalid", "cogstop", "locknew", "lockret", "locktry", "lockrel",
|
||||||
"invalid", "invalid", "invalid", "invalid", "invalid", "invalid", "qlog", "qexp",
|
"invalid", "invalid", "invalid", "invalid", "invalid", "invalid", "qlog", "qexp",
|
||||||
"rfbyte", "rfword", "rflong", "wfbyte", "wfword", "wflong", "setq", "setq2",
|
"rfbyte", "rfword", "rflong", "rfvar", "rfvars", "wfbyte", "wfword", "wflong",
|
||||||
"getqx", "getqy", "getct", "getrnd", "setdacs", "setxfrq", "getxcos", "getxsin",
|
"getqx", "getqy", "getct", "getrnd", "setdacs", "setxfrq", "getxacc", "waitx",
|
||||||
"setse1", "setse2", "setse3", "setse4"};
|
"setse1", "setse2", "setse3", "setse4"};
|
||||||
|
|
||||||
static char immd6[] = {
|
static char immd6[] = {
|
||||||
|
@ -90,16 +89,15 @@ static char *group7[] = {
|
||||||
|
|
||||||
static char *group8[] = {
|
static char *group8[] = {
|
||||||
"setint1", "setint2", "setint3",
|
"setint1", "setint2", "setint3",
|
||||||
"waitx", "invalid", "push", "pop", "jmp", "call", "calla", "callb",
|
"setq", "setq2", "push", "pop", "jmp", "call", "calla", "callb",
|
||||||
"jmprel", "skip", "skipf", "execf", "getptr", "getint", "setbrk", "setluts",
|
"jmprel", "skip", "skipf", "execf", "getptr", "getbrk", "brk", "setluts",
|
||||||
"setcy", "setci", "setcq", "setcfrq", "setcmod", "setpix", "setpiv", "cogatn",
|
"setcy", "setci", "setcq", "setcfrq", "setcmod", "setpix", "setpiv", "cogatn",
|
||||||
"dirl", "dirh", "dirc", "dirnc", "dirz", "dirnz", "dirrnd", "dirnot",
|
"dirl", "dirh", "dirc", "dirnc", "dirz", "dirnz", "dirrnd", "dirnot",
|
||||||
"outl", "outh", "outc", "outnc", "outz", "outnz", "outrnd", "outnot",
|
"outl", "outh", "outc", "outnc", "outz", "outnz", "outrnd", "outnot",
|
||||||
"fltl", "flth", "fltc", "fltnc", "fltz", "fltnz", "fltrnd", "fltnot",
|
"fltl", "flth", "fltc", "fltnc", "fltz", "fltnz", "fltrnd", "fltnot",
|
||||||
"drvl", "drvh", "drvc", "drvnc", "drvz", "drvnz", "drvrnd", "drvnot",
|
"drvl", "drvh", "drvc", "drvnc", "drvz", "drvnz", "drvrnd", "drvnot",
|
||||||
"splitb", "mergeb", "splitw", "mergew", "seussf", "seussr", "rgbsqz", "rgbexp",
|
"splitb", "mergeb", "splitw", "mergew", "seussf", "seussr", "rgbsqz", "rgbexp",
|
||||||
"xoro32", "rev", "rczr", "rczl", "wrc", "wrnc", "wrz", "wrnz",
|
"xoro32", "rev", "rczr", "rczl", "wrc", "wrnc", "wrz", "wrnz"};
|
||||||
"rfvar", "rfvars"};
|
|
||||||
|
|
||||||
static char immd8[] = {
|
static char immd8[] = {
|
||||||
1, 1, 1,
|
1, 1, 1,
|
||||||
|
@ -111,8 +109,7 @@ static char immd8[] = {
|
||||||
7, 7, 7, 7, 7, 7, 7, 7,
|
7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
7, 7, 7, 7, 7, 7, 7, 7,
|
7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 6, 6, 0, 0, 0, 0,
|
0, 0, 6, 6, 0, 0, 0, 0};
|
||||||
6, 6};
|
|
||||||
|
|
||||||
|
|
||||||
static char *group9[] = {
|
static char *group9[] = {
|
||||||
|
@ -168,7 +165,7 @@ char *GetOpname2(unsigned int instr, int *pczi, int *pformat, int *perrflag)
|
||||||
strcpy(name, group1[opcode]);
|
strcpy(name, group1[opcode]);
|
||||||
*pczi = 6;
|
*pczi = 6;
|
||||||
}
|
}
|
||||||
else if (opcode <= 0x5e)
|
else if (opcode < 0x5e)
|
||||||
{
|
{
|
||||||
int index = ((opcode - 0x40) << 2) + czflags;
|
int index = ((opcode - 0x40) << 2) + czflags;
|
||||||
if (index < 24)
|
if (index < 24)
|
||||||
|
@ -191,22 +188,38 @@ char *GetOpname2(unsigned int instr, int *pczi, int *pformat, int *perrflag)
|
||||||
else
|
else
|
||||||
*pczi = 0;
|
*pczi = 0;
|
||||||
}
|
}
|
||||||
else if (opcode == 0x5f)
|
else if (opcode == 0x5e)
|
||||||
{
|
{
|
||||||
if (cflag == 0)
|
if (cflag == 0)
|
||||||
{
|
{
|
||||||
if (dfield > 0x1f)
|
if (zflag)
|
||||||
strcpy(name, "invalid");
|
{
|
||||||
|
if (dfield > 0x1f)
|
||||||
|
strcpy(name, "invalid");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(name, group3[dfield]);
|
||||||
|
if (!zflag)
|
||||||
|
*perrflag = OPCODE_BAD_BITS;
|
||||||
|
}
|
||||||
|
*pformat = OP_ONEREL9;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(name, group3[dfield]);
|
strcpy(name, "tjv");
|
||||||
if (!zflag)
|
*pformat = OP_TWOREL9;
|
||||||
*perrflag = OPCODE_BAD_BITS;
|
|
||||||
}
|
}
|
||||||
*pformat = OP_ONEREL9;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
strcpy(name, "invalid");
|
||||||
|
*pczi = 0;
|
||||||
|
}
|
||||||
|
else if (opcode == 0x5f)
|
||||||
|
{
|
||||||
|
if (cflag)
|
||||||
strcpy(name, group4);
|
strcpy(name, group4);
|
||||||
|
else
|
||||||
|
strcpy(name, "invalid");
|
||||||
*pczi = 0;
|
*pczi = 0;
|
||||||
}
|
}
|
||||||
else if (opcode <= 0x6a)
|
else if (opcode <= 0x6a)
|
||||||
|
@ -282,7 +295,7 @@ char *GetOpname2(unsigned int instr, int *pczi, int *pformat, int *perrflag)
|
||||||
strcpy(name, "modcz");
|
strcpy(name, "modcz");
|
||||||
*pczi = 6;
|
*pczi = 6;
|
||||||
}
|
}
|
||||||
else if (sfield > 0x71)
|
else if (sfield > 0x6f)
|
||||||
{
|
{
|
||||||
strcpy(name, "invalid");
|
strcpy(name, "invalid");
|
||||||
*pczi = 0;
|
*pczi = 0;
|
||||||
|
@ -359,6 +372,7 @@ int InvalidAddress(int hubmode, int pc, int offset)
|
||||||
invalid = (target < 0 || target >= 0x400);
|
invalid = (target < 0 || target >= 0x400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return invalid;
|
return invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +450,7 @@ void Disassemble2(int32_t instruct, int32_t pc, char *outstr, int *perrflag)
|
||||||
}
|
}
|
||||||
|
|
||||||
dflag = ((czi & 1) && (opcode == 0x6b)) ||
|
dflag = ((czi & 1) && (opcode == 0x6b)) ||
|
||||||
((czi & 2) && (opcode == 0x5d || opcode == 0x5e || (opcode == 0x5f && (czi & 4)) || (opcode >= 0x60 && opcode <= 0x6a)));
|
((czi & 2) && (opcode == 0x5a || opcode == 0x5e || (opcode == 0x5f && (czi & 4)) || (opcode >= 0x60 && opcode <= 0x6a)));
|
||||||
|
|
||||||
// Check for extended address instructions
|
// Check for extended address instructions
|
||||||
if (opcode >= 0x6c)
|
if (opcode >= 0x6c)
|
||||||
|
|
395
pasmsim2.c
395
pasmsim2.c
|
@ -223,13 +223,13 @@ static int32_t stream_fifo_level(PasmVarsT *pasmvars)
|
||||||
#define INSTR_RFBYTE 0x0d600010
|
#define INSTR_RFBYTE 0x0d600010
|
||||||
#define INSTR_RFWORD 0x0d600011
|
#define INSTR_RFWORD 0x0d600011
|
||||||
#define INSTR_RFLONG 0x0d600012
|
#define INSTR_RFLONG 0x0d600012
|
||||||
#define INSTR_WFBYTE 0x0d600013
|
#define INSTR_WFBYTE 0x0d600015
|
||||||
#define INSTR_WFWORD 0x0d600014
|
#define INSTR_WFWORD 0x0d600016
|
||||||
#define INSTR_WFLONG 0x0d600015
|
#define INSTR_WFLONG 0x0d600017
|
||||||
#define INSTR_GETQX 0x0d600018
|
#define INSTR_GETQX 0x0d600018
|
||||||
#define INSTR_GETQY 0x0d600019
|
#define INSTR_GETQY 0x0d600019
|
||||||
|
#define INSTR_WAITX 0x0d60001f
|
||||||
#define INSTR_WAITXXX 0x0d602024
|
#define INSTR_WAITXXX 0x0d602024
|
||||||
#define INSTR_WAITX 0x0d600028
|
|
||||||
#define OPCODE_WMLONG 0x53
|
#define OPCODE_WMLONG 0x53
|
||||||
#define OPCODE_RDBYTE 0x56
|
#define OPCODE_RDBYTE 0x56
|
||||||
#define OPCODE_RDWORD 0x57
|
#define OPCODE_RDWORD 0x57
|
||||||
|
@ -1975,15 +1975,15 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // andn, and, or, xor, muxxx
|
case 5: // and, andn, or, xor, muxxx
|
||||||
switch (opcode & 7)
|
switch (opcode & 7)
|
||||||
{
|
{
|
||||||
case 0: // andn
|
case 0: // and
|
||||||
result = value1 & (~value2);
|
result = value1 & value2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // and
|
case 1: // andn
|
||||||
result = value1 & value2;
|
result = value1 & (~value2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // or
|
case 2: // or
|
||||||
|
@ -2060,7 +2060,7 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
zflag = (result == 0);
|
zflag = (result == 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // incmod, decmod, encod, testn, test, anyb
|
case 7: // incmod, decmod, zerox, signx, encod, ones, test, testn
|
||||||
switch (opcode & 7)
|
switch (opcode & 7)
|
||||||
{
|
{
|
||||||
case 0: // incmod
|
case 0: // incmod
|
||||||
|
@ -2079,7 +2079,16 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
result = value1 - 1;
|
result = value1 - 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // encod
|
case 2: // zerox
|
||||||
|
result = value1 & ~(0xfffffffe << (value2 & 31));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // signx
|
||||||
|
temp = 31 - (value2 & 31);
|
||||||
|
result = (value1 << temp) >> temp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // encod
|
||||||
cflag = (value2 == 0);
|
cflag = (value2 == 0);
|
||||||
for (result = 31; result > 0; result--)
|
for (result = 31; result > 0; result--)
|
||||||
{
|
{
|
||||||
|
@ -2089,31 +2098,23 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
if (kludge) cflag = result & 1;
|
if (kludge) cflag = result & 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // empty
|
case 5: // ones (was anyb)
|
||||||
NotImplemented(instruct);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4: // testn
|
|
||||||
result = value1 & (~value2);
|
|
||||||
cflag = parity(result);
|
|
||||||
write_czr &= 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5: // test
|
|
||||||
result = value1 & value2;
|
|
||||||
cflag = parity(result);
|
|
||||||
write_czr &= 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6: // anyb
|
|
||||||
result = value1 | value2;
|
result = value1 | value2;
|
||||||
cflag = parity(result);
|
cflag = parity(result);
|
||||||
write_czr &= 6;
|
write_czr &= 6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // empty
|
case 6: // test
|
||||||
NotImplemented(instruct);
|
result = value1 & value2;
|
||||||
break;
|
cflag = parity(result);
|
||||||
|
write_czr &= 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: // testn
|
||||||
|
result = value1 & (~value2);
|
||||||
|
cflag = parity(result);
|
||||||
|
write_czr &= 6;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
zflag = (result == 0);
|
zflag = (result == 0);
|
||||||
break;
|
break;
|
||||||
|
@ -2166,7 +2167,7 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9: // rolbyte, setword, getword, rolword, altxx, setx, decod, bmaks, zerox, signx, muxnits, muxnibs, muxq, movbyts
|
case 9: // rolbyte, setword, getword, rolword, altxx, setx, decod, bmaks, muxnits, muxnibs, muxq, movbyts
|
||||||
write_czr = 1;
|
write_czr = 1;
|
||||||
temp = (instruct >> 16) & 0x18;
|
temp = (instruct >> 16) & 0x18;
|
||||||
switch(opcode&7)
|
switch(opcode&7)
|
||||||
|
@ -2380,7 +2381,7 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // decod, bmask, zerox, signx
|
case 6: // decod, bmask, crcbit, crcnib
|
||||||
write_czr = 1;
|
write_czr = 1;
|
||||||
switch (czi >> 1)
|
switch (czi >> 1)
|
||||||
{
|
{
|
||||||
|
@ -2392,13 +2393,12 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
result = ~(0xfffffffe << (value2 & 0x1f));
|
result = ~(0xfffffffe << (value2 & 0x1f));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // zerox
|
case 2: // crcbit
|
||||||
result = value1 & ~(0xfffffffe << (value2 & 31));
|
NotImplemented(instruct);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // signx
|
case 3: // crcnib
|
||||||
temp = 31 - (value2 & 31);
|
NotImplemented(instruct);
|
||||||
result = (value1 << temp) >> temp;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2470,15 +2470,15 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
|
||||||
zflag = (result == 0);
|
zflag = (result == 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // sclu, scl
|
case 1: // sca, scas
|
||||||
write_czr &= 2;
|
write_czr &= 2;
|
||||||
if (czi&4) // scl
|
if (czi&4) // scas
|
||||||
{
|
{
|
||||||
value1 = (value1 << 16) >> 16;
|
value1 = (value1 << 16) >> 16;
|
||||||
value2 = (value2 << 16) >> 16;
|
value2 = (value2 << 16) >> 16;
|
||||||
result = (value1 * value2) >> 14;
|
result = (value1 * value2) >> 14;
|
||||||
}
|
}
|
||||||
else // sclu
|
else // sca
|
||||||
{
|
{
|
||||||
value1 &= 0xffff;
|
value1 &= 0xffff;
|
||||||
value2 &= 0xffff;
|
value2 &= 0xffff;
|
||||||
|
@ -2705,77 +2705,7 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
check_hubexec_mode(pasmvars);
|
check_hubexec_mode(pasmvars);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // ijz, ijnz, ijs, ijns
|
case 2: // callpa, callpb
|
||||||
write_czr = 1;
|
|
||||||
result = value1 + 1;
|
|
||||||
zflag = (result == 0);
|
|
||||||
cflag = (result == 0);
|
|
||||||
// Determine if we should jump
|
|
||||||
if (czi & 4) // ijs, ijns
|
|
||||||
{
|
|
||||||
if (((result >> 31) & 1) != ((czi >> 1) & 1))
|
|
||||||
{
|
|
||||||
value2 = (value2 << 23) >> 23;
|
|
||||||
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
|
||||||
pasmvars->pc1 |= INVALIDATE_INSTR;
|
|
||||||
check_hubexec_mode(pasmvars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // ijz, ijnz
|
|
||||||
{
|
|
||||||
if (zflag != ((czi >> 1) & 1))
|
|
||||||
{
|
|
||||||
value2 = (value2 << 23) >> 23;
|
|
||||||
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
|
||||||
pasmvars->pc1 |= INVALIDATE_INSTR;
|
|
||||||
check_hubexec_mode(pasmvars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: // djz, djnz, djs, djns
|
|
||||||
case 4: // tjz, tjnz, tjs, tjns
|
|
||||||
if ((opcode & 7) == 3)
|
|
||||||
{
|
|
||||||
value1--;
|
|
||||||
cflag = (value1 == -1);
|
|
||||||
write_czr = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_czr = 0;
|
|
||||||
}
|
|
||||||
result = value1;
|
|
||||||
zflag = (result == 0);
|
|
||||||
// Determine if we should jump
|
|
||||||
if (czi & 4) // djs, djns, tjs, tjns
|
|
||||||
{
|
|
||||||
if (((result >> 31) & 1) != ((czi >> 1) & 1))
|
|
||||||
{
|
|
||||||
value2 = (value2 << 23) >> 23;
|
|
||||||
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
|
||||||
pasmvars->pc1 |= INVALIDATE_INSTR;
|
|
||||||
check_hubexec_mode(pasmvars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // djz, djnz, tjz, tjnz
|
|
||||||
{
|
|
||||||
if (zflag != ((czi >> 1) & 1))
|
|
||||||
{
|
|
||||||
value2 = (value2 << 23) >> 23;
|
|
||||||
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
|
||||||
pasmvars->pc1 |= INVALIDATE_INSTR;
|
|
||||||
check_hubexec_mode(pasmvars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5: // empty
|
|
||||||
NotImplemented(instruct);
|
|
||||||
write_czr |= 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6: // callpa, callpb
|
|
||||||
if (czi&4)
|
if (czi&4)
|
||||||
rsltaddr = REG_PB;
|
rsltaddr = REG_PB;
|
||||||
else
|
else
|
||||||
|
@ -2793,11 +2723,91 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
check_hubexec_mode(pasmvars);
|
check_hubexec_mode(pasmvars);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // setpat, jint, jnint, ...
|
case 3: // djz, djnz, djf, djnf
|
||||||
|
value1--;
|
||||||
|
cflag = (value1 == -1);
|
||||||
|
write_czr = 1;
|
||||||
|
result = value1;
|
||||||
|
zflag = (result == 0);
|
||||||
|
// Determine if we should jump
|
||||||
|
if (czi & 4) // djf, djnf
|
||||||
|
{
|
||||||
|
if (cflag != ((czi >> 1) & 1))
|
||||||
|
{
|
||||||
|
value2 = (value2 << 23) >> 23;
|
||||||
|
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
||||||
|
pasmvars->pc1 |= INVALIDATE_INSTR;
|
||||||
|
check_hubexec_mode(pasmvars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // djz, djnz
|
||||||
|
{
|
||||||
|
if (zflag != ((czi >> 1) & 1))
|
||||||
|
{
|
||||||
|
value2 = (value2 << 23) >> 23;
|
||||||
|
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
||||||
|
pasmvars->pc1 |= INVALIDATE_INSTR;
|
||||||
|
check_hubexec_mode(pasmvars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // ijz, ijnz, tjz, tjnz
|
||||||
|
if (czi&4) // tjz, tjnz
|
||||||
|
{
|
||||||
|
write_czr = 0;
|
||||||
|
result = value1;
|
||||||
|
}
|
||||||
|
else // ijz, ijnz
|
||||||
|
{
|
||||||
|
write_czr = 1;
|
||||||
|
result = value1 + 1;
|
||||||
|
}
|
||||||
|
zflag = (result == 0);
|
||||||
|
cflag = (result == 0);
|
||||||
|
// Determine if we should jump
|
||||||
|
if (zflag != ((czi >> 1) & 1))
|
||||||
|
{
|
||||||
|
value2 = (value2 << 23) >> 23;
|
||||||
|
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
||||||
|
pasmvars->pc1 |= INVALIDATE_INSTR;
|
||||||
|
check_hubexec_mode(pasmvars);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: // tjf, tjnf, tjs, tjns
|
||||||
write_czr = 0;
|
write_czr = 0;
|
||||||
if (czi&4) // setpat
|
result = value1;
|
||||||
|
zflag = (result == 0);
|
||||||
|
cflag = (result == -1);
|
||||||
|
// Determine if we should jump
|
||||||
|
if (czi & 4) // tjs, tjns
|
||||||
|
{
|
||||||
|
if (((result >> 31) & 1) != ((czi >> 1) & 1))
|
||||||
|
{
|
||||||
|
value2 = (value2 << 23) >> 23;
|
||||||
|
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
||||||
|
pasmvars->pc1 |= INVALIDATE_INSTR;
|
||||||
|
check_hubexec_mode(pasmvars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // tjf, tjnf
|
||||||
|
{
|
||||||
|
if (cflag != ((czi >> 1) & 1))
|
||||||
|
{
|
||||||
|
value2 = (value2 << 23) >> 23;
|
||||||
|
pasmvars->pc = (pc + pc_incr * (1 + value2)) & ADDR_MASK;
|
||||||
|
pasmvars->pc1 |= INVALIDATE_INSTR;
|
||||||
|
check_hubexec_mode(pasmvars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: // tjv, jint, jnint, ...
|
||||||
|
write_czr = 0;
|
||||||
|
if ((czi&6) == 0) // tjv
|
||||||
NotImplemented(instruct);
|
NotImplemented(instruct);
|
||||||
else // jint, jnint, ....
|
else if ((czi&6) == 2) // jint, jnint, ....
|
||||||
{
|
{
|
||||||
temp = (value1 & 15);
|
temp = (value1 & 15);
|
||||||
temp = (pasmvars->intflags >> temp) & 1;
|
temp = (pasmvars->intflags >> temp) & 1;
|
||||||
|
@ -2815,6 +2825,16 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
check_hubexec_mode(pasmvars);
|
check_hubexec_mode(pasmvars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // empty
|
||||||
|
NotImplemented(instruct);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: // setpat
|
||||||
|
write_czr = 0;
|
||||||
|
if (czi&4) // setpat
|
||||||
|
NotImplemented(instruct);
|
||||||
|
else // empty
|
||||||
|
NotImplemented(instruct);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
case 0: // rdbyte
|
case 0: // rdbyte
|
||||||
|
@ -3198,8 +3218,7 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
if (srcaddr == 0x24) srcaddr = (instruct & 0x3ffff);
|
if (srcaddr == 0x24) srcaddr = (instruct & 0x3ffff);
|
||||||
switch (srcaddr)
|
switch (srcaddr)
|
||||||
{
|
{
|
||||||
case 0: // clkset
|
case 0: // hubset - TODO Need to implement. Ignore for now.
|
||||||
NotImplemented(instruct);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // cogid
|
case 1: // cogid
|
||||||
|
@ -3249,18 +3268,35 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
lockalloc[result] = 0;
|
lockalloc[result] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // lockclr
|
case 6: // locktry
|
||||||
result = value1 & 15;
|
result = value1 & 15;
|
||||||
zflag = (result == 0);
|
zflag = (result == 0);
|
||||||
cflag = lockstate[result] & 1;
|
if (!lockstate[result])
|
||||||
lockstate[result] = 0;
|
{
|
||||||
|
cflag = 1;
|
||||||
|
lockstate[result] = 0x100 | pasmvars->cogid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cflag = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // lockset
|
case 7: // lockrel
|
||||||
result = value1 & 15;
|
zflag = 0;
|
||||||
zflag = (result == 0);
|
temp = value1 & 15;
|
||||||
cflag = lockstate[result] & 1;
|
result = lockstate[temp] & 15;
|
||||||
lockstate[result] = -1;
|
cflag = (lockstate[temp] != 0);
|
||||||
|
if (cflag && result == pasmvars->cogid)
|
||||||
|
{
|
||||||
|
cflag = 0;
|
||||||
|
lockstate[result] = 0;
|
||||||
|
}
|
||||||
|
write_czr &= 6;
|
||||||
|
if ((czi&4) == 0)
|
||||||
|
write_czr = 0;
|
||||||
|
else if (czi&1)
|
||||||
|
write_czr = 4;
|
||||||
|
else
|
||||||
|
write_czr = 5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 14: // qlog
|
case 14: // qlog
|
||||||
|
@ -3308,47 +3344,51 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
zflag = (result == 0);
|
zflag = (result == 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 19: // wfbyte
|
case 19: // rfvar
|
||||||
|
result = temp = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result |= read_stream_fifo_byte(pasmvars) << temp;
|
||||||
|
temp += 7;
|
||||||
|
} while ((temp < 28) && (result & (1 << temp)));
|
||||||
|
cflag = 0;
|
||||||
|
zflag = (result == 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 20: // rfvars
|
||||||
|
result = temp = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result |= read_stream_fifo_byte(pasmvars) << temp;
|
||||||
|
temp += 7;
|
||||||
|
} while ((temp < 28) && (result & (1 << temp)));
|
||||||
|
temp = 31 - temp;
|
||||||
|
result = (result << temp) >> temp;
|
||||||
|
cflag = (result >> 31) & 1;
|
||||||
|
zflag = (result == 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 21: // wfbyte
|
||||||
write_czr = 0;
|
write_czr = 0;
|
||||||
write_stream_fifo_byte(pasmvars, value1);
|
write_stream_fifo_byte(pasmvars, value1);
|
||||||
if (pasmvars->printflag > 1)
|
if (pasmvars->printflag > 1)
|
||||||
fprintf(tracefile, ", fifo = %2.2x", value1);
|
fprintf(tracefile, ", fifo = %2.2x", value1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 20: // wfword
|
case 22: // wfword
|
||||||
write_czr = 0;
|
write_czr = 0;
|
||||||
write_stream_fifo_word(pasmvars, value1);
|
write_stream_fifo_word(pasmvars, value1);
|
||||||
if (pasmvars->printflag > 1)
|
if (pasmvars->printflag > 1)
|
||||||
fprintf(tracefile, ", fifo = %4.4x", value1);
|
fprintf(tracefile, ", fifo = %4.4x", value1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 21: // wflong
|
case 23: // wflong
|
||||||
write_czr = 0;
|
write_czr = 0;
|
||||||
write_stream_fifo_long(pasmvars, value1);
|
write_stream_fifo_long(pasmvars, value1);
|
||||||
if (pasmvars->printflag > 1)
|
if (pasmvars->printflag > 1)
|
||||||
fprintf(tracefile, ", fifo = %8.8x", value1);
|
fprintf(tracefile, ", fifo = %8.8x", value1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 22: // setq
|
|
||||||
write_czr &= 6;
|
|
||||||
pasmvars->qreg = value1;
|
|
||||||
pasmvars->memflag = 1;
|
|
||||||
pasmvars->phase = 0;
|
|
||||||
pasmvars->skip_mask >>= 1;
|
|
||||||
//printf("qreg = %d\n", value1);
|
|
||||||
return breakflag;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 23: // setq2
|
|
||||||
write_czr &= 6;
|
|
||||||
pasmvars->qreg = value1;
|
|
||||||
pasmvars->memflag = 2;
|
|
||||||
pasmvars->phase = 0;
|
|
||||||
pasmvars->skip_mask >>= 1;
|
|
||||||
//printf("qreg = %d\n", value1);
|
|
||||||
return breakflag;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 24: // getqx
|
case 24: // getqx
|
||||||
pasmvars->qxposted = 0;
|
pasmvars->qxposted = 0;
|
||||||
result = pasmvars->qxreg;
|
result = pasmvars->qxreg;
|
||||||
|
@ -3375,12 +3415,12 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
NotImplemented(instruct);
|
NotImplemented(instruct);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30: // getxcos
|
case 30: // getxacc
|
||||||
NotImplemented(instruct);
|
NotImplemented(instruct);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 31: // getxsin
|
case 31: // waitx
|
||||||
NotImplemented(instruct);
|
write_czr &= 6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32: // setse1
|
case 32: // setse1
|
||||||
|
@ -3482,8 +3522,24 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
write_czr &= 6;
|
write_czr &= 6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // waitx
|
case 40: // setq
|
||||||
write_czr &= 6;
|
write_czr &= 6;
|
||||||
|
pasmvars->qreg = value1;
|
||||||
|
pasmvars->memflag = 1;
|
||||||
|
pasmvars->phase = 0;
|
||||||
|
pasmvars->skip_mask >>= 1;
|
||||||
|
//printf("qreg = %d\n", value1);
|
||||||
|
return breakflag;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 41: // setq2
|
||||||
|
write_czr &= 6;
|
||||||
|
pasmvars->qreg = value1;
|
||||||
|
pasmvars->memflag = 2;
|
||||||
|
pasmvars->phase = 0;
|
||||||
|
pasmvars->skip_mask >>= 1;
|
||||||
|
//printf("qreg = %d\n", value1);
|
||||||
|
return breakflag;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // push
|
case 42: // push
|
||||||
|
@ -3632,6 +3688,7 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
zflag = (result = 0);
|
zflag = (result = 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
case 53: // getint
|
case 53: // getint
|
||||||
result = pasmvars->intflags;
|
result = pasmvars->intflags;
|
||||||
result |= (pasmvars->intstate & 2) << 15;
|
result |= (pasmvars->intstate & 2) << 15;
|
||||||
|
@ -3640,8 +3697,16 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
result |= (pasmvars->intstate & 8) << 18;
|
result |= (pasmvars->intstate & 8) << 18;
|
||||||
zflag = (result = 0);
|
zflag = (result = 0);
|
||||||
break;
|
break;
|
||||||
|
#else
|
||||||
|
case 53: // getbrk, cogbrk
|
||||||
|
if (czi & 6) // getbrk
|
||||||
|
NotImplemented(instruct);
|
||||||
|
else // cogbrk
|
||||||
|
NotImplemented(instruct);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case 54: // setbrk
|
case 54: // brk
|
||||||
NotImplemented(instruct);
|
NotImplemented(instruct);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -4338,30 +4403,6 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
|
||||||
result = zflag ^ 1;
|
result = zflag ^ 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 112: // rfvar
|
|
||||||
result = temp = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result |= read_stream_fifo_byte(pasmvars) << temp;
|
|
||||||
temp += 7;
|
|
||||||
} while ((temp < 28) && (result & (1 << temp)));
|
|
||||||
cflag = 0;
|
|
||||||
zflag = (result == 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 113: // rfvars
|
|
||||||
result = temp = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result |= read_stream_fifo_byte(pasmvars) << temp;
|
|
||||||
temp += 7;
|
|
||||||
} while ((temp < 28) && (result & (1 << temp)));
|
|
||||||
temp = 31 - temp;
|
|
||||||
result = (result << temp) >> temp;
|
|
||||||
cflag = (result >> 31) & 1;
|
|
||||||
zflag = (result == 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NotImplemented(instruct);
|
NotImplemented(instruct);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
' Author: Dave Hein
|
' Author: Dave Hein
|
||||||
' Version 0.97
|
' Version 0.98
|
||||||
' Copyright (c) 2010 - 2017
|
' Copyright (c) 2010 - 2018
|
||||||
' See end of file for terms of use.
|
' See end of file for terms of use.
|
||||||
'******************************************************************************/
|
'******************************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -99,7 +99,7 @@ void spinsim_exit(int32_t exitcode)
|
||||||
|
|
||||||
void usage(void)
|
void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Spinsim Version 0.97\n");
|
fprintf(stderr, "Spinsim Version 0.98\n");
|
||||||
fprintf(stderr, "usage: spinsim [options] file\n");
|
fprintf(stderr, "usage: spinsim [options] file\n");
|
||||||
fprintf(stderr, "The options are as follows:\n");
|
fprintf(stderr, "The options are as follows:\n");
|
||||||
fprintf(stderr, " -v# Set verbosity level\n");
|
fprintf(stderr, " -v# Set verbosity level\n");
|
||||||
|
@ -669,7 +669,7 @@ void RebootProp(void)
|
||||||
if (baudrate)
|
if (baudrate)
|
||||||
{
|
{
|
||||||
if (propmode)
|
if (propmode)
|
||||||
bitcycles = 60000000 / baudrate;
|
bitcycles = 80000000 / baudrate;
|
||||||
else
|
else
|
||||||
bitcycles = (LONG(0) / baudrate) >> 2;
|
bitcycles = (LONG(0) / baudrate) >> 2;
|
||||||
SerialInit(&serial_in, 31, bitcycles, 2);
|
SerialInit(&serial_in, 31, bitcycles, 2);
|
||||||
|
|
Loading…
Reference in New Issue