From page 6-6 of DEC STD 032 (the VAX architecture spec):
"Execution of MTPR src, #PR$_ASTLVL with src<31:0> GEQU 5 results in
UNDEFINED behavior. The preferred implementation is to cause a reserved
operand fault." MicroVAX II, CVAX, and Rigel all conform to the preferred
behavior, as does the current simulator, which was written from the CVAX
microcode. NVAX masks to 3b and does not take an exception on a value
GEQU 5.
The 1982 Architecture Handbook describes ASTLVL as a 3b register, with
src<31:3> ignored/read as zero, and exceptions taken on values GEQU 5.
The780 microcode masks the input value to 3b before doing the GEQU 5 test.
The ASTLVL test needs to be model specific.
I suspect the behavior became undefined when MicroVAX II simplified the
original test to save a microword. I do not see how the code fragment Matt
references could work on a MicroVAX II, which was supported under 4.5.
Perhaps the device Matt mentions couldn't exist on a MicroVAX II?
For those who wants the gory details... uVAX, CVAX, and Rigel do an
unsigned compare on the unmasked src and the constant 5. Carry out
means reserved operand. Overflow is ignored. So an input of 0x80000002 -
0x00000005 (done in the data path as 0x80000002 + 0xFFFFFFFB) generates overflow (ignored) and carry out.
Maurice Marks, at VMS Software Inc, is using the Alpha instruction emulator
from SimH as a backup to an Alpha binary translator! He found a bug in the
instructions definitions: function fields, both integer and floating, are 7b not
6b.
the opcode table first word consists of bits:
<7> = FPD is legal for this opcode.
<4:6> = number of specifiers for unimplemented opcodes (VAX subsets)
<3> = unused
<0:2> = number of specifiers
The mask used to be 0x70. The convention is that x_M_y is a mask value
<right-justified>, for a macro like:
#define get_foo(x) (((x) >> x_V_foo) & x_M_foo)
For a subset VAX (like the 3900), the unimplemented opcodes are those
that are recognized on a full VAX but simply trap as reserved instructions
(e.g., the H-floating instructions). This really only affected symbolic
printing and decoding of these instructions.
The code wasn't handling interrupts correctly when TCCM was written. In
particular, if the GO bit clears DONE, the code looked for the "SET IE" case
too soon and didn't clear the interrupt that was incorrectly generated.
The new code factors "GO" into the calculation.
IPL_UBA already has the subtract built in:
So it shouldn't be extracted again.
The whole routine looks a little strange, but the way it works is
that an interrupt from the UBA itself sets <bit 31> in the returned vector.
Because the vector is read by code and not used by hardware, the flag
bit is "harmless."
UBA interrupts occur only under strange circumstances, like bad map
pages and device NXMs. Under the simulator, with a debugged OS, they
never happen.