A Bit About the HP3000
Today's anonymously submitted story is a case where the WTF isn't the code itself, per se. This arguably could be a CodeSOD, and we'll get to the code, but there's so much more to the story.
Our submitter, let's call them Janice, used to work for a financial institution with a slew of legacy systems. One such system was an HP3000 minicomputer. "Mini", of course, meant "refrigerator sized".
The HP3000 itself is an interesting, if peripheral story, because it's one of the tales of a product launch going incredibly wrong. Let's talk a little history.
We start with the HP2100 in 1966, which Hewlett Packard did nothing to design, and instead purchased the company that designed it. The core innovation of the HP2100 was that it was architecturally similar to a PDP-8, but supported full 16-bit memory, instead of PDP's 12-bit.
HP didn't really know what they had bought- they marketed it as a "test and instrumentation" system, and were surprised when businesses purchased it for back office operations. They ended up with one of the most popular minicomputers for office use, despite it not being designed for that purpose.
Thus began the projects "Alpha" and "Omega". Alpha was a hardware refresh of the 2100, with a better memory model. Omega was a ground-up redesign for 32-bit memory, which would allow it to support a whopping 4MB of RAM. There was just one problem with the Omega design: they didn't have funding to actually finish it. The project was killed in 1970, which threw some of the staff into "wear black armbands to work" levels of mourning.
Unfortunately, while work was done on Omega, the scope of Alpha crept, which resulted in another project management wasn't sure could be delivered. But the market was there for a time-sharing minicomputer, so they pressed on despite the concerns.
The HP2000-line had time sharing system that used multiple processors. There was a front-end processor which handled user interactions. Then there was the actual CPU, which ran programs. This meant that time-sharing was simplified- the CPU just ran programs in a round-robin fashion, and didn't have to worry about pesky things like user inputs. Essentially, it was really just a batch processing system with a multi-user front-end.
The designers of Alpha wanted to support full multiprogramming, instead of this hybrid-ish model. But they also needed to support traditional batch processing, as well as real-time execution. So the team split up to build the components of the "Multi-Programming Executive" module, which would allow all of these features.
The Alpha, which was still 16-bit, didn't have the luxurious 4MB of RAM- it had 128kB. The MPE used much more memory than 128kB. This led to a massive crunch as the programmers worked to shrink MPE into something usable, while marketing looked at the deadlines and said, "We were supposed to be selling this thing months ago!"
The result was a massive war between engineering and marketing, where marketing gave customers promises about what the performance would be, engineering told marketing what the actual performance would be (significantly worse than what marketing was promising), and then management would demand engineering "prove" that marketing's over-promises could be met.
The initial ship-date was November, 1972, and by god, they shipped on time. Nothing actually worked, but they shipped. The first computer out the door was returned almost immediately. It could only handle two simultaneous users before slowing to a crawl, and crashed every ten minutes. By December, HP had gotten that to "crashes every two hours". They kept shipping machines even as they had to cut features and reliability promises.
Those frequent crashes also concealed another bug: after running for 24 days, the HP3000's clock would overflow (2^31 milliseconds) and the clock would magically reverse by 25 days. As one sysop of a purchased HP3000 put it: "The original designers of MPE never thought the OS would stay up for 25+ days in a row".
After a bunch of management shuffling, the titular Packard of Hewlett Packard sent a memo: production was stopping and all sold computers were being recalled. Customers were offered HP2000s in its place, or they could wait until fall 1973 for a revised version- that would only support 4-6 users, far fewer than marketing's initial promises of 64. This pleased no one, and it's reported that some customers cried over the disappointment.
With sales paused, the entire computer underwent a design overhaul. The resulting machine was faster and cheaper and could actually handle 8 simultaneous users. One year after the botched launch, the HP3000 went back on the market, and ended up being a full success.
It was so successful, HP continued supporting the HP3000 until 2010, which is where Janice enters our story. Circa 2006, she needed to update some Pascal code. That code used a lot of bit-masks to handle flags, which is normally a pretty easy function in Pascal- the language has a standard set of bitwise operations. So Janice was surprised to see:
FUNCTION BITON(A , B : INTEGER): BOOLEAN;VAR C : INTEGER;BEGIN CASE A OF 15 : C:=1; 14 : C:=2; 13 : C:=4; 12 : C:=8; 11 : C:=16; 10 : C:=32; 9 : C:=64; 8 : C:=128; 7 : C:=256; 6 : C:=512; 5 : C:=1024; 4 : C:=2048; 3 : C:=4096; 2 : C:=8192; 1 : C:=16384; 0 : C:=32768; OTHERWISE BITON:=FALSE; END; IF ((B DIV C) MOD 2) = 1 THEN BITON:=TRUE ELSE BITON:=FALSE;END;FUNCTION SETBITON(A, B : INTEGER) : INTEGER;VAR C : INTEGER;BEGIN CASE A OF 15 : C:=1; 14 : C:=2; 13 : C:=4; 12 : C:=8; 11 : C:=16; 10 : C:=32; 9 : C:=64; 8 : C:=128; 7 : C:=256; 6 : C:=512; 5 : C:=1024; 4 : C:=2048; 3 : C:=4096; 2 : C:=8192; 1 : C:=16384; 0 : C:=32768; OTHERWISE C:=0; END; IF NOT BITON(A,B) THEN SETBITON:=B + C ELSE SETBITON:=B;END;FUNCTION SETBITOFF(A, B : INTEGER) : INTEGER;VAR C : INTEGER;BEGIN CASE A OF 15 : C:=1; 14 : C:=2; 13 : C:=4; 12 : C:=8; 11 : C:=16; 10 : C:=32; 9 : C:=64; 8 : C:=128; 7 : C:=256; 6 : C:=512; 5 : C:=1024; 4 : C:=2048; 3 : C:=4096; 2 : C:=8192; 1 : C:=16384; 0 : C:=32768; OTHERWISE C:=0; END; IF BITON(A,B) THEN SETBITOFF:=B - C ELSE SETBITOFF:=B;END;FUNCTION LAND(A,B : INTEGER) : INTEGER;VAR I : INTEGER;BEGIN I:=0; REPEAT IF BITON(I,A) THEN IF BITON(I,B) THEN A:=SETBITON(I,A) ELSE A:=SETBITOFF(I,A) ELSE A:=SETBITOFF(I,A); I:=I + 1; UNTIL I > 15; LAND:=A;END;
This is a set of hand-reinvented bitwise operations, culminating in an LAND, which does a bitwise and (not a logical and, which makes it annoyingly misnamed). I wouldn't call the code a horrible approach to doing this, even if it's definitely an inefficient approach (and when you're running a 33 year old computer, efficiency matters), but absent built-in bitwise operations, I can't see a lot of other options. The biggest problem is that LAND will set bits on that are already on, which is unnecessary- an AND should really only ever turn bits off.
Which, as it turns out, is the root WTF. The developer responsible wasn't ignorant about bitwise operations. The version of Pascal that shipped on the HP3000 simply didn't have any. No and, or, not, or xor. Not even a shift-left or shift-right operation.
In any case, this is what happens when I start doing research on a story and end up getting sucked down a rabbit hole. As always, while Wikipedia's true value is as a bibliography. A lot of those links have much more detail, but I hope this quick overview was an interesting story.
[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!