Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

« Previous Version 3 Current »

The Unibone emulates a PDP 11/20 CPU. This is the very first PDP-11 CPU, the KA11, and it lacks a lot of instructions that were present on later machines. This is a pity, because it limits what the Unibone can run: code that uses the later instructions will fail. This is particularly sad for a great use case for this wonderful thing which is to test hardware: some XXDP tests fail because they use these instructions. I had this happening while I wanted to test the DELUA adapter, and I decided to try to add the missing instructions to the Unibone.

Work in progress, incomplete

Implementing the first set: the EIS instructions

The Extended Instruction set, implemented in part for the 11/20 by the KE11-A extension, added the following instructions in the 007x000 range: ASH, ASHC, MUL, DIV. Later CPUs added XOR to this list.

I implemented these by adding a parameter “extended_inst” to the cpu20 device. When set the code now emulates these instructions.

Testing the EIS instructions: FKAC..

The 11/34 (KD11-B) implements these instructions, and there is a specific test for them, details here. The FKAC test tests these EIS instructions, so, let’s run it. Sadly enough it halts “CPU Halt by instruction” at 000014. I enabled Trace level on the Unibone, and the log (dbg s) shows:

[22:02:01.655324 Dbg    cpu 02267@ka11.c:0412] EXEC [000620] MOV
[22:02:01.655328 Dbg    cpu 02267@ka11.c:0161] DATI [000622] => 000004
[22:02:01.655331 Dbg    cpu 02267@ka11.c:0161] DATI [000004] => 000006
[22:02:01.655335 Dbg    cpu 02267@ka11.c:0161] DATI [000576] => 000000
[22:02:01.655338 Dbg    cpu 02267@ka11.c:0174] DATO [000576] <= 000006
[22:02:01.655346 Dbg    cpu 02267@ka11.c:0161] DATI [000624] => 013746
[22:02:01.655350 Dbg    cpu 02267@ka11.c:0412] EXEC [000624] MOV
[22:02:01.655353 Dbg    cpu 02267@ka11.c:0161] DATI [000626] => 000006
[22:02:01.655357 Dbg    cpu 02267@ka11.c:0161] DATI [000006] => 000000
[22:02:01.655360 Dbg    cpu 02267@ka11.c:0161] DATI [000574] => 000576
[22:02:01.655363 Dbg    cpu 02267@ka11.c:0174] DATO [000574] <= 000000
[22:02:01.655370 Dbg    cpu 02267@ka11.c:0161] DATI [000630] => 012767
[22:02:01.655374 Dbg    cpu 02267@ka11.c:0412] EXEC [000630] MOV
[22:02:01.655377 Dbg    cpu 02267@ka11.c:0161] DATI [000632] => 000644
[22:02:01.655381 Dbg    cpu 02267@ka11.c:0161] DATI [000634] => 177146
[22:02:01.655385 Dbg    cpu 02267@ka11.c:0161] DATI [000004] => 000006
[22:02:01.655388 Dbg    cpu 02267@ka11.c:0174] DATO [000004] <= 000644
[22:02:01.655395 Dbg    cpu 02267@ka11.c:0161] DATI [000636] => 005777
[22:02:01.655399 Dbg    cpu 02267@ka11.c:0671] EXEC [000636] TST
[22:02:01.655402 Dbg    cpu 02267@ka11.c:0161] DATI [000640] => 177640
[22:02:01.655406 Dbg    cpu 02267@ka11.c:0161] DATI [000502] => 177570
[22:02:01.655409 Dbg    cpu 02267@ka11.c:0161] DATI [177570] => 000000
[22:02:01.655415 Dbg    cpu 02267@ka11.c:0161] DATI [000642] => 000407
[22:02:01.655419 Dbg    cpu 02267@ka11.c:0722] EXEC [000642] BR
[22:02:01.655425 Dbg    cpu 02267@ka11.c:0161] DATI [000662] => 012637
[22:02:01.655428 Dbg    cpu 02267@ka11.c:0412] EXEC [000662] MOV
[22:02:01.655432 Dbg    cpu 02267@ka11.c:0161] DATI [000574] => 000000
[22:02:01.655435 Dbg    cpu 02267@ka11.c:0161] DATI [000664] => 000006
[22:02:01.655439 Dbg    cpu 02267@ka11.c:0161] DATI [000006] => 000000
[22:02:01.655442 Dbg    cpu 02267@ka11.c:0174] DATO [000006] <= 000000
[22:02:01.655450 Dbg    cpu 02267@ka11.c:0161] DATI [000666] => 012637
[22:02:01.655453 Dbg    cpu 02267@ka11.c:0412] EXEC [000666] MOV
[22:02:01.655457 Dbg    cpu 02267@ka11.c:0161] DATI [000576] => 000006
[22:02:01.655460 Dbg    cpu 02267@ka11.c:0161] DATI [000670] => 000004
[22:02:01.655464 Dbg    cpu 02267@ka11.c:0161] DATI [000004] => 000644
[22:02:01.655467 Dbg    cpu 02267@ka11.c:0174] DATO [000004] <= 000006
[22:02:01.655474 Dbg    cpu 02267@ka11.c:0161] DATI [000672] => 106427
[22:02:01.655478 Dbg    cpu 02267@ka11.c:0800] TRAP 10

So, an illegal instruction.

Looking at the EXEC parts we can see the instructions being executed and their address. The last one that worked was a MOV at 000666, the DATI before the trap shows a read of 000672 with opcode 106427.

The fiche database only contains a fiche for “DFKACA”, and I cannot match the above execution with its content:

image-20241206-213339.pngimage-20241206-213254.png

But there is an instruction there with the same opcode, at 000620: MTPS. Which is according to the docs a LSI11 only instruction which moves a word to the PSW. It has an accompanying read called MFPS. This is odd because the 11/34 is not a LSI11 CPU, but the test’s documentation says:

image-20241206-213942.png

Implementing MTPS and MFPS

So, apparently the 11/34 implemented that MTPS instruction. Sigh. This was confirmed here:

“The Micro/J-11 supported all of the possible PDP-11 instructions, except for those unique to the PDP-11/60, and the PDP-11/34 (MTPS and MFPS).“

I implemented the mtps (1064xx) and mfps (1067xx) instructions by adding yet another cpu20 parameter:

    parameter_bool_c allow_mxps = parameter_bool_c(this, "allow_mxps", "mxps",/*readonly*/
                             false, "Allow mtps and mfps instructions (1=11/34, LSI11, 0=standard 11/20 behavior)");

Next run

The next run came a lot further but still died with a trap 010, illegal instruction. The log showed:

[11:42:20.938773 Dbg    cpu 03410@ka11.c:0412] EXEC [000726] MOV
[11:42:20.938777 Dbg    cpu 03410@ka11.c:0161] DATI [000730] => 000001
[11:42:20.938780 Dbg    cpu 03410@ka11.c:0161] DATI [000732] => 000440
[11:42:20.938784 Dbg    cpu 03410@ka11.c:0161] DATI [000440] => 000000
[11:42:20.938787 Dbg    cpu 03410@ka11.c:0174] DATO [000440] <= 000001
[11:42:20.938793 Dbg    cpu 03410@ka11.c:0161] DATI [000734] => 005037
[11:42:20.938797 Dbg    cpu 03410@ka11.c:0639] EXEC [000734] CLR
[11:42:20.938800 Dbg    cpu 03410@ka11.c:0161] DATI [000736] => 000442
[11:42:20.938803 Dbg    cpu 03410@ka11.c:0161] DATI [000442] => 000014
[11:42:20.938807 Dbg    cpu 03410@ka11.c:0174] DATO [000442] <= 000000
[11:42:20.938814 Dbg    cpu 03410@ka11.c:0161] DATI [000740] => 010701
[11:42:20.938817 Dbg    cpu 03410@ka11.c:0412] EXEC [000740] MOV
[11:42:20.938824 Dbg    cpu 03410@ka11.c:0161] DATI [000742] => 013700
[11:42:20.938827 Dbg    cpu 03410@ka11.c:0412] EXEC [000742] MOV
[11:42:20.938831 Dbg    cpu 03410@ka11.c:0161] DATI [000744] => 000434
[11:42:20.938834 Dbg    cpu 03410@ka11.c:0161] DATI [000434] => 000001
[11:42:20.938840 Dbg    cpu 03410@ka11.c:0161] DATI [000746] => 032737
[11:42:20.938843 Dbg    cpu 03410@ka11.c:0423] EXEC [000746] BIT
[11:42:20.938847 Dbg    cpu 03410@ka11.c:0161] DATI [000750] => 000001
[11:42:20.938850 Dbg    cpu 03410@ka11.c:0161] DATI [000752] => 000406
[11:42:20.938854 Dbg    cpu 03410@ka11.c:0161] DATI [000406] => 000000
[11:42:20.938860 Dbg    cpu 03410@ka11.c:0161] DATI [000754] => 001004
[11:42:20.938864 Dbg    cpu 03410@ka11.c:0738] EXEC [000754] BNE
[11:42:20.938870 Dbg    cpu 03410@ka11.c:0161] DATI [000756] => 013701
[11:42:20.938873 Dbg    cpu 03410@ka11.c:0412] EXEC [000756] MOV
[11:42:20.938877 Dbg    cpu 03410@ka11.c:0161] DATI [000760] => 000436
[11:42:20.938880 Dbg    cpu 03410@ka11.c:0161] DATI [000436] => 000000
[11:42:20.938886 Dbg    cpu 03410@ka11.c:0161] DATI [000762] => 072001
[11:42:20.938890 Dbg    cpu 03410@ka11.c:0498] EXEC [000762] ASH
[11:42:20.938897 Dbg    cpu 03410@ka11.c:0161] DATI [000764] => 000402
[11:42:20.938900 Dbg    cpu 03410@ka11.c:0737] EXEC [000764] BR
[11:42:20.938907 Dbg    cpu 03410@ka11.c:0161] DATI [000772] => 106737
[11:42:20.938911 Dbg    cpu 03410@ka11.c:0715] EXEC [000772] MFPS
[11:42:20.938914 Dbg    cpu 03410@ka11.c:0174] DATOB [000772] <= 000000
[11:42:20.938920 Dbg    cpu 03410@ka11.c:0161] DATI [000774] => 000432
[11:42:20.938924 Dbg    cpu 03410@ka11.c:0737] EXEC [000774] BR
[11:42:20.938930 Dbg    cpu 03410@ka11.c:0161] DATI [001062] => 177354
[11:42:20.938933 Dbg    cpu 03410@ka11.c:0815] TRAP 10

The FKAC test

Reading the fiche to understand the ASH part of it..

The test tests the ASH instruction for the registers R0..R5, where those registers are the ones to be shifted. On even passes, when we test Rn, the shift count (coming from temp2) is moved to R(n+1) and that register is used as the count. On odd passes it uses test2 directly.

The test loops 30x (36oct) though the same sets of code. Every EVEN run it

Variables:

  • temp1: current value to be shifted.

  • temp2: shift count. On even passes this gets moved to a register, and the register is used as the count source. On odd passes the ash instruction addresses temp2 directly (mode 67).

  • temp3 : the expected result of the shift operation expected in the shifted register

  • temp4: the expected PSW result

Debugging using Unibone and FKAC

Speed up emulation

By default the emulation will fully control the Unibus. This means that when it runs all data is sent to it. This is necessary when testing real hardware, of course, but for my use case, testing the emulation, I do not need the Unibus to be controlled. And disabling that greatly speeds up the emulation!

Set the parameter “pmi” to 1 to disable Unibus control.

Use Unibone breakpoints

Invaluable is the “bp” parameter in the Unibone which can be used to set a single breakpoint. As the fiche I had of FKAC was a lot different from the actual code I converted the BIC file to a binary and then used pdp11dasm to disassemble that binary. With that I could at least match pieces of actual code with the fiche.

In my version of FKAC the $HLT routing which gets called at error is at location 16440oct, and this routine’s return statement is at 16622oct, so I added a breakpoint at the last address causing the test to stop as soon as an error has been found- and has been printed.

  • No labels