SCS-Draw: teaching the Kaypro to draw

SCS-Draw: teaching the Kaypro to draw

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 Fortran 77 syntax, which I knew well from my work at Boeing in Seattle a few years earlier.

Kaypro II

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.

1984: my home office tucked in a 1-room apartment in Chicago; it's a grainy faded old Polaroid, but I can make out the Kaypro II, HP Thinkjet 2225C ink-jet printer, and Microsoft Multiplan

Character-mode "graphics"

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 photo of SCS-Draw in action:

SCS-Draw

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:

mapping pixels to characters/bytes

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.

NOTE: Version 16.0 of the Unicode standard, currently scheduled for release in September 2024, will include the Kaypro character set! More information can be found here: https://www.unicode.org/L2/L2021/21235-terminals-supplement.pdf
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:

Bresenham line-drawing algorithm

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:

SCS-Draw - Appendix B
SCS-Draw - Appendix B (continued)

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:

SCS-Draw's anti-license license

SCS-Draw features

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):

SCS-Draw slip case, back cover

I also provided details and screenshots in an informal 2-color brochure, printed and folded at my local PIP print shop in the Chicago area:

SCS-Draw brochure - front
SCS-Draw brochure - back

Putting it all together

There’s a particular photo taken by my friends Donna and George (Siede Preis Photography) 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:

SCS-Draw in action

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.

tabletop shrink wrap machine with heat gun

There were also various things to sign up for: a PO Box, an ISBN prefix, a prepaid postage account (for “business reply mail”), a credit card processing service, 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:

Profiles magazine, March 1986

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:

SCS-Draw 1.1 packaging

Here’s a full-page ad that I ran six times in Profiles Magazine:

SCS-Draw ad 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.

Note: as of the end of 2023, SCS-Draw is now freeware, published under a GNU GPLv3 license on Github in this repository: https://github.com/dmahugh/scs-draw

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:

SCS-DRAW (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.

Addendum: comments from the original blog post

This post was originally on my old WordPress blog, and below is the comment thread from that post. I decided to preserve it here because it has a few details of interest to those of us who remember those days.

Leif – 9/12/2014, 11:14PM

I was just doing a Google search for references to the old lowes Printmaster images (thought they might prove interesting source material for some ASCII art doodling I was doing – these moods take one from time to time), and I wandered into this wonderful account of the creation and marketing of SCS-Draw. The Kaypro II was a great little CP/M system, and I was so fond of it that I replaced it with the slightly more capable Kaypro 1 when it came out at the tail end of the CP/M era. It was very affordable, effectively a repackaged Kaypro 4 with a slashed price tag, but I don’t think I’ve ever had a salesman try so hard to talk me out of buying something. I patiently explained that I knew what I was doing, enjoyed tinkering with CP/M, and didn’t really feel like spending the money on a PC clone at the time (that would come a few years later when AT-clone prices shot earthward).
Having read that glowing PROFILES review and gotten a kick out of the idea of doodling on a machine that didn’t actually have graphics, one of the very first things I bought after I got the K1 was my own copy of SCS-Draw with Image Extractor (as I’d bought several Printmaster libraries). In a drab landscape of WordStar and BASIC, SCS-Draw sparkled like a jewel, and I wasn’t surprised in the least to read here that it was a true “labor of love” – I can tell you from a user’s perspective that’s just how it looked and felt. A real artist could no doubt do interesting work with SCS-Draw (albeit in a very specific format), but for me it was just a lot of fun to play around with when taking a break from more serious work. The Image Extractor inspired me to write my own C program for Unix systems to select and display Printmaster images on terminals that had a mosaic character set similar to the Kaypro’s “graphics”. It was a great office toy in our shop, as I think there’s something about seeing “text-only” devices displaying images, however crudely, that just tickles the imagination. Though by that time we had all seen Macs and “real” VGA graphics, it was the dumb terminal context that made it feel almost magical.
SCS-Draw had that same magic, and I’ve never forgotten it. Thanks for creating it, and thanks for sharing its story with us. Reading this was quite a treat.

Dmahugh – 9/13/2014 1:08AM

Thank you so much for taking the time to comment here, Leif. You have absolutely made my day! I threw myself into SCS-Draw with reckless abandon, and it’s great to hear from somebody who appreciated it. I got some nice letters from SCS-Draw users back in the day, but I’ve lost those and your comment is the only feedback I have from a customer now.
You make a great point about how seeing graphics on “text-only” devices is somehow magical. I’m not sure whether everyone felt that way, but I sure did, and it’s great to hear from a kindred spirit. Thanks again.

Peter Donnelly – 2/3/2016, 3:57PM

Hi, I’m the creator of Artie and Artpage, two other graphics programs for the old Kaypro, and the author the short review that appears at the bottom of this article. How great to stumble on this reminder of the old days and programming for 64 Kb of RAM! Unlike you I did all my work in Turbo Pascal, and parts of the bulkier code had to be compiled as “overlays” that could swap in and out of memory as required.
Neither of these programs was as slick as SCS Draw, but I like to think that Artpage was the first and only “desktop publishing” application for Kaypro, since it enabled text and graphics to be combined on the same page.
After the death of CP/M, I went on to write many more shareware programs, with very little financial result, but always with fun and learning. Eventually, I finished my working life at Microsoft, where I documented SDKs and wrote sample code.

Dmahugh - 2/4/2016, 9:00AM

Hey Peter, great to hear from you! I remember reading about Artpage in Profiles, small world. And I happened to find that page linked above where you described how graphics worked on those Kaypro screens, which fun to come across when I was writing this post. We’ve followed similar paths, in that I’m at Microsoft now, after many years of fun with my own little software company back in Chicago. Those early days of personal computing were a blast, it’s nice to hear from somebody else who was immersed in that world.

Peter Donnelly – 2/4/2016, 4:06PM

Funny story that illustrates the dangers of self-teaching. I got curious about MBASIC and started to learn how to program on the Kaypro. As you may remember, the computer came with a terribly written CP/M manual and not much else in the way of documentation. The manual introduced the line editor as a tool for writing code (for those whose memories don’t stretch back that far, a line editor was literally that, letting you view and edit one line at a time). I soldiered away for a while trying to untangle spaghetti code in this editor, before stumbling on the fact that code files were just text, and I could use WordStar, which let me see 24 lines at once!

Brian Kresge – 10/30/2016, 6:05AM

I know this post is three years old, but I wanted to thank you for your work.
I was one of those “no fine print” users of your software. I think it was 1988, and my father made the transition to DOS and I received his old Kaypro as my “learning computer.” Someone duped SCS-Draw at our local microcomputer user group for me, and I was hooked. The Kaypro and the accompanying printer carried me through all of my word processing needs, from junior high to my junior year of high school in the mid-1990s. I used SCS-Draw extensively to include “figures” in many of my reports.
There were times when the operations were a little kludgy, especially when my friends had 286s or 1990s-era Macs, but it was more than capable.
I still use my Kaypro 10 for spare word processing on WS4 today. I haven’t considered using it to the extent that I did 30 years ago, but I do have Peter Donnelly’s ARTIE installed on it. It’s fun for when I want to show my children how we did things in the “dark ages.”
I attribute my success as a programmer today to having to “make things work” with a Kaypro, and SCS-Draw was a vital component of what kept my output from looking too far behind my peers.
Thank you!

Dmahugh – 10/30/2016, 9:15AM

Thanks, Brian! It’s great to hear from a kindred spirit from the early days. :)
I’m glad you got so much use out of SCS-Draw.

Tom – 1/12/2017, 10:24AM

Uh it’s super hard to find details like this about Kaypro. Do you know any sources where the original character set is available? Hexa values would be the best.

Tom – 1/13/2017, 5:28AM

Or the fonts were part of the CP/M operating system?
Could you confirm that any of these fonts were on the original Kaypro II (1982)?
http://www.cpcwiki.eu/forum/applications/fonts-for-cpm/
many thanks,
Tom

Dmahugh – 1/13/2017, 8:18AM

Hey Tom, no I’m not sure about the fonts. I haven’t used a CP/M machine since the late 80s, and don’t remember all the details clearly, but I believe there was a single monospaced font character set in ROM and that was used for everything. That Skookum Pete link in the post above is the most complete info I found only regarding the Kaypro character set, so perhaps he would know more.

Tom – 1/13/2017, 10:19AM

Thanks for the ROM tip! I’ve found this: http://www.retroarchive.org/maslin/roms/kaypro/index.html
I’ll try to extract the character sets from one of them.

Tom – 1/13/2017, 2:22PM

Done. :)
Kaypro II (1982) characters:
0x0C, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 0
0x00, 0x00, 0x00, 0x0D, 0x12, 0x12, 0x0D, 0x00, // Char 1
0x00, 0x00, 0x1C, 0x12, 0x1C, 0x12, 0x1C, 0x10, // Char 2
0x00, 0x00, 0x01, 0x1A, 0x04, 0x0B, 0x10, 0x00, // Char 3
0x00, 0x08, 0x10, 0x0C, 0x12, 0x12, 0x0C, 0x00, // Char 4
0x00, 0x00, 0x0C, 0x10, 0x1C, 0x10, 0x0C, 0x00, // Char 5
0x04, 0x04, 0x0E, 0x15, 0x15, 0x0E, 0x04, 0x04, // Char 6
0x00, 0x00, 0x00, 0x09, 0x15, 0x02, 0x02, 0x04, // Char 7
0x00, 0x0E, 0x11, 0x1F, 0x1F, 0x11, 0x0E, 0x00, // Char 8
0x00, 0x00, 0x00, 0x08, 0x08, 0x0A, 0x04, 0x00, // Char 9
0x00, 0x00, 0x00, 0x0F, 0x12, 0x12, 0x0C, 0x00, // Char 10
0x00, 0x00, 0x12, 0x12, 0x1C, 0x12, 0x12, 0x00, // Char 11
0x00, 0x00, 0x10, 0x08, 0x04, 0x0A, 0x11, 0x00, // Char 12
0x00, 0x00, 0x00, 0x12, 0x12, 0x1C, 0x10, 0x10, // Char 13
0x00, 0x00, 0x11, 0x09, 0x09, 0x06, 0x04, 0x00, // Char 14
0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x0E, 0x00, // Char 15
0x00, 0x00, 0x00, 0x0F, 0x1A, 0x0A, 0x0A, 0x00, // Char 16
0x00, 0x00, 0x00, 0x16, 0x19, 0x11, 0x11, 0x01, // Char 17
0x00, 0x00, 0x06, 0x09, 0x09, 0x0E, 0x08, 0x08, // Char 18
0x1F, 0x08, 0x04, 0x02, 0x04, 0x08, 0x1F, 0x00, // Char 19
0x00, 0x00, 0x00, 0x0F, 0x14, 0x04, 0x04, 0x00, // Char 20
0x00, 0x0A, 0x15, 0x05, 0x04, 0x04, 0x04, 0x00, // Char 21
0x04, 0x15, 0x15, 0x0E, 0x04, 0x04, 0x04, 0x00, // Char 22
0x00, 0x00, 0x02, 0x1F, 0x04, 0x1F, 0x08, 0x00, // Char 23
0x00, 0x00, 0x1F, 0x00, 0x0E, 0x00, 0x1F, 0x00, // Char 24
0x00, 0x00, 0x0E, 0x11, 0x11, 0x0A, 0x1B, 0x00, // Char 25
0x00, 0x10, 0x16, 0x0E, 0x04, 0x02, 0x02, 0x0C, // Char 26
0x06, 0x08, 0x08, 0x10, 0x08, 0x08, 0x06, 0x00, // Char 27
0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x04, 0x00, // Char 28
0x0C, 0x02, 0x02, 0x01, 0x02, 0x02, 0x0C, 0x00, // Char 29
0x00, 0x00, 0x00, 0x08, 0x15, 0x02, 0x00, 0x00, // Char 30
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // Char 31
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 32
0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, // Char 33
0x0A, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 34
0x0A, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x0A, 0x00, // Char 35
0x04, 0x0F, 0x14, 0x0E, 0x05, 0x1E, 0x04, 0x00, // Char 36
0x18, 0x19, 0x02, 0x04, 0x08, 0x13, 0x03, 0x00, // Char 37
0x08, 0x14, 0x14, 0x08, 0x15, 0x12, 0x0D, 0x00, // Char 38
0x06, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 39
0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02, 0x00, // Char 40
0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00, // Char 41
0x04, 0x15, 0x0E, 0x04, 0x0E, 0x15, 0x04, 0x00, // Char 42
0x00, 0x04, 0x04, 0x1F, 0x04, 0x04, 0x00, 0x00, // Char 43
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x04, // Char 44
0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, // Char 45
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, // Char 46
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, // Char 47
0x0E, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0E, 0x00, // Char 48
0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x0E, 0x00, // Char 49
0x0E, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1F, 0x00, // Char 50
0x0E, 0x11, 0x01, 0x06, 0x01, 0x11, 0x0E, 0x00, // Char 51
0x02, 0x06, 0x0A, 0x12, 0x1F, 0x02, 0x02, 0x00, // Char 52
0x1F, 0x10, 0x10, 0x1E, 0x01, 0x01, 0x1E, 0x00, // Char 53
0x0E, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x0E, 0x00, // Char 54
0x1F, 0x11, 0x02, 0x04, 0x08, 0x08, 0x08, 0x00, // Char 55
0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E, 0x00, // Char 56
0x0E, 0x11, 0x11, 0x0F, 0x01, 0x01, 0x0E, 0x00, // Char 57
0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x00, // Char 58
0x00, 0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x08, // Char 59
0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 0x00, // Char 60
0x00, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00, 0x00, // Char 61
0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x00, // Char 62
0x0E, 0x11, 0x11, 0x02, 0x04, 0x00, 0x04, 0x00, // Char 63
0x0E, 0x11, 0x15, 0x1B, 0x16, 0x10, 0x0E, 0x00, // Char 64
0x04, 0x0A, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x00, // Char 65
0x1E, 0x11, 0x11, 0x1E, 0x11, 0x11, 0x1E, 0x00, // Char 66
0x0E, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0E, 0x00, // Char 67
0x1E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1E, 0x00, // Char 68
0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x1F, 0x00, // Char 69
0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x10, 0x00, // Char 70
0x0E, 0x11, 0x10, 0x13, 0x11, 0x11, 0x0E, 0x00, // Char 71
0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11, 0x00, // Char 72
0x0E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E, 0x00, // Char 73
0x01, 0x01, 0x01, 0x01, 0x01, 0x11, 0x0E, 0x00, // Char 74
0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11, 0x00, // Char 75
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // Char 76
0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x11, 0x00, // Char 77
0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x00, // Char 78
0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, // Char 79
0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10, 0x00, // Char 80
0x0E, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0D, 0x00, // Char 81
0x1E, 0x11, 0x11, 0x1E, 0x14, 0x12, 0x11, 0x00, // Char 82
0x0E, 0x11, 0x10, 0x0E, 0x01, 0x11, 0x0E, 0x00, // Char 83
0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // Char 84
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, // Char 85
0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04, 0x00, // Char 86
0x11, 0x11, 0x11, 0x15, 0x15, 0x1B, 0x11, 0x00, // Char 87
0x11, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11, 0x00, // Char 88
0x11, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00, // Char 89
0x1F, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1F, 0x00, // Char 90
0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0E, 0x00, // Char 91
0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, // Char 92
0x0E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x00, // Char 93
0x04, 0x0A, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 94
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // Char 95
0x0C, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 96
0x00, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F, 0x00, // Char 97
0x10, 0x10, 0x1E, 0x11, 0x11, 0x11, 0x1E, 0x00, // Char 98
0x00, 0x00, 0x0E, 0x11, 0x10, 0x10, 0x0E, 0x00, // Char 99
0x01, 0x01, 0x0F, 0x11, 0x11, 0x11, 0x0F, 0x00, // Char 100
0x00, 0x00, 0x0E, 0x11, 0x1F, 0x10, 0x0E, 0x00, // Char 101
0x06, 0x09, 0x1C, 0x08, 0x08, 0x08, 0x08, 0x00, // Char 102
0x00, 0x00, 0x0E, 0x11, 0x11, 0x0F, 0x01, 0x0E, // Char 103
0x10, 0x10, 0x1E, 0x11, 0x11, 0x11, 0x11, 0x00, // Char 104
0x04, 0x00, 0x0C, 0x04, 0x04, 0x04, 0x0E, 0x00, // Char 105
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x11, 0x0E, // Char 106
0x08, 0x08, 0x09, 0x0A, 0x0C, 0x0A, 0x09, 0x00, // Char 107
0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E, 0x00, // Char 108
0x00, 0x00, 0x1A, 0x15, 0x15, 0x15, 0x15, 0x00, // Char 109
0x00, 0x00, 0x1E, 0x11, 0x11, 0x11, 0x11, 0x00, // Char 110
0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x0E, 0x00, // Char 111
0x00, 0x00, 0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, // Char 112
0x00, 0x00, 0x0F, 0x11, 0x11, 0x0F, 0x01, 0x01, // Char 113
0x00, 0x00, 0x16, 0x09, 0x08, 0x08, 0x08, 0x00, // Char 114
0x00, 0x00, 0x0E, 0x10, 0x0E, 0x01, 0x0E, 0x00, // Char 115
0x08, 0x08, 0x1C, 0x08, 0x08, 0x09, 0x06, 0x00, // Char 116
0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, // Char 117
0x00, 0x00, 0x11, 0x11, 0x0A, 0x0A, 0x04, 0x00, // Char 118
0x00, 0x00, 0x11, 0x11, 0x15, 0x1F, 0x0A, 0x00, // Char 119
0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x00, // Char 120
0x00, 0x00, 0x11, 0x11, 0x11, 0x0F, 0x01, 0x0E, // Char 121
0x00, 0x00, 0x1F, 0x02, 0x04, 0x08, 0x1F, 0x00, // Char 122
0x06, 0x08, 0x08, 0x10, 0x08, 0x08, 0x06, 0x00, // Char 123
0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x04, 0x00, // Char 124
0x0C, 0x02, 0x02, 0x01, 0x02, 0x02, 0x0C, 0x00, // Char 125
0x00, 0x00, 0x08, 0x15, 0x02, 0x00, 0x00, 0x00, // Char 126
0x0A, 0x15, 0x0A, 0x15, 0x0A, 0x15, 0x0A, 0x00 // Char 127
I plan to create a nice terminal emulator in OpenGL (like Cathode, but for Windows), but I’ll read the Skookum Pete article first to see how these chars were used,
best,
Tom

Stefano Bodrato – 3/16/2018, 2:00AM

The current Kaypro ’84 emulation in MESS lacks the text attributes handling.This results in a bug on the graphics output, because the character representing (IIRC) the bottom-left pixel was missing and was replaced by its inverted equivalent (bottom-left pixel left blank, all the other pixels set) plus the inverse text attribute.