Applesoft Disassembly

I went looking for a disassembly of Applesoft.
The best one I found was the S-C DocuMentor Applesoft listing which has meaningful labels and comments, but was a little cumbersome to peruse as it was spread over multiple files and lacked hyperlink crossreferences.

So I have created a consolidated and cross-linked version.

the ruby script I used to create this is:

$<.each_line do |line|
 if line=~/^....-.{21} [J|B]...([A-Z]\S+)\s/
 line[31,dest_label.length]="<a href=\##{dest_label}>#{dest_label}</a>"

 if (!line.include?(" .EQ ") && (line=~/^.{20}([A-Z]\S+)\s/))
 line[20,this_label.length]="<b><a name='#{this_label}' id='#{this_label}'>#{this_label}</a></b>"
 line[15,4]="" if line[15,4]=~/\d\d\d\d/
 html+="#{line}" unless line=~/^\s+SAVE /
puts html

More classic computer footage from the MIT Vault

I’ve been poking around some more in the film archive at MIT that I found “Making Electrons Count” and a few other items caught my attention.

First is a news report from 1951 showing the WHIRLWIND computer being used to solve some differential equations that would be very tedious to compute by hand (e.g. determining remaining fuel, height and velocity of a rocket as it is launched). Output to an oscilloscope and a flexowriter is shown, as well as some very early electronic music. 6 minutes long.


Then there is a talk from 1985 reflecting on 40 years of computing, covering the transition from computers being batch-mode number crunching machines, where any single programmer would be allowed a short window every few days in which they could attempt to run their program, into “time-sharing” data processing machines, in which multiple users could be constantly interacting with, allowing for (amongst other things) ‘on-line’ programming. It is hard to comprehend what the act of developing and debugging a program would be like when you would only be allowed 1 attempt to run it every 3 days.

This film is 90 minutes long, but the main speaker (who appears about 7 minutes in, after a somewhat boring introduction from the MC) is very engaging and uses photos and other props to entertain and inform.


Ancient I/O & Making Electrons Count

The RPC-4000 (like many computers of the same vintage) used a device called a Friden Flexowriter for input and output. This device was a combination typewriter, printer and paper tape reader & writer.

Input to the RPC-4000 could be done either by typing on the keyboard, or reading a paper tape. Output from the RPC-4000 would be printed to the flexowriter.

The character set used by the RPC-4000 is essentially the Flexowriter character set. It uses 6-bit codes, allowing for 64 characters, as opposed the 128 characters in 7-bit ASCII. However the flexowriter had a typewriter  mechanism that allowed for shifting between upper and lower case, and there are codes in the character set that select which case to use for printing of subsequent characters.

The Flexowriter character set also has some ‘control codes’, similar to the control codes that make up the first 32 ASCII characters. Nowadays most of these control codes are long since obsolete, since they relate to long dead media like 80 column punch cards, paper tape or magnetic tape reels.

While looking for the definition of some of the Flexowriter control codes referenced in the RPC-4000 documentation, I stumbled across ‘Making Electrons Count‘ – a documentary made in the early 1950s about the MIT “Whirlwind” digital computer facility. It is 20 minutes long, the first 10 minutes or so are a breathless description of the wonders of digital computers and the bright future they would bring us.

The 2nd half I found eye-opening; it tells the story of someone with a complex maths problem to solve, and the journey they go on to program the Whirlwind to solve it, which includes digesting a thick tome on  “PROGRAMMING: Statement; Mathematical Analysis; Flow Diagram; Code; Tape Preparation; Computing; Debugging; Interpreting Results.”, attending a 2 week programming course, several interactions with Flexowriters, and a 4:00am visit to the “Night Typist”.

As well as the video itself, I also came across a nice commentary on it that gives a lot of useful context to the technology and techniques captured in the film.

On the trail of a Real Programmer

Coders of a certain vintage will be familiar with the story of Mel, the Real Programmer in which Ed Nather (writing in 1983) relates his experience from 20 years previously in attempting to patch a BlackJack program written by his ex-colleague (Mel Kaye) for the ancient RPC-4000 computer, and how the complexity of the code he had to work through left him so impressed with Mel’s familiarity with the inner workings of the computer that he abandoned the attempt to patch the code and even 20 years later, he still held Mel as the archetype of a “Real Programmer”.

I first came across the story on a BBS sometime the early 90s, at a time when I was just starting to become competent with x86 assembly code, and self-modifying code was a pretty fascinating idea, as was extreme performance optimisation.

Then recently I came across the Mel story again, and went looking to see what (if anything) of the legendary machines and codes had made their way into the retro-computing archives across the net. The ‘holy grail’ would be a copy of the original BlackJack program with the back-to-front cheat option, and major bragging rights would come from being able to make the patch that Ed Nather had given up looking to make.

I’m not there yet.

What I have found so far is:

From looking at the opcodes in the programming manual, I believe that the loop in question must have been based around opcode 21 “COMPARE MEMORY GREATER”, with the eventual ‘overflow’ to opcode 22 (TEST MINUS).

I don’t know what sort of work this loop would have been doing, although given the program documentation clearly states program execution starts at 00000, and that is also where (in the story) control is eventually transferred to once the loop exits, the loop must have been some kind of post-game cleanup, ready to re-start.

So my current theory is

  • the data stored in the upper memory locations is the card deck, (stored initially perhaps as numbers 1..52)
  • as cards were “dealt” they were marked as such by (e.g.) setting the sign bit
  • the loop without apparent exit is going through the pack removing the ‘dealt’ marker, prior to being shuffled at the start of a new game.

It is apparent that Ed’s memory was not completely accurate; not completely surprising given the 20 year gap from when the events occurred until when they were documented. He mentions the clue that helped him understand the way the loop exited as being the fact that the index register bit was set even though Mel never used the index register, and says this index register bit is “between the address and the operation code in the instruction word”. However reference manual is clear that the index register bit is the least significant bit, and in fact the opcode bits (0..4) are adjacent to the data address bits (5..16). I can’t see any way the index bit could have been part of the loop/overflow.

copy of Acorn MOS annotated disassembly

These were zipped at The BBC Lives!

The BBC Micro Operating System ( a series that first published on Micronet between April and October 1991 )

Acorn MOS 1.2 Disassembly part 1 (VDU fonts & contstants : $C000 – $C4BF)
Acorn MOS 1.2 Disassembly part 2 (OSWRCH : $C4C0 – $CA38)
Acorn MOS 1.2 Disassembly part 3 (misc graphics routines : $CA39 – $D4BC)
Acorn MOS 1.2 Disassembly part 4 (D4BD – $DB10)
Acorn MOS 1.2 Disassembly part 5 ($DB11 -$DEFE – possibly incomplete file? )
Acorn MOS 1.2 Disassembly part 6 ($E114 – $E6AF)
Acorn MOS 1.2 Disassembly part 7 ($E6B0 – $EAD8)
Acorn MOS 1.2 Disassembly part 8 ($EAD9 – $F134)
Acorn MOS 1.2 Disassembly part 9 ($F135 – $F9B3)
Acorn MOS 1.2 Disassembly part 10 ($F9B4 – $FFFF)

peekbot update

I added some new decoders to peekbot

Also, the symbols table used by the disassembler has been extended to allow for decoding of functions that are all called via a single address (e.g. the BBC has a routine called OSBYTE which is accessed via $FFF4, but has hundreds of different sub-functions which can be selected via different values of A,X & Y registers). Only immediate loads in the vicinity of the JSR are interepreted (e.g. LDA #$01/ JSR $FFF4).

XMODEM in ruby

I’m working on adding support for XMODEM file transfers to KipperTerm, and I needed something to act as the “other end” of the XMODEM transmission. Obviously I could have used a real BBS, but that would have a pain to set up, plus the typically convoluted login/file selection process would have made the test itself quite cumbersome. So I decided to put together a simple ruby server that would accept telnet connections and just require transmission of a single character to start dishing out a file via XMODEM.

Unfortunately there didn’t seem to be any existing ruby implementations of XMODEM. So I have released a gem called “modem_protocols” – currently only XMODEM is implemented, although I may add ZMODEM support over Christmas.

The API is pretty simple – you  call “xmodem_tx” or “xmodem_rx” to send or receive a file respectively. Each function takes two IO objects – the “remote” object will typically be a TCP session or serial port connection, and the “local” object will typically be a file. The XMODEM protocol is spoken over the “remote” connection, and the file being transmitted is read from/written to the “local” connection.

Here’s the “dummy BBS” I am using. In this case, I am using “StringIO” objects rather than “File” objects on the “local” side, but it should give you the flavour.

require 'modem_protocols'


Thread.abort_on_exception = true
ModemProtocols::logger.outputters = Outputter.stdout

def run_server
  server = LOCAL_PORT)
  loop do 
    puts "listening"
      session = server.accept
      puts "connected"
      loop do
        session <<"will you (R)eceive, (S)end with standard XMODEM, or send via XMODEM-(C)RC16 (R/S/C)?\r\n"
        break if ['c','s','r'].include?(command)
        session << "invalid option #{command}\r\n"
      case command
        when 'c' then
          session << "start sending now\r\n"
          session <<  "rx complete\r\n"

        when 's' then
          session << "start sending now\r\n"
          session <<  "rx complete\r\n"
        when 'r' then
"this is a test\n"*100)
          session << "start receiving now\r\n"
          session <<  "tx complete\r\n"

    rescue Exception=>e
      puts e
      puts e.backtrace
end {run_server}
loop do
  break unless server_thread.alive?
  sleep(0.1)  #wake up occasionally to get keyboard input, so we break on ^C


introducing peekbot

peekbot is an attempt to make vintage computing artifacts visible to the modern intarweb.It is a web proxy that allows navigation through online collections of disk images. For disk images in formats which peekbot understands, the file system contained on that disk image can be explored.
Many of the common file types found in the file systems can be converted to a format that can be viewed in a browser.For example, tokenised BASIC files can be listed as ASCII, or (some) old graphic formats converted to PNG.There is also a track/sector viewer, and any file found on a disk image can be viewed as a hex dump.

peekbot is based on ripxplore, a ruby library for identifying and extracting data from disk images [ripxplore is a substantial reworking of dsktool – I have attempted to make it much more modular, to allow plug-ins to be developed for different file systems and file types. It also now understands C64, Atari and TRS80 disk images and file systems, whereas dsktool was Apple 2 specific]

here’s some simple steps to try it out:

0) go to the peekbot home page –
1) click on "Apple 2 image collections mirrored at" from the list of disk image archives
2) click on "" under "Navigation Options"
3) click on "images/" under "Navigation Options"
4) click on "communications/" under "Navigation Options"
5) click on ‘explore’ to the left of ‘hacking_construction_set.dsk.gz’ (under ‘Peekable Images’), to get a list of all files on that disk.

From that files list, you can
 – click on ‘PNG’ to the left of ‘HCS Title’ (under "files") to see the HCS Logo as a PNG
 – click on ‘LISTING’ to the left of ‘HCS BOOT’ to see the Applesoft BASIC listing
 – click on ‘TEXT’ to the left of ‘HCS DOCS’ (under "files") to see the HCS AppleText docs as ASCII


peekbot is very much a work in progress. I am putting this version out now as a ‘proof of concept’, and to see if anyone finds it intersting enough to help work on it.

Areas where assistance would be most valuable:

1) web design. peekbot uses camping, with markaby + css for layout, so hopefully someone with css chops could make it look much slicker without too much effort. I’m sure the UI and navigation could be much improved as well – I am a humble backend hack so would be very happy to work with anyone who knew how to make a web app easy to use.

2) plug-ins for image formats (especially .sdk), file systems, and native file types. My goal for ripxplore is to have everything in 100% native ruby for maximum portability, and the framework is convoluted and not yet well documented, so it’s probably a bit early for anyone but a masochist ruby freak to try writing a plugin unaided, but I would be happy to work with anyone interested, or else if someone has some images they’d particularly like to see peekbot interpret, and can give specs or source code i can convert, that would be great too.  There is a heap of opporunity for the C64 particularly, including converters to detect various image formats and render as PNG.

3) disassemblers. Currently ripxplore includes a 6502 disassembler, and I am debugging a Z80 diassembler for a future release. However it is not a very intelligent disassembler, and makes no attempt to determine what parts of a program file are code and what is data.

4) documentation – how to use the website, how to use ripxplore for specialised conversion and extraction tasks (e.g. I have a ruby script that generates a PDF map with room names & contents for a "Sword Thrust" disk) & how to write a plugin.

if you’re interested in helping with any of the above, send an email to jonnosan at gmail dot com