Mimsy Were the Borogoves

Hacks: Articles about programming in Python, Perl, PHP, and whatever else I happen to feel like hacking at.

Less primitive Model 100/200 Data Transfer Script

Jerry Stratton, December 12, 2018

Linux On My Back

I have been using the C.H.I.P. Linux box with my Python data transfer script (Zip file, 11.5 KB) for two and a half years now to get files to and from my Model 100 and Tandy 200. I’ve improved it considerably over that time, so that it now works with Dropbox to more easily transfer files from the Model 100/200 to my Mac OS X workstation or iPad.

Next Thing, the makers of the C.H.I.P., has unfortunately gone defunct, but the script should work on the Raspberry Pi or any Linux computer. The Raspberry Pi (and probably Arduino) are especially useful because, like the C.H.I.P., they are small enough to fit on the back of the portable. I have a velcro square on the top of my Tandy 200 and on the back of my Model 100, and its twin on the C.H.I.P.’s battery pack. You can see in the photos that while it isn’t pretty, it works well.

Other than changing from 98E1D to 98N1D since the last version of the script, the new features mainly involve two things: working with the server, and working with the network. Some of them involve things that were fun to write, but that I rarely use, such as browsing the web or defining words.

Whenever I’m working on the Tandy 200 at home, its easy to go into the TELCOM app when done and

  • UPLOAD file.md


  • REPLACE file.md

if the file already exists.

I’ve also improved the DOWNLOAD process. There’s no longer an extraneous cursor at the end. When you type “DOWNLOAD filename”, it prints a message explaining how to download the file. First, invoke the download function of the Model 100/200; then press another key to start the download. When you can see that the download has completed, revoke the download function of the Model 100/200, and then press another key to get to the cursor.

I’ve also improved the LIST command to provide details of files, mainly when they were last updated.

> LIST details
Listing directory /users/jerry/dropbox/
abe.md              3.1KB          Nov 4
angel.md           931.0B          Aug 5
bird.ba            946.0B         Nov 17
checkers.ba         3.3KB   Nov 12, 2016
cram.ba             1.1KB   Nov 12, 2016
funhouse.ba         3.3KB   Nov 29, 2016
poems.txt           2.1KB    Sun 3:22 PM
poetry.ba           5.9KB    Sun 3:06 PM
twinkle.ba         557.0B         Nov 17
typer.ba            3.2KB    Sun 9:18 PM
walker.ba          456.0B         Nov 15
weekday.ba         703.0B   Nov 12, 2016
wheels.ba          164.0B    Wed 2:15 PM
wonder.md          983.0B          Nov 9

It continues to feel a little weird to use a Model 100/200 when I have a full Linux computer hanging off the end of it. But no longer that weird. The keyboards on these things are great; they provide a focused writing environment; and they allow writing immediately, at the flick of a switch. The difference between writing now and writing in a minute or so after waiting for the tablet or computer to wake up, bringing up an app and waiting for it to be ready, and waiting for the keyboard to connect is huge. Especially after waking up in the middle of the night with a great idea, the difference between now and a minute or so after I’ve dealt with manipulating the modern computer is easily the difference between getting the idea down and not remembering what made it seem important.

It also really is a lot of fun to write BASIC programs for this old thing, as you’ll see in the coming weeks. I was inspired recently by my visit to Tandy Assembly. I tend to start them on the Model 100 (if I’m traveling) or Tandy 200 (if I’m not), then when they get unwieldy transfer them to Dropbox and work on them on the Mac, and then bring them back for debugging on the Tandy 200.

I’ve also discovered an easy way of uploading BASIC programs from the portable, without saving it as ASCII. After initiating the UPLOAD/REPLACE, go into BASIC, load the program, and:

  • SAVE "COM:98N1D"

This will output the BASIC program, as ASCII, to the serial port. Use 98N1DNN on a Tandy 200.


The script should work without any changes except the serial port, stored in a variable at the top of the script. On my C.H.I.P. the serial port is /dev/tty/USB0 because I am still using the USB to serial adapter.

There are three files in this archive. One for the script itself, and two for using WiFi. I store the Python wifi script in ~/bin alongside the model100 script. The wifi script itself requires nmcli to manage the WiFi connection(s), and on my computer this is in /usr/bin.

Linux on My Back 100
jerry:~$ bin/wifi
* Moon Tower           +++++ WPA2      
  Chandler             ++    WPA2      
  MySpectrumWiFi04-2G  ++    WPA2      
jerry:~$ bin/wifi --current
* Moon Tower           +++++ WPA2      

You can also use —help to see the other options.

Now, if you look closely at the main script, you’ll see that it refers to /usr/local/bin/wifi. That’s because, in order to connect to a new wifi network you need to run the script as root. Rather than run the whole model100 script as root I have a wrapper just for wifi (this is also why the wifi script is separate). You’ll need to edit wifi.c and put in the direct path to the wifi script, then compile it, put it in /usr/local/bin, and setroot it.

  • gcc wifi.c -o wifi
  • mv wifi /usr/local/bin
  • sudo chown root /usr/local/bin/wifi
  • sudo chmod u+s /usr/local/bin/wifi

If you really want to be safe, you could jettison the wrapper, and only choose a new WiFi connection by logging into your server and using the command line, with sudo. After the device knows a connection, it should connect to it automatically afterward. The other features of the wifi script do not need root. You will want to change the location of the wifi script in the model100 script if you do this. It’s not a bad idea, but it does (for me at least) mean not writing for several minutes while I tangle with getting wifi working.

If you want to be able to look at the battery’s status you need a script to provide that information. I use RzBo’s script, and store it at /usr/local/bin/battery.sh. Again, you can change this location at the top of the file.

Finally, if you’re going to use Dropbox you need to both install the Python API and set up a Dropbox token. Once you have a token, put it in ~/etc/dropboxToken. To help test whether you have a working Dropbox connection the script can be run on the command line with three dropbox options, to copy a file to Dropbox, to copy a file from Dropbox, and to list the available files on Dropbox. I would start with the latter. Once you can see what files are on Dropbox, you can copy to and from, and watch them change on your workstation.

jerry:~$ bin/model100 --listDropbox
NUMAZE.BA    TSWEEP.BA    bird.ba
checkers.ba  cram.ba      funhouse.ba
poems2.txt   poetry.ba    trek.ba
twinkle.ba   typer.ba     walker.ba
weekday.ba   wheels.ba    wonder.md

Once you know it works on the command line, it should also work within the script’s telcom environment, from the Model 100/200.

The script assumes that ~/dropbox is your dropbox area. The folder’s contents are not automatically updated; they are updated through the PULL command in the script.

The Good Stuff

In the process of using this script a lot, I’ve added a lot of new features. HELP will show a list of all commands, and “HELP command” will show what options that command can accept, if any.

Probably the biggest and most annoying change is that the C.H.I.P. does not pay any attention to any form of flow control, at least that I’ve been able to determine. Because of this, I have to throttle the transfer speed from the server to the portable.1 I have a THROTTLE command for testing the appropriate speed, but unless your models act differently than mine, you shouldn’t have to worry about it. When you first use the script, type MODEL 100 or MODEL 200 as appropriate, and it will set the appropriate throttle.

It defaults to Model 100 speeds, height, and communications parameters. If you’re on a Model 100, use 98N1D, and on a Tandy 200 use 98N1DNN. You can technically see this by typing “SETUP stat” but if you need it you probably can’t see the response.

A more useful feature from SETUP is a BASIC program to set the time, date, and day. Type “SETUP code” and you can download a short program to query the server any time to update your portable’s date, time, and day strings.

When running the C.H.I.P. off of battery power, it helps to be able to see (a) where the battery’s at, and (b) whether it is charging. The BATTERY command does this. You’ll need to install a battery script to do this, and may have to alter what the program expects, or what the script provides to match what the program expects.

To help keep the directory listings clean of old junk, I’ve added a KILL and a RESTORE. KILL just moves a file into a trash directory. You can RESTORE it as long as you haven’t KILLed another file with the same name. You can also VIEW a file on the server, paging through its contents without downloading it.

Model 100 workstation

As long as you have a WiFi connection when you UPLOAD or REPLACE a file, and you’ve set up a Dropbox token, the script will PUSH the uploaded file to Dropbox automatically. But if you’ve uploaded a file without access to Dropbox, you may want to specifically PUSH that file later. You can PUSH any file that’s in the server’s directory. You can also PULL any file from the directory you’ve created for this app on Dropbox. If you PULL without specifying a filename, it will list all of the files in that directory.

Managing your network connection is performed through the WIFI command. Just typing WIFI provides a list of networks that the server sees. If you’re connected to one of them it will be starred. You can also “WIFI connect” and “WIFI disconnect”. It will ask for the name of the network you want to connect to, and then its password. If there is no password, just press RETURN.

There’s usually no need to connect to a network more than once; after you’ve connected once the server should remember it and automatically connect later. That’s a server setting, and has nothing to do with this script, so you may want to verify it in your server’s settings.

The Silly Season

I’ve also added a few useless commands. They are mainly as proofs of concept; it is rare that I am writing and I take the time to go into TELCOM to look something up on the web or even spellcheck a word.

  • WEB to display the text of a web page.
  • WIKI to look up a term on Wikipedia.
  • SPELL to check a word against the Linux spell-check.
  • DEFINE to look up a word in the Linux dictionary.

WEB and WIKI require elinks on the command line. SPELL requires the Python aspell module. DEFINE requires the Python nltk.corpus module.

WEB with no option will ask you for a URL. Once you’ve visited one web page, you can type WEB and a number, and it will display the URL, from the list of links on the previous page, corresponding to that number. WEB and some text will provide a list of all URLs from that page whose URLs include that text along with their corresponding number.

URL? http://www.hoboes.com/Mimsy/hacks/
   Mimsy Seal Mimsy Seal

              Mimsy: Hacks

     * Why don't the answers to
       "security questions" need to
       be stored securely?

> WEB monsters
102 http://www.godsmonsters.com/
103 http://www.godsmonsters.com/News/wa
104 http://www.godsmonsters.com/Feature
105 http://www.godsmonsters.com/Feature

WIKI allows searching Wikipedia:

Term? TRS-80 Model 100
            TRS-80 Model 100

   From Wikipedia, the free
   Jump to navigation Jump to search

            TRS-80 Model 100
   Radio Shack TRS-80 Model 100.jpg
     Developer   Kyocera, Tandy,
       Type      Portable computer
   Release date  1983; 35 years
                 ago (1983)
                 for 8K version
   The TRS-80 Model 100 is a portable
   computer introduced in 1983. It is
   one of the first notebook-style
   computers, featuring a keyboard
   and liquid crystal display, in a

DEFINE provides a definition of a word:

> DEFINE portable
NOUN a small light typewriter; usually
     with a case in which it can be
ADJ. easily or conveniently transported
     antonyms: unportable
ADJ. of a motor designed to be attached
     to the outside of a boat's hull

And SPELL provides likely spellings of a word:

> SPELL midcentury
mid century, mid-century, century,
misadventure, McIntyre, denture,
dysentery, misandry, momentary,
adventure, misfeature, monetary,
sedentary, sentry, mercenary, midwinter,
misidentify, Accenture, denature,
minatory, modesty, decently, Mideastern,
ministry, midwinter's

You can probably do just fine without any of these.


Finally, for testing purposes there’s a DUMP command, which simply appends all incoming data to the file “logs/dump.txt”, sixteen characters per line. It dumps the character itself, if it’s a character that appears on the screen (this includes spaces, but not tabs or carriage returns, for example) and the hexadecimal code for the character.

DUMP START 2018-12-04 11:25:51.597988
00000000	5 TEST = 0..10 R	35 20 54 45 53 54 20 3d 20 30 0d 0a 31 30 20 52
00000016	EM configuration	45 4d 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e
00000032	 variables..11 L	20 76 61 72 69 61 62 6c 65 73 0d 0a 31 31 20 4c
00000048	M = 7:BELL=60:TA	4d 20 3d 20 37 3a 42 45 4c 4c 3d 36 30 3a 54 41
00003360	END ELSE MENU..9	45 4e 44 20 45 4c 53 45 20 4d 45 4e 55 0d 0a 39
00003376	99 TEST = 1:GOTO	39 39 20 54 45 53 54 20 3d 20 31 3a 47 4f 54 4f
00003392	 10...And some c	20 31 30 0d 0a 1a 41 6e 64 20 73 6f 6d 65 20 63
00003408	ontrol characdte	6f 6e 74 72 6f 6c 20 63 68 61 72 61 63 64 74 65
00003424	rs:......graphic	72 73 3a 01 13 04 06 06 07 67 72 61 70 68 69 63
00003440	s?......The End.	73 3f 82 84 8f 94 8b 0d 54 68 65 20 45 6e 64 0d
DUMP END 2018-12-04 11:27:51.756898
Model 100 Triangle

This will be mainly useful in testing new features, should you wish to attempt to integrate the box more fully into the portable. You may find it useful when testing to run the model100 script on the command line with “--verbose” to see the dumped data show up in real time.

Keep it up

You can run the script just by using bin/model100&. But this requires logging in every time you restart the server. I put a line in my crontab file to keep the script running:

  • * * * * * /users/jerry/bin/keepItUp

The keepItUp script checks to see if the model100 script is running already, and if it isn’t, starts it up.

[toggle code]

  • #!/bin/bash
  • if [[ ! `pidof -sx model100` ]]; then
    • /users/jerry/bin/model100 --verbose 2>> /users/jerry/logs/model100.err 1>> /users/jerry/logs/model100.log &
  • fi

You can start it up with or without verbosity. I start it up with because I keep adding features, and those features have bugs. It helps to see what I was doing when a bug is triggered.

The script does not need to run as root. I run it as a non-privileged user, one that isn’t even in sudoers.

The Future

What’s next? If I continue using this script, and I expect to do so at least on the Tandy 200, it will help to be able to use folders to manage the different kinds of files I store on the server end.

It may or may not be useful to integrate this with TPDD. I have a REX on the Model 100 now, because the Model 100 is the computer I use on the road. The REX is great because I can save work areas to about sixteen different slots on the REX, pulling them in, updating them, and/or switching them out as needed. Unlike the Model 100, the REX’s memory does not requires power to keep it safe, which keeps my programs and writing from disappearing over long trips without plugging in.

Since the REX comes with a handful of disk operating systems, I may be able to use that with the C.H.I.P., or with a Raspberry Pi. It may even be possible to use it with this script. That’s why I changed from Even Parity to No Parity: it’s what TPDD uses. This is what I see if I turn on DUMP and then try to save a file under TS-DOS:

Dumping for 5 minutes.
00000000	M1.ZZ.....M1.ZZ.	4d 31 0d 5a 5a 08 00 f7 0d 0d 4d 31 0d 5a 5a 07
00000016	........f....~..	00 f8 e6 98 06 98 1e 98 66 9e 06 80 00 7e e6 80
00000032	........f.....EN	e6 80 e6 98 06 98 1e 98 66 9e e6 00 00 80 45 4e
00000048	D               	44
Dumped 49 bytes.

Those ZZs are the preface for disk access requests. END is me typing END just to see it show up after canceling the “save”.

Depending on what I choose to do next, I may install this script on the Raspberry Pi so as to have one tiny Linux box dedicated to the Model 100 and another dedicated to the Tandy 200. With the Dropbox feature, there’s no issue with conflicting versions of files.

The real problem I’ve been having, and why I haven’t done this already, is that I don’t want to spring for a second USB to Serial Port adapter. As you can see in the photos, I still have too many adapters hanging off the back of the portables: a crossover adapter, a DB25-DB9 adapter, and then the USB to Serial adapter. I haven’t been able to get the serial pins working on the C.H.I.P., and the Raspberry Pi appears to be even worse than the C.H.I.P.—it may not even have a fixed serial speed on its serial pins in its default state.

The real real problem is that this script works so well I haven’t gotten around to looking at using a Linux-based TPDD server with REX (I got the REX in February).

Other features that I’d like to add are printing to an AirPrint printer for zero configuration printing. There is a metric shitload out there on using Linux to serve over AirPrint. There is Jack All on using Linux to print to those nice, no-configuration-necessary printers that you’ve just served up or, more importantly, that someone else has just served up. And it would be awesome, occasionally, to use these great keyboards as a Bluetooth keyboard for my tablet. However, while I’ve found lots of questions from people wanting to emulate a keyboard in code, all of the answers are about relaying a real keyboard to Bluetooth, using a modern OS that has direct access to the real keyboard.

In response to Primitive data transfer script for the Model 100/200: This script is basically just a very simple BBS, for transferring data to and from a Model 100/200 over an RS232 serial connection.

  1. The other way around is not a problem, as it appears completely impossible for the Model 100/200 to overwhelm the CHIP.