Most folks these days probably find it hard to imagine computers without graphics. But back in January of 1984, when Apple unveiled the original Macintosh in an unforgettable Super Bowl ad, most computers (of all sizes) only displayed characters on the screen, and the MacPaint program in the Mac was perceived as an amazing breakthrough. You could draw with it! Lines, circles, even pattern fills! Sure, you just had two colors to work with (black and white), and a resolution of 512 X 342 pixels (less than most phones today), but it was still an unprecedented level of graphical capability for a personal computer.
As a coin-op video game fanatic at the time, I was fascinated by MacPaint. I had spent many hours in the previous couple of years writing BASIC programs to generate crude approximations of video-game characters on dot-matrix printers, and with MacPaint I could have drawn those characters interactively, right on the screen. What a concept.
The Mac’s $2500 price tag, however, was well out of my reach, as was an IBM PC AT with an expensive EGA graphics monitor. But then Kaypro, one of the biggest personal computer manufacturers in the world at the time, added a crude graphics capability to their Kaypro II model. There wasn’t yet any MacPaint-like software that took advantage of this capability, but in the summer of 1984 I plunked down $1400 cash for a brand-new Kaypro II at a computer store in the Chicago Loop, and set out to write such a program.
Programming the Kaypro II
The Kaypro II “portable” computer weighed 29 pounds, so carrying it around town was good exercise, and it sported 64K of RAM, two 5.25” floppy disk drives (single-sided, 191KB each), a gorgeous 9” green monochrome CRT screen, and the peppy Zilog Z80 processor running at 2.5 megahertz. It ran the CP/M operating system and came bundled with WordStar and a few other programs including SBASIC, a “structured BASIC” variant that was compatible with Fortran77 syntax, which I knew well from my work at Boeing in Seattle a few years earlier.
I started playing around with writing a paint program in SBASIC, and quickly realized that the performance and functionality were going to be even more limited by SBASIC than they already were by the crude screen, limited memory, and slow processor. So I decided to learn Z80 assembly language, which would allow me to wring the maximum possible performance out of the Kaypro hardware.
After a little research, I bought a copy of the 2500AD macro assembler and linker, as well as a couple of classic programming books of the time: “Programming the Z80” by Rodney Zaks, and “CP/M Assembly Language Programming” by Ken Barbier. I spent long hours in the summer and fall of 1984 studying and practicing, and by the end of the year I felt ready to start on a bigger project. I decided to call myself Second City Software, and got to work on SCS-Draw, a MacPaint-like program for the CP/M Kaypros.
I noodled around with some design ideas, then got sidetracked finishing up an article for Unix World Magazine on the future of programming languages. After sending the article off to Dr. Rebecca Thomas in the first week of 1985, I dove into SCS-Draw and didn’t do much of anything else until it shipped, nine months later.
These days, most of the low-level tasks a programmer may need to do are handled by pre-existing code in specialized APIs, libraries, or frameworks, or by the operating system itself. But back in the early 80s, when a significant portion of the best programmers were also pretty good with a soldering iron, the operating system didn’t have a lot to offer and third-party frameworks and libraries were few and far between.
Programmers were on their own, and had to spend long hours building low-level functionality. This was especially true for a program like SCS-Draw, trying to do things that few or no other applications were doing on the same hardware.
Getting interactive graphics working on the Kaypro CP/M computers was a pain in the ass. Consider this screenshot of SCS-Draw in action:
What you’re seeing there is a typical CRT (cathode ray tube) of the 70s and early 80s, with 25 rows of 80 characters each. And in the “graphical” area of the screen, each of those “characters” is actually a 2×4 group of pixels. For example, the area inside the red rectangle in the image above is represented in the Kaypro’s memory as this set of five characters, each stored as a single byte:
The values of those bytes are determined by setting bits that correspond to each of the pixels, per rules that are well documented to this day by Skookum Pete. Each 2×4 block of pixels was represented by a single byte in memory, and each time a pixel changed between black and green you had to go through several steps including determining the row/column of the 2×4 block of pixels containing this one, getting the current value of that byte, figuring out how it needs to be modified, and writing the new value out.
Drawing straight lines
These days, all personal computers and similar devices have a math coprocessor: a dedicated chip for handling floating point arithmetic, offloading that computing-intensive task from the CPU. Back in 1984, coprocessors weren’t nearly as common. The IBM PC was sold with a socket for an optional Intel 8087 math coprocessor, but the Kaypro CP/M computers had no such option.
This lack of floating point arithmetic ability meant that SCS-Draw had to do everything in simple integer arithmetic. The alternative was to use a floating point math library for the Z80, and although such libraries did exist at the time, they were way too big for my requirements. The executable code in SCS-Draw ran about 40,000 bytes, leaving roughly 24K of the computer’s (non-expandable) 64K of memory available for the drawing itself. So I couldn’t afford to waste several KB of memory on a math library that would only be used while drawing straight lines.
Enter the Bresenham line-drawing algorithm, which defines a method for drawing a straight line between two points in a grid through the use of integer arithmetic and bit shifting: no floating-point calculations required. The Bresenham algorithm is a very efficient method for answering the question of which pixels should be included in an approximation of a straight line, as shown here:
I wrote an implementation of the Bresenham algorithm in Z80 assembly language that was fast and small, using only a fraction of 1KB of memory. I won’t get into the details of the algorithm here (Wikipedia has a nice explanation), but the basic concept is that you keep track of the running “error” in your line as you move from pixel to pixel – that is, how far above or below the “true line” you are. This error ranges from +.5 to –.5, and whenever it strays outside that range it’s time to move to the next row of pixels above or below. (All done without decimals, of course – see “Algorithm with Integer Arithmetic” on the Wikipedia page if you’re curious about the details.)
Printing graphics in the CP/M world
To make SCS-Draw print on a variety of printers, I had to write custom print drivers in Z80 assembly language (with no operating system support at all, of course) for each specific printer. I supported 25 different printers, including the most popular dot-matrix printers, inkjet printers, and even daisy wheel printers like the Diablo 630 or Juki 6100. I wrote a driver for the HP Thinkjet first (since that was the printer I owned), then I wrote drivers for the Epson MX-80, the other Epsons, the C. Itohs, the Okidatas, the Mannesman Tallys, and a few other popular models.
You may be wondering: how can a daisy wheel printer print graphics? Well, you only use one character, the period, and you move the printhead in tiny increments, translating each row of pixels into a row of periods or spaces. It takes forever to print even a simple image, and the constant hammering on the period makes it get hot and the plastic gets soft and pretty soon the period gets flatter and bigger and the images get blurry. I threw away several Diablo 630 daisywheels that were in like-new condition on every character expect for the period.
After studying the technical documentation for a few different dot-matrix printers, I realized that they were all just variations on some common themes. You send some bytes to tell the printer to get ready for graphics, you send some bytes representing a row of graphics data, you deal with the end of the line, repeat until done, then send some bytes to say we’re done. And some of those byte strings had to have values encoded in them for things like the number of pixels across, or the number of rows. So I wrote a single generic print driver, allocating buffers for these various byte strings, assigning various settings to bits in a few control bytes, and then I created a table of all of the data for a set of supported printers. The user could select a printer, and the generic print driver was then customized to match the necessary control codes for that printer. Adding support for a printer meant adding another row structure to the data table. Fun stuff, or so I thought at the time.
The “Technical Information” appendix of the user guide contained some information about how SCS-Draw’s print drivers worked, as well as a few other things that are sort of interesting to me as historical footnotes:
When I pulled out a copy of the user guide to photograph those two pages, I came across the first page, entitled No Fine Print, which I hadn’t thought about in many years. Sort of amusing now, in hindsight:
I included a summary of SCS-Draw’s functionality on the back cover of the package (which was designed by my friend Jeff Hapner, graphic designer extraordinaire):
I also provided details and screenshots in an informal 2-color brochure, printed and folded at a PIP print shop:
Putting it all together
There’s a particular photo taken by my friends Donna and George that is the image I always think of when I remember SCS-Draw, because it sort of sums up what the program was all about:
To users of modern personal computers, there’s nothing particularly impressive about that photo, but for Kaypro users in the early 80s this was a striking image. No other software had shown off the graphics capability of the Kaypro hardware in this way, and the fact the same image was printing on a printer (the ubiquitous HP Thinkjet 2225C) was also something new in the CP/M world.
Like so many things, software development was different in the 80s
It’s striking to look back on how much software development has changed in the last 25 years. In the 1980s, I can remember being fascinated to overhear somebody talking about programming in a restaurant in Chicago; these days, I feel lucky if I sit next to some young guys at the Starbucks who aren’t talking about their software idea that’s going to set the world on its ear.
Back then, to sell software you had to have a fax machine for receiving orders and a postage meter for shipping packages, as well as a shrinkwrap machine like the one shown here, for sealing up the plastic cases that each held a disk, a registration card, and a user manual. Shrinkwrap machines were fun – you could shrinkwrap the boots onto your feet and run around in the snow, for example.
There were also various things to sign up for: a PO Box, an ISBN prefix, a prepaid postage account (for “business reply mail”), and so on. And things to explain: In Appendix C of the SCS-Draw user manual, I provided detailed instructions on how to connect a 4-position joystick for use with SCS-Draw (some soldering required), and I bought a supply of joysticks from an electronics surplus store and sold them to customers.
I was a regular at the local speedy print shop, where I printed brochures, package covers, mass mailings, registration cards, and related materials. For the user guide, I went with a large commercial printer, and I had to go on a press proof in the middle of the night when my print job was running, to verify that everything was coming together as planned. I had batches of custom floppy disk sleeves printed by a firm specializing in such things, and I’d have batches of 100 or 500 disks duplicated by a large duplicating house. Sometimes I’d fix a bug in response to a support letter and burn them a new disk right away.
Tech support via snail mail was time-consuming. People would mail me a letter explaining the problem they were having, and I’d write a response and mail it back. I deliberately didn’t have an 800 number the first few years, because I didn’t want to spend my time answering phone calls. The fact a support call was a toll call seemed to keep the calls to a minimum, and people often wrote letters instead.
I had a single registered SCS-Draw user in Little Rock, Arkansas, but I received several support calls and letters from Little Rock. I handled them all as if they were paying customers, but I knew something wasn’t right. Years later, I heard from an SCS-Draw user in Little Rock who had gotten the program at a local user group meeting, where a disk was available for duplication as needed. Apparently they hadn’t read the No Fine Print page.
Sales and Marketing
Nothing really happens in business until somebody sells something. With SCS-Draw, I tried a variety of techniques for selling copies, some successful, most not.
I started out with a small quarter-page ad in Profiles Magazine, the primary magazine of the Kaypro community in the United States, as well as a full-page ad in Micro Cornucopia, the eccentric microcomputer hobbyist magazine published by David Thompson, an engineer in Bend, Oregon. Micro Cornucopia was the kind of magazine that published as many electronic circuits as source-code snippets, whereas Profiles was more of a business-oriented publication that ran reviews of hardware and software as well as how-to articles for Kaypro users.
Those ads sold a couple hundred copies (finally some revenue!), and then in the winter of 1985/1986 two things happened in quick succession: an order from Central Computer Products (Fillmore, CA) for 600 copies, and a review in Profiles that wound up putting SCS-Draw on the cover:
The money quote from Chris Meeks’s review in Profiles was that SCS-Draw was a “fabulous program” that “permits you to draw to the best of your abilities – and your computer’s.”
I spent a year thinking about ways to capitalize on the publicity generated by the Profiles review. For example, my friend Scott Phillips helped me put together a press release about SCS-Draw, complete with an attached 8×10 black and white glossy print, and I left stacks of those press releases in the press room at Comdex and other shows. I got some free coverage in InfoWorld as “one of the interesting products at Comdex Atlanta,” despite the fact that I had no booth and was just another bearded attendee in an ill-fitting suit and high-top sneakers. I remember getting on a shuttle bus while sporting that look, and a guy nearby said “let me guess, programmer and company founder.” I beamed and said yes, of course.
I managed to convince a Kaypro employee whom I met at a trade show to send me a dBase file (on a floppy disk) containing a list of all of their registered dealers. I did a custom mailing to those dealers offering a low price on a “six pack” of SCS-Draw, and sold a few hundred copies that way.
Before long, the first version of SCS-Draw had sold 1500 copies and I was releasing version 1.1. (Why didn’t I call it version 2.0? I don’t remember.) For the 1.1 release, my friend Jeff designed a nice cover for the package and user manual:
Here’s a full-page ad that I ran six times in Profiles Magazine:
That ad includes a reference to the “Image Extractor,” a program that gave SCS-Draw access to the largest set of pre-existing bitmap graphics available for CP/M computers. PrintMaster was (and still is!) a popular program from Broderbund Software for printing greeting cards and many other things, and it included a set of clip-art images. I bought a copy and analyzed their image library to figure out how they stored bitmapped graphics, then wrote the Image Extractor to pull those images out of PrintMaster and put them into SCS-Draw image libraries instead.
By the end of 1986, the CP/M era had come to a close, and in the following year many of the big CP/M players would go under, including Profiles Magazine. I was lucky enough to owe Profiles a few thousand dollars in ad fees at the time they went out of business, and nobody ever contacted me about it. 🙂 Over the next couple of years, I moved into new areas, polishing up my MS-DOS assembly language programming skills, becoming a Novell Netware CNE (Certified Network Engineer) and learning dBase so that I could customize SBT accounting systems.
SCS-Draw was a labor of love, and one of three programs that I’ve put thousands of hours into. The other two were Gen-Bar, a generic bar-code tracking application, and Servis, a line-of-business system for wholesale auto auctions – maybe I’ll do a blog post about each of those some day. It was fun to write up some details of SCS-Draw days here, for my own amusement if nobody else’s.
In researching some things for this post, I came across a nice one-paragraph review of SCS-Draw on this page, which seems a fine way to end this long rambling post:
(Second City Software, Box 267960, Chicago IL 60626)
A very likeable program for designing images to be printed to paper. Drawing is done in black on a large green canvas of 336 x 362 pixels, a portion of which is displayed in a window that occupies about two-thirds of the screen, the rest being taken up by a menu and window-position indicator. While inversion is used to good effect (you can draw a line that shows black against green and green against black), every pixel is simply either on or off, and hence there are no real video effects like half-intensity or blinking. A nice touch is that you can draw or erase a single pixel without leaving “move” status, saving much confusion. Text can be added in a choice of rudimentary fonts and enlarged to as much as banner size. There are many other features including cut-and-paste, merging of images in various ways, automatic drawing of lines, circles, and rectangles, easy block erase, rapid cursor moves, pattern-fill, and on-screen enlargement in two separate dimensions. Options at the printing stage enable further enlargement, flipping, rotating, and repeating of images. The program is helpful, quick, and easy to use throughout.