This release contains one really big thing and a number of smaller things.
P2 Lives!The really big thing is that the second processor, P2, is now functional. Getting this to work is especially gratifying to me, as it is an important feature of the B5000/B5500 and I have wanted it to work from the beginning. It has been very frustrating trying to get this going, as there are only a few places in the processor design where it needs to know whether it's P1 or P2, and it should have just worked. It didn't.
The processors on a B5500 are physically identical, with a manual switch in Central Control determining which one is P1 (the control processor) and which is P2. Unlike the B6500/B6700 that followed it (and most multiple-processor systems today), the processors on the B5500 do not operate symmetrically. P1 is the control processor. Only P1 can run in Control State, service interrupts, and initiate I/Os. Much of the MCP runs only on P1.
P1 can also run in Normal State, which is used for user tasks. P1 enters Normal State during an Initiate P1 (IP1) syllable, which effectively assigns the processor to a user task by automatically loading state from a few words in the task's stack. P1 reverts to Control State when any interrupt occurs, automatically storing the task's state in the stack and PRT in the form required by IP1 for reactivation.
P2, on the other hand, can run only in Normal State, and thus can be used only to run user tasks. The MCP (running in Control State in P1) assigns P2 to a user task by means of the Initiate P2 (IP2) syllable, which functions similarly to the IP1 syllable. P2 runs until it detects one of its internal interrupts or the MCP running in P1 executes a Halt P2 (HP2) syllable. When one of those events occurs, P2 stores its state in the stack and PRT as P1 does and then idles, waiting for the next IP2 to occur. P2 does not sense external interrupts (such as the timer and I/O completions) and is not directly affected by them. They are handled by P1 instead.
P1 never idles until the system is halted -- its equivalent of idling is for the MCP to continuously execute its NOTHINGTODO loop, waiting for some interrupt or change in system status to occur.
The design of the MCP is intended to assign user tasks preferentially to P2 if it is available. If there is more than one user task ready to run and P1 does not have any Control State duties at the moment, then both processors can simultaneously run user tasks. When running a single program in the mix, we have seen the program bounce between the processors, but if there is enough processor-bound work in the mix, then P2 will stay busy. Every time P2 senses an internal interrupt or needs some MCP service (which it signals by triggering a COM interrupt), P2 stores its registers and idles. If there is another task waiting for a processor, the MCP will generally initiate P2 again right away on it.
Compared with today's sophisticated SMP system designs, the multiple-processor mechanism on the B5500 probably seems a little clunky and inefficient, and in hindsight it was. But then, even multi-tasking was rare and controversial in the early 1960s, and for the B5000/B5500 to support both that and multi-processing was so far out that Burroughs was often accused of faking it when the capability was demonstrated. It did work, though, and was quite effective if you had a sufficiently processor-bound workload and the memory to support that workload. The two main reasons P2 can be underutilized are insufficient memory (generally resulting in MCP overhead and I/O to overlay memory to and from disk) and high levels of requests for MCP services, such as I/O, both of which can handled only by P1.
You can enable second-processor functionality for the emulator by a setting in the emulator/B5500SystemConfiguration.js script. Set both PA and PB to true, and set PB1L to indicate which processor is P1. The other will be P2. At present, the second processor is disabled by default in the standard release.
Those of you using a hosted web site are not able to modify that configuration script, so we have implemented a temporary workaround to allow you to enable the second processor:
- Clicking the NOT READY lamp on the Console display will toggle the availability of Processor B in your local copy of the system configuration. When enabled, it will run as P2.
- When P2 is enabled in this way, the version level to the left of the "retro-B5500" logo will be yellow. When P2 is disabled, the logo will be white as usual.
- The availability of P2 is evaluated only when the POWER ON button on the Console is clicked, so it is best to change the status of P2 when the emulator is in a powered-off state.
When the system is running and P2 is available, you should see P2BF turn on and off in concert with the B NORMAL lamp (assuming Processor B is configured as P2) as the MCP assigns user tasks to the processor. You may also see the HP2F (Halt Processor 2 flip-flop) annunciator flash occasionally as the MCP stops P2, usually to assign another task to it after the current task's time slice has expired.
You will need a fairly fast system to run both processors simultaneously at full speed. If the P1 Slack indicator on the emulator console is not at least 50% when running one processor, then your system may not be powerful enough. My one-year old, 3GHz, quad-core Dell Optiplex 390 running 64-bit Windows 7 Pro handles this with ease, as does a six-year old Mac Mini with an Intel Core 2 Duo processor running OS X Snow Leopard. An eight-year old Dell Optiplex GX 520 with a 2GHz Pentinum P4 running Windows XP is borderline. All of these tests were done using Firefox 24.0. Dual B5500 processors will still work on less powerful hosts, but the entire emulation will run slower than it otherwise would.
Tape Drive Oscillation at Load PointSince the initial magnetic tape drive implementation was released in 0.15, a few people have been bedeviled by some odd behavior when a drive is made ready after loading a tape image, or after a tape is rewound by the MCP. There were some problems in the way that the driver was handling the tape image and reporting status to the MCP at load point (also known as Beginning of Tape or BOT). Those were mostly fixed in release 0.16, but a couple of people were still having significant problems. I couldn't reproduce them.
After about two weeks of collective hair-pulling, we finally determined that the problem was not the tape drive module, but an MCP configuration problem. Paul Cumberworth and Tim Sirianni were the ones still having the problem on 0.16, but they were also the ones working on cold-starting the emulator from card decks. In fact, they had that working, and had each cold-started their emulator instances from the Mark XIII cold start deck instead of the ColdLoader web script.
For some reason that we still have not run to ground, that version of the cold-start program does not properly set bit #2 (MOD3IOS) in the MCP option word. The emulator's I/O Control Units were written to behave like Mod-III I/O units, but that setting in the option word was telling the MCP that the I/O units did not have Mod-III capabilities. As a result, the MCP was handling the reading of tape labels entirely differently, and that difference was resulting in an endless cycle of the MCP reading the tape label and then rewinding the tape.
Paul Cumberworth reported this past week that the problem does not occur when cold-starting using the Mark XVI deck.
Fortunately, we found an easy workaround for systems that have been cold-started using the Mark XIII card deck. After the MCP has halt/loaded and you have entered the time of day, simply enter this command on the SPO:
SO USE OPTN 2That will set bit #2 in the option word, and that setting will persist across halt/loads and emulator/browser restarts. Note that you will not need to do this if you have cold-started using the ColdLoader script. Also note that the SPO TO command does not display the status of bit #2 in its output.
If anyone feels left out and wants to experience the tape oscillation problem for themselves, you can manually reset bit #2 in a similar way and see what was driving Paul and Tim batty:
RO USE OPTN 2Then load a tape image and make the drive ready. When you are tired of watching the tape drive misbehave (it probably won't take long), just use the first command above to set things right again.
Other Changes in this Release
- The Character Mode syllables FAD (Field Add) and FSU (Field Subtract) would complement the wrong operand in certain cases. This was due to the initial compare of the operands being done in an alphanumeric mode instead of a numeric mode.
- The Character Mode syllables TRN (Transfer Numerics), TRZ (Transfer Zones) and TBN (Transfer Blank for Non-numeric) did not work properly if the transfer spanned more than two words of memory. Words other than the first and last in the destination string were not being fetched into the B register.
- If you have access to the B5500SystemConfiguration.js script, you may now configure up to 16 tape drives on the system.
- The flip-flop latching mechanism in Central Control that is used by B5500Console for displaying annunciators was completely redone.
- The routine that cleared interrupts in Central Control was reworked for more efficient operation.
- New algorithms were implemented to compute average slack and delay in the Processor.schedule() routine.
- Some Character Mode syllables were optimized by substituting local variables for Processor object "this" properties.
- The Processor single-precision divide syllables were leaving the stack in an incorrect state after a divide by zero in Control State. This has been corrected.
- A few further minor tweaks to performance throttling were implemented.
- References to this.cc in the Processor.run() routine were optimized.
- A few improvements to the tape drive module were implemented to eliminate oscillation at load point and improve the timing of rewind operations. The bulk of the tape drive oscillation problem was caused by the configuration problem discussed above.