Saturday, December 25, 2021

Merry Old VCR Christmas

Signs you married well: your wife buys you vintage artifacts for Christmas, in this case a logic chip and fragment of a PCB from the Cray-1 at the Lawrence Livermore National Laboratory.
(The other chips in this picture are IBM dies from a 90MHz PowerPC 601+ and a POWER9.)

The chip is a Fairchild SL56660, a 5/4 NAND gate. The original design only employed four ICs but in huge quantities: this one, an alternative but slower NAND gate, 1Kx1 bipolar SRAMs (usually the Fairchild 10415FC, about 70,000 of them in the 1976 Los Alamos National Laboratory unit), and the specialized Fairchild SL82747. This chip bears a date code of 14th week 1981 and is based on emitter-coupled logic (ECL), making it very fast for the time but also very power-hungry; CMOS made ECL and MECL obsolete. The later date code can be attributed to the fact this was probably from a board installed for repair purposes.

Merry Christmas and a very happy holiday season.

Sunday, December 19, 2021

Monitoring the vintage server room (and reverse-engineering USB sensors)

We're house hunting because of $JOB and $HOUR hour commute, and I just got word that the reseller I contract with for Floodgap's leased line is getting out of that business in mid-January. This makes finding new digs (or at least setting up some sort of temporary static IP alternative) a must because one of the gotta-haves is space for my vintage server room. Sure, you can outsource, or host things on slices, or put things on a rack of Raspberry Pis and call it a day. And admittedly that would probably take up less space, generate less heat, use less power and result in less inconvenience, but where's the fun in that when you can be running your own 2008-vintage IBM POWER6 for mail, web and gopher, or a Sawtooth Power Mac G4 file server, or a 1989 Mac IIci that still happily handles internal network DNS?

Part of the task of any home server room, vintage or otherwise, is monitoring. After all, you're now your own L1, L2 and L3 support. A camera passively observes the room that can be remotely viewed. The main server can generate alerts if it fails over to a UPS (power outage, blown supply, etc.). If the WAN connection goes down, an SMS gateway can communicate with me by text message and I can query it about the state of the internal network. I use an SMSEagle for that, basically a Raspberry Pi in a cool case with an LTE modem running modified Raspbian (which I naturally have modified further). All of the systems can send it alerts for broadcast via its internal APIs.

(The USB device plugged into it I'll discuss a little later.)

That leaves environmental controls. Here in Southern California, winters aren't that cold, so the major need is cooling during summer and fall. The room is cooled by a 12,000 BTU portable air conditioner that vents to an outflow portal on the roof and whose power is controlled by a programmable power strip. The A/C turns itself off and on based on its thermostat but the A/C isn't network enabled, so I need to know what temperature it actually is in the room, and whether the air conditioner is in fact running — ideally something that would assess if there's airflow.

The temperature sensor is a THUM.

I bought it back in the day because they had a native Power Mac command line client, but now that I have other things I'd like to connect it to (and the client was closed-source, at least at the time), I decided to reverse-engineer the protocol. Naturally, the first thing to do when you're doing that is to crack it open.
Internally the THUM is actually a relatively simple device. A small Sensirion SHT75 temperature and humidity sensor sticks out of the side of the case and is connected to a PIC 16C745-I/SP, which is the main chip dominating the board (the TMS SN65240 is there to suppress transient signals on the USB port). The theory of operation is thus fairly obvious: the PIC merely reads raw sensor data from the SHT75 and provides it to the connected system (it shows up as a USB HID). The next step was thus to reverse-engineer the actual wire protocol.

Snooping on a mysterious USB device is most easily done with the USB monitoring tools in Wireshark. I installed it on my MacBook Air and, with Wireshark running, would run the closed-source THUM Mac tool, note the temperature and relative humidity the official client reported, and then save the trace. Here's an example.

Every single session showed two URB_CONTROL and URB_INTERRUPT couplets. The control from the connected Mac was a two byte message, first 00 00 (which appears to be a temperature command), and then 01 00 (which appeared to be humidity). The THUM would then reply with its own two byte response. One would assume any reported value would increase as temperature and humidity both increased, so looking at the reports this value was most likely a 16-bit big-endian (yay!) unsigned short. I made a number of readings and then plugged them into LibreOffice.
Using LibreOffice's regression analysis tools, the fit is perfectly linear (assuming, of course, the sensor doesn't vary at its extents, which is always a risk with sensors) and we should now have an accurate intercept and slope to compute temperature in Centigrade from the provided value.

Humidity was a little harder, as relative humidity depends on temperature to determine how much water vapour the surrounding air can actually carry, and I wasn't able to get a good regression fit. After messing around with the numbers some, it dawned on me I could just go pull the datasheet for the sensor to see if the manufacturer had any coefficients I could plug in. Not only did the datasheet have a nice graph, it actually had formulae for computing a linear relative humidity value from the sensor value, and then to adjust it for the observed temperature. The formula matched the official THUM client's computation perfectly.

Now we have all the steps needed to actually write our own client, so I did, which I'll link to at the end (the same C source file compiles on Mac OS X and Linux). The only other glitch I ran into was that you must fetch the humidity after you fetch the temperature, and you must read both; you can't just fetch one or the other. If you try to do that, the PIC may flip out and even stop responding to you until the box is reset.

As a post-script, the datasheet also contained a formula for the temperature (as well as the valid ranges), but the coefficients didn't quite match my linear regression values. Later on someone at Practical Design Group responded to my E-mail and put up source code and pre-built binaries for the Raspberry Pi. This client seemed slower than my own client on my Raptor Talos II (and there wasn't Mac source code), so I'm sticking with my homebrew version, which is what runs on the G4 server now (which runs OS X Tiger). Interestingly Practical uses the Sensirion formulae for relative humidity, but their coefficients matched mine for computing temperature, so I kept those also.

Now, airflow. I decided an easy approach would be to monitor sound levels, since any audio pickup with its wind screen off will detect air passing by as noise. As an added bonus, if any alarms were going off, dying cooling fans, dying other things (always a possibility with old hardware), etc., the resulting audio disturbance would also be detectable.

The most inexpensive and easy way to get "live" USB-based decibel meters are versions of the GM1356, shown here in operation "monitoring" the air conditioning unit.

This ubiquitous meter is easily recognized by its six-button control panel and standard case and accessories, and was rebadged by a number of manufacturers (here a BAFX 3608) with logging software for Microsoft Windows. Fortunately some enterprising soul had already written a Ruby-based monitor for this device, so I figured it would be a simple matter to convert it to C and have it run on the G4 server too. I patterned off the same code I used to query the HID for the THUM, plugged it into the G5, and ... nothing but errors trying to talk to it. On the possibility this device was uncovering an irregularity with HID support in OS X Tiger, I plugged it into my NetBSD G4 Mac mini. It said there was a problem with the device and disabled the port.

Now wondering if I had a defective unit, I then plugged it into my Linux Raptor Talos II, determined its vendor and ID with lsusb and tried to pull a device report with lsusb -v -d 64bd:74e3. Besides showing an impossible HID polling interval of zero (!), lsusb did faithfully display the USB configuration report but then hung up and timed out with cannot read device status, Resource temporarily unavailable (11). At this point, since they were cheap, I bought a second one. It did the exact same thing.

It turns out this unit is obnoxiously non-compliant with the USB HID standard, just enough to work with Windows, which is its only supported platform. You can't use normal HID queries with it on apparently any operating system (for that matter, Linux libhid doesn't like it either), but if you send raw queries with usb_interrupt_write and usb_interrupt_read you can get something out of it in Linux, at least. I gave up trying to get OS X IOKit to play nice, so after porting the Ruby client to C on the Talos II, I put it on the only Linux system I have running in the vintage server room — the Raspbian SMSEagle. And that's what you see connected to it.

Does this work for monitoring? After all that, yes. I took some measurements and the baseline noise in the server room ranges from 54 to 56dB depending on how warm it is (on warmer days the cooling fans are louder). When the A/C comes on, it runs at full blast and the device picks up the airflow at 60dB+. This is a significant and easily noticed jump, so this benighted piece-of-crap still ends up being more than enough to know if the A/C's actually hauling A.

The next thing I'll add, probably in whatever crumbling shack we're able to afford in this hideous housing market, is power monitoring. While I can control outlets, I can't really determine short of manually grabbing a Kill-O-Watt how much draw is occurring on any given circuit or power strip. It would be nice to know who's sucking the amps other than, of course, the beasts themselves. They get a pass because they're still doing useful work, even if they aren't as sexy or efficient anymore.

The C code for the THUM command line tool (OS X, at least 10.4, possibly earlier and Linux) and GM1356 command line tool (Linux) are available as Github gists.

Friday, November 26, 2021

xa 2.3.12

I've updated xa, André Fachat's venerable 6502 cross-assembler, to version 2.3.12. This contains a bug fix for a regression in 65816 mode which I'd meant to release earlier but got sidetracked on (thanks Samuel Falvo for the nice test case, which is also incorporated into the suite). As with prior versions it is tested on pretty much all of my Un*x-alike systems here including AIX, Mac OS X (PowerPC, Intel and Apple Silicon), NetBSD/mac68k and Linux/ppc64le. I said this before for 2.3.11 but one more time for the record: this will probably be the last in the exceptionally long-lived 2.3 series before 2.4, which as I keep warning you will definitely have some minor compatibility breaks and jettison a couple long-deprecated options and syntaxes (but will have some new features to make up for it). Again, more to come on that.

Sunday, October 3, 2021

Shiner ESB, an Apple Network Server prototype, and what it did at Netscape/MCom

The Apple Network Server was, with the possible exception of the Apple Workgroup Server 95, Apple's first true server. I have a particular soft spot for the ANS because it was also my first server: an ANS 500 ran Floodgap (even before Floodgap in 1998 as and from 2000 until 2012, and stockholm is still in my collection. While Apple had the Workgroup Server line, these were merely contemporary Mac designs with value-added software or hardware options, and as such ran Mac OS. (The AWS 95 ran A/UX, Apple's SVR2 Unix-System 7 hybrid, though it could also run Mac OS — being really a rebadged, hopped-up Quadra 950 — with its custom PDS SCSI card removed.)

The ANS, however, was a real honest to goodness server with hotswappable drive bays and fans, and (its most notable feature) an award-winning lockable translucent door so you could keep the unwashed masses out of your drives but still watch the blinkenlights. If you bought the bigger model, you even got dual power supplies and additional rear bays.

Also notable about the ANS was that they weren't supposed to run Mac OS, and were never sold with it, not least of which because the classic Mac OS wasn't really up to the task of being a server. Unfortunately, while A/UX supported larger needs on the 68K-based Workgroup Servers that could run it, A/UX 3 couldn't run on Power Macs even under emulation. The plan with A/UX 4 was to use a new PowerPC-native OSF/1-based kernel and possibly to also integrate portions of IBM's AIX operating system, but this plan (along with Taligent and other doomed projects) stalled out with everything else in Apple around that period. For a time Apple even considered using Novell NetWare on PowerPC; the port actually existed, codenamed Wormhole, but its tepid reception eventually led to the release of the weird Workgroup Server 9150 which just ran Mac OS. Eventually, to get to market Apple reached for what was then the only professional-level Un*x running on the new PowerPC architecture, which was AIX itself. Three Apple Network Server models were developed but only two (the "Low End" 500 and "High End" 700) were released; the 3U rack 300 "Deep Dish" remained solely a prototype, which I'd still love to acquire if its current owner ever gets tired of it. Oddly, even though they were only ever sold as AIX machines, they were initially demonstrated running a custom version of MacOS which was never released with them (I'd love to see this release myself), further confusing potential customers who already didn't want to buy Workgroup Servers. Introduced in 1996 at a retail cost starting north of US$10,000, which didn't even include the AIX license, they were very poor sellers and the line was canned by Gil Amelio around a year later.

I got my ANS 500 barely used for the cost of some consulting work after Apple stopped supporting it; you can see some scanned Polaroids of when it was in production way back in 1998. Later, I acquired an ANS 700 which I use as a spare and was briefly in service while I diagnosed a hardware issue with the 500. More recently, however, I managed to land a Shiner HE prototype dated 1995 from a scrapper in San Rafael, California. That is the unit depicted in these pictures.

The codename "Shiner" is a brand of beer named for its town of manufacture in Texas, and was reportedly the favourite adult beverage of the 1990s Server Group Division based out of Apple's Austin offices, thus lending its name to the product. Although all of the boards within this machine are marked as EVT (engineering validation test) prototypes, they are very similar to production hardware save the labelling, and the machine itself is labelled with the unknown acronym "ESB." [drudru on suggests, keeping with the beer theme, that this might mean Extra Special Bitter. That makes sense!]

Appropriately, Apple Network Servers remained a significant portion of even after their commercial exit; reportedly some units were still in operation as late as 2005, well into the Xserve era and almost up to the Intel transition. However, this machine — unimaginatively named shiner — had a different path, where at its place of residence it seemed to function as a test server. The disk it came with was partially recoverable and we'll look at some goodies in a moment. Unfortunately, at some point after decommissioning it was improperly stored in a high moisture environment with the lithium PRAM battery still installed. Never do this with old Macs: the battery exploded and leaked all over the board, and when I acquired the unit it was no longer working. The door keys were also missing which required me to force the lock to get into the front bays. Despite the damage and the rough handling it's endured, the board markings and residual history nevertheless make it an interesting show-and-tell piece, so I present it here.

After the pictures we'll talk about what was on the hard disk ...

Portrait. Notice the badge doesn't say Apple Network Server like a production machine — it's just a plain Apple logo and blank where the text would go. The plastic is also not textured, although it does appear to be injection-moulded.

There are two missing trays in the front. One was the hard disk it came with that I removed for safe storage, but the other came to me empty, and was probably part of the rootvg which we'll talk about later.

Close-up on the asset stickers. This machine is marked "Property of America Online" but its best documented operation appears to be earlier (again, more later). It also has a front sticker with its hostname showing it ran AIX 4.x (the hard disk I got was AIX standard JFS) and an IP that doesn't respond to anything. Also notice consistent with the pre-production plastic that there are no icons on the keyswitch for lock, unlock or service mode.
The rear has an FCC warning sticker and, on the backplate where the model and regulatory approvals would go, the simple legend "SHINER ESB H.E."
Sadly, with the logic board drawer pulled out, you can see the damage where the battery contents dripped down. You can also see the rather alarming amount of rust, er, oxidation on the fan bay. When I got the unit there wasn't anything installed in the slots except the processor card.
That said, even if the logic board were working, it would probably be somewhat anticlimactic: the money is in the markings, not in the layout, which looks very similar to my production 500 and 700. The EVT logic board is dated 1995 and the part number 820-0744-02 suggests a second revision (the production board is 820-0744-A). On this unit and the previous picture the chips themselves have their codenames on the EVT board; on the production board they are replaced with boring functional names.
For example, HAMMERHEAD and ZAX are printed on the EVT board, but the production board has their actual roles, i.e., MEMORY CNTRL (the memory controller) and DATA PATH. The appelation "SIM" on the cache and ROM slots does not appear on the production board. Hammerhead is limited to 512MB of RAM, but this was a lot in 1997, and it could accept FPM or EDO sticks. You really wanted parity in this thing, too: if all the RAM was parity, it would use 60ns timing, but if any of the DIMMs weren't, besides disabling parity it would slow RAM access to 70ns. Parity FPM RAM in particular was expensive as hell and almost impossible to find anymore. Apple sold parity FPM DIMMs in upgrade kits at typical Apple prices.
When the logic board drawer is closed, it mates with this slot on the mezzanine board which handles interconnects with the power supply, front panel and SCSI backplane. The mezz board has its own codename "HENDY." Hendy had a lot of changes as suggested by its part number 820-0713-07 but I'm not sure what they are. On the other hand, the SCSI backplane on the other side of the panel has no codename at all and is identical to my production 700 except for the 1995 date and pre-production part number.
The processor board also has its own code name ("FIGMENT"). ANS CPU boards came with a 132MHz (base 500), 150MHz (base 700) or 176MHz PowerPC 604 or a 200MHz 604e, along with a prototype dual-CPU card which was never released. The 132MHz and 176MHz cards use a 44MHz bus but the 150MHz and 200MHz cards run at 50MHz. The single-CPU boards differ only in the processor and speed resistors and use a common daughterboard otherwise. Other than markings it appears pretty much identical to production cards and appears to have had only one revision (this one is 820-0740-01; my production cards are 820-0740-A).
In particular the debugging jumpers are still on production cards (plus-minus actual contacts, but the holes are still present), just marked differently. There is hardware information on this picture and the previous one along with a bus speed and 604 power table "LEDGEND" [sic].

So, the hard disk.

The single hard disk it came with suffered the same external oxidation as everything else, but the drive itself powered up when I connected it. So I pulled the regular trays from my 500 as a precaution, installed this single tray, booted from the "Harpoon" AIX 4.1.5 CD and tried to mount it.

The bad news is that this disk seems to be only part of a larger JFS rootvg (in AIX parlance, this refers to the collection of logical hard disks that compose the default volume group), and attempting to bring it up as a standalone volume just caused a lot of errors. I suspect the missing tray contained the other disk (and, irritatingly, /). However, although Apple sold a RAID option for the ANS, this remaining disk didn't appear to be a member of an RAID array and I was able to get a sensible image of it with dd. Its hostname?

Yup. This ANS was at Mosaic Communications Corporation, though by this time it would have been fully converted to Netscape Communications Corporation.

strings, grep and less will get you a long way with digital archaeology on unencrypted drives. I found lots of old and new files, but overall after piecing them together the machine's primary task was running Netscape Collabra Server v3.01 21301. This was one of the all-singing-all-dancing enterprise server solutions then in vogue and was roughly contemporary with Netscape Navigator 3.0. These screenshots were extracted from its installation instruction document.

Collabra, you will recall, attracted jwz's apparently everlasting ire by being a Netscape acquisition that somehow managed to take over Netscape instead of the other way around. LDAP, NNTP and HTTP strings are present along with symbols that anyone familiar with Mozilla source code will recognize as old-school NSPR and NSS. I found part of what appears to be its configuration file:

NetsiteRoot /home2/Collabra/drd970801
Port 4444
User root
ErrorLog /home2/Collabra/drd970801/admin-serv/logs/errors
AccessLog /home2/Collabra/drd970801/admin-serv/logs/access
PidLog /home2/Collabra/drd970801/admin-serv/logs/pid
Backups 10
AdminUsers /home2/Collabra/drd970801/admin-serv/config/admpw
Hosts *
ONEAclDir /home2/Collabra/drd970801/adminacl
ConfFile /home2/Collabra/drd970801/admin-serv/config/cron.conf
Dir /tmp
Status on

drd970801 sounds like a developer release path. This header appears on most of the control panel files:

* Copyright (c) 1997 Netscape Communications Corporation. All Rights Reserved.
* Use of this Source Code is subject to the terms of the applicable license
* agreement from Netscape Communications Corporation
* author:

This guy wrote a lot of stuff, too.

The presence of LDAP and HTTP support notwithstanding, the scattered log fragments present on the machine suggest it was mostly doing NNTP (newsgroup) duty. For example, here's the administrator logging in via the web interface: - - [01/Aug/1997:14:29:12 -0500] "GET / HTTP/1.0" 401 223 - nsadmin [01/Aug/1997:14:30:48 -0500] "GET /news-shiner-119/bin/pcontrol HTTP/1.0" 200 1341 - nsadmin [01/Aug/1997:16:07:23 -0500] "GET /news-shiner-119/bin/index HTTP/1.0" 200 343, by the way, turns up in this Oracle discussion (allowed is not! is planet forbidden!).

And here's somebody from posting and reading:

4 [97/08/01 16:07.20] nnrpd(0.13570) post ok <5rtj5n$>
4 [97/08/01 16:07.20] nnrpd(0.13570) post ok <5rtj5j$>
4 [97/08/01 16:07.20] nnrpd(0.13570) exit articles 0 groups 0
4 [97/08/01 16:07.20] nnrpd(0.13570) posts received 55 rejected 0
4 [97/08/01 16:07.20] nnrpd(0.13570) posts received 55 rups 0
4 [97/08/01 16:07.20] nnrpd(0.13570) times user 569.800 system 302.310 elapsed 4535.986

In fact, a generated report of the Top 10 Hosts by Number of Articles Posted only shows There's a reason for this we'll discuss in a moment.

As you would expect for a machine generally occupied as a news spool, various copies at various stages of the newsgroup active file are present. They include the default (example?) groups, like acl, control, junk, test and virtual (shown here in the administration interface),

but also some slightly suspicious internal newsgroups,

mcom.url 0000000000 0000000001 y
mcom.url.bad 0000000000 0000000001 y
mcom.url.bad.bad 0000000000 0000000001 y
mcom.url.bad.bad.bad 0000000000 0000000001 y
mcom.users 0000000000 0000000001 y
mcom.users.clue-impaired 0000000000 0000000001 y
mcom.white-trash 0000000000 0000000001 y
mcom.wreck 0000000000 0000000001 y 0000000000 0000000001 y

and most famously

mcom.bad-attitude 0000000000 0000000001 y

as subpoenaed by Microsoft in 1998, though sadly, as the numbers imply, no articles from any of these groups are actually present on the drive. Instead, what is present is a lot of test material. Rich Salz's 1991 post "Seeking beta-testers for a new NNTP transfer system" <> exists as a test file for INN; the real on-spool posts on the disk have headers like this:

From: AutoPost@shiner
Newsgroups: kstress,pstress
Subject: AutoPost: shiner:119 18491-2-5
Date: 1 Aug 1997 19:54:26 GMT
Organization: Another Netscape Collabra Server User
Lines: 2216
Message-ID: <5rteti$>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="------------36A62DDA30E4"
X-Mailer: Mozilla 2.01 (X11; I; IRIX 5.3 IP22)
X-Mozilla-Status: 0001
Xref: kstress:34 pstress:34

This is a multi-part message in MIME format.

Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="UsenetPast.jpg"

The posting agent is actually Netscape 2, which is interesting, from an IP22 Silicon Graphics machine (probably an SGI Indy: I was using an Indy myself in 1996 when I did an independent study block at the Salk Institute). Parenthetically, a fun hostname turned up in a few places looking through the news spool, which seems to be the same system as

These newsgroups (kstress and pstress) appear to be strictly local. In fact, their very name alone indicates they were solely there for testing purposes. All the other articles on the machine are just big binary base64 blob posts, made by an mewing. There is an LDAP entry for this person (here represented in LDIF).

dn: cn=NewsHackers
objectclass: top
objectclass: groupOfUniqueNames
cn: NewsHackers
creatorsname: uid=nsadmin
createtimestamp: 19970407202758Z
uniquemember: cn=Mike Ewing
uniquemember: cn=splat poster
modifytimestamp: 19970505183057Z
modifiersname: uid=nsadmin
entrydn: cn=newshackers
parentid: 0

(They don't appear to be the system administrator, though. Here's that person's LDAP entry; no other users were obvious.)

dn: cn=Administrators
objectclass: top
objectclass: groupOfUniqueNames
cn: Administrators
creatorsname: cn=Directory Manager
createtimestamp: 19970407165907Z
modifytimestamp: 19970515174534Z
modifiersname: uid=nsadmin
uniquemember: cn=splat poster
uniquemember: cn=Gena Cunnanan
entrydn: cn=administrators
parentid: 0

mewing also appears in logs,

4 [97/08/09 04:01.02] news.daily:sending a copy of the daily report by email to

and the Collabra junk group on this machine is actually called Mike's Junk. Assuming this isn't an oblique anatomical reference (there are a lot of binaries, after all), this person appears to have been the machine's primary user, and I thus conclude the machine's primary purpose — at least at that time — was as a test spool for the news server functionality of Collabra that this person was working on.

And that brings me to the most important question I wanted to answer: how long was this machine actually in service? The timestamps from the LDAP-LDIF entries are the earliest unambiguous dates I can find on the machine (April 4, 1997), and the most recent log entry I can find in the image is this one from September 4, 1997:

4 [97/09/04 12:46.32] indexsend:[8388] stop Thu Sep 4 12:46:32 1997

A solitary 1998 timestamp 29/Mar/1998:4:36:53 -0800 appears as an example in a help document, but that document has a 1997 copyright date, so it could just be illustrative.

That said, it's entirely possible and even probable that still more recent log entries were present on the other, missing drive. The machine had to be at Netscape through at least 1999 in order to pick up an America Online asset tag; AOL hadn't even announced it was acquiring Netscape until November 24, 1998, and the deal wasn't complete until March 17 the following year (for US$10 billion — in 2021 dollars, US$16.42b). Likewise, it wouldn't make sense for Netscape to pick up the machine as a beta test and then not do anything with it for nearly a year, unless it was a later used purchase (but that doesn't make sense either because in 1997 they would probably have just bought a production machine). It thus may have been paved over at some point, or alternatively it wasn't initially running Collabra.

After all that, and with the incomplete information at hand, best guess says this machine was at Netscape/Mosaic from 1995 or so to about 1999 where it performed at least a solidly documented several months of test work. That's not a bad run for an old beast that by then was no longer being supported by Apple at all.

Are you Mike Ewing or Gena Cunnanan, formerly of Netscape? Did I miss anything? Please post in the comments if you have any light to shed. Meanwhile, you can see some more pictures of the prototype, or just read more about the ANS, the best server Apple ever disowned.

Tuesday, September 21, 2021

A happy ending (and future) for Plua

In my previous article on Plua, a port of Lua to classic PalmOS, I mentioned I was hopeful we'd have a happy ending where there was a clean-room implementation, or better still, that the original author would get in touch with me and we could redistribute it.

Well, I'm pleased to announce that Marcio himself did get in touch (he's got a lot of fun Palm and retro projects still underway, incidentally) and graciously consented to relicense Plua2c, the "cross-compiler" portion, under the same MIT license as Lua itself. You can now download the source code from Github, which I'll keep maintained.

As for Plua-the-Palm-app and its various components, I will still be hosting the .prcs on Plua Revisited indefinitely, and Marcio and I have been discussing how we can add some improvements such as expanded screen size support and the like. This means Plua has a future again, and I couldn't be happier. Thanks, Marcio!

Thursday, September 16, 2021

RIP Sir Clive Sinclair

In the US the name Sinclair is more associated with gas stations and partisan media outlets than computers. We had only the Timex Sinclair series States-side, of which the major models were the T/S 1000, a rebadged ZX-81, and the 2068, which was an upgraded but partially incompatible ZX Spectrum. (There was also the T/S 1500, a more upmarket version of the T/S 1000 roughly analogous to calling the Cimmaron by Cadillac a more upmarket Cavalier, and two minor non-American spinoffs of the T/S 2068, the TC2068 and UK2068.) These sold quite poorly in the United States because of the dominant position of the obviously superior Commodore 64 (I'm bracing for the comments from Martin), despite at least one retailer selling T/S 1000s at firesale prices so customers could get a rebate on a Commodore purchase. (Commodore reportedly used some of them for doorstops.) In the UK and Europe, however, they were a hit because they were cheap, and they introduced a generation to computers that may not have been able to afford them otherwise. My T/S 1000's keyboard has crapped out and I'm not even sure where my 2068 is, but on the announcement of Sir Clive Sinclair's death from cancer at 81, hats off, gentlemen, and godspeed.

Thursday, September 9, 2021

The Incredible KIMplement 0.2b: a KIM-1 emulator for the Commodore 64 (and the Superkim)

As I manage to eke out a little more time now for personal projects, since TenFourFox is coming to a close and the OpenPOWER JIT is developing at record pace, it's time to dust off some older items I've really neglected. This last week I started by updating the Incredible KIMplement, my MOS/Commodore KIM-1 emulator for the Commodore 64.

No, that's not a joke. The KIMplement runs real KIM-1 code using a software 6502 core I've christened "6o6" (6502-on-6502). 6o6 implements protected memory, exception handling and all legal NMOS instructions. In addition, the KIMplement not only emulates those famous six seven-segment LEDs and the hex keypad, but also is one of the few KIM-1 emulators that emulates a TTY connection (an old-school ASR-33) and a KIM-4 expander with 16K of RAM, allowing you to run "big programs" too.

The KIM-1 is one of the earliest single-board computers, at least in the sense we conceive of them today. It was introduced in 1976 as an enticement for engineers to play with the MOS Technology 6502 which was then the cheapest microprocessor on the market. MOS had just gotten its pants sued off by Motorola, who did not like the prospect of an inexpensive drop-in replacement for their 6800 CPU; the MOS 6501 was completely pin- and bus-compatible, and where the 6800 cost $179 the 6501 was priced at just $25. The "lawsuit compatible" 6502 was just as cheap, but because the pins had been rearranged, couldn't be substituted without additional design work. The KIM-1 provided a platform for engineers to become more accustomed with the 6502, featuring a 1MHz CPU, 1K of RAM, cardedge I/O, a keypad, LEDs and in-ROM support for teletypes, punch tape and cassette tape, for only $245.

MOS expected this would be a low-volume item mostly of interest to circuit designers. Instead, hobbyists bought them in large numbers because it was easily the least expensive microcomputer you could purchase at the time. With a KIM-1 at its center, you could have a full system with teletype, power supply and cassette storage for around $500. No other system came close to competing on cost. When Commodore Business Machines bought the ailing MOS in 1977, they wisely kept producing the KIM-1 until 1979 even after the introduction of the PET. Several clone systems exist, most notably including the Synertek VIM-1/SYM-1, as well as one unusual clone I'll talk about in a moment. I am the proud owner of four KIMs (including an original pre-Commodore KIM-1) and they all work.

I don't know if KIMplement's CPU core could be truly considered "virtualizing" the 6502, but it's more than just a naïve emulation. Rather than manually setting results and flags, the core looks at the guest instruction and runs the same instruction (or a safe variant) in the core context so that all the side effects, in particular changes to the status register, occur "for free." There is no way that a Commodore 64 at 1.0225MHz (or, worse, 0.978MHz for PAL) can do full-speed emulation of a KIM-1 running at 1MHz, but because there is much less code running per instruction, I think this scheme is probably near the fastest way a 6502 can run "untrusted" 6502 code. In practice it is about 35-50 times slower than native code, and this upsets programs that use tight timing or cycle counts, but it's still absolutely enough to actually "do things."

What sorts of things? Besides a couple LED-based games (originally Jim Butterfield's version of Lunar Lander, and I also added the misère game variant Black Match) and toy applications, you can run Tom Pittman's Tiny BASIC in the TTY, and with the bug fixes in 0.2b now you can successfully run FOCAL-65:

This screenshot in VICE shows the emulated 64 running a full FOCAL-65 program to manually compute square roots using Newton's method. It takes it a few seconds to do each iteration, but it all works. This is also a good demonstration of the FOCAL programming language itself including its unusual "floating point" line numbers (actually module and line), which it inherited from its more complex ancestor JOSS.

For this version of the emulator (0.2b), I finally finished some performance improvements to the CPU core that had been gestating in my mind for literally years -- the last version of the KIMplement was released in 2006! -- and also fixed a problem with the TTY emulation where typing characters could get out of sync under CPU load. It can still drop keystrokes if you overflow the Kernal keyboard buffer, but it's a lot smoother generally. I also worked around a bug in VICE where, if you try to load files from a directory on the host machine, the RENAME-the-file-to-itself test used to check for the file's presence doesn't work (a real 1541 would respond with error 63 FILE EXISTS but VICE says 0 OK).

The other bug I fixed was caused by the CPU core, but can't be fixed in it. The 6502 has a decimal flag which can be set in the status register and causes add and subtract instructions to operate in binary coded decimal (e.g., $90 - $01 normally is $8F, but in BCD mode it's $89). Famously, or perhaps infamously, the Commodore 64 Kernal IRQ doesn't turn off the decimal flag, and there is at least one SBC in the normal execution path. Because 6o6 executes instructions for their side effects, if a program had previously set the decimal flag (and this is not at all uncommon in KIM-1 code) it needs to be on for those math operations. The usual solution is to turn on the interrupt flag first with SEI to suppress IRQs while decimal mode is on, but the normal state of guest code is to have the interrupt flag clear because the KIM-1 doesn't have this problem. If an IRQ hits right that moment, the IRQ will be executed with the decimal flag on, and possible unexpected behaviour could result.

This is an extremely infrequent occurrence, but in a long-running system "infrequent" is a synonym for "inevitable." This can't be efficiently solved in the core because there is no atomic method for controlling two flags at once. A better solution is very simple: we just make a patched IRQ that clears the decimal flag explicitly, and calls the normal Kernal IRQ. I did the same for NMIs as a belt-and-suspenders approach.

The eventual goal is to open-source the KIMplement, and in particular 6o6, but I want to have another demonstration application for 6o6 as well before I do. A small multitasking general-purpose kernel sounds like an ideal way to show off how it works.

On my main KIM-1 site I also put in a few words about the microproducts Superkim. This 1979 variant of the KIM-1 was developed in Redondo Beach by Paul Lamar, who had been using KIM-1s for automotive performance testing but was unsatisfied with their expansion capacity. Unlike the hobbyist audience of the KIM-1, the Superkim is all business. The unit in my possession was clearly in a card cage; the hex keypad was never even fitted. It uses a custom board rather than a modified KIM-1 with sockets for RAM, ROM and up to four 6522 VIAs (this unit has 4K of static RAM and a Rockwell R6502P), and sports a full prototyping breadboard on-unit. But its most noticeable (and, I might add, intimidating) characteristic is the 200 gold wirewrap pins penetrating the board:
I have no idea what the sam heck this board was doing, but it clearly did something major in whatever its application was. Don't ask me to power this thing up because I'm worried I'll short something out somewhere. I don't know how many of these were ever sold and Commodore and MOS seem to have had nothing to do with its development.
Of the clones I find the Superkim the most interesting. While many people mention the Rockwell AIM-65 as a clone (my unit is above), and it is strongly based internally on the KIM-1, its substantial expansion (wide alphanumeric LED screen, full keyboard, printer) would not make it generally recognizeable as such. I think the Synertek VIM-1/SYM-1 are more characteristic, though that is one unit I don't personally possess.

In the future, and hopefully that future isn't in another 15 years, I want to add actual cassette support (right now you just dump memory to and from disk) and maybe support for one of the hi-res video boards like the Visable. It may also be worth trying to port the KIMplement to a faster 6502-based system like the Commodore Plus/4 or the Commodore 128 in 80-column mode, or maybe even the Apple IIgs, though all of these would need a solution for the sprites I currently use for the LEDs. (Okay, you Atari freaks, I know, I know.) The KIM-1 is a great little machine and surprisingly capable. The fact all of mine have survived over four decades proves they don't make them like they used to.

You can download a .d64 or .sdas of the Incredible KIMplement and its demo applications, or read more about the KIM-1.

Monday, August 30, 2021

More Tomy Tutor homebrew

Even the more obscure machines have their homebrews, and for the Tomy Tutor, I'm not just talking about third-pary tapes (though those are a thing too). In addition to 2018's Team Europe bounty (two multicarts and a reproduced "Game Adaptor" for those cartridges requiring additional addressing lines), a couple gamepads wired for the Tomy Tutor turned up on eBay. They are available in singles and doubles to replace either the Joy Stick or the Joy Controllers. Since the Tutor uses a unique pinout, these must indeed be made specifically for it; they all work fine with the Pyūta as well. (Not affiliated, just satisfied.)

Monday, August 23, 2021

The Commodore Plus/4, 3-Plus-1 and computer literacy

I'm testing lots of units in storage, including a whole mess of Commodore 264-series machines, mostly C16s (in both the domestic U.S. and Mexican Sigma variants, which are exactly the same internally), but also a couple of Plus/4s. The Plus/4 was beaten up in the United States press as the "Minus/60" because of TED's deficiencies (more colours but no sprites and worse sound) and its intentional incompatibility with the Commodore 64's large software library. Indeed, that's probably why my family upgraded to the 128 instead and completely skipped it.

Another aspect of the +4 that was mercilessly derided was the 3-Plus-1 pack-in software. Based on an integrated suite called Trilogy by Pacific Tri-Micro, it included a word processor, database and spreadsheet; the fact they were intended to be basic applications did not prevent critical displeasure. Popular Computing Weekly pointed out how small the working space was and their limited features, and InfoWorld complained that "[t]he word processor is the worst I've ever seen," but The Transactor's editor Richard Evers was particularly barbed, famously observing that "[t]he word processor is barely that, the data base [sic] defiles the name and the spreadsheet has little spread." But while this quote got wide currency, the rest of the article is actually far more complimentary, adding, "Each package is well written, taking into consideration the limitation of trying to make them all work within the confines of each other. Running two packages in tandem is possible with this system ... think of the software as an almost free bonus, and accept its limitations."

I certainly thought so. While I didn't pick up my first +4 until I was a starving medical student, it was a cheap thrift store purchase and I made good use of the spreadsheet as a household budget. The word processor was just good enough for letters (school papers I typed in Pocket Writer on the 128D, until I got a Macintosh IIsi) and I barely used the database at all, but the spreadsheet actually worked fairly well for basic figures. Best of all, it loaded instantly because everything was in ROM, and you really could switch back and forth from one to the other and exchange data without losing anything, neither of which was true of the programs I had on the 128. In some respects it was even more "integrated" than bigger integrated packages (think Lotus Symphony, etc.) on the PCs of the time. It is debatable how useful this feature would have been versus simply having the applications run one at a time for a larger workspace, but it did work.

Something else that worked was this Plus/4 that I dredged out of storage to test. While checking the contents, I found it had this letter in the box which I don't even remember noticing before:

The previous owner, in August 1986 (granted about a year and change after the +4 had flamed out), was invited to a computer literacy class, "an introduction to computers, teaching you basic data entry terminology, to help you feel confident working with computers. You will recieve [sic] a Commodore Plus 4 [sic] computer that adapts to your television for passing the class." The class was administered in Oregon.

There is no mention of any peripherals being included, and no Commodore could directly connect to a standard cassette deck for storage. Furthermore, it is likely the Plus/4 was selected solely because they got donated stock that didn't sell. Still, here was a computer that was cheap enough to just give somebody and connect up to their television. You pressed a key and almost instantaneously you got a word processor, a spreadsheet and a database that came built-in. You could type letters, do a household budget and maintain an address book. If you picked up a 1541 disk drive, which by then was selling for under $200, you could save files. If you picked up any of the cheap Commodore 1525-compatible printers on the market, you could print letters. If you cared to crack out the manual, you could learn to write your own programs.

For this person in western Oregon, this Plus/4, as idiosyncratic and artificially limited as it was, may have been their gateway to computer literacy — and at that time it very likely was all the computer they actually needed.

Thursday, August 19, 2021

Plua revisited: Lua for PalmOS (and resurrecting plua2c)

I was not an early adopter of Palm PDAs, but my experience with handheld computers is actually rather longer; my first handheld was a Tandy Pocket Computer PC-4. It had 544 free bytes (1,568 with the 1K expansion pack) and you programmed it in BASIC. Other than the TI-85 in college my next step up from there was an HP 95LX, which was the first of Hewlett-Packard's well-regarded handheld DOS machines. But Palm was the rage in the mid-to-late-1990s when I was in medical school, and I picked up a brand-new colour m505 in 2001. From there I upgraded to the Zire 72 in 2005, which I kept using until the iPhone 3GS arrived because it had better apps and it could record video. Later on I got a used AlphaSmart dana, which is the closest thing to a PalmOS laptop; it had a wide screen, full keyboard, built-in word processor, a WiFi option, two SD/SDIO slots, and USB to connect it to a printer or to have the unit act as a keyboard for a PC or Mac. Just connect it to the computer, start your favourite word processor app, and the dana would "type" your entire document into the larger computer. No drivers necessary! Although I have a few other Palm units in my collection, including an original Palm 1000, a Tungsten T|X and a couple Centro phones, plus a Pre 2 and Veer from the webOS days, I still use my Zire 72 and Dana now and then for specific tasks.

The classic Palm OS (also known as Garnet in its final revisions), not to be confused with Palm's later and technologically unrelated webOS, actually feels a lot like classic MacOS. (The "Classic" mode in webOS 1.x for running Garnet apps doesn't seem like a coincidence to me, either.) Besides the common original architecture (68K), the heavy reliance on structured resources for both applications and data storage is very reminiscent of the Mac. When ARM-based Palm OS 5 devices emerged, not only was there a 68K emulator like the Power Mac's for running older software (called PACE, the Palm Application Compatibility Environment), but the normal state of the system was to be running 68K code.

I got a lot of wear out of pre-programmed Palm apps but I'm a nerd at heart, and I like to program things. The PC-4 was easy: it was BASIC, and it had 10 segmented program spaces, so I wrote simple games and tools for school classes. The 95LX ran DOS programs, and would happily run anything I wrote in Turbo Pascal 5.5 (though optimally if formatted for the smaller screen first). However, Palm development was primarily proprietary at the time, officially requiring CodeWarrior with specific Palm support and the appropriate hardware. I used Macs (at the time, a hand-me-down Power Mac 7300), so the hardware was no problem, but I was a starving student back then and CodeWarrior wasn't cheap.

So late in 2001 it was a real boon to discover a beta Palm OS 3.1 port of the Lua programming language to Palm OS, written by Marcio Migueletto de Andrade. The part I liked best (well, other than the fact it was free!) was it was fully self-hosted, with what today we would recognize as a simple IDE, such that you could develop right on the device. In those days Plua was based on Lua 4 and offered easy graphics, serial and UI support, so I used it for writing my own internal calculation apps which (thanks to an external separate runtime, the Palm's ubiquitous IR beaming, and everyone having a Palm device) everyone on the clinical team ended up using. Eventually Plua evolved into a full-fledged 1.0 release in 2003 instead of a time-limited beta.

Plua also included a small "cross-compiler" (really, a bytecode dumper) based on luac, though with additional code to link resources as well as emit a stub PRC header to call the runtime. This allowed you to develop on a desktop PC and build the PRC there, and then HotSync it over. More about that in a moment.

Plua was already pretty great by then, but what really moved it forward was support for TCP networking in Plua 1.1. Unfortunately, networking in Plua 1.1 had several significant bugs and Marcio was already working on Plua 2.0, which was based on Lua 5, so these weren't fixed. (One of my early apps that got bitten by this was Port-A-Goph, a gopher client for Palm OS. I got a mention in Wired and the code really did exist, but the socket bugs were difficult to work around. I probably have the source code around here somewhere.) Plua 2.0 also required Palm OS 3.5 and wasn't source compatible with Plua 1.1; the functions were similar, and many function calls could be rectified with text search-and-replace, but it still had some important differences plus the jump in the core language as well. For me personally it took awhile to convert over, but Plua 2.0 was a definite improvement and the bugfixes made it a very solid package.

This screenshot, of POSE (Palm OS Emulator 3.5) running under Mac OS 9 (emulating the emulator on my Raptor Talos II), shows that Plua 2 was perfectly capable of native controls and a standard application UI. With the socket issues resolved, networking was actually stupidly easy.

At the time I was an active participant in the Yahoo! Group for Plua (now gone, along with the rest of Yahoo! Groups), which was the only official place to get Plua 2. Marcio issued an analogous "cross-compiler" for Plua 2 called, analogously, plua2c, using 5.0.3's luac as the base. However, Plua was freeware but (Lua 5 is MIT-licensed) not open source, and the plua2c binaries — which, unlike Plua 1.0 and 1.1, were distributed separately — were only available for Windows and x86 Linux.

During the Plua 2.0 betas in 2006, I privately asked Marcio if I could build a PowerPC Mac OS X-compatible version of plua2c. He agreed to this with the condition that the source be kept private (I suspect, but do not know, that he had some interest in making it a commercial product or having a commercial support option). I agreed and over the next couple years ended up issuing four binary-only releases of the Mac OS X plua2c which I hosted on Floodgap. However, after Plua 2.0 left beta around 2008, although Marcio indicated he had interest in starting on a 2.1 based on Lua 5.1, I don't know if he ever actually did; the introduction of webOS in 2009 and the lack of interest in Palm OS Cobalt or further Garnet devices essentially ended classic Palm OS's market relevance in any case. I lost contact with Marcio and never received further replies from him regarding Plua or plua2c.

Still, I kept using it for various minor projects even if I didn't regularly keep a Palm in my pocket anymore. I eventually gave up on Port-A-Goph and started on a Plua 2 rewrite (the screenshot above), and turned my Zire 72 into a Plua-powered Hue light controller:

All of this development was done on my 32-bit Power Macs, using 32-bit builds, which was all that was ever supported. In the meantime, the Plua Yahoo! Group disappeared along with the rest of everything in the Yahoo! Groups genocide and along with it the only definitive source of Plua and plua2c. Although a few people have the PRCs, no one seems to have kept the cross-compiler, and other things like documentation and examples similarly evaporated.

When I recently decided to continue work using my Raptor Talos II, which is a 64-bit POWER9, I decided I would dust off the source code of plua2c still sitting in my G5 and develop on the new machine. plua2c compiled and appeared to function but ended up generating defective executables that weren't compatible with the Plua runtime (Plua2RT). They were dramatically bloated in size and caused the runtime to emit a low-level VM error.

Recall that plua2c is descended from luac, which more or less just dumps the Lua data structures in place. Lua's documentation says that "[t]he binary files created by luac are portable to all architectures with the same word size." To this end, luac 5.0.3 actually emits sizeof(int), sizeof(size_t) and sizeof(Instruction) (i.e., the typedef quantity for the size of individual bytecode instructions) into the bytecode header which should make an amphibious loader capable of selecting different bit widths, but Plua2RT doesn't swing both ways, at least not in that respect. To make the Plua VM happy, I had to force all of these to be 32 bits in size and change the emitter to only emit 4-byte int and size_t quantities.

This partially fixed the size, but it was still abnormally enlarged, suggesting 8-byte quantities were still being injected into the file somewhere else. After some detective work I found it was actually coming from plua2c's PDB header struct, so I hardcoded the correctly sized types in its typedefs, and the length matched up and the Plua VM could now execute the generated PRC. plua2c was now ported to 64-bit OpenPOWER.

You'll notice I said the length matched what my Power Macs emitted, but not the file itself. Besides a timestamp, the Lua bytecode is emitted using the native system's endianness, and the dump also has an endianness flag to indicate what that was. Interestingly, this is one situation in which the Plua VM does swing both ways: although the native endianness of the 68K Palm OS is big, and Plua was never ARM-native (which for Palm OS 5 is little, and PACE handles the endianness switch as part of thunking), it transparently converts the values just fine, just like Lua would. The docs even say, "binary files created on a 32-bit platform (such as Intel) can be read without change in another 32-bit platform (such as Sparc [sic]), even if the byte order ('endianness') is different." In fact, it has to, because Marcio's builds of plua2c were for little-endian 32-bit x86. Only my PowerPC Mac OS X builds actually emitted big-endian data, since that was the native endianness there. My POWER9 system runs Fedora in little-endian, so the endianness didn't match the Power Macs, but that was no problem for Plua.

I intend to honour my gentleman's agreement with Marcio about not disclosing the source code. Even if he's unable or unwilling to discuss changing the arrangement, a deal is a deal and I would want this to be a sign to anyone else who would share code with me for porting purposes that I keep my promises even a decade and a half after the fact. Still, I think Plua is a great way for retrocomputing enthusiasts to get back into Palm development. Yes, there are tools like OnboardC which compile on the Palm as well, and some but not all of the C cross-compiler infrastructure works on modern 64-bit systems, but Plua is a lot more straightforward for beginners and has tons of built-in functionality that would require external libraries or a lot of additional code with other development systems. The use of a separate runtime is a little obnoxious but hardly a dealbreaker for me personally.

So, in the spirit of our original arrangement to issue PowerPC Mac OS X binaries, I have compiled plua2c for modern 64-bit platforms, at least the ones I have a compiler or cross-compiler for. Besides the 32-bit PowerPC OS X version, which I still offer, and the 64-bit OpenPOWER ppc64le Linux binary I personally use, I also compiled it for Intel macOS 10.14+ with clang and 64-bit Intel Windows with a cross-compiling MinGW gcc. I'm willing to consider other platforms if I can easily set up compilation without a lot of additional work or disk space.

But these aren't much good without Plua itself, so I've additionally started hosting the Palm OS package on Floodgap with the runtime, onboard IDE and online help, along with Marcio's documentation and license terms. I also had a complete copy of the Plua 2 examples, so I've provided those, like the animated fishtank you saw on the introductory image. And, because building them from scratch needs the PILot Resource Compiler, I also made a minor 64-bit fix to its bitmap handling for modern systems too (it's GPL, so for that you get the full source code). Fortunately, pilot-link is still readily available for most modern platforms to sync your binaries over to the device.

It is my hope that one of two things will happen: Marcio will get in touch and bless an open-source release, or, with this tool, someone(tm) can work on a clean-room implementation of the runtime and maybe fix a few of the issues like memory usage and custom screen sizes. Sadly, that someone(tm) can't be me, because I've obviously seen the source code and know at least some of how it's implemented and that makes me a tainted implementor. But combined with the source for Lua 5.0.3 — and none of what I've divulged here can't be inferred from it — folks should be able to tease apart how the VM is constructed and how calls get to the OS, because except for the Palm-specific bits the VM core is still regular old Lua. Which is why, by the way, Plua was so great and is worth resurrecting. Maybe we could even get later releases of Lua 5 working. Who knows?

Even if we don't get either of those outcomes, at least now folks interested in Palm OS have another solid homebrew development option available once again. I got a lot of wear out of Plua and Marcio's hard work is why. I don't think he ever made a cent off it, but even with its minor warts it's still my favourite way to program the classic Palm OS. Now you can enjoy it too.

The binaries, documentation and examples are at Floodgap. As for the gopher client you saw? Well, that's a future post. But when I push that out, you can compile it yourself.

Tuesday, August 17, 2021

Unplanned Floodgap downtime

Floodgap is down due to an upstream circuit cut; all Floodgap services including web, gopher and E-mail are affected. The telco is on it, but I have no ETA for repair. If the downtime will be prolonged, I may host some services temporarily on a VPS. I apologize for the inconvenience.

Monday, August 2, 2021

Cracking into the Sun Ray General Dynamics-Tadpole M1400

Tadpole has this storied history as a maker of truly unusual laptops, particularly after their 1998 merger with RDI, another company that made truly unusual laptops. Most geeks are aware of Tadpole's (and RDI's) SPARC line, and I myself own a 2005 Sun Ultra-3 (a rebadged Tadpole Viper, complete with its unique lavender case) and a 1998 UltraBook IIi, plus a 1991 RDI BriteLite IPX, basically a portable SPARCstation IPX that even required a separate mouse. However, Tadpole didn't just make SPARC laptops: they made the N40, a PowerPC 601 workstation under contract for IBM that ran AIX, the PrecisionBook, a PA-RISC based laptop that runs HP-UX (I have the 160MHz version, basically a HP 9000 C-class workstation), and the one and only DEC Alpha-based portable, the ALPHAbook. With a 233MHz 21066A CPU, the very-hard-to-find ALPHAbook was at least briefly the world's most powerful laptop.

But for however original their early designs were, in 2005 General Dynamics bought them out, merged them with their other acquisition Itronix and triggered the end of the RISCy business. General Dynamics wasn't in the retail market; they sold to the military and other large institutional customers, and those folks wanted thin clients. All the rage then was Sun Ray, launched by Sun in 1997 and killed, like many things, by Larry "The Terrible" Ellison's Snoracle in 2014.

Sun Ray clients are simply networked display devices that connect to a server using ALP, or Appliance Link Protocol. Properly configured, a user could go from terminal to terminal and have their session follow them from client to client with no interruption (with a smart card, they wouldn't even need to type their login and password). The user has no local storage access; everything is centrally administered, including their desktop and the apps they run. Naturally Sun Ray Servers were originally Solaris-based, but there was a later binary available for Linux, and the Java open-source kOpenRay (which yours truly maintains) implements portions of the protocol. Using the Sun Ray Server as a gateway, connection to "conventional" Windows Terminal Server sessions via RDP was also possible.

The clients themselves came in several distinct generations. The first generation ("Sun Ray 1") were based on the MicroSPARC IIep, first discretely, and then as a custom SoC; the second generation were MIPS, more specifically the orphaned Alchemy microarchitecture which we'll talk about in a future post, and the third generation at least initially continued with the same. However, since the firmware was CPU-agnostic (in fact, later there was even a software client you could run as a Windows application), there was nothing particular about the protocol or the implementation that irreversibly tied Sun Ray to any one specific architecture.

That brings us back to the zombified Tadpole under General Dynamics (I'll call it "GD-Tadpole"). The MIPS Sun Rays were very power-efficient (again, a topic for a future post when we look at the Accutech Gobi systems) and performed well in laptops and even several Sun Ray tablets, but the chips weren't available in volume and didn't have the economies of scale of low-end PC laptops. So GD-Tadpole chose ... a low-end PC laptop, specifically the Taiwanese Compal FT01, fitted it with Sun Ray software and a custom BIOS, and released that as the Tadpole M1400 in 2008. And here are two, one so new the sticky protective plastic cover picked up hairs:

Notice that one is badged General Dynamics and one is not. More about that in a moment. Opened up, however, they are indistinguishable:
And here it is with my Gobi 8 (Sun Ray 2), both connected to a default configuration of kOpenRay. The M1400 is the larger of the two on the right.
These laptops were a larger family of otherwise unremarkable PCs with weird firmware, the M1400 being the first. In 2010 General Dynamics delivered the successor Tadpole M1500, which is a rebadged Compal HL91, along with the netbookish M1000 with a smaller screen and form factor. All of these machines were only meant to run as Sun Ray clients, enforced by their modified BIOS, but the desktop Tadpole Pulsar and Pulsar Premium introduced at the same time have a hidden conventional AMIBIOS and can boot a conventional operating system. Not so the laptops: Sun Ray or bust.

The FT01 wasn't a terribly flash laptop even for the time, but it didn't have to be. The M1400 variant has 512MB of RAM (one SO-DIMM with two sockets) and a Socket P receptacle with a 1.86GHz Intel Celeron 540. We can confirm that by carefully cutting the warranty stickers on the "new" 1400:

and then removing the retaining screws from the doors:
This exposes the CPU (peeping out from under the heatsink), the fan, the single SO-DIMM and the Intel PRO/Wireless 3945ABG mini-PCI card. There is a second mini-PCI slot available, but the M1400's default OS probably wouldn't make use of it. Similarly, I installed a second SO-DIMM for a total 1GB of RAM as an experiment but it didn't seem to make any difference.

Also notice that there is no obvious main storage; the SATA hard drive bay is empty. That's because it's actually in the optical drive slot where the smart card reader is, using a carrier tray that is the system's only custom GD-Tadpole component. It is an otherwise off-the-shelf 256MB Transcend 40-pin IDE flash module which connects to the optical drive's PATA and power port using a bespoke passive interposer board. The smart card reader connects internally with its own data cable and draws power from the drive connection using the flash module's interposer. Like all such optical drive trays of the era it is easily extracted once the data cable is disconnected by removing the retaining screw and gently pulling it out. We will take advantage of this later.

The M1400's BIOS is locked down to only boot an approved OS. It can be on a drive in the SATA bay if you pull out the flash module's carrier tray, but if it doesn't recognize the operating system, it will put up a red screen with an error message and refuse to continue. There is no obvious way to enter the BIOS setup, if it even has one. So far there are at least three OS versions, all Linux-based. By default the machines use a 1280x800 screen resolution neither my 1080p flat panel nor my INOGENI VGA2USB3 like, so these screen grabs are unfortunately not at their native resolution.

The earliest version I have came with the "unbadged" laptop. This version of the firmware flashes a plain cyan screen if the discovered boot device and operating system pass muster and then starts the client. If installed in the "badged" laptop it will flash the same cyan "happy" screen, but then the screen blacks out and it doesn't get any further. As the hardware is the same I can only conclude there is a difference in the BIOS between these two units.

Once loaded it starts up directly in the typical Sun Ray On-Screen Display "OSD" client window of the time, with its MAC address as its ID and various icons and progress codes as it obtains a DHCP address and then tries to connect to its configured server.

All firmware versions of the M1400 implement the standard Sun Ray key combinations and add some unique ones. Menu-M, for example, brings up the internal configuration menu (the trackpad is also active) from which network and other system settings are adjusted.
However, an unusual feature of the M1400 family is the built-in minibrowser, which can be enabled from the menu.
This version of the firmware has an annoying habit of automatically resetting and trying to reconnect if it isn't connected to a Sun Ray server instance, making the minibrowser a bit less useful than it would be ordinarily. There doesn't seem to be any easy way of turning that off, so to placate it we'll startup kOpenRay on the Raptor Talos II to give it something to connect to. Here is its firmware version ("Tadpole-mb02-V3.4.0-0101," dated 15 September 2008).
Although the menu says we can "enable features," there appears to be only one feature to enable (virtually all of the later generation Sun Ray clients have some sort of VPN support, including encryption).
Now that we are connected to our dummy server, let's enable the minibrowser with Menu-B. Huh, that's ... a unique choice of layout engine.
The übernerds have recognised this atypical choice of browser already, but for the rest of you ... it's Links!
More specifically, it's 2.1pre33, which would have been approximately current at the time. The user agent also rats out the underlying operating system as Linux 2.6.25, running everything on a custom framebuffer. (A consequence of its limited user interface is that the browser window can be moved but not resized.)

This is actually the only mass-produced device I've seen that comes with Links from the manufacturer as the browser of choice. It's certainly very quick and small and I delight in its quirkiness, but there were more mainstream choices available in 2008 — including one we'll examine in a moment — so I'm not sure what went into the decision.

You can browse to file:///, but it seems to exist in a very limited chroot environment (darn) that is apparently recreated on startup. For example, you can download files and they appear in your home directory, and you can use the bookmark manager and changes appear to stick, but when you reboot the machine and go back to file:///home/user everything is wiped. It would have seemed a simple matter to disable these features but for some reason they didn't.

Only four files are in the chrooted /etc; here's
And here's the only inhabitant of /usr/bin, the links binary itself.
TLS 1.0 is supported, which would have also been appropriate for the time. It does not seem to use the same certificates as the rest of the system; indeed, it accepted's Let's Encrypt certificate without complaint (it doesn't appear to validate them at all).
Still, one thing they did customise, if you can call it that, was the name ("Browser"). I don't know why they just didn't keep Links. If you're going to be weird, be proud.
The "badged" laptop came with a later version of the firmware. Instead of just a plain cyan "happy" screen when powered on, it also has a Bondi blue screen that says "Loading."
After possibly flashing the Loading screen a couple times, it then launches into the Sun Ray client. (The "unbadged" laptop halts at this point with this firmware, by the way. It shows "Loading" and briefly displays the Sun Ray OSD status window, but then goes back to "Loading" and freezes.)
Here's the firmware version ("Tadpole-mb02-V3.6.1-0101," dated 25 June 2009).
This firmware version doesn't have the earlier one's obnoxious watchdog reset if it has no Sun Ray Server to connect to. This not only makes the minibrowser more functional as a standalone application, but also facilitates logging into networks using the browser itself, which the prior firmware would make rather difficult. In fact, there's even an option in the menu for it:
The minibrowser (also on Menu-B) is very different in this release:
It's WebKit! The toolkit is Qt for Embedded Linux; the layout engine version (527) is comparable to Safari 4.0, which again would have been roughly current at the time of release. It calls itself meteorbrowser/0.1:
Meteorbrowser is both more and less functional than Links. For example, the encryption support went backwards; Meteorbrowser cannot connect to over TLS, even TLS 1.0, and doesn't explain why:
They also closed the "hole" with file:/// (ftp://, recently killed by Firefox for no good reason, generates the same error).
Still, the improved engine means its layout capability is more modern (with odd gaps like fonts and Unicode characters, however) and things like basic JavaScript work. Here, testing it on my page on California State Highway 136, popups and closes for the images work correctly (as tabs). There are undoubtedly some potential exploits possible in this version of WebKit though its JavaScriptCore version does not seem to have a JIT. Shellcode explo(it|r)ations perhaps to come in a future post ...
You may have noticed that the kOpenRay session didn't look quite right. That's because it seems to bug out on this version of firmware. It's probably kOpenRay's bug, but I'm not sure why it happens yet.

The third version of the firmware I've encountered was courtesy David Parkinson, who was one of the early explorers of this system and discovered it could be booted over SATA if the IDE flash module tray was ejected. He sent this firmware image to me and I flashed it to a CF card of the same size, booting it from an off-the-shelf CF-to-SATA adapter.

This firmware works on both the "badged" and "unbadged" systems. It uses a Windows XP-inspired interface and is much more sophisticated than the basic Sun Ray OSD even though it still preserves the same status codes. It is also clearly badged "General Dynamics" — not Tadpole.
This image came up defaulting to the WiFi, though if you connect an Ethernet cable it would still get a DHCP address from it.
It has specific tabs in its interface with better video configuration options,
more user interface configurations,
and a status tab showing it as Tadpole-mb02-V4.6.2-0101, but undated. If it corresponds with the M1500, then this would put it circa 2010.
However, Menu-M yielded a nasty surprise, as photographed when I initially tried it:
I tried all the usual typical passwords. It naturally resets if you try too many, which slows you down further. The browser was disabled and there seemed to be no way to set network information. Locked down hard! At this point I figured I should have a look at what was actually in the firmware.

The 256MB image David sent me mounts as two VFAT volumes called CONFIG and CARD. Here they are in Midnight Commander.

The CARD side seems to have most of the meat. 1* files are bitwise identical copies of 0*, presumably spares if something goes wrong with the filesystem. The extensions .ime and .tle are opaque binary files. They do not appear obviously compressed and strings shows no recognisable ASCII text within them, and their magic number 80 00 00 00 doesn't match any file format I know. The only readable files are factory.conf, with two lines (KbdType=pc and Language=uk), features with some sort of hex product key, a 384-byte license file also containing ASCII hex, and and, which are identical and have lines like this:,S,4.6.2,3.0.0,30c4[...]

Like the license file, the hex data is 384 characters encoding 192 bytes. Best guess is some sort of checksum hash which is checked on startup. The 4.6.2 matches the version number of the firmware, but I don't know what the H or S indicate, or the 3.0.0. BOM therefore probably stands for Bill Of Materials.

The CONFIG side is mysterious in different ways. Notice that the 0* files have a different modification date than the 1* files, and they are not identical copies (their CRC32 checksums differ). The significance of this was not known to me at the time, but we'll come back to why they differ presently. These files, however, are not encrypted. In fact, 0certs.img is another mountable FAT image that despite its filename calls itself METEOR:

This is obviously the certificate store. However, I didn't find any of the configurable screen or UI settings in CARD, CONFIG or this METEOR.

Were the other firmware versions the same? Time to dump them and see! Attempting to extract the IDE module started to perilously bend the pins on the interposer because of its tight fit, so I pulled a beat-up Dell Vostro 1400 out of the closet with a PATA optical drive slot to plug the whole tray in as a unit. The retaining screw didn't quite align between its drive and the GD-Tadpole tray; since I have two trays I decided it was Dremel cutting tool time for one of them:

I chose the tray from the "badged" unit since that one was in worse shape anyway. Notice that there were differences in the smart card reader too (earlier one at left), but they probably look the same to the operating system.
Once installed dumping the images was then a matter of booting Clonezilla on the Dell Vostro, having it mount a second USB drive and dd the entire IDE module with both partitions over to it. To dump both modules I just switched the entire interposer board with the module attached.
The older firmware versions lack factory.conf, but are otherwise laid out the same with a set of similarly mysterious binaries and corresponding license, features and *.bom files. Fewer components are in these earlier versions, and the Links-based firmware's BOM is the only one where every file's version matches the firmware's displayed version (3.4.0). They also divide themselves into CARD and CONFIG partitions.

The second version firmware allows you to configure the default address for Meteorbrowser. I figured this was a useful test, so I made a single character change from "i" to "j" to see how this altered the dump and compared both images in VBinDiff. The result was unexpected:

It's cleartext ASCII! I grepped every single file in the image to determine where it was stored and found it in CONFIG/0meteor.cfg ... which turns out to be another FAT image! This image is also called METEOR:
The string appeared in base.conf. You can see all the folders for the individual profiles, suggesting this is where user settings are written to. The clock was set wrong on this unit, but the times differed here as well, just as they did on David's image. I should have realized there was something special about those files in the first place.

With this new information I returned to his image and mounted CONFIG/0meteor.cfg. After grepping around a little, in profiles.conf appeared this string:


A theory came to mind: if I munge it to a key it doesn't recognise, then it hopefully will think it doesn't have a password at all. I directly loaded the image into a hex editor and changed every occurrence of Password_Enc to Aassword_Enc (gotta make sure the length matches). This string appeared in four places. I then flashed this to the CF card and rebooted, and pressed Menu-M.

Bingo! No password, unrestricted access!
Time to turn on the minibrowser, which it calls a Mini Bowser.
Unlike every other version of the firmware, this one directly allows you to update the BIOS. I didn't try this because I actually like what's there, but I bet David will try. It did not prompt for a filename and I did not click Confirm.
Another nice feature: NTP is supported. Time to fix the clock.
Configured and talking to kOpenRay. Whatever issue was with the second firmware version is fixed now.
Unfortunately, Meteorbrowser is still the same and has all the same limitations. Fixing the clock didn't fix TLS.
I haven't found any other versions of the firmware. If you have one, let's explore it.

Things to do:

  • Try to bust into the OS by exploiting the version of WebKit in Meteorbrowser. Hopefully it isn't similarly chrooted.
  • Figure out what those hashes are and what algorithm it uses. It may have something to do with license, which could be an encryption key. However, the 192 byte length is a little unusual.
  • Unmunge at least one of the files. The obvious target is ?bootarg.ime, which is small enough where brute forcing may actually be possible especially since I strongly suspect it should yield ASCII text, and at that size it probably isn't compressed.
  • Links can do "more" and is more "fun," so see if I can make a hybrid firmware using the improved General Dynamics launcher but replacing ?browser.tle with the ones from the original firmware. Assuming the hashes match between releases, I should be able to just copy the needed lines from ?

In a future blog post besides hopefully any or all of the above, we'll look at the Gobi series, the MIPS-based Sun Ray 2 ancestors to the M1400 and their unusual Alchemy-based CPUs.