The first cut at a microcode disassembler for the CP16xx/WD21xx
chipsets, written in Python 3, is now on github:
https://github.com/brouhaha/cp16dis
The disassembler uses hexadecimal, in C notation, rather than octal as
used by DEC. Branch targets are labeled as L with the three-digit hex
address. The disassembler doesn't know about branch targets only
reached from the control chip translation PLA.
The disassembler probably needs a lot of work to be truly usable. It
does not even attempt to produce code that could be assembled by DEC's
"MICRO" microassembler that is in the KUV11 writable control store
support software, or any other assembler or microassembler. (I don't
have the KUV11 support software, but would *really* like to obtain a
copy!)
The register names decoded are specific to the LSI-11 microcode. I
don't yet know what the Pascal Microengine registers are used for, so
I don't have suitable names for them.
Here's an excerpt from the LSI-11 microcode at address 0x018 where you
can see one of the techniques for a computed jump, with entry occuring
at 0x20:
L018: jmp L101 ;018: 000101
jmp L161 ;019: 000161
jmp L192 ;01a: 000192
jmp L0f5 ;01b: 0000f5
jmp L0a5 ;01c: 0000a5
jmp L19e ;01d: 00019e
jmp L192 ;01e: 000192
jmp L192 ;01f: 000192
mi RIRL,RIRH ;020: 00ec89
jmp L018 ;021: 000018
This is used by an implicit jump caused by the translation array in
the control chip to location 0x20. The mi instruction causes the
instruction register (RIRH) to be OR'd into both bytes of the next
microinstruction, which is a jump to L018. Presumably before jumping
to the mi, all of the bits of the instruction register have been
masked off, except for the least significant three. It's also possible
that it's been shifted before masking. Also possible, not all of the
bits might be masked off, and there might be more of the jump table
elsewhere, depending on those bits. Note that if the most significant
five bits are not masked off, this could even change the jump
instruction at 0x21 to a different kind of instruction.
Eric