Archive | retrotech RSS for this section

Gopherus on Debian 10

Download, unpack, cd into it:

$ cd ~/installs/gopherus-1.1
$ sudo apt install libsdl2-dev
$ cp Makefile.lin Makefile
$ make

And there is the binary. make install does nothing, but it would be easy to make a soft link in your local bin directory.

$ gopherus gopher://

My gopher page -- no useful content

And that’s it. There’s also gopherus-sdl.

Useful example gopher code is used to beat

View gopherspace in browser at:


Back to the future past

Making icons for the HP 200LX

Method 1

The first way is to use the built-in icn200lx.exe and draw them pixel-by-pixel on the HP.

Method 2

Another way, useful for converting existing icons and images, is outlined below. It is not very automatic.

Here we have a putative format:

The first 8 bytes seem to be (viewed in bvi)

01 00 01 00 2C 00 20 00

And that leaves 192 bytes, or 192 x 8 = 1536 bits. Now, 44 x 32 = 1408, the number of bits needed for a icon of those dimensions. That would leave a tail of 1536 – 1408 = 128 bits = 16 bytes. Now, we have 44 pixels across and 32 rows.

But the last 16 of each file are NOT the same. This is because each row is padded. The image rows are 44 bits long but that would be 5.5 bytes, so each row is actually 6 bytes long with the last half of the last byte ignored. Since there are 32 rows, that gives 32 x 0.5 = 16 bytes.


So a black row is           FFFFFFFFFFF0
So a white row is           000000000000
Chequered row starting 0 is 555555555550
Chequered row starting 1 is AAAAAAAAAAA0

We could invent an icon in in bvi.

We can import an icon into ImageJ. File → Import → Raw


Can we change it and save it back?

File → Save As → Raw data

But no, it is now 8-bit colour depth. If I save to pgm and then convert to pbm using convert from ImageMagick, I get a file that, if I put the standard ICN header in place of the pgm header (perhaps using bvi), might do the job…

Yep, that works! OK, so that allows an image to be imported into ImageJ and then converted to an HP LX icon. Because of the padded bytes, can we just take a 32×44 image, convert it and use it? Let’s try!

I’ve got an old version of Cal(vi)n, a small vi clone on the LX. Let us see.

ImageJ, File → New →  (we have to make it 8-bit; make it bigger and type on it then crop to the right size and threshold it.

Save as pgm

$ convert vi.pgm vi.pbm
$ bvi vi.pbm

This image has a working ICN on the right and the pbm on the left. All we do it make the top few bytes match up, and the overall file size the same (delete the pgm header, basically, and add the ICN header).


The copy the vi.pbm to vi.icn on the CF card and put the card back in the LX and … yep, it works. Not very automatic, but it works.

Method 3

Here is a thing to automatically convert almost any image into an icon — of course, it may be garbage! Many nice images don’t work at 1-bit depth, and it changes the aspect ratio.

# This script requires convert from ImageMagick, plus the netpbm tools.
# It works via some temporary files because I am a simpleton.
# Anyone who finds this useful can use it in any way they like.
# Convert the image to pgm for intermediate processing; convert's
# rescale did not work for me.
convert "$1" "$1"temporary.pgm
# Rescale, convert to pbm, and grab the last 192 bytes; you may
# want to add some options to pgmtopbm to darken or lighten the result.
pnmscale -xsize 44 -ysize 32 "$1"temporary.pgm | pgmtopbm | tail -c 192 > "$1".tail
# Create the 8-byte icon header
echo -n -e \\x01\\x00\\x01\\x00\\x2c\\x00\\x20\\x00 > /tmp/ICNHEADER
# Concatenate the ICNHEADER and the 192 bytes of image into an .icn file.
# To get the filename, we cut off the extension (everything after the
# FIRST dot). We don't use basename because we don't know the extension.
# (But does not work with relative paths or paths with dots -- eg ../filename.png.)
cat /tmp/ICNHEADER "$1".tail > $(echo "$1" | cut -f 1 -d '.').icn
# Clean up.
rm "$1"temporary.pgm "$1".tail /tmp/ICNHEADER

Note: One should use pamditherbw instead of pgmtopbm. If doing so, we replace pgmtopbm with pamditherbw | pamtopnm. First step dithers, second converts to pbm. pamtopnm should do the right thing automagically, since it chooses pgm/pbm/etc based on image depth.

Yes, that works.

This compares source images with icons, as imported into ImageJ:

This better represents how the look on the LX screen — small and (re)inverted:


A free Sanplé

Ever heard of a Sanplé 3000EL? I am guessing EL means electric.

looks like a black plastic suitcase

The case

front and above view of the machine

The Sanplé

Advertised as ‘keys stuck’ for free. Clearly otherwise in very good nick. I’d almost say perfect.

Plug in, turn on, verify that the belt is in good nick but the fluted rod cannot turn. Notice the first problem — return band is all over the place…

shows the loose return string

Spot the loose return string

Slip the band back into place; that seems to have fixed some of the problems, but the return still doe not work. Time to dismantle… undo screws in middle of feet and under carriage ends. Also undid the screws that that hold the plastic cover on the carriage and removed that.

Now, tilt and remove the top.

getting the top off

Once the bottom is removed, it is easy to tilt the top and get if off past the carriage.

With the top off; note the conventional ribbons rather than some custom cassette (see Brother 3912) — good. Very plasticky — the spool mountings, for example, are almost entirely plastic. I’d guess this is a very late example of an electric basket typewriter.

Another photo

General top view, sans case

Space bar works, return does not, nor do any letter keys — shaft is not turning. Looks like the return key is not releasing and the lug is not letting go of the end of the fluted shaft.

Photo of the right side of the machine

The tip of the screwdriver shows the stop that prevents the fluted rod from turning.

Following a trail of rods and levers shows that a sliding strip at the back is connected to the carriage stop. When the carriage returns, it should hit the stop, which disengages the lug in the picture above and allows the fluted rod to rotate. This is currently not happening. If I give the carriage a push, I can force it to work.

the sliding rod that disengages the return mechanism and lets the fluted rod rotate; it was sticky

The screwdriver points to the sliding rod that needed a light oil to slide properly.

Give the strip a drop of sewing machine oil and clean the carriage movement to make it move more easily so it can whack into the stop harder and so release the return more cleanly.

That sort of works; it looks like the return and draw bands could use more tension; or just a clean and some use. Gave some key points a thorough clean and a light oil, wiping off as much oil as I could after application. Yes, that seems to help. Works pretty well now.

The typing feel is very light once it works. The keys respond well, the sound is not too loud, and the alignment is adequate though no more. The electric return is slow. Perhaps the springs have got old and soft, I don’t know. But otherwise it seems to perform well. There is a lug on the right for attaching a spring, but it’s not clear where it would go. There’s no exclamation mark — I guess we use a single quote ‘ and backspace and a stop . to get !

A sort of distorted 70 or 10 with a back-to-back A and R below.

The symbol on the typebars

Because the return spring seems too weak, when I hit return close to the start of a line, the carriage does not get up enough speed to actuate the return release, ad the thing jams up. The solution is to tug on the carriage end to trip the release. If you’re too slow, the drive band may slip off … this seems to be improving with use.

I can’t find out much about it. There are no identifying marks on the chassis anywhere (that I can find). Is it a Citizen? Nakajima? I’ve no idea, though the repeat spacer makes it look like a cheaper Brother (were Brothers ever this plasticky?). On the typebars, between the upper and lower case letters, is a thing that could be a 10 or a 70, but looks more like a tent peg followed by a high o, and below that what looks like an underlined AR with the letters merged, kind of like they’re back to back. Apart from the badge on the casing and the serial number on the back:

Made in Japan, Ser. No. 006375

that’s it. No more. For free, it’s very nice. Still a bit gummy, though.

Oh, and here’s the character set, though low quality — I’ve not yet replaced the ribbon and so the type was very faint and the scan was very noisy. I’ve used ImageJ to increase the contrast, and it’s still not very good. Nothing interesting in this font.

The character set of the Sanplé 3000EL

Free! Free at last!

Sharp MZ-700 fonts in virtual terminal

Virtual terminals need PSF fonts.

The DSPACE archive contains virtual terminal versions of some BDF (xterm) fonts based on the character glyphs that came in the ROM of the Sharp MZ-700 series of microcomputers in the early 1980s.

Construction of the BDF fonts is explained elsewhere (; they were converted to PSF by opening in gbdfed and exporting to PSFU. Nothing fancy.

The files are all just versions of the same font, but in different sizes. Note that outside of the US keyboard characters, the encoding is a bit random!


They could be copied to wherever your *.psf and *.psfu files live on your system, but the easiest way to test them out, at least on Debian (untried elsewhere!) is simply to use setfont. For example:

$ setfont MZ7int1_recode_double.psfu

The character set is shown here:

The character set -- US keyboard

The glyph positions outside of the US keyboard characters are not all good. I really need to do something about that… the drawing characters especially would be better in the right slots, since ncurses applications would work a lot better.


ex-X: Linux without X windows

What works without X?

Screen shot of WordGrinder runnin in FBterm with a very big Glass TTY VT220 font.

Green on black is easy on the eyes!

Here is a screenshot of the Glass TTY VT220 font. Not sure how to grab a screen while inside the program, though. This was grabbed by exiting then running:

$ fbcat > screen.ppm
  • w3m with w3m-img (web browser)
  • cmatrix (screen saver —  actually works in any terminal)
cmatrix -- green letters cascading down the screen

cmatrix at work

  • Alpine (mail)
  • acpi (battery status)
  • shutdown -h now (don’t use sudo halt)
  • alsamixer (to set volume)
  • ogg123 and mpg123 (music player)
  • apt-cache search <searchterm> (find Debian packages without synaptic)
  • gnuplot-nox (plotting)
  • vim (of course)
  • DOSBox (uses SDL, so works too. That means you can run Windows 3.1 on Linux without running X. Fiddling with the config file lets it run fullscreen. The main trick is that usescancodes=false MUST be selected in the dosbox.conf file, or there’s a good chance it will misread the keyboard, preventing you from typing any commands or even using Alt+Ctrl+Fn to change virtual terms. This may force a hard reset.)
  • twin — text-mode window manager (
  • tty-clock
  • cal/ncal/calendar
  • bastet (tetris…)
  • freesweep (minesweeper)
  • sopwith (sopwith)
  • sc (spreadsheet)

LaTeX plus fbgs works perfectly well for writing documents. If Vim is set up to allow compiling and viewing from within Vim, then LaTeX works really seamlessly. I added a command to my .vimrc:

cat ~/.vimrc

syntax enable

command L !latex %
command B ! %
command V ! %
command A ! %
command D ! %
command G ! %
command M ! %
command F ! %
command I ! %
command PP ! %
command PDF !pdflatex %
command W !wc %
command XF !xfig &
command T ! %
command WT ! %
command VT ! %
command FB ! %

So within Vim in command mode I run :L to LaTeX a file (makes the dvi) then :D to make the PostScript and  :FB to view it in the framebuffer viewer. When I exit the viewer, I drop back into Vim. Could also run fbgs in a second virtual term.

$ cat ~/bin/

NM=`basename $1 .tex`.ps
fbgs -r 300 $NM

Or we can go totally text and view the output of dvi2tty; this script runs dvi2tty then views the result:

NM=`basename $1 .tex`.tty
IM=`basename $1 .tex`.dvi
dvi2tty -w80 $IM > $NM
echo Created $NM, piping into view
sleep 2s
view $NM

Ahh… it’s like being in DOS.

Using multiple news servers (NNTP) through Alpine and tin

I was trying to set up tin to read Gmane and Usenet. They don’t cover the same territory.

In the end, I found that I just need to have two different configurations for tin.

I went:

$ vim ~/.tin/newsrctable

and made it look like this:

$ cat ~/.tin/newsrctable .newsrc.gmane gmane .newsrc es

So now the list of subscribed Gmane groups will be written to ~/.newsrc.gmane, not .newsrc

I also created ~/.newsauth to hold the authentication information for

$ cat .newsauth PASSWORD USERNAME

(See here for setting up access to eternal-september.)

I then created 2 little scripts and put them in ~/bin:

$ cat ~/bin/myes
tin -r -A -g es

$ cat ~/bin/mygmane
tin -r -g gmane

So, the first says:

-r = read a remote news server

-A = get authentication information — if ~/.newsauth is present, use that, otherwise prompt the user

-g es = look up entry ‘es’ in ~/.tin/newsrctable

The Gmane one is much the same but does not need authentication.

This seems to work.

Copied .newsrc and .newsrc.gmane to backups then tried to get it to work in Alpine.

In Alpine, I went (S)etup (C)onfig and checked ‘Enable Multiple Newsrcs’, then went to (S)etup Co(L)lections and (A)dded the following:

Nickname : EternalSeptember
Server :
Path : #news.
View :


Nickname : Gmane
Server :
Path : #news.
View :

Then went to Folder List and under EternalSeptember chose:

[Select Here to See Expanded List]

This asked me if I wanted to rename .newsrc. I said yes and it renamed it to ‘‘. It then showed my subscribed groups — good!

But when I went to expand Gmane, .newsrc was gone (having been renamed) and it found nothing, even though I have the .newsrc.gmane from tin — because why would Alpine know to look for that file? So, I tricked it. I exited Alpine and typed:

$ cp ~/.newsrc.gmane ~/.newsrc

The opened Alpine again, and went straight to the Gmane list and expand it. It went to the default file for the list of groups — .newsrc — and then asked me if I wanted to rename it. I said yes.

So now I have 2 .newsrc files, one for each NNTP server:

But, the original .newsrc files I set up using tin have been renamed away. But that is OK. I can now edit


and change the names in that file to match the ones created by Alpine. That way, I can read mail in either application — handy, since Alpine aggregates but tin is better for managing subscriptions. So here is ~/.tin/newsrctable:

$ tail -4 ~/.tin/newsrctable .newsrc.gmane gmane .newsrc es gmane es</.pre>

And that’s the way to access some slowly dying bits of the internet.

Next, I suppose, is Gopherspace.


Printing to the EP44 — doing it properly

I rigged up a dodgy way to print to the Brother EP44 using a simple three-wire cable. The problem with that is the printer cannot keep up with the serial port and the text starts to go funny.

Later, trying to play with it as a terminal device, I made a null modem cable. I tried using that as a print cable, and because it has the full complement of wires for flow control, if I set the printer spooler to use XON/XOFF (software) flow control, I can print using lp without using a script that sends one line at a time — the printer can use the extra wires to signal to the computer to wait.

screenshot showing the menu giving flow control options -- xon/xoff is software control

Using the CUPS interface at http://localhost:631 to set the options on the Brother EP-44 printer

The end result is that printing to the machine is very simple — if the full null modem cable is used. The 24-pin typeface is quite nice and very readable, and the only disadvantage really is the thin thermal paper (fax roll) that I have to use.

Printing from GUI applications does not work unless (like, say, nedit) they call lp to send the job. Using the CUPS browser interface to set up the printer works, but I have to use lp to send the job. Maybe I can figure it out, but it’s not really important.

The EP44 is a very portable printer. Works for ages off its batteries, or can even be run from the 5V output from a USB powerpack, if you don’t mind butchering a USB cable, as shown on YouTube.

It’s just a curiosity, but an impressive little one.


The future is 1984!

AlphaSmart 2000 — preventing accidental power on

Okay — modifying the AlphaSmart 2000 with a stick and some tape. I say ‘modifying’ because I don’t like the word hacking. It’s kind of pseudocool. I think the phrase ‘lifehack’ should be hacked to death.

But anyway. There is one massive design flaw of the 2000, at least when it is being used as a portable device chucked carelessly into a backpack. It’s old now and uses a PS/2 cable to type the text into a computer — which is fine, plenty of machines have PS/2 ports still, and PS/2-to-USB adapters are cheap. It’s in that nice zone where it’s useful but kind of worth little (at most $20 on ebay). So they are perfect for taking places you might hesitate to take a nice machine. Problem is, the on/off key is exposed (it’s just another keyboard key, at the top-left where Esc would usually be) and gets pushed and jabbed by other items in the bag and the thing turns on and off over and over again and you end up with a string of nonsense (or just one character over and over again), and since it is an older AlphaSmart, you have to delete the unwanted characters one by one using backspace (it calls it delete, but it is really backspace — the thing has got some kind of Mac’s disease; symptoms include a curly command key, ⌘, and a company address in Cupertino). That is clearly a pain. The newer ones (sorry, the ‘newer’ ones) — like the Neo — have a two-button-on option, whereby they won’t turn on unless you hold down Enter then on/off.

No such option on the 2000, so for the 2000 the simplest answer is to use a bit of tape and attach a Paddle Pop/Icy Pole/iced lolly/popsicle/icy pop (choose your local term, sorry if I’ve left it out) stick over most of the button, leaving just enough poking out to turn it on and off.  Version 1 used Sellotape (ie sticky tape). Version 2 stuck some blue insulation tape over the stick so you can’t tell it’s a stick. Now that’s technological advancement!

photo showing the stick taped over the top-left corner of the keyboard, where the power button is

Tape and wood works a treat

Works a treat. Now the old thing can go in my bag and only turn on when I want it to, not when it gets bumped. It’s so light and easy to carry, has space for 8 files and batteries last months — recommended for typing and hiking, typing and biking, that kind of thing.

Thank you and goodbye.

Native edlin on windows 10 (!)

The FreeDOS edlin code is clearly very carefully written to allow cross-platform use. For example, it can be readily and simply compiled for Windows 10.  It will also compile on a POSIX system — I’ve used Cygwin. That means I have an editor that will work on pretty much any system I’m ever likely to encounter. Impressive.

First I got the FreeDOS edlin code from here:

I installed CodeBlocks with gcc from here:

Then I opened a CMD.EXE window and (temporarily) added the path to the gcc binary to my path:

C:\> path=%path%;C:\Program Files (x86)\CodeBlocks\MinGW\bin

Then I went to where the edlin code was unzipped and …

C:\edlin>copy config-h.bc config.h


And that was it! Now can put edlin.exe into some directory and away I go!

Note this:

C:\>which make
C:\>which gcc
C:\Program Files (x86)\CodeBlocks\MinGW\bin\gcc.EXE

So it is getting make from gnuwin32, but gcc from CodeBlocks, which installs MinGW. So what I have done in my ignorance seems to need gnuwin32 ( to be installed and in your path as well (which also comes from gnuwin32).

Hybrid, but it works.

C:\edlin>copy edlin.exe \users\username\bin

And it is in my path (only 100 kB).

screen shot

FreeDOS edlin running natively on Windows 10

When compiled for, say, Cygwin, the commands are case sensitive, so that 23,43l needs to be 23,43L.

edlin is also scriptable using input redirection.

C:\> type edlin.inp
i insert lines
That is line 1
That is line too.
l list lines
2i Insert a line before line 2
New line in front of line too.
1,1,3m Move lines 1 to 1 to above line 3
3,3,3,1c copy line 3
3,4,3,c copy lines 3 and 4


C:\> edlin blarg < edlin.inp 
edlin 2.17, copyright (c) 2003 Gregory Pietsch This program comes with
ABSOLUTELY NO WARRANTY. It is free software, and you are welcome to 
redistribute it under the terms of the GNU General Public License -- 
either version 2 of the license, or, at your option, any later version. 
blarg: 0 lines read 
* : : : *1: That is line 1 
2:*That is line too. 
*1: This is line 1 
2: This is line too. 
*1: This is line 1. 
*1:*This is line 1. 
2: This is line too. 
* : : **1: New line in front of line too. 
2: This is line 1. 
3:*This is line too. 
***blarg: 6 lines written 

C:\> type blarg
New line in front of line too.
This is line 1.
This is line too.
This is line too.
This is line too.
This is line too.

Note, though, that if the file (blarg in this case) is not empty, edlin will open it and apply the commands to the existing file.


Printing from HP 200LX palmtop

The HP 200LX has a serial port on the side. It’s little and rectangular, but pretty standard apart from that. Since I have acquired an appropriately vintage serial printer, I thought I’d give printing from the LX a try.

It turns out to be remarkably simple once the hardware is in place.

The printer has a female DB25 plug on it. I had an old serial line that had a male DB9 (DE9) on one end and a female DB25 on the other, but I also have an adapter that will make a male DB9 into a male DB25. Thus, it seemed to me I could put a rectangular plug on the end of the cable attached to the male DB9, then convert that to DB25 and plug it into the printer.

The first way I tried to get a plug that would fit the 200LX serial port was using a 5 x 2 section of IDE ribbon connector — but the pin spacing is too big by a factor ot 5/4 (4 pins fit in the space where 5 need to go). Purely by chance, I found a broken Conner CP2121 hard drive, and you can see that on the PCB there are some pins and on them is a sort of socket plug thingy (see, I know all the technical terms). Since the drive was cactus, I pulled this off, filed it down to be 5 x 2 and found that it fitted perfectly!

Photo of dismantled hard drive

The Conner HDD opened up — yellow arrow shows the pins in question

photo showing the white plastic plug

The case of the Conner HDD with the plug, after it was removed from the pins shown in the previous picture and filed down to size

Soldering the wires on was tricky, but since I was making a 3 wire null modem (see this page), I did not need to deal with all of them. I decided to solder them all because I might want to make up a full handshaking cable at some time, but I could not use them all because the DE9 was missing some wires. I think it was a commercial ‘dumb’ null modem cable or something. Checked for continuity and crosstalk frequently.


photo of the plug, held in pliersphoto of the plug, held in pliers

Soldering the wires onto the back of the plug

I then used a multimeter to check which wire went with what pin on the DB9 plug, and soldered the two halves together to get my LX null modem cable. The main challenge is really anchoring the wires such that you don’t break the connections when pulling out the plug (my main tactic — very subtle —  is to use lots of tape). The other trick is that a rectangular plug can be put in upside down. The LX socket has a rebate in the top edge to prevent this, so I glued and taped a waste bit of wire insulation to the appropriate side of the plug so it would only go in one way. The other trick is to remember that the pin numbering you see on the LX has to be mirrored (right to left become left to right) when numbering the wires on the plug.

Here is a picture of the final cable — hardly a professional job, but I could confirm using a multimeter that the three wires I needed (2-3, 3-2 and 5-5) were unbroken, and that there was no crosstalk between wires. Ready to go!

photo, showing lots of tape

The final cable — hardly tidy

I set the printer to 300 baud (it is very old), 8 data bits, no parity.

I used the Setup menu on the LX to turn on the COM1 port (to save batteries, I keep this turned off whenever I am not actually using it) and to configure the printer. The old printer is plain text, so Epson FX-80 is the most suitable of the three printers built into the LX; chose 300 baud.

Saved all the changes and exited Setup.

Opened Memo, opened a memo and sent it to the printer. No worries! Almost … the printer is really a typewriter, and it prints slowly and has only 160 bytes (not KB, B) of a print buffer, so even at 300 baud the characters are soon coming too fast for it. It can only print small files, or bits of a file. But I can print from:

  • Lotus 123
  • Memo
  • Appointment
  • And probably other things if I could be  bothered.

What about printing from the command line?

Opened the DOS prompt and typed:

a:\> mode com1:300,n,1,8,b

Now, it is tempting to then use mode to redirect the printer (lpt1:) to the COM1 port, but Setup has already done this, so now I just need to go:

a:\> copy file.txt lpt1:

the serctl program that comes with the LX can turn the serial port on or off, wired or infrared, from the command line.

So there it is, the LX can print to the EP44. There was one other thing to try. The LX comes with a terminal program, and the EP44 can store 2 pages of text in its own memory, Can the EP44 text be dumped into the LX?


If I run the terminal program, set the baud rate to match the typewriter, and then start capturing the session (but without echoing local commands to the file!) then I can hit ‘Text’ on the typewriter and the contents of its memory will appear on the screen of the LX and then in the capture file.

Thus, the battery-powered HP 200LX can be paired with the battery-powered (but much larger) EP-44 in some weird kind of 1990s mobile office situation.

Who cares?

Serial port pinout

[1 2 3 4 5 ]
[6 7 8 9 10]

1 – DcD
2 – Rx
3 – Tx
4 – DTR
5 – GND
6 – DSR
7 – RtS
8 – CtS
9 – RI
10 – Shield ground