CPU corrections

This commit is contained in:
Guy Perfect 2021-09-20 21:29:00 +00:00
parent b33a6c3055
commit a7985bad6e
4 changed files with 108 additions and 59 deletions

View File

@ -88,8 +88,8 @@
{ format: 6, mnemonic: "ST.W" },
{ format: 6, mnemonic: "IN.B" },
{ format: 6, mnemonic: "IN.H" },
{ format: 6, mnemonic: "IN.W" },
{ format: 6, mnemonic: "CAXI" },
{ format: 6, mnemonic: "IN.W" },
{ format: 6, mnemonic: "OUT.B" },
{ format: 6, mnemonic: "OUT.H" },
{ format: 7, mnemonic: null },
@ -258,9 +258,6 @@
case 0b000110: // JMP
inst.operands = "[" + reg1 + "]";
break;
case 0b001111: // NOT
inst.operands = reg1;
break;
default: // All others
inst.operands = reg1 + ", " + this.PROREGNAMES[bits >> 5 & 31];
}
@ -275,7 +272,7 @@
case 0b010010: // SETF
inst.operands = this.SETFS[other & 15] + ", " + reg2;
break;
case 0b011001: // TRAP
case 0b011000: // TRAP
inst.operands = other;
break;
case 0b011100: // LDSR
@ -355,6 +352,7 @@
case 0b110011: // LD.W
case 0b111000: // IN.B
case 0b111001: // IN.H
case 0b111010: // CAXI
case 0b111011: // IN.W
inst.operands = disp + "[" + reg1 + "], " + reg2;
break;

View File

@ -194,6 +194,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window {
case "ArrowLeft" : change = - 1 ; break;
case "ArrowRight": change = 1 ; break;
case "ArrowUp" : change = -16 ; break;
case "Enter" : change = 0 ; break;
case "PageDown" : change = visible; break;
case "PageUp" : change = -visible; break;
case "0": case "1": case "2": case "3": case "4":

View File

@ -137,9 +137,35 @@
let text;
switch (this.format) {
case "float":
text = CPUWindow.Register.intBitsToFloat(value).toString();
let e = value >> 23 & 0xFF;
let s = value & 0x007FFFFF;
// Check for denormal number
if (e == 0x00 & s != 0) {
text = "Denormal";
break;
}
// Check for reserved operand
if (e == 0xFF) {
text = s!=0 ? "NaN" : value<0 ? "-Infinity" : "Infinity";
break;
}
// Check for negative zero
if ((value & 0xFFFFFFFF) >>> 0 == 0x80000000) {
text = "-0.0";
break;
}
// Format the number
text = CPUWindow.Register.intBitsToFloat(value).toFixed(6);
if (text.indexOf(".") == -1)
text += ".0";
while (text.endsWith("0"))
text = text.substring(0, text.length - 1);
if (text.endsWith("."))
text += "0";
break;
case "hex":
text = ("0000000" +

View File

@ -229,24 +229,24 @@ static int32_t cpuAdd(VB *emu, int32_t left, int32_t right) {
}
/* Bit string search */
static int cpuBitSearch(VB *emu, int bit, int dir) {
static int cpuBitSearch(VB *emu, int32_t bit, int32_t dir) {
int32_t offset; /* Bit offset in source word */
int32_t value; /* Alias of source word */
/* Read the source word */
if (!emu->cpu.busWait) {
/* Initialize state */
emu->cpu.program[30] &= 0xFFFFFFFC;
emu->cpu.program[27] &= 0x0000001F;
emu->cpu.psw.z = 1;
/* The bit string is of zero length */
if (emu->cpu.program[28] == 0) {
emu->cpu.clocks = dir == 1 ? 13 : 15;
return 0;
}
/* Read the source word */
if (!emu->cpu.busWait && !emu->cpu.substring) {
/* Initialize state */
emu->cpu.program[30] &= 0xFFFFFFFC;
emu->cpu.program[27] &= 0x0000001F;
emu->cpu.psw.z = 1;
/* Read the data unit from the bus */
if (cpuRead(emu, emu->cpu.program[30], VB_S32))
return 1;
@ -260,6 +260,10 @@ static int cpuBitSearch(VB *emu, int bit, int dir) {
return 0;
}
/* Update state */
emu->cpu.busWait = 0;
emu->cpu.substring = 0;
/* Search the bit string */
for (
offset = emu->cpu.program[27], value = emu->cpu.access.value;
@ -268,31 +272,36 @@ static int cpuBitSearch(VB *emu, int bit, int dir) {
) {
/* The current bit does not match */
if ((value >> bit & 1) != bit)
if ((value >> offset & 1) != bit)
continue;
/* The current bit matches */
emu->cpu.substring = 0;
emu->cpu.clocks = dir == 1 ? 46 : 51;
emu->cpu.program[27] = offset;
emu->cpu.clocks = dir == 1 ? 45 : 50;
emu->cpu.psw.z = 0;
return 0;
}
/* No bit in the current word matches */
emu->cpu.program[27] = offset & 31;
if (emu->cpu.program[27] != offset)
emu->cpu.program[30] += (uint32_t) dir << 2;
if (emu->cpu.program[28] != 0) {
emu->cpu.substring = 1;
emu->cpu.clocks = 5;
emu->cpu.program[30] += dir << 2;
emu->cpu.program[27] &= 0x0000001F;
} else emu->cpu.clocks = dir == 1 ? 46 : 51;
return 0;
}
/* Bit string bitwise operation */
static int cpuBitString(VB *emu, VB_INSTRUCTION *inst) {
uint64_t bits; /* Shift register */
int32_t dest; /* Destination word value */
int32_t mask; /* Bit mask */
int32_t src; /* Source word value */
/* Initial invocation */
if (emu->cpu.busWait == 0 && !emu->cpu.substring) {
if (emu->cpu.busWait == 0) {
/* Initialize state */
emu->cpu.program[30] &= 0xFFFFFFFC;
@ -355,9 +364,12 @@ static int cpuBitString(VB *emu, VB_INSTRUCTION *inst) {
/* Compute and store the destination word */
if (emu->cpu.busWait == 3) {
bits = ((uint64_t) inst->aux[1] << 32 | (uint32_t) inst->aux[0]);
dest = emu->cpu.access.value;
src = ((int64_t) inst->aux[1] << 32 | (uint32_t) inst->aux[0]) >>
(32 + emu->cpu.program[27] - emu->cpu.program[26]);
src = emu->cpu.program[27] <= emu->cpu.program[26] ?
bits << (emu->cpu.program[26] - emu->cpu.program[27]) :
bits >> (emu->cpu.program[27] - emu->cpu.program[26])
;
/* Perform the operation */
switch (inst->bits[0] & 7) {
@ -372,13 +384,13 @@ static int cpuBitString(VB *emu, VB_INSTRUCTION *inst) {
}
/* Incorporate only the bits occupied by the bit string */
src = (int32_t) 0xFFFFFFFF << emu->cpu.program[26];
mask = (uint32_t) 0xFFFFFFFF << emu->cpu.program[26];
if ((uint32_t)emu->cpu.program[28] < (uint32_t)32-emu->cpu.program[26])
src &= (1 << (emu->cpu.program[28] + emu->cpu.program[26])) - 1;
dest = (dest & src) | (emu->cpu.access.value & ~src);
mask &= (1 << (emu->cpu.program[28] + emu->cpu.program[26])) - 1;
dest = (dest & mask) | (emu->cpu.access.value & ~mask);
/* Write the data unit to the bus */
if (cpuWrite(emu, emu->cpu.program[30], VB_S32, dest))
if (cpuWrite(emu, emu->cpu.program[29], VB_S32, dest))
return 1;
/* Update state */
@ -391,23 +403,30 @@ static int cpuBitString(VB *emu, VB_INSTRUCTION *inst) {
}
/* Working variables */
dest = 32 - emu->cpu.program[26]; /* Bits processed this invocation */
if ((uint32_t) emu->cpu.program[28] < (uint32_t) dest)
dest = emu->cpu.program[28];
src = emu->cpu.program[30] + dest; /* New source bit offset */
mask = 32 - emu->cpu.program[26]; /* Bits processed this invocation */
if ((uint32_t) emu->cpu.program[28] < (uint32_t) mask)
mask = emu->cpu.program[28];
dest = emu->cpu.program[26] + mask; /* New destination bit offset */
src = emu->cpu.program[27] + mask; /* New source bit offset */
/* Update state */
emu->cpu.busWait = 0;
emu->cpu.substring = dest != emu->cpu.program[28];
if (src >= 32) {
inst->aux[0] = inst->aux[1];
emu->cpu.program[30] += 4;
}
emu->cpu.substring = mask != emu->cpu.program[28];
emu->cpu.program[26] = dest & 31;
emu->cpu.program[27] = src & 31;
emu->cpu.program[28] -= mask;
if (dest >= 32)
emu->cpu.program[29] += 4;
emu->cpu.program[28] -= dest;
emu->cpu.program[27] = src & 0x1F;
emu->cpu.program[26] = 0;
emu->cpu.clocks = emu->cpu.substring ? 6 : 36;
if (src >= 32)
emu->cpu.program[30] += 4;
if (emu->cpu.substring) {
emu->cpu.busWait = 1;
emu->cpu.clocks = 6;
inst->aux[0] = inst->aux[1];
} else {
emu->cpu.busWait = 0;
emu->cpu.clocks = 36;
}
return 0;
}
@ -502,7 +521,8 @@ static int32_t cpuFloatResult(VB *emu, double resultd) {
static void cpuFloatToWord(VB *emu, VB_INSTRUCTION *inst, int truncate) {
int32_t bits = emu->cpu.program[inst->bits[0] & 0x1F];
int32_t result; /* Output value */
int32_t x; /* Working variable field */
int32_t x; /* Working variable */
int32_t y; /* Working variable */
/* Zero */
if ((bits & 0x7FFFFFFF) == 0)
@ -524,7 +544,7 @@ static void cpuFloatToWord(VB *emu, VB_INSTRUCTION *inst, int truncate) {
}
/* Invalid operation */
if (x >= 135) {
if (x >= 158) {
emu->cpu.causeCode = 0xFF70;
emu->cpu.psw.fiv = 1;
return;
@ -534,22 +554,22 @@ static void cpuFloatToWord(VB *emu, VB_INSTRUCTION *inst, int truncate) {
result = (bits & 0x007FFFFF) | 0x00800000;
/* Left shift */
if (x >= 127)
result <<= x - 127;
if (x >= 150)
result <<= x - 150;
/* Right shift */
else {
x = 127 - x; /* Number of bits to shift */
y = result; /* Significant bits */
x = 150 - x; /* Number of bits to shift */
result >>= x; /* Update state */
x = 1 << x; /* Position of the "one halfths" bit */
/* Precision degradation */
if ((bits & (x - 1)) != 0) {
if ((y & ((1 << x) - 1)) != 0) {
emu->cpu.psw.fpr = 1;
/* Apply rounding */
if (!truncate && (bits & x) != 0)
result += x;
if (!truncate)
result += y >> (x - 1) & 1;
}
}
@ -885,6 +905,7 @@ static void cpuCVT_WS(VB *emu, VB_INSTRUCTION *inst) {
/* Divide */
static void cpuDIV(VB *emu, VB_INSTRUCTION *inst) {
int32_t right = emu->cpu.program[inst->bits[0] & 0x1F];
int32_t *r30; /* Program register r30 */
int32_t *reg2; /* Program register reg2 */
/* Zero division */
@ -902,7 +923,10 @@ static void cpuDIV(VB *emu, VB_INSTRUCTION *inst) {
/* Perform the operation */
else {
emu->cpu.program[30] = *reg2 % right;
r30 = &emu->cpu.program[30];
*r30 = *reg2 % right;
if ((*r30 ^ *reg2) < 0)
*r30 = -*r30;
*reg2 /= right;
emu->cpu.psw.ov = 0;
}
@ -1592,7 +1616,7 @@ static int cpuException(VB *emu) {
emu->cpu.eipcTo = emu->cpu.pcTo;
emu->cpu.psw.ep = 1;
emu->cpu.pc = (causeCode & 0x0040) != 0 ?
0xFFFFFF60 : ((uint32_t) 0xFFFF0000 | causeCode);
0xFFFFFF60 : ((uint32_t) 0xFFFF0000 | (causeCode & 0xFFF0));
}
/* Interrupt */
@ -1658,8 +1682,8 @@ static int cpuFetch(VB *emu) {
/* Determine the internal ID of the instruction */
inst->id = CPU_OPCODES[opcode];
switch (inst->id) {
case CPU_BITSTRING: inst->id = CPU_BITSTRINGS[inst->id & 0x1F]; break;
case CPU_FLOATENDO: inst->id = CPU_FLOATENDOS[inst->bits[1]>>10&0x3F];
case CPU_BITSTRING: inst->id=CPU_BITSTRINGS[inst->bits[0]&0x1F]; break;
case CPU_FLOATENDO: inst->id=CPU_FLOATENDOS[inst->bits[1]>>10&0x3F];
}
/* Update state */