Wednesday, March 28, 2018

Exhaustive documentation and deconstruction of original FORTH


One aspect of FORTH on the 1130 makes the task of investigating and deconstructing the behavior easy. The assembler code is always loaded starting at hex 0900 and that means the locations of the dictionary entries are always the same for the FORTH statements executed off the disk file as part of FORTH bootup.

I dug through core memory to extract the locations of the dictionary entries once FORTH typed its HI THERE prompt for user input. Every dictionary entry has a fixed part, four cells that are sequentially arranged from the built in primitives up to the final word in the dictionary. In addition, there is a variable part that is arranged beginning at hex 1A00 and growing upwards.

The fixed entry has the first four characters of the name of this entry, an address to execute when this word is encountered, and a parameter cell that is used for some but not all types of words. Notice that words are only defined by the first four characters, thus CHARACTER and CHARSUM will refer to the same entry in the dictionary. 

Entries that are defined by : and ; bracketing a string of words will establish a dictionary entry in the name of the first word, then in the variable entry will store the remaining words, separated by blanks, up to an including the trailing ; character. 

Entries that are defined by an initial OPERATION word are stored as an entry under the next word. The remaining words are compiled immediately into 1130 machine instructions, set up as a callable subroutine. Subroutines are entered using the BSI instruction, which stores the return address in the first cell and then executes for a while before branching back to the return address. 

If the words being compiled (in an OPERATION block, called a CODE block in more recent FORTH) are definitions that were saved as text by :;, then they are now compiled. This proceeds recursively if an entry in turn references another regular definition, or calling the subroutine if the entry in turn references some CODE/OPERATION compiled code.

I can see the 1130 instructions and data that are set up in the code blocks, helping me to understand how it all works. For the text saved entries (those defined with :;) I have to see that entry used in a code block before it is actually compiled. I can either find a code block which referred to a text definition, seeing what was generated from it, or I can set up my own code block as a new entry after the user prompt. My code block can refer to a text entry, causing it to be compiled. 

Using these tricks, I very slowly and painfully built up an annotation of every FORTH statement, showing what it produced. There are two results of these statements - changes to the stack and additions to the variable dictionary -- so I extended normal FORTH shorthand for documentation.

It is normal for a FORTH definition to show what must be on the stack before execution and what is left on the stack afterwards. For example, (n m -- c) means n is on the top of the stack and m is the entry below it. They are both consumed and a result c is left on the stack after we finish execution.

I chose to add a new shorthand for the output to the variable dictionary entry as var: (a, b, c, . . . ) where a, etc are what is added to the variable entry. I discuss any unusual aspects in the text below that shorthand. As an example, the statement:
   :L 400 INST;               (n -- ) var: (n OR 0400)
takes a cell on the stack which is the basis for an instruction, ORs that with 0400 to produce an instruction that is in 1130 long format, and sticks that instruction in the variable stack. If this is called with C000 in the stack, the basis for a load instruction, then we will have C400 on the variable stack when the word L is executed. 

Later in the disk file of FORTH commands, very sophisticated operations are built from these more basic verbs. My documentation will shift to focus upon the high level behavior, although I will still retain my stack and variable dictionary shorthands. 

It will take me several more days before I have the entire file interpreted. At that point I should be able to use it properly. 

Saturday, March 24, 2018

Verifying 1130 FORTH is working properly, plus continued battle with the demon disk drive


On Friday we put the microscope, so to speak, on the Diablo disk drive we are repairing for a fellow Xerox Alto owner. It was set up on the workbench hooked to my FPGA disk tool in order to read and write to the drive in a controlled way.

First, we took a disk cartridge that was written properly on our Xerox Alto primary drive, inserted it in the demon drive and read the image to the FPGA. The archived image matched exactly with the image we had written, confirming that the demon drive is:

  1. Properly aligned to address tracks 0 to 202
  2. Able to read successfully

I then took the image and wrote it from the disk tool to the cartridge in the demon drive. When we attempted to read the image back that was just written, the reading attempt encountered a huge number of checksum errors. 

The drive cannot properly write data, but can read it just fine. The same disk heads and windings are used for both reading and writing. We swapped all the circuit cards from a working Diablo drive to determine if we had failing logic on those cards, but the results were unchanged.

These swaps eliminated the vast majority of the parts in the demon drive, leaving us a very few remaining suspects. The heads themselves might be bad, however since they read properly and both the top and bottom head produce the same failures, this is unlikely. 

The disk drive has logic to verify that appropriate current is flowing in the erase windings and the read/write coils - further reducing the chance that the heads or cabling between circuit board and head are defective. 

The signals for writing - Write Gate, Erase Gate, and Write Data+Clock - are all delivered directly from the interface cable to the board that we swapped. The possible failure points seem to be:

  • connector from the interface cable
  • signal traces on the backplane from connector to PCB
  • bad power levels or quality
  • common flaw in both heads on this drive

We checked the power quality. The drive takes in +15V and -15V, delivered by very expensive HP power supplies on our workbench and from the Alto power supplies when cabled up. The behavior is the same on workbench and Alto, so we can eliminate the 15V supplies. 

Onboard the Diablo drive, +5V is generated to power most of the circuit board logic, except for the op amps handling analog signals. That power was almost identical in voltage and noise to the power on the correctly working drive we used as a reference. 

Diablo drives operate at several densities - the Alto version uses the high density (2200 bit per inch) version. If we somehow had standard density heads, that might match the symptoms, if the head is unable to produce sharp enough flux transitions.

We used the stereo microscope to examine the heads, looking for any sign that they are different from the high density heads we use in the other drives. No visible difference existed, but that is not conclusive. 

When a properly written disk cartridge is booted on the demon drive, the Xerox Alto monitor will try to rewrite some sectors to adjust timestamps on file access. This corrupts the cartridge and causes the cartridge to become unusable quickly. 

Taking a cartridge which was corrupted by the demon drive, we watched what was being read by the heads as the cartridge spun around. We saw that the signal was weaker and less distinct, so much so that the limiter and clipper circuits could not restore them to full ranges swings between the op amp rails. 

Next session, we plan to swap to a different set of spare heads, to eliminate them as the cause. We will swap the remaining two boards that should have nothing at all to do with read/write operations, just to eliminate all possible circuitry on boards. Then, we will instrument the drive to see what it is doing during write operations. Hopefully we will find the smoking gun and get this drive repaired.


Bob Flanders and I have been examining the running FORTH on the 1130, looking to validate its operation and learn to use it. Ken Boak studied the scanned pages of code that we used for this restoration and came to the same conclusion that this is a complete version of original FORTH. 

Ken chose to name the antique version of FORTH as Proto-FORTH, which I love. It captures the flavor of a predecessor, different from but clearly the sire of all the FORTHs to come. 

Using the IBM 1130 simulator, I was able to verify stack and verb operation even though we don't have a verb to print the value on the top of the stack (or any other value from the stack). That is, I entered sequences such as 10 20 30 +  then stopped the 1130 and examined the core locations where the stack exists. I saw the result of the addition (50) and the remaining value 10 on the stack.

It became clear that any numbers being entered are interpreted as hexadecimal values. Thus, when I type 10 to the interpreter it stores hex /0010 in the word, which is decimal 16. The internal character set used by FORTH has the digits stored as hex values 00 to 09, then the first six letters stored as 0A to 0F. That is handy, because a valid number has no character higher than /0F and matches the hex values directly. 

If characters other than space are entered and don't match a word in the dictionary, it is stored as a literal hex value if it is legal hex, otherwise the interpreter reports an error with a typed ? mark. 

The Enter key and Backspace are not implemented in the system as it comes up, thus if you try to terminate a line with a CR or Enter, you get a ? error. Some verbs such as REPLY will return the carrier to the left margin and type a prompt, otherwise the verb $ will do a return and type OK.

Bob Flanders and I will try to put together a forth verb that will convert the top of the stack into a sequence of four characters, then print them on the console. That will make life easier as we continue exploring original FORTH. 

Thursday, March 22, 2018

Original FORTH from IBM 1130 under the microscope


The biggest challenge here is the lack of a manual or documentation, which is understandable since FORTH was a language with a single person using it - Chuck Moore - back in the 1968-70 timeframe. Coupled with that lack, the language evolved quite a bit before the versions known to the public and covered in available material.

As an example, in more modern FORTH implementations, the verb . (period) will take the top element off the stack and print it. In this implementation, the period is a synonym for : (colon) and starts a definition.

There must be a command to pop the top element and print it, but I can't figure it out. I have been trying every verb or verb sequence I can think of. So far, it has defeated me. There are only a couple hundred entries in the dictionary but when you include combinations then a random walk approach is going to consume a lot of time.

The other major issue is understanding how to use the disk block and editing features. The verbs like CREATE, DELETE, ACTIVATE and INTERPRET will act on disk files that are managed by this FORTH code, but so far I haven't pieced together enough to do what I want, which is to create a file, store some FORTH statements in the file then cause them to be executed. 

These are the forerunners of the 1024 word disk blocks and verbs in more modern FORTH but far enough away that the modern verbs and procedures don't work with the original FORTH.

The expansion from the few primitives up to the running FORTH system was produced by a bit over 200 lines of FORTH statements but these are an admixture of 1130 machine instructions and text strings, not simply a series of FORTH phrases as you would see in a more current implementation.

Thus, understanding the code takes quite a bit of effort, leaping back and forth between the 1130 hardware and the FORTH verbs and nouns. It is slow going. 

Wednesday, March 21, 2018

Our Alto's Diablo disk drive is restored to working order


In a prior post I mentioned the drive we are repairing for a fellow Alto owner, a drive which is still fighting us tooth and nail. In our last session we had connected the suspect drive to our own drive to form a dual drive Alto system, but soon our own drive was not working properly any more.

We met this afternoon and put our drive on the workbench. First, I hooked up my FPGA based disk tool, which stalled because our drive would no longer do seeks beyond track 0. We swapped the three cards that implement seeking, but it made no difference.

As I relayed in the prior post, there is no mechanism we could image that would cause problems in one disk drive to spread to another; the only vulnerability would be head crashes or damage to the disk surface but all heads and packs remained pristine.

Normally, when power is switched on to a drive, the positioner motor is held rigidly in position. At startup or switchoff, the arm is pulled all the way back to track 0 (called a Restore operation), otherwise the servo mechanism holds the motor steady at its current track. There is a positioner release button we can push, which turns off the motor so we can rotate the arm to whatever track we want.

On our failed drive, the arms could be moved in or out at any time without pushing the release button. The drive did not perform a Restore operation at startup or turnoff. When it was moved to any track position, it did not 'snap' to exactly the track but sat whereever we left it.

To get to the bottom of this,  Ken hooked up the oscilloscope to several test points on the board driving seeks plus the output of the arm drive amplifier. The results looked odd indeed, so we repeated them on a different drive where the Restore, positioning and track holding behavior was normal.

We could see the drive amplifier deliver almost the full 15V supply voltage to the motor, but it didn't move. The schematic showed precious few parts that could fail - the motor that moved the arm, a capacitor and a resistor. Flipping the drive on its side, we began inspecting the components one by one.

The capacitor - exactly on spec and working right. The resistor - on spec and working right. The motor had appropriate resistance and appeared okay. All parts okay but the drive didn't work. To isolate the various parts, I pulled connectors off the motor one by one.

In the process of reconnecting the motor, I noticed that the plate to which the connector fitted would move a bit on the motor body. It was a plate with a nut that should jam it against the body. We used a wrench to tighten it down, then tested the motor with a bench power supply.

Suitable power moved the motor, one direction or the other depending on polarity. Given that promising sign, we stuck in a cartridge and powered up the drive. The Restore worked! The arm wouldn't move in or out unless the release button was pushed! The servo would 'snap' the arm to a precise position at whatever track we had moved it near!

Ken and I hauled the drive back to the Alto, cabled it up, and used Ken's ethernet tool to network boot the Alto to run a diskcopy operation. The source was a disk cartridge image on the Alto server built into the ethernet tool and the target was the cartridge in our drive. The copy completed, then the Alto booted fine off the disk.

All is well with our drive again. It appears we had a coincidental failure, a gradual loosening of the motor connection which first showed problems as we began testing the 'demon' drive. Next up on Friday, we work on the demon drive itself. 

Sunday, March 18, 2018

Demon Diablo Disk Drive - attempted repair


A fellow Alto owner suffered a series of head crashes on her Diablo disk drives, which, in spite of careful cleaning or replacement of the heads, recurred. She had shipped the drive to us where we installed new heads and attempted alignment before returning the drive.

We encountered a series of unfortunate incidents during this process. Something was bent, undoubtedly due to shipping trauma, which led to bending a disk head irreparably.  The bad head caused minor crash damage on our precious alignment cartridge. The track pointer was indicating track 1 rather than 0 at the rest stop, leading us to misalign the heads by one track.

Finally, after repairing the bent parts in the drive, putting in new heads, resetting the track pointer and performing an alignment, we believed we had the drive ready to work properly. In order to test this, we performed a series of checks.

First, we used my disk driver tool to read one of our existing cartridges and verified that it read properly and got the track numbers right. Then we moved it over to the Alto and daisy-chained the drive to our working Diablo drive. With our drive powered down and the repaired drive set as the first drive, we attempted to boot up the Alto. It began okay but quickly reported errors.

We used Ken's ethernet tool, which has an Alto server inside with disk images, to rewrite the disk pack, but once again it quickly degraded. Running Scavenger against it, a program to attempt to repair disk corruption, resulted in crashes of the Scavenger program.

At points during the access we could see the software repeatedly restore the disk arm to track zero and seek back out again - a kind of error recovery action. During those excursions, it appears to randomly write or erase sectors as they come up with hard errors afterwards.

We tried to swap a board from a known working drive, but had the same behavior, random writing from software that should be read-only, seek excursions and corruption. By the end of the day, we only wanted to restore the images on the disk cartridges using our primary disk drive, after disconnecting the demon drive entirely. 

Of course, we opened and examined the cartridges for any sign of damage, plus inspected and cleaned the heads on all the drives. This is not a matter of crashing heads by moving damaged packs from drive to drive.

At the end of the work day, we found that we could not even write and boot from the images using our previously working primary drive. Something is going quite wrong. It is not software corruption since we reload the images. It is not head or pack damage. It acts as if some demonic hardware virus is jumping to the formerly good drive.

We could have damage caused to the Alto disk driver board as a result of some problem on the possessed drive in question - if that blew any driver chips then it might cause the good primary drive to cease operating. We might have had voltage spikes or other bad things occurring over the cable.

Remember that when we attached the demon drive, we had a cable from Alto to our good drive, a jumper cable from good drive to demon drive, and then a terminator on the demon drive. They were interconnected electrically. 

Next session we will check out power quality, look for problems on the Alto card and good drive, then debug the odd behavior of the demon drive. This is a battle to the death between that drive and us, but we are not giving up yet. 

Saturday, March 17, 2018

Historical recreation/restoration of original FORTH on the IBM 1130


FORTH was created back in 1968 on an IBM 1130 by Charles Moore, then ported to a large number of machines and expanded over the years. I managed to get the scanned listing pages of his original code working on the IBM 1130 simulator from Brian Knittel.

The system consisted of a 12 page assembler program that scanned input from disk, parsed it into words and processed a dictionary. It implemented a small number of primitive operations itself, but opened and processed a disk file with more than 200 punched card images to extend the language to its full breadth. 

The disk file teaches the system how to compile FORTH statements into 1130 machine code, adds a wealth of verbs, provides console/keyboard support and implements a disk based file access. The culmination of this 'boot up' disk file is a prompt on the console printer (HI THERE) and the ability to type in FORTH statements interactively.

The language evolved quite a bit from this first implementation, thus part of the restoration of the system involves reverse engineering, with the aid of 'archeological study' using old documents written by Moore and others from 1970 and later. 

The modern FORTH language defines words (verbs) using a colon (:) to begin and terminates the definition by a semicolon (;). Chuck Moore allowed for and used synonyms of period (.) and comma (,). In modern FORTH, the period is used to print the contents of the top of stack, but not in the original system.

The 200+ card images on the disk file used to 'boot up' FORTH are mostly sequences of definitions such as


The above definition builds on many prior definitions - only the word INC is provided in the assembler program primitives while the rest are built up by prior card images. This establish an area on disk for FORTH statements to be stored and read, at a hard coded sector /02E0 on disk, thus working outside the 1130's monitor system and utilities. 

In addition to definitions, FORTH will compile verbs to 1130 machine instructions using the keyword OPERATION, but that keyword is not used in modern FORTH. These compiled definitions look like 


This verb CHARACTER above will compile an 1130 instruction to directly do I/O to the keyboard, yielding an XIO instruction which reads one keystroke. It then calls a compiled routine to convert the input character from hollerith card code, converts it over to the console printer coding (selectric PTTC/8) and does an echo of the key to the printer. 

By the time of the CHARACTER definition, substantial functionality is already present, culminating in the final card image (FORTH statement) that starts the interactive user session:


The verb HOME, for example, will cause the disk drive to seek to track 0 (its home position), types HI THERE on the console printer and waits for user commands from the console. 

Since FORTH bypasses the 1130 monitor system and utilities, it takes direct control of the disk for its boot up file and user files. The assembler program has hardcoded the location on disk of the 200+ boot up card images. The FORTH statements in the boot up disk file have hardcoded locations such as sector /2E0 which is track 92, head 0, sector 0 on the disk. 

In order to get this running, I had to coerce the 1130 monitor and utilities in order to store the boot up card images on disk and to allow writing to sector /2E0 where FORTH is pointing. The monitor protects stored programs and data by setting a file protect line, below which writes are blocked, so I needed a disk image where the file protect line was below track 92. 

An 1130 can have disk packs mounted in a number of different disk drives. The monitor uses cartridge serial numbers to name packs, allowing files to be located by cartridge number and file name. FORTH does away with this. The verb HOME was coded to talk to the second disk drive, thus I had to discover this and establish a disk image mounted on that drive to allow FORTH to run.

At this point, I can issue FORTH commands and interact, but I don't understand some critical facts yet. These would have been documented in a language reference or with comments in a more modern version of FORTH, but this first instance was purely used by Charles Moore. It had no other users and no need for such documentation.

Before the second programmer began to use FORTH, it had been ported to a Burroughs machine with some significant change to the language, then evolved further as Charles Moore moved to new employment and eventually founded the FORTH company to spread the language. 

I have two documents written by Moore while he was at the original site of FORTH (Mohasco Inc) but written in 1970 after he had already evolved it to the Burroughs versions with features such as multi-user operation that didn't exist on the 1130. Neither of these is a language reference, but they do reflect the concepts and principles upon which FORTH was built. 

Somewhat later documents, such as a history of the early years of FORTH written by Moore or a user guide from Kitts Peak Observatory written in 1979, offer hazier hints. Some command verbs had changed two or more times between the 1968 FORTH and the versions discussed in these later documents.

Bob Flanders and I will be painstakingly studying the dense and undocumented FORTH boot up card images alongside the Rosetta Stone documents listed above, hoping to build up enough of an understanding, an informal language reference for original 1968 FORTH, that we use it for programming purposes. 

Monday, March 5, 2018

Various items - disk drives, ethernet tools and FORTH exploration


We had two disk drives that needed to have heads cleaned, installed, and aligned. One was left over from the archiving of the final group of Xerox PARC cartridges, where we had a minor crash trying to read a damaged pack. The other is a drive we are repairing for another Alto owner, who kept suffering disk crashes until shipping the drive to us for a look.

The heads were cleaned and installed in both drives. We decided to align and test the second drive, which would allow us to send it back to its owner and free up space for other restoration work. The alignment process worked fine and the heads fly with no crashing, but the drive fails to respond to the Alto when cabled up.

We will have to spend time debugging this to figure out what other components are not working. Not enough time was left to align our first drive, but it is ready for when we return next week. 


Marc built a nice enclosure for the ethernet tool developed by Ken. This tool hooks to the Alto ethernet card on the back of the computer, eliminating the need for an external transceiver and the need to run the original Xerox 3Mb/s version of ethernet. The tool converts to modern 10/100Mbs ethernet, provides a file server and other functionality, plus other routing services, all in a compact shape.


The FORTH system consisted of an assembler program that did the most basic functions of the language, reading an extensive set of FORTH statements from a disk file to yeild the full language and its interactive use of the IBM 1130 console printer and keyboard. The assembler program appears to be working correctly and my focus is now on ensuring the bootstrap statements on the disk file are working properly.

The assembler program expects the file to contain punched card images, in EBCDIC, packing two card columns per 16 bit word. Thus, each 320 word disk sector holds eight punched cards at 40 words per card.

The file is a sequential set of disk sectors, with the lowest sector containing the first 8 cards, the next higher sector holding cards 9 to 16, and so forth. Unfortunately, it gets a bit strange within each sector.

The eight cards in each sector are loaded in reverse, meaning that the first sector has card 8 at the beginning of the disk sector, next comes 7, all the way to card 1 at the end of the sector. That means a strictly sequential read through the disk file would receive cards 8 . . . 1, 16 . .. 9, 24 . . . 17 and so on. I need to reorder the card images within each sector but not across sectors.

The last oddity is that the card images, forty words that hold columns 1 to 80 normally, are swapped around so that the first word read in each card image has card columns 79 & 80, the next word is columns 77 & 78, all the way to the right where the last word has columns 1 & 2. I need my program to reverse all the words in each card image, after reordering the card images inside the sector.

I first did this reversing with an assembler program but I later switched over to a Fortran IV program because it provided a more natural way to reference sectors in a file. The Disk Monitor System attempts to file protect any stored file, blocking assembler I/O calls that attempt to write below the protect line, while Fortran ignores the protection scheme entirely.

With the file loaded with all its reversals, I set into debugging the operation of the FORTH system - I can see it loading elements into the dictionary but after just a few dozen card images executed, it goes awry. 

Friday, March 2, 2018

Restoring the original source code for FORTH on the IBM 1130


Working my way through the source code highlighted a few challenges to be overcome before we have this running fully. The format of some FORTH code on disk was more obscure than it appeared and the coding techniques in the assembler code, while clever, were not clear.

The assembler code in turn will read data from a fixed location on the disk drive, which are the card images of the FORTH code that extends from the few primitives built in to provide all the math, stack manipulation, disk, typewriter and keyboard control, queueing, and functions to compile FORTH statements into native 1130 machine instructions.

The code shows that the card images are 40 words each, with two card columns packed into each 16 bit word. That format, packed EBCDIC, is directly handled by the 1130 monitor system. Therefore, I used the utility program DUP to load the card images to disk in the target area. Each disk sector of 320 words contains eight cards.

After further inspection, however, it was clear that the code would take card images starting at the end of the sector and working back to the beginning, thus the utility load had reversed the order of each group of eight cards.

In addition, the code flipped all the words inside a card image, so that the code could read from the highest memory address down to the first word. That is, reading it right to left. I had to store the card images in the format expected, not the way that DUP would load them.

The code that scanned the lines coming in from disk employed a virtual algorithm that had each character in its own 16 bit word. To save space, however, they were actually processed in packed mode. Thus, all the pointers to the disk buffer were multiplied by two, appearing to address a 640 word buffer at a core location twice that of the actual buffer. In retrieving words, the code would shift the address right by one bit to pick up the real word. It took a few minutes to realize this.

No diagnostic output exists as the code operates and no easy method exists to watch what is happening inside. I have to put in simple wait instructions and step through the operation on the console of the simulated 1130, if I wish to see what is occurring and where any problems first arise.