Some Mainframe Nostalgia

I only dabbled on the IBM mainframe over my 30+ year career. One thing that gives me great nostalgia now is SPF. SPFLite2 in particular.

I don’t actually remember what we had on ROSCOE when I made the mistake of attending DeVry in Lombard. It kind of reminded me of the editor I had to use later at client sites. You see, I was either a PC consultant or a DEC/VAX consultant. Prior to the Internet you either used VMSMail for company email, or you had to have a mainframe account because your client used PROFS. You can read more about VMSMail in this book.

The Minimum You Need to Know to Be an OpenVMS Application Developer

Since you already had an account and you could do COBOL on that VAX thing, once in a while they asked you to do some mainframe COBOL too. I talk quite a bit about terminals in my latest book.

In large part because that book walks through IT history from the days of paper tape and punched cards through to today. Everything happens because of what came before. The American Greenback determined the size of the punched card.

Sadly those images aren’t to scale, but the greenback determined the size of the punched card because people were already used to handling things of that size. We already had wallets to carry them and trays to hold them. The card divided out into 80 columns. Early terminals had to support 80 columns. Many paper terminals supported 132 from the beginning, but CRT and other video terminals weren’t viable until they could support at least 80 columns.

paper terminal
DEC Paper terminal commonly used for systems consoles long after the VT-100 was introduced

The featured image of this post is an IBM 3278 Courtesy of Richard Thomson and and that is where our journey begins. Maybe I spent too much time using emulators? I seriously remember the later 3270 family terminals having quite a few colors.

There was also a red that would show up. Don’t get me wrong, they were still considered “green screens” but they had colors other than green on them. Given my mono-colored VT terminals of the day, I found that kind of nice. Kind of like you see in this emulator shot.

You need to understand the terminal being used so you can take my statements about SPFLite2 with the grain of salt they need. The default installation opted for a blue on white color scheme. It is easy on the eyes, but it saddened me as well.

First screen of first run

When you download and install SPF on Windows this will be what you see for your first run. Be sure to choose (C) for the keymap.

3277 keyboard

ENTER is that funky key on the right side of the space bar. RETURN is that hooked arrow key above the shift key. I talk a lot about this in the AGILE book because the CUA battle and the “ENTER is on the numeric keypad” insurgence left casualties. IBM had “smart” terminals. You could arrow to any cursor position on the screen in any application. The TAB key would navigate between fields flagged for entry. If you want to know more about those days and why things shook out the way they did, you can buy a copy of my AGILE book.

If you know nothing about IBM choose the (C) option because that key is about where the ENTER key was. Prior to Microsoft adding worthless Windows keys to the keyboard, IBM really spaced the CTRL keys out.

IBM 1391472 PS/2 Keyboard 84 Key keyboard

You have to be slightly better aim with 104 key keyboards.

right control key for typical 104 key keyboard.
Main Window with help open

What you have to understand is that we didn’t have GUI or mouse back then. ISPF (Interactive System Productivity Facility) was a complete file commander. You would have to dig back to DOS applications to find something close to part of it. GNU Midnight Commander would be the closest analogy to the file navigation now. GNU Emacs is the closest I’ve used. I’m told THE (The Hessling Editor) also has an SPF emulation mode.

The file path

Let me direct your attention to the File / Path line in the above image. You who have only worked on the x86-wanna-be-a-real-computer-one-day-when-I-grow-up platforms wont’ understand just how critical this was. With hundreds of network drives you might be starting to understand. Far too many of you have had one hard drive and maybe one DVD/CD drive. As drives got bigger people could not be trusted to be organized so Microsoft created a GUI file navigator and tried to force all of your stuff to be in Documents.

Imagine yourself during a time like this:

Tape library and librarian

There would be anywhere from six to forty tape drives. You would issue a mount request for a specific tape to operations. Some time later operations would reply to your request with the device where the tape was mounted.

The same thing happened with disk packs.

Removable disk pack in drive

We didn’t have GUI and nobody wanted to GUI navigate through a device hierarchy of forty-plus drives.

After entry

I type in the path and hit the funky enter key (mapped to right CTRL) and presto! I’m taken directly to the place of interest. Had I chosen to enter something for Filter Mask as well, only files passing the filter would show up.

Bottom of window

The bottom of the window displays incredibly useful information that we had to memorize. It is important to note that when on a file line the commands can be shortened to the single underlined letter. Please note that DIFFA/B has more than one underlined character. Just typing D will delete.

Brows a directory
OPEN on a source file will OPEN for EDIT. Yes, EDIT will do same. EDIT will always EDIT. OPEN may not.

Note: If OPEN opens for edit, it will OPEN in a new window that will have the File Manager tab and your file tab. EDIT will open a new tab in the existing window.

Define Profile

Here is the answer to the question your mind had about my previous statement. You from the PC world most likely have never worked on anything that did not have default file associations. SPFLite2 has its own file associations called profiles. Here I was opening a BASIC source file for the first time. Note that you can flag files to ‘Do not Edit’ and tell SPFLite2 to ‘Open with Windows.’ You can also do some kinky profile linking and associating one profile to multiple file extensions.

Editing our BASIC file

You will notice that SPFLite2 supports a tabbed interface. It also supports multiple windows ala the help window and others. Above is what the BASIC program looks like when I open it.

Note: The numbers on the left side are SPFLite2 line numbers. They do not exist in the source file though they look just like standard COBOL line numbers.

Some of you might now start to understand why I made such a stink about the 3270 terminal colors. I wanted a much more purist color scheme. The blue on white isn’t bad, it just isn’t 3270 SPF. You can try messing with this via the OPTIONS command.


I like to set editors to Re-Open last file(s) at start if they support such a feature. I really like it when they are persistent and will save even unnamed buffers between sessions. No such luck here.

Note: You can change anything you want and just rename the configuration file to start over. You can also copy the configuration file to a new name.

Configuration file is under Documents/SPFLite

One of the download options was some AUTO color files for a few languages. I downloaded and installed them. I’m probably going to delete all of them. They assume a default color theme and, well, let me just show you how things went.

I’m pretty certain I could have fixed the line number coloring if I was willing to put more time into messing with all of the schemes. I was trying to see how COBOL was handled. I also wanted to see how other things were handled.

The file list didn’t look too bad.

I don’t think the COBOL AUTO recognized .COB as COBOL as many PC things only recognize .cob. Some might also recognize .cbl but that isn’t an old school standard.

The C-language stuff didn’t impress me either.

A large part of my disappointment with the AUTO stuff is I was unwilling to put however long it took doctoring the schema settings to get something I could live with. I might at some point, just not now. You can easily figure out which each AUTO uses. The AUTO files go in Documents/SPFLite/AUTO. Here is a snippet of the C-language one.

; SPFLite Colorize File
  QUOTED    5
  COMMENT1  7 // 0
  COMMENT2  7 /* */
 ;DELIMS    !"#$%&'()*+,-./:;<=>?@[]^_{|}~    (all delimiters between 33 and 127)  DELIMS    !"$%&'()*+,-./:;<=>?@[\]^{|}~
 WORD  8 !
  WORD  8 "
  WORD  8 #
  WORD  8 $
  WORD  8 %
  WORD  8 &
  WORD  8 '
  WORD  8 (
  WORD  8 )
  AUTOCAPS 10 #define
  AUTOCAPS 10 #elif
  AUTOCAPS 10 #else
  AUTOCAPS 10 #endif
  AUTOCAPS 10 #endregion
  AUTOCAPS 10 #error
  WORD 11 break
  WORD 11 case
  WORD 11 char
  WORD 11 const
 ; done

You will notice it appears 5, 6, 7, 8, 10, and 11 are what C uses. As long as each AUTO file for a language assigns 8 to symbols, 11 to keywords, and 10 to compiler directives one could come up with a color schema they really like that worked for all languages.

It was at this point when I nuked the config file and started over. I, like far too many humans, can spend days getting colors “just right.”

Both Screen and Schemes have color settings

For those who want to go down the path of getting things “just right” I need to point out that both the Screens and Schemes tabs have color settings. Schemes apply to the text and screens applies to everything around the text like tabs and line numbers. I cam here to set the font.

People who do not read the text to the right will find changing the font non-intuitive. While you can type the name in if you happen to know it, you click the “Choose” button below the values.

Font dialog
After new font

Ah, I should point out I downloaded the optional font library and installed just a token few of them.

Notice the dot lines in front of some directories. That is SPFLite telling you that your current priv level will not let you edit in those directories. When you own everything you don’t see that.

Drive I own everything on

Exiting a file isn’t as straight forward as most PC users would like. You can read the documentation for AUTOSAVE. This is a feature for automatically saving your files. I’m talking about ending the edit session in a single file tab. For that you use END at the command prompt. Close won’t work, quit won’t work, and EXIT will bail all the way out of that SPFLite2 window.

You can also right click on the file tab. Unlike many PC applications this will not bring up a special menu, it just closes the tab.

NEW isn’t a command either

Probably the shocking thing for me was “NEW” wasn’t a command. You can create a new tab by left-clicking on “New” or by typing the command EDIT NEW and hitting the ENTER key.

New blank tab not yet associated with a file

SPFLite2 is a Line Editor

The help text is massive for SPFLite. You could literally spend days skimming through all of the commands. There is so much kinky stuff you can do if you want to put the time into learning it. SPFLite2 deviates from the mainframe inspiration in some subtle but critical ways.

When you create a new file on the mainframe the editor opens to a screen of blank temporary lines. As you can see above, SPFLite does not do this. You have to insert at least one line yourself. The “Top” and “Bottom” things don’t exist.

I seem to remember being able to set an “insert mode” by typing I* in the line number area which would then just keep inserting lines while you typed on the mainframe. I have not found such a feature on SPFLite2. I’m sure there is something, I just haven’t found it.

Here’s a little beginning sequence to get you going. Be sure to remember to hit ENTER (the right <Ctrl> key if you followed my instructions) after each thing.

Note that temporary lines do not have line numbers. “I” inserts temporary lines and “N” inserts permanent. Temporary lines will use whatever MASK is set. When you set a MASK it is set for the entire edit session. You can change the MASK value but not actually get rid of the MASK. When you SPLIT lines or Insert temporary lines, the MASK is used.

After hitting ENTER I got the temporary line below the =MASK> prompt and my cursor was on that temporary. I had to arrow up to the MASK line, type the MASK and hit enter again. I’m sure there is an easier way, but this way was obvious.

The MASK can be very handy when you have a bunch of comments to enter. Remember, the editor defaults to overstrike.

Viewing file in Notepad++

You will note that SPFLite2 takes the term “temporary” seriously. We see lots of extra comment lines but they don’t have line numbers so they are temporary.


This is nowhere near a complete tutorial on SPFLite2. You could spend days reading the help text and learning the incredibly powerful features built into this editor. I had a blast reminiscing with this.

You have to remember that this is a different mode of thinking that all of today’s PC editors. This is from a time when we were told to keep functions and COBOL paragraphs to one screen length. Definitely no more than a page.

You can’t really understand the mainframe world until you get at least a tiny understanding of the primary editor.

You can’t really understand why people call midrange and mainframe systems real computers until you walk a mile in that world. This is not a hack-on-the-fly universe. We had to actually design things.

CopperSpice Experiments – Pt. 9

Diamond text editor now has many new features, including backups. Here is a run-down.

Yeah, it’s been a while. Life keeps getting in the way of actually writing something here. I’m also migrating from through to inMotion hosting service. That gets its own blog post once complete. Despite all of that, a lot of code has changed in the repo. Just be sure you choose the diamond-themes branch.

Themes work really well. Not perfect, but really well. Perfect would be instant coloring. I can seemingly get that to happen even with large source files if the syntax is set on a tab before the file is loaded. It appears the QPlainTextEdit class is smart enough to only paint the visible rows first. The problem is I haven’t unwound the MainWindow class object creation far enough to stop a segment fault crash with autoload enabled. If I set the syntax before setting the document in the tab during program load there is some “resource not yet available” segment fault death that happens. I’ve sped things up as fast as I can for right now without causing that problem.

So, let’s review my original ideas:

  1. Themes
  2. A decent default font
  3. EDT numeric keypad emulation
  4. Compiling
  5. COBOL syntax

The first three are basically done. Part of me wants to add custom background and foreground colors for selected text; but living with default white text on blue background for now.

Colors dialog

You can import/export and even change color themes. There are even an acceptable number of “default” themes built in.

Built in Themes

Sorry I had to use my phone for that shot. Have I mentioned the screen shot utility built into Ubuntu 20.04 LTS completely sucks? Eventually someone will set up a site where all of you dear people can upload your personal favorite themes along with screen shots. It should encourage wider use of the editor. Everyone wants their own personal theme.

Do you think I spent all of this time just sitting here going “oooh look at the colors?” Silly Wabbit!

Even more options

As part of improving overall performance, Overlord now holds all of the syntax highlighting. You have the option of preloading your favorite. Whenever an editor needs a syntax it asks Overlord for it. We only bite the bullet loading the JSON once.

There are three new check boxes on the right. One for enabling EDT. Another for Astyle on Save and finally one for to enabled backup versions. You will notice I have a field to enter the Maximum number of backup versions to keep and allow you to choose a directory other than the default for said backups.

I’ve used a lot of editors over the years. Far too many editors on wanna-be-a-real-computer-some-day x86 based platforms just create one backup with a ~ or # or something like that at the end of the name in the exact same directory as the original file. This “one” backup tends to be created either the moment you open the file for editing or just in front of your last save. If you are a save-early-save-often type developer these backups are Fahrvergnugen useless. Adding insult to injury, on any brand new project you always end up with half a dozen of these files getting into your source control until someone takes the time to both delete them from source control and create an ignore file.

Backups and file versioning

I come from an OpenVMS background. FILES-11 Records Management System had file versioning built in. Every time you saved a file it created a new version. You could have versions from 1-32767. You could PURGE all older versions and rename the current version back to 1 to start the numbering process all over again. In short, on a real platform, it is very difficult to “lose” something. We had this long before we had source control systems. When you combine file versioning with source control, it takes a very deliberate and stupid thing to “lose” a file.

We didn’t have to create utilities to manage these versions either. The PURGE command had a /KEEP=nn qualifier. If you only wanted the last 6 versions of any file on a backup tape, you just purged down the entire drive with /KEEP=6 before running the backup.

Some PC based editors try to implement the central backup directory. There are varying levels of success with it. I like what Emacs did with their backups. They mungify the full path and stick a version on the end. This keeps main.cpp from Project A from pushing main.cpp from Project B backups off the end of your keep chain. I kinda ripped that off but changed it a bit.

View Backups

When you have a file open in the current tab you can choose View->Backups and

All backups for that file

Yeah, the names don’t all appear the same here because I was doing battle with just how to do this. Eventually those will purge off or I will just recreate the directory.

Backups became very important to me while I was working on the Astyle interface. Let’s just say there were a few zero length styles that wiped out my buffer and the file on disk which of course hadn’t been checked into Git for hours. When you open a backup file you should note the tiny change to the status line.


Ordinary files will have Write listed where ReadOnly is.

Ordinary file opened for Write

There is one issue I haven’t decided about fixing. There is code in Diamond to always set a last directory value based on the file you just opened. When you open a backup file that gets set to your backup directory. I haven’t decided if it is worth blocking that in the code or not. I found it annoying when getting all of this working. Now that it is working I have to wonder just how many times one will open a backup file and shouldn’t I make it a wee bit painful? You are opening the backup because you did something stupid. Shouldn’t there be a bit of a price to re-enforce you learning not to do that again?

EDT Options

I cannot make this work the way I want without making changes to QKeySequence and then creating CsPlainTextEdit from the QPlainTextEdit source code and getting that accepted into the project. It is too big of a chunk for right now. I’m not proud of the code I had to write to get EDT functionality into this editor, but it does make a quite usable editor. It’s not perfect. There are a few minor issues.

You will note I had to put a radio button box for Delete Word. The built in help text tied to the HELP key on the keypad kind of explains this. QKeySequence really only deals with strings. Ctrl+, Alt+, DEL is a different key sequence than Alt+, Ctrl+, DEL. QKeyEvent deals with a binary modifier block and a binary key value. With QKeySequence order is important but QKeyEvent simply doesn’t care. I have to fix that little piece before rewriting plain text edit so it can support editor states. Putting it bluntly, those of you with a “proper” keyboard won’t be able to use this right now.

Wyse ‘transtec branded’ DEC LK401 layout keyboard

Honestly, even if I did have this set up for you to enter a key sequence, I don’t think Qt has mapping values for a proper keypad. I know you can make it work in Emacs if you mod the terminal. Modifying the terminal definition is against my religion though. I just used the Scroll Lock and cussed about it every time I hit the wrong key. Until I had to log back into a proper computer and edit source code I had almost adapted. All it took was about twenty minutes on there and two decades of muscle memory returned. I was completely useless in Emacs because I kept hitting NumLock for GOLD. That’s pretty much why you are getting this editor. My level of pain got too high.

All of those non-standard GOLD key functions on the right must be tied to a single keystroke sans any modifiers. I really liked GOLD = for goto line in Emacs so I ripped that off. You will notice the last one is GOLD A for Astyling a buffer.

All of this functionality is checked in if you wish to pull the branch down and build it to try things out for yourself. I’m currently working at adding a Debian build procedure to the source base so I can install this on multiple machines without having to local build Copperspice followed by Diamond.

Hopefully I will have the energy to document my attempts at getting Copperspice to build on OpenSuSE Leap 15.2. So far it has not gone well. Of the RPM based distros, OpenSuSE is the one I find least offensive so that is the one I use when I have to use an RPM.

Oh! You probably noticed the Clipboard option. I needed a method of validating the EDT “append to paste buffer” functionality so the clipboard viewer got added.

Clipboard contents

There is no GOLD-7 [command] implementation in this. Yes, back in the day I used it a lot. Some of the functions could be useful today, but I had to draw the line somewhere. The GOLD-ENTER [subs] function isn’t implemented either. When you hit it you see the advanced search and replace dialog. Honestly, I had to look up what that key combination actually did. I had never used it in all my years on EDT. It was always soooo much easier to hit GOLD-7 and type


With the SUBSTITUTE command I also had the options of REST, WHOLE, SEL instead of QUERY. If I was ever going to implement the command window it would be to bring in this functionality, but I have more important priorities right now.

As long as I’m talking about “not done” I should mention FILL isn’t done. I have no plans. I remember using it pre-wordwrap days typing up documentation. This editor has word wrap and spell check. I realize the critical difference was FILL was a hard wrap. A newline character was physically placed at the end of each line. This was for various things like printers and Usenet newsgroups with fixed column limits. If someone really needs that today I guess they can join the project and add it in.

My personal view is that creating a Debian of the current functionality is more important than any additional features at this point. I dabbled with OpenSuSE contemplating an RPM as well. I’ve always managed to duck out of RPM creation, not so much when it comes to DEB creation. When you only do it once every few years it always takes a while to get back into.

I don’t enjoy doing it. Well, that’s not actually true. I always get asked to do the convoluted sh*t.

We need to create a package that is going to create a user account and install all of this in to run like a Kiosk. It will also include a tool to completely remove the installation.

Typical client request

I’ve never created a need to know nothing straight forward hard coded install directory tree DEB. This is completely uncharted territory for me. I may actually have completely empty pre and post install files.

<Previous-part Next-part>

Most Text Editors Get Tabs Wrong

Why do PC based text editors get tabs wrong?

I’ve been getting back into COBOL and writing a book on GnuCOBOL. This lead me to writing a book on Emacs. For no more people than they have, they’ve done an amazing job. This lead me to poking around for the correct editor, preferably one that could be close to a full blown IDE.

I know. During my VAX/VMS days I happily used EDT, dropped to the command line to compile, then ran the executable under the VMS Debugger. All in a hardwired terminal. When we got LSE where I could compile and fix errors in the editor it was fantastic.

When I’m on a PC, I want something close to an IDE. It’s a psychological thing and no, I don’t feel like going through therapy. I have the same psychological thing about driving. When I’m in the city of Chicago I will walk for miles once I have a place to park my car. When I’m in the suburbs I’ll drive if it is more than a block. This can happen on the same day.

Visual SlickEdit Pro

This lead me to try many different editors. I tried Visual SlickEdit Pro. At $299 or whatever dollars for a single OS installation, man does it suck. I spent half an hour trying to get it to compile and debug GnuCOBOL and couldn’t make it work. The only reason I was interested in the Pro version was it claimed debugger support. I uninstalled the free trial within two hours of getting it.

Quick COBOL failures

Sublime Text kind of let me down as well. I still own it, but it was kind of rough when it came to COBOL. Actually the real downfall was the Debugger package required creation of a “project.” I wasn’t ready to bite the bullet of yet another “project file” syntax. Notepadqq had great color syntax if and only if you were using the original 80-colum fixed format. KDevelop has had people begging for a COBOL plug-in for years but no takers. The Eclipse COBOL plug-in is apparently abandoned.


Someone pointed me to VSCodium. This had some issues, but it looks nice when you are writing fixed format COBOL.

VSCodium with fixed format COBOL

Not so much when using free format COBOL.

VSCodium with free format COBOL

The one thing it got right is the TAB key. Your first TAB puts you into Area-A (column 8, just over the second gray vertical line). Your second TAB puts you into Area-B (column 12). The first two gray vertical lines mark the comment/continuation column. I guess technically the first one marks the end of the line number column range.


All of this lead me to try justifying once again paying $99/year for UltraEdit. I have a love/hate relationship with UE. There are things I really like. There are far too many things half-assed. That is one of the many reasons I don’t currently pay $99/year to them.

If I’m paying for an editor I shouldn’t have to hack a hidden script somewhere to change the C++ coding style. When the Linux version is treated like an ugly red headed step child chained in the basement, I don’t feel compelled to fork over the cash either. Professionals don’t use Microsoft products.

Oh yeah, debugger support. That only works in UltraEdit Studio. Oh yeah, UltraEdit Studio only runs on Windows.

UltraEdit free format COBOL
UltraEdit fixed format COBOL

Tabs are inexcusable

The syntax highlighting wasn’t bad. What was inexcusable was the tab. Sublime Text, UltraEdit, notepadqq, and KATE all get this wrong. The vast majority of PC text editors get it wrong. Emacs gets it right. Emacs also supports GDB on Linux. I can put the following two lines in my .emacs file and tabs work exactly as they should.

(setq-default intent-tabs-mode nil)
(setq default-tab-width 4)

Sitting in an empty file in Emacs with those in my init file, my cursor is at column 1. Hit the tab key and my cursor is in column 4. Exactly as it should be. COBOL programmers adapted to this years ago when we were forced to use non-COBOL specific coding tools. Today’s kids never used a manual typewriter. They have no idea how tabs are supposed to work, so they guess.

I hate linking to images. The sites go down and you get an empty spot. If ever comes back up you should see the images.

I no longer have either my VT-100 or VT-220 so cannot take a shot myself. Given that we will first go here.

tab-setup-screen.png (136.13KiB)

Well, I found one of the shots, just not the one I was looking for.

Now we have to think why COBOL’s Area-A starts in column 8.

COBOL coding sheet image
COBOL coding sheet

Hopefully your browser will let you zoom that image to full screen. Yes, that is a picture of COBOL coding sheets I’ve saved since junior college. We bought these tablets by the pack. We had to hand write every line of COBOL, get it proofed, then we were allowed to type it in.


Typewriters set the standard for tabs

On both manual and electric typewriters, well, IBM and Smith Corona which were the two biggest brands of the “modern” typewriters once we got rid of the Underwood that didn’t even have all of the keys, the first physical tab stop put the next printable character at column 8. Wow! Someone had a good one of these!

The carriage/platen stop was always placed one character travel beyond the type guide. There was a gear with a toothed rail controlling all of this. Keypunch machines and paper terminals maintained this convention in large part because the early models of both were little more than customized typewriters.

VT terminals saved the day

COBOL programmers fortunate enough to have a VT-52, 100, or later were overjoyed. Not only did it allow you to manually set the tab stops, it came with two setups, A and B. A, the default power-on setup, was almost always left to factory tabs of 8. This was so if mere mortals needed to use it they could. Setup B was normally used by COBOL programmers. The first tab stop of 8 was left in place but an extra tab stop was placed at 12. If you worked at a shop that had a “final comment” standard, you added a tab stop which put your cursor in column 73.

PC based editors suck at tabs

What happens with UltraEdit and most ill designed PC editors is they simply insert 4 spaces. Sitting in column 1, you hit tab and you land in column 5 when you have tab-width set to 4. The second tab lands you in column 9. You can do the math from there.

The ultimate test is rather simple. Pull down GnuCOBOL. Use UltraEdit or your favorite text editor with soft tabs set to 4. Type in a simple “Hello World” COBOL program using the tabs you say are correct and the 80-column “fixed” card format pasted above. Compile the program. It should fail miserably because Area-A starts in the wrong place. When text editors implement tab stops correctly, this doesn’t happen.

cobc -x -fixed -std=cobol85 COB001.COB

There was a method to the madness. Today’s kids just didn’t bother to learn it. Thank God for Emacs!

Related posts:

The Best Part of Low End

KWrite and KATE