MicroVAX II, rtVAX1000: Fix NVR behavior to precisely reflect original hardware
Observations made about NVR behavior on real hardware: 1) Aligned writes only affect a single RAM location without regard to the size of write, so no double pumping on writes. 2) Unaligned (offset 3) writes do nothing without regard to size of the write 3) Unaligned (offset 1) write 0 to the next higher NVR RAM location. 4) Longword aligned and Unaligned (offset 3) reads return the same NVR RAM value in the the upper and lower words of the result. 5) Unaligned (offset 1) reads reference the next higher NVR RAM cell for word and longword reads. - Fix write behavior to match hardware. - Fix read behavior to double pump word values for all unaligned word and longword reads.
This commit is contained in:
parent
b502558df7
commit
2498fafd46
1 changed files with 19 additions and 17 deletions
|
@ -27,7 +27,7 @@
|
||||||
This module contains the MicroVAX II system-specific registers and devices.
|
This module contains the MicroVAX II system-specific registers and devices.
|
||||||
|
|
||||||
rom bootstrap ROM (no registers)
|
rom bootstrap ROM (no registers)
|
||||||
nvr non-volatile ROM (no registers)
|
nvr non-volatile RAM (no registers)
|
||||||
sysd system devices
|
sysd system devices
|
||||||
|
|
||||||
08-Nov-2012 MB First version
|
08-Nov-2012 MB First version
|
||||||
|
@ -431,16 +431,16 @@ return "read-only memory";
|
||||||
|
|
||||||
int32 nvr_rd (int32 pa)
|
int32 nvr_rd (int32 pa)
|
||||||
{
|
{
|
||||||
int32 rg = (pa - NVRBASE) >> 1;
|
int32 rg = (pa + 1 - NVRBASE) >> 1;
|
||||||
int32 result;
|
int32 result;
|
||||||
|
|
||||||
if (rg < 14) /* watch chip */
|
if (rg < 14) /* watch chip */
|
||||||
result = wtc_rd (pa);
|
result = wtc_rd (pa);
|
||||||
else
|
else {
|
||||||
if (rg & 1)
|
result = (nvr[rg] & WMASK) | (((uint32)nvr[rg]) << 16);
|
||||||
result = ((int32)nvr[rg]) << 16;
|
if (pa & 1)
|
||||||
else
|
result = result << 8;
|
||||||
result = nvr[rg] | (((int32)nvr[rg+1]) << 16);
|
}
|
||||||
|
|
||||||
sim_debug (DBG_REG, &nvr_dev, "nvr_rd(pa=0x%X) nvr[0x%X] returns: 0x%X\n", pa, rg, result);
|
sim_debug (DBG_REG, &nvr_dev, "nvr_rd(pa=0x%X) nvr[0x%X] returns: 0x%X\n", pa, rg, result);
|
||||||
|
|
||||||
|
@ -449,21 +449,21 @@ return result;
|
||||||
|
|
||||||
void nvr_wr (int32 pa, int32 val, int32 lnt)
|
void nvr_wr (int32 pa, int32 val, int32 lnt)
|
||||||
{
|
{
|
||||||
int32 rg = (pa - NVRBASE) >> 1;
|
int32 rg = (pa + 1 - NVRBASE) >> 1;
|
||||||
|
|
||||||
if (rg < 14) /* watch chip */
|
if (rg < 14) /* watch chip */
|
||||||
wtc_wr (pa, val, lnt);
|
wtc_wr (pa, val, lnt);
|
||||||
else {
|
else {
|
||||||
int32 orig_nvr = (int32)nvr[rg];
|
int32 orig_nvr = (int32)nvr[rg];
|
||||||
int32 v = val;
|
|
||||||
int32 r = rg;
|
|
||||||
int32 l = lnt;
|
|
||||||
|
|
||||||
while (l > 0) {
|
switch (pa & 03) {
|
||||||
nvr[r] = (uint8)v;
|
case 0:
|
||||||
++r;
|
case 2:
|
||||||
l -= 2;
|
nvr[rg] = (uint8)val;
|
||||||
v = (v >> 16);
|
break;
|
||||||
|
case 1:
|
||||||
|
nvr[rg] = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lnt > 1)
|
if (lnt > 1)
|
||||||
|
@ -784,7 +784,9 @@ MACH_CHECK (MCHK_READ);
|
||||||
|
|
||||||
int32 ReadRegU (uint32 pa, int32 lnt)
|
int32 ReadRegU (uint32 pa, int32 lnt)
|
||||||
{
|
{
|
||||||
return ReadReg (pa & ~03, L_LONG);
|
if (lnt == L_BYTE)
|
||||||
|
return ReadReg (pa & ~03, L_LONG);
|
||||||
|
return (ReadReg (pa & ~03, L_WORD) & WMASK) | (ReadReg ((pa & ~03) + 2, L_WORD) & (WMASK << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WriteReg - write register space
|
/* WriteReg - write register space
|
||||||
|
|
Loading…
Add table
Reference in a new issue