Did a lot of reading on the FP11 design. A few interesting notes that are buried in the maintenance manual:

  • When debugging FP11 microcode with a KM11 in single-microstep mode, the 11/45 front panel microcode display shows the address of the next microinstruction, NOT the current microinstruction. This is because the stop-point for single microinstruction is at a point between T2 and T3, just after the next microinstruction addr has been calculated. This is different behavior than the 11/45 CPU front panel microaddress display.

  • There's a note in the maintenance manual that explicitly cautions that when using extender boards for debug, the RC maintenance clock should be used, and set with period >50ns. I had not been doing similar while debugging the KB11-A CPU, and maybe this explains the occasional different behavior I'd see when throwing boards out on extenders... In particular, I had seen this when debugging a spare CPU GRA; next time I return to that board I will try the CPU RC clock.

Okay, so here's my first simple test program for STST:

1
2
3
4
5
6
7
8
9
000000                          AC0=%0
000000                          .ASECT
001000                          .=1000
001000  170127  044000  START:  LDFPS   #044000         ;FID+FIUV
001004  172467  000004          LDF     NEGZ,AC0        ;LOAD A MINUS-ZERO
001010  170300                  STST    R0              ;STORE FEC TO R0
001012  000000                  HALT
001014  100000  000000  NEGZ:   .WORD   100000,000000   ;MINUS-ZERO
001000                          .END    START

This would be expected to produce the 000014 "Floating Undefined Variable" (minus-zero) exception code in R0, but I see an incorrect value of 177417. Using the KM11 on the FPU shows the -0 trap and STST microstate flow is per expectation.

Put the FRL out on the extender and started stepping the microcode, examining the state of the pins at the AC register file along the way. In the -0 trap flow, the FEC code 000014 presented (inverted) at TRP.50 via the EALU, and subsequently retrieved at TRP.60 looks correct. However, the value presented at TRP.70 via QR, BR, and the FALU does not. Out of time this weekend; Will have to chase signals back through those paths next time!


Slotted in FP11 spares that I hadn't tried previously, and this has produced some improved results -- returning to diagnostic CKBME0 (11/45 traps) this now passes with the floating point installed. Additionally, diagnostic CFPAB0 passes.

CFPBB0 and CFPCD0, however, are failing. Unfortunately, the source code for these is not available in the PDP-11 diagnostics database at retrocmp. The names of the diagnostics tell which instructions they are testing, though. CFPBB0 is annotated as testing the STST instruction. Rather than work through disassembling the rather lengthy diagnostics, I'll probably just write some simple test programs around the STST instruction for next time. In the meantime, I'll do some reading on the FP11 in preparation for microcode-step debug.


Moving on to the KT11 MMU: running the first diagnostic in the CKT suite, got error reports at 010340, 010560, and 011000. Consulted the diagnostic listings, and these particular tests have to do with D-space translations from kernel, supervisor, and user modes. The D-space logic is largely on module SSR, so I swapped this out for a spare. After that, I was able to pass the full suite of basic MMU tests:

DiagnosticBELDescriptionStatus
CKTAB0.BIC017412KT11-C basic logic part 1pass
CKTBC0.BIC015674KT11-C basic logic part 2pass
CKTCA0.BIC023304KT11-C access keyspass
CKTDA0.BIC016360KT11-C MTPD and MTPIpass
CKTEB0.BIC015310KT11-C MFPD and MFPIpass
CKTFD0.BIC016422KT11-C abortspass

Put the failing SSE module in the repair queue along with the other failed spares I've identified along the way, and will return to troubleshoot/repair it later. For now, things are looking pretty good with the CPU! I still need to run and pass the more heavyweight diagnostics: the 11/45 instruction exerciser, KT11 exerciser, and MS11-L exerciser. All three of these still seem to have halts, but they are quite complicated diagnostics in comparison to the rest, making use of additional peripherals, etc. I'll need to study these a bit before I can be sure I am using them correctly. I have also skipped the power fail diagnostics for now as I will need to restore some core memory in order for these to work correctly.

Next up will be to work on the FPU...


Data I/O Series 22 PROM programmer from eBay showed up, as well as some unprogrammed Signetics 82S123. Punched in the subsidiary ALU control ROM contents from the listing on GRAK in the 11/45 engineering drawings and burnt a new PROM. Put a socket and the new PROM in place of the failed part on my original GRA, slotted it into the CPU, and success! Diagnostic CKBOA0 now passes. I will probably return to the other faulty GRA at a later point, as it is partially diagnosed and I like to have spares working and ready to go.

Next time I'll be moving on to the CKT series of tests for the KT11 memory management cards...


The day gig has been keeping me pretty busy for the last couple of weeks, but had some time to work on the PDP-11 again this weekend, so here's an update.

Looking a little deeper at the diagnostics database over on retrocmp.com, I realized that I had skipped the entire set of generic 11-family "D0" tests. Downloaded and ran these via PDP11GUI and they all passed. BEL character patch locations, as described previously, are summarized here for future reference:

DiagnosticBELDescriptionStatus
D0AA0.BIN014212Branchpass
D0BA0.BIN004336Con branchpass
D0CA0.BIN005526Unarypass
D0DA0.BIN016370Binarypass
D0EA0.BIN010562Rotate/shiftpass
D0FA0.BIN017224CMP equalitypass
D0GA0.BIN013650CMP non-equalitypass
D0HA0.BIN013434Movepass
D0IA0.BIN014126Bit set clear testpass
D0JA0.BIN007472Addpass
D0KA0.BIN007124Subtractpass
D0LA0.BIN015722Jumppass
D0MA0.BIN003250JSR RTS RTIpass

Of the "CKB" series of tests, CKBOA0 (11/45 states) is the only one I that is not yet passing. Looking into this a little further, the first failing sub-test is T65:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
010540 010701                  T65:    SCOPE                    ;
010542 012737  030000  177776          MOV     #PUM,@#PSW       ;KERNEL MODE, PREV USER MODE
010550 012706  000500                  MOV     #KPTR,KSP        ;SET KERNEL STACK POINTER
010554 012716  000700                  MOV     #UPTR,(KSP)
010560 106606                          MTPD    USP              ;SET USER STATCK POINTER
010562 005067  170110                  CLR     UPTR-2
010566 052737  140000  177776          BIS     #UM,@#PSW        ;USER MODE, PREV USER MODE
010574 106506                          MFPD    USP              ;PUSH USER STACK POINTER ONTO USER STACK
010576 042737  140000  177776          BIC     #UM,@#PSW        ;KERNEL MODE, PREV USER MODE
010604 106506                          MFPD    USP              ;PUSH USER STACK POINTER ONTO KERNEL STACK
010606 022716  000676                  CMP     #UPTR-2,(KSP)    ;CHECK THAT USER STACK POINTER WAS
010612 001401                          BEQ     .+4              ;PUSHED PROPERLY (ONCE)
010614 000000                          HLT                      ;ERROR!
010616 022767  000700  170052          CMP     #UPTR,UPTR-2     ;CHECK THAT USER STACK POINTER IS ON THE
010624 001401                          BEQ     .+4              ;USERS STACK
010626 000000                          HLT                      ;ERROR!

This runs amok on the MFPD instruction at 010574, which should push the user stack pointer onto the user stack. Instead, the user stack pointer is pushed to memory at an incorrect address; 010676 instead of 000676. This actually overwrites subsequent test code. Since the value pushed is 000700, a hard-coded loop is created that prevents the test from completing the pass even if resumed from halt.

The relevant states in the microcode flow here are MFP.80, MFP.90, and MFP.10:

Stopping at T2 of MFP.10 using the KM11, I can see that the correct value 000700 was fetched to DR (as displayed by the console address lights), but the incorrect value of 010676 is appearing at the output of the ALU/shifter (as displayed by the console data lights when set to data paths). Throwing the DAP card out on extenders and taking a look around with a logic probe revealed that the errant bit 12 is sourcing from the ALU. At each slice of the ALU, function selectors S3-S0 are correct, CIN is correct, and overall B-mux constant value "2" is correct. The errant bit is arriving to the ALU from the A-mux...

Chasing this upstream, A-mux selectors S1,S0 are correct, but the bad bit arrives to the mux input on GRAH SR12. Hmmm, maybe this is one of the things the "BAD" sticker on the GRA is referring to... Next step is to throw the GRA on the extender, and chase the signal back towards SR and the register files. However, here I hit a snag: the M9301 monitor does not run correctly when the GRA is on the extender! That's pretty weird. Some investigation with the KM11 and some hand-toggled instructions revealed that at least the Z status bit is not set correctly/reliably when the card is on the extender. Some of the Z bit logic lives on the GRA also, so I can take a look at that, but I am now out of time for this weekend. Next time!

A few other miscellaneous notes in wrap-up:

  • I have been running with the spare GRA marked "BAD" because the first GRA I was using turned out to have a failed ALU subsidiary PROM. In the meantime I tracked down a PROM programmer and some compatible parts on eBay -- these should arrive sometime this week at which point I should be able to repair the original board and give it another try.

  • The uPB feature of my home-brew KM11 really doesn't work quite right. It often stops the machine at the requested micro-state but on the wrong instruction (skipping the first occurrence of the target state seemingly). This caused me a great deal of confusion today, as I was stepping through flows at a different program location than I had assumed, until I finally noticed the address lights on the console.

  • ESC key on the VT52 is non-functional, making it impractical to use for RT-11. The key mechanism looks okay from the top (thanks for more helpful advice from the vcfed forum!). I think I'll need to pull the keyboard PCB and re-flow the solder on the affected mechanism as a next step.

  • Looking forward to checking out Vintage Computer Fest West sometime next weekend!


Some progress with the CKBME0 diagnostic mentioned previously. It seems the concern with how the test behaves wrt. preconditions of the serial interface was well founded.

In order to debug more easily, I extracted the failing test and built a small loop around it, with a pass counter and display register update, etc. In the original test suite, a RESET instruction is executed immediately prior to the failing test, and it takes some time to come around the failing test on each pass, so I included a RESET and a delay loop in my test code as well. I then got failure modes and rates consistent with the original test suite.

The experiments previously described had indicated timing sensitivity (e.g. running on the RC maintenance clock at 50% clock speed changed the pass failure rate from ~50% to 100%) so I began to think more seriously about timing between the processor and the serial card, and how the time taken to circulate the entire suite of tests could affect the precondition of the serial interface when entering the test in subsequent passes. A re-read of the DL11 documentation showed that the transmit data is also double-buffered; if the transmit shift register is empty, a character written to the output buffer will be latched to the transmit shift register causing the output buffer to go ready again almost immediately.

I inserted the following code before the BIS/WAIT sequence in the original diagnostic (listed previously), which establishes consistent preconditions (shift register full, buffer empty) before the BIS. Success rate went to 100%:

1
2
3
        MOV     #40,@#177566    ;ENSURE XMIT SHIFT REGISTER HAS SOMETHING TO CHEW ON
L0:     TSTB    @#TTCSR         ;CHECK XMIT BUFFER
        BPL     L0              ;LOOP UNTIL READY, ENSURES INT IMMEDIATELY AFTER BIS

I then further verified that the unmodified original diagnostic suite passes 100% if I turn the M7800 down to 4800 Baud. Worth noting when trying to run these older diagnostics!


Replacement oscillator arrived for the VT52, so spent some time getting it back going again. Things got much better with a stable timing chain, but some glitchiness remained -- tracked this down to the socketed microcode ROMS which just required a reseat.

Here you can see the new oscillator fitted (silver rectangular can with tie-wrap). The microcode ROMS are the four socketed chips towards the right in the picture. Interestingly, the schematic I have calls for 8 ROMS of half the size of the ones that are in here, and indeed you can see the unpopulated spaces for these on the board.


Okay, digging into the CKBME0 traps diagnostic now in more detail. Here I've transcribed the source of the failing test from the older available diagnostic listing, then re-assembled it at the address matching the more modern binary. This makes it a little easier to follow along while debugging the newer binary:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
013604 000230                          SPL     0               ;SET PRIORITY LEVEL 0
013606 012706  000500                  MOV     #STKPTR,%6      ;SET STACK PTR
013612 012737  013650  000064          MOV     #TTY7A,@#TPVEC  ;LOAD TTY INTERRUPT VECTOR
013620 012737  013644  000014          MOV     #TTY7B,@#BPTVEC ;LOAD 'T' BIT TRAP VECTOR
013626 005002                          CLR     %2              ;CLEAR INDICATOR
013630 052737  000100  177564          BIS     #100,@#TTCSR    ;ALLOW INTERRUPT INTERRUPT OCCURS AFTER
                                                               ;THIS INSTRUCTION & BEFORE NEXT
013636 000001                  WAIT1:  WAIT                    ;WAIT FOR AN INTERRUPT
013640 005202                          INC     %2              ;INCREMENT INDICATOR
013642 000000                          HLT                     ;ERROR! NO 'T' TRAP AFTER INTERRUPT
013644 000000                  TTY7B:  HLT                     ;ERROR! 'T' BIT TRAPPED OUT OF WAIT
013646 000424                          BR      TTY7EX          ;EXIT TEST
013650 012737  000040  177566  TTY7A:  MOV     #40,@#177566    ;TYPE SPACE CHAR
013656 012737  013674  000064          MOV     #TTY7C,@#TPVEC  ;REPOSITION TTY INT VECTOR
013664 012766  000020  000002          MOV     #20,2(6)        ;PUT 'T' BIT IN RETURN STATUS
013672 000006                          RTT                     ;RETURN TO WAIT WITH 'T' BIT SET
                                                               ;AND WAIT FOR TTY INTERRUPT WHEN NULL
                                                               ;CHARACTER IS TYPED
013674 012737  013716  000014  TTY7C:  MOV     #TTY7D,@#BPTVEC ;REPOINT 'T' BIT TRAP VECTOR AFTER
                                                               ;TTY HAS INTERRUPTED
013702 005037  177564                  CLR     @#TTCSR         ;DISABLE INTERRUPT ENABLE
013706 012737  000015  177566          MOV     #15,@#177566
013714 000006                          RTT                     ;RETURN TO INST FOLLOWING WAIT WITH 'T'
                                                               ;BIT SET
013716 000240                  TTY7D:  NOP
013720 012737  000016  000014  TTY7EX: MOV     #BPTVEC+2,@#BPTVEC;RESTORE VECTORS TO HALT AT
013726 012737  000066  000064          MOV     #66,@#TPVEC     ;VECTOR +2
013734 005302                          DEC     %2              ;CHECK INDICATOR
013736 001401                          BEQ     .+4
013740 000000                          HLT                     ;ERROR! DID NOT DO INC INST AFTER INTERRUPT

This test seems to be designed to return from an interrupt handler to a WAIT instruction, with the T bit set in the PSW and a serial xmit interrupt pending. It verifies that the WAIT still "waits" in this circumstance. It also verifies that a trace trap does occur after the immediately following INC instruction when the xmit interrupt subsequently terminates the WAIT.

One potential problem with this test concerns the apparent assumption that enabling the xmit interrupt will cause an immediate trap before the subsequent WAIT instruction. This is true if the serial transmitter is empty, but if the transmitter is ever full/busy when this code is entered this assumption may not hold. Not sure yet if this will ever be a problem for this test given the surrounding code.

In any case, as currently written this routine fails about 50% of the time on my 11/45. The failure mode is that the processor sits at the WAIT instruction, (address display 013640, PC+2). Intervention with the console halt switch (halt then back to enabl) breaks the WAIT microcode loop; console cont then takes us to the halt at 013740 (address display 013742, PC+2).

The fact that the routine is tailing out through the halt at 013740 without hitting the halts at 013642 or 013644 is interesting; this implies that the second serial xmit interrupt to TTY7C has executed. This is verified by examining the break trap from the console after the test hangs up on the WAIT -- in the failure case, it is already reset to point to TTY7D. So the failure mode seems to be that the return from the second xmit interrupt sometimes goes to the WAIT instead of the subsequent INC.

Here is the microcode flow around the WAIT instruction. The horizontal line across the top is the A fork:

Using the KM11, in the failure case I can see the T bit set and the microcode looping through states WAT.00, WAT.20, WAT.30, WAT.11, which seems expected. I have also verified that executing a WAIT without the T bit set loops through states WAT.00 and WAT.10.

Lastly, running on the RC maintenance clock at about half the usual clock frequency makes the failure case happen almost 100% of the time.

Next I'll be needing to learn more about the BRQ logic, and in particular the mechanism by which the second xmit interrupt nominally causes INTRF to be asserted. Understanding that should lead me to some things to check with the logic probe and analyzer...


Investigated some of the halted diagnostics a bit today. CKBGB0 (SPL instruction test) was halting at 001404. Looking at the sources, the diagnostic was waiting at this point for a transmit interrupt from the DL11 that didn't seem to be arriving. Some troubleshooting turned up that the vector address on my DL11 was jumpered incorrectly. Fixed this, and the diagnostic now passes.

CKBME0 (11/45 traps test) is a bit more complicated. The halt address of 005320 here indicates that the floating point coprocessor is detected but not trapping per design. Pulled the floating point cards for now; the diagnostic now runs through several passes successfully, but regularly hangs up at 013640. Hitting the halt switch when it is hung up displays 000342 in the address lights, then with a couple continues it will start up again, run a bunch more passes, but sooner or later hang up at 013640 again with the same behavior. This behavior is a little more difficult to decode because the diagnostic itself is more complicated, and also the binary available from classicmp is a later revision than the available source code so the addresses don't quite match up. So I'll need to spend a little more time reading the diagnostic sources and examining the disassembly in PDP11GUI to make sense of this one. And it looks like there will be some downstream work to debug the floating point unit as well; I haven't studied its design yet at all.


Okay, now that serial is straightened out, on to running diagnostic tests via PDP11GUI. PDP11GUI itself, as well as a thorough and useful database of DEC diagnostic programs, are available at http://www.retrocmp.com/tools.

Since my home computer is a MacBook, I had intended to run PDP11GUI under Wine. I ran into a problem with this where PDP11GUI under Wine could not generate its pre-processed machine description temp file, seemingly because of some incompatible behavior wrt. multiple backslashes in pathnames. Rather than fight with this too long, I just sprang for a Windows 10 license and installed a Windows 10 VM; it will come in handy for other Windows-only tools that have been tweaky to use under Wine as well.

With PDP11GUI up and running under Windows, results of the initial set of 11/45 CPU diagnostics were very encouraging! In summary:

DiagnosticBELDescriptionStatus
CKBAB0.BIC002562SXT instructionpass
CKBBB0.BIC003604SOB instructionpass
CKBCB0.BIC007410XOR instructionpass
CKBDC0.BIC007262MARK instructionpass
CKBEC0.BIC002212RTI/RTT instructionspass
CKBFD0.BIC002272stack limitpass
CKBGB0.BIC001446SPL instructionhalt 001404
CKBHB0.BIC00376211/45 registerspass
CKBIB0.BIC013746ASH instructionpass
CKBJA0.BIC014722ASHC instructionpass
CKBKA0.BIC014430MUL instructionpass
CKBLA0.BIC011574DIV instructionpass
CKBME0.BIC01600011/45 trapshalt 005320
CKBNC0.BIC004702PIRQ instructionpass
CKBOA0.BIC01364011/45 stateshalt 000610

Note that these tests are written to output an ASCII BEL to the console on each successful pass. The terminal built in to PDP11GUI doesn't sound when given a BEL, however, so it is convenient to patch the BEL literal in the programs to a visible character (e.g. 000052, ASCII '*') before running them. This may be done in the memory loader window in PDP11GUI after "Load" but before "Deposit all". The patch address I identified for each diagnostic is listed in the table above as well for convenience.

So, out of this initial set of tests, only three halts to investigate. I'll be posting more information here as I look further into these.

Regarding the backplane SPC issue discussed in the previous post: Marty from the vcfed.org forum did some investigation of his 11/45, and reports that he does have +15V (actually +12V on his system) distributed to pin CU1 on slots 26-28. It seems to be wired over from slot 15 on his system, but it is not clear whether this was a factory wire, an ECO, or a user mod.

Marty's 11/45 also has no power distributed to CA1 on this slots, so it's really looking to me like the reference to that on page 5-10 of the 11/45 maintenance manual is a misprint. Thanks to Marty for checking all this out! I'd be curious to hear from any other 11/45 owners out there regarding wiring of CU1 and CA1 on slots 26-28 in their systems.