I wanted to make a send-off in one way or another. I was thinking about using my AxiDraw pen plotter machine to draw a picture to G+, but that didn't click for me. And then I thought that it'd be fun to have an Apple ][ welcome G+ into the afterlife, a place where systems go after they're shut down for good.
First, I started up LinApple, an emulator of an Apple //e, and wrote a test program into it that would print some text to the screen, one character at a time, reminiscent of reading chat on an old BBS system at maybe 1200 baud.
Aside: years ago, I bought a 1200 baud modem for my family's Apple IIgs, and Dad was suspicious of what purpose I'd put it to. I pointed out that I could dial in to the county library and reserve books. Also, there were BBS systems where I could send messages and play games, but I knew that those purposes would be less compelling to Dad. So, Dad, I bought that modem so that I could remember using it and remember using Google+ and see the similarities. Probably still not compelling.
Listing 1
As you can see here, I first clear the screen and set the cursor to the upper left corner of the screen (Line 10), then I take two lines of text, assign them to the string variable A$ and call out to a subroutine. (Lines 20-50). That subroutine iterates through the line, printing one character at a time, then calling an additional subroutine (Lines 1000-1020), which simply spins, slowing down the program, making the text scroll onto the screen at a readable rate. (Slowdown from lines 2000 to 2020).
Interestingly, there's a bug in this code - the subroutine at 2000 doesn't return explicitly. I guess that it reaches the end of memory, knows that it needs to return, and goes back to line 1030.
At 1030, we continue on to the next character in the string, then at 1040, we print nothing other than a newline, terminating our printing to that row of the screen, automagically moving to the left and down one row. Later, we'll see scrolling, as well. All handled by the system. BASIC had a lot going on that I took for granted as a kid.
So, that structure seemed to work. I set out to write a blort of text that would be long enough to be fitting, short enough to be readable. I knew I didn't want to do text editing in my emulated Apple, so I copied this code out of the emulator and onto my Linux machine. Well, it was already ON my Linux machine, just in a disk image that the Apple emulator could read, but my Linux machine couldn't usefully edit.
So, I used AppleCommander to "export" the BASIC program to a text file, which I saved as reference.
The text file I wrote in emacs, because a) of course I did, and b) emacs is pretty good for editing fixed-width text files, which is the sort of thing that I wanted. It's got word wrapping, which made my life easier, too.
So, I wrote a page and a half or so of text, saved that out as a text file.
This next bit is perhaps unnecessary, but I wrote a Python script (again, because of course I did) that read the lines of my text file and wrote out a BASIC program that would print those lines to the screen. Sort of a compiler of sorts, that compiled a text file to BASIC.
The structure of the output file was the same as my test BASIC file (Listing 1), I just had a lot more calls to the line printing subroutine; one each for each line in the text file.
Listing 2
With this, you can see a few things. For one, you can see that emacs is happier providing syntax highlighting for Python than it was for BASIC. Maybe I don't have the Applesoft BASIC major mode installed. The structure is pretty simple - read all the source text file into memory, write a preamble, write out instructions to handle each line, and then write the closing matter, particularly the subroutines.
The header is super straightforward:
Listing 3
All it does is use the HOME command to move to the top left of the screen and clear it. You'll see that I also increment the line number by a healthy 10 numbers and return that.
Kids these days with their IDEs and their structured programming languages, they don't appreciate the value of leaving a healthy amount of space between line numbers, so that you could go back and add in extra commands if you needed to later.
Listing 4
This simply takes a provided string of text (which I had read from my text file) and generate a line of BASIC that assigns that string into the A$ string variable, then on the same line (something done more in BASIC than any other language I've ever seen) invoked the print subroutine. Again, I increment the line number and return.
Listing 5
And that wraps up the BASIC output, and also the Python script. I just write out the code to print one character at a time, placing that subroutine at line 5000, because that seemed like a safe space. Just to be sure, though, I assert that my text printing body of the code hasn't pushed us past 5000 before we got here. Similarly, I have the delay subroutine at 6000.
So, I ran the program, and ran into a few bugs - I had forgotten the semicolon on "PRINT MID$(A$,I,1);" - the semicolon means "print this string, but do not move the cursor afterwards", which achieves the teletype incremental progress. I had also forgotten the carriage-return (again, the kids don't remember typing on a typewriter where there was a physical lever that would RETURN the physical cylinder (the CARRIAGE) such that the typewriter would go on from the left margin.
I fixed those things up, tweaked the text, and output my WELCOME.BAS output file.
I struggled a bit with AppleCommander, trying to get the BASIC code back onto the disk image that the emulator would use. The tricky bit was that Applesoft BASIC is stored on floppies in a "tokenized" format, not in plain text. This takes one step off the job of the interpreter at runtime, and it makes it more efficient to save BASIC programs to a 140k floppy.
So, I needed to figure out a way to take my plain-text WELCOME.BAS file and tokenize it, and store the tokenized output onto the disk image.
Turns out, AppleCommander has a command-line version with a -bas option that does exactly this. Almost exactly this. It isn't perfect about carriage return / line feed combos, so I tinkered with that, and eventually got my WELCOME.BAS onto a disk image.
I actually had some shenanigans with getting it onto the disk image that I wanted to use, which took some rebooting of my emulator, but in the end, I got the program running as expected.
I fiddled with the display options to get the green monochrome monitor effect, and set out to record the results. The first recording I did was using byzanz, a recorder that outputs an animated GIF. This has been effective enough for many of my previous projects, so I fired it up, and got pretty good results. I loaded the output into GIMP, and cropped the image to the size I wanted, and this was the outcome:
Figure 1 - Animated GIF
Good enough for a post to Google+. But I'm never sure if an animated GIF is really going to make it all the way to the viewer without being resampled, reprocessed, and ultimately de-animated. So, maybe that's not good enough. Also, somehow, there was a glitch of random white rectangles. I don't know what that was.
So, I used SimpleScreenRecorder to capture a movie (MPEG?), suitable for upload to YouTube, in case a GIF (appropriately enough, super old technology) doesn't work into the future. SimpleScreenRecorder has a lot of good options, including allowing me to tweak my recording window, turn off recording the mouse, turn off sound, all good things for this project. And, boom, I uploaded it to YouTube, and by the time that I had filled in the metadata, the upload and processing were complete, and my little bit of remembrance was ready to go live.
Figure 2 - Video on YouTube
At this point, I used the following technologies in this project:
- LinApple
- Ubuntu Linux
- emacs
- Python 2.7
- Applesoft BASIC
- AppleCommander 1.5.0 (GUI and command-line)
- GIMP
- byzanz
- simple screen recorder
- Google+
- YouTube
- Blogger
Seems like a lot, and a big part of writing this blog post was to capture the workflow in case anybody (mostly, my later self) could re-use a part of that flow for later projects.
Because I am putting myself to the fullest possible use, which is all I think that any conscious entity can ever hope to do.
Farewell, G+, we will miss you.