Updated to support P2 FPGA v32b

This commit is contained in:
davehein 2018-04-14 11:31:57 -05:00
parent 56e4571636
commit 1b0c107390
4 changed files with 264 additions and 209 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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);