For years I've used a headless Linux box to store and play my music collection (ripped CDs, MP3s from EMusic, music podcasts, old tracker modules, etc. -- all of it in one place). The main drawback of this setup is having to boot up another computer in order to communicate with the music box. A solution I came up with was to take an ancient laptop I had on-hand and hack it into a wireless text terminal. I used it for several years, but eventually retired it (in 2008) after I finally bought a laptop with wi-fi built in.
This was probably a rather ridiculous solution, but that's what makes it fun, right? I started with a Panasonic Business Partner 150, a laptop built in 1990. It must have been underpowered even when it was built: it has an NEC V20 CPU (equivalent to an 8088 at 10MHz), about 640K of RAM, a 720K floppy disk, a disk-on-chip with DOS and not much else. That was good enough for my purposes however. I added a radiomodem so that it could communicate wirelessly with the linux box and coded up a terminal program. To eliminate the boot-up time, I inserted the terminal program into the BIOS and set it up to load and run automatically immediately after the POST routine. This also let me remove the floppy drive, making room for a new battery.
Refurbishing the laptop
The donor laptop was fourteen years old when I started this project so I wasn't surprised to find that it didn't work any more. It didn't show any signs of life at all, even with the power supply (which I made sure was good) plugged in. I traced that problem to some blown solid-state fuses on the motherboard, which I replaced.
The original battery was long since dead. This laptop used a lead-acid battery; I don't know if it predated the widespread usage of NiCd batteries or if they just decided not to use that technology. At one time there were companies on the internet advertising replacement NiCd batteries for this model laptop. I don't see how they could possibly have worked correctly and I didn't try one. Instead I bought a rechargable lead-acid battery that had about the same dimensions from Digikey and then hacked away a bit of structure inside the laptop case to make it fit.
Getting the laptop to run a program was also a problem. It could boot from a disk-on-chip very quickly. However, the chip was an EPROM soldered into the motherboard, so I had no way of putting a program onto it. The laptop could also boot from a floppy drive, but the drive had failed as well (the belt connecting the motor to the spindle had stretched out). So, I installed a standard 3.5" floppy drive and wired up an interface cable to make it work. See this article by Ivan Baggett for details on the interface cable. His article is about a close cousin to the Business Partner 150, the Tandy 1100FD. They share the same floppy drive interface.
Installing a Radiomodem
Once the laptop was functional I could start modding it. The first step was to stuff a radiomodem into the laptop's case and wire it up. For the radiomodem I used a pair of Radiotronix Wi232DTS modules. (It appears that they don't sell that product any more. If I had to do this again, I'd make sure to get something easier to interface to -- something with an RF connector on it already, and pins or holes for the power and digital connections.) For the Wi232DTS I had to make a little home-made PCB to mount the module, the antenna, and a voltage regulator. I initially stuck the radiomodem into a cavity towards the right-front corner of the laptop underneath the keyboard -- other laptops in this family have a hard drive there, but in this one it is just empty space. Later after I removed the floppy drive I put the battery where the floppy used to be and moved the radiomodem to the battery's old location. In the original location I was worried about the metal base of the keyboard (right above the antenna) blocking the signal.
Inside the laptop I took power and ground off of some nearby pins that were conveniently unused. The laptop uses a 16C452 chip to run the serial ports (plus the parallel port). The first serial port goes through some level shifters to the DB-9 connector on the back of the laptop, the second port is connected to an internal expansion connector that is meant for a 2400 baud modem. I cut the traces between the first serial port and the level shifters and then soldered wires from the radiomodem's TxD, RxD, and CTS lines to the appropriate pins on the 16C452. Cutting the traces eliminates the possibility of having two devices trying to drive a line at the same time. (It also means the serial connector on the back of the laptop is no longer usable - I should have used the second port instead.) The Wi232DTS is compatible with 5V logic so there's no need for any sort of glue logic. The final layout of the components is illustrated at right.
I had to make up a similar PCB for the other radiomodem that connects to the linux box. That one also required additional components that go along with being an external device -- a MAX232 line level shifter so that the radiomodem module could talk to the computer's serial port, a second voltage regulator for the MAX232, and a rectifier (because the wall wart I used for power provided AC).
There was one final hardware change. Partway through this project the laptop's keyboard started to act up. I eventually figured out that the keyboard was fine, the keyboard interface chip on the motherboard was going bad. I didn't see any way to replace the chip so I replaced the whole motherboard instead. I got a Tandy 1110HD off of Ebay for about $25 and swapped that motherboard for the Business Partner's. It was an easy drop-in replacement, the motherboards are the same size and all the important connectors were in the exact same places. The 1110HD motherboard doesn't have a driver for the Business Partner's screen's backlight, but that wasn't a problem - I never needed to use the terminal in the dark. (I stuck with the Business Partner's case and screen because the 1110HD I bought off of Ebay stank of cigarette smoke.) My guess is that the entire Tandy 1100 family is similar.
Editing the BIOS
At this point all the hardware changes were complete. All that was left was to put a terminal emulator in the BIOS and make it run at power-on.
I wasn't able to find any terminal emulators that would run acceptably on the old laptop so I wrote my own. There aren't many compilers still around that will produce programs for the DOS environment on an 8088! I ended up using Borland's Turbo C++ v1.01 and Turbo Assembler, which were freely (legally) available online at the time. It was also a nice walk down memory lane; Borland was what I taught myself C with, back around 1992! I still remember Dad taking me shopping for a C compiler, I think at Egghead Software... Anyway! A good source of information on programming serial ports is a file called ibmcom.txt, by Christian Blum. It is also floating in several places (and in a few different versions) out there on the internet, a google search should find a copy with no trouble. For examining the terminal emulator and BIOS code, I used an old version of a program called Hacker's View. A good 8086 instruction set reference is also useful; I used Microcomputer Systems: The 8086/8088 Family by Yu-cheng Liu and Glenn A Gibson. The book is fairly ancient, but hey, so is the hardware. And so is all that software, for that matter. All this felt a little like being back in high school.
I wrote a simple terminal emulator that is somewhat compatible with DOS's ANSI.SYS. (Because that's just what the world needs, another bad terminal emulator!) The program isn't 100% compatible because I saw no need for color support on a black-and-white display and I changed some of the control codes created by the laptop for greater efficiency. I wrote a new entry for the linux box's terminfo database to match. Also, since I prefer to type with a Dvorak keymap, I made one of the function keys switch between querty and Dvorak on the laptop. One feature I'd like to add that is currently lacking is to update the hardware cursor with the software cursor location. Currently it just sits in the middle of the screen.
It was important for the emulator to be efficient. These laptops have an NEC V20 CPU, roughly equivalent to an 8088, running at 10 MHz. I wanted the radiomodem to run at as fast a rate as possible (I ended up using 38400 bps), and that doesn't leave very many CPU cycles per character received. That meant using assembly language for (at least some of) the serial interrupt and display routines. The emulator also had to be small. The program had to fit into an unused 8k chunk of memory in the laptop's BIOS. That meant no use of the C library functions - I had to program all the display functions myself. Finally, DOS functions aren't available if the program runs from BIOS, so the program had to access the serial port and keyboard directly by itself.
Despite avoiding any library or DOS calls in the program, I still had to make some changes to the executable to make it work outside of DOS. First, the program had an initialization routine that called several DOS interrupts before starting the program. I examined the executable to find the beginning of the main() routine and made the BIOS jump straight to that location rather than the entry point in the .EXE header. I don't know what the initialization routine was supposed to do, but in this case it obviously wasn't important. Also, in the executable any reference to the code's segment (as would be found when setting the serial interrupt vector!) was replaced with 00. It was necessary to find those references and change them to the segment that the code was actually in.
Finally, I had to figure out the BIOS's startup routine enough to know when to break into it. I didn't want to skip the startup sequence entirely since it does properly set up a lot of the basic hardware of the laptop. That was something I didn't want to have to figure out how to do myself. I found the point where the BIOS started looking for a boot sector to load and then rewrote the next few lines of code to copy the emulator program into RAM, set various registers (stack pointer, data segment, etc), and then jump to the previously identified entry point of the program. I'm not providing the code for the teminal program here because it was rather embarassingly bad. Like I said above, the world doesn't need another bad terminal emulator.
And that's it. Like I mentioned at the top, I used this terminal for several years until I finally got a laptop with wi-fi. The hardware has been retired again, but I still have it sitting on a shelf somewhere. You never know, I might need that display or some other part for a project some day.