Beginning

After I moved to Southern California in late 1981 I got a job at the Analect Instruments division of Laser Precision Corp. While Laser Precision was located in Utica, New York, the president of the company lived in Laguna Beach, probably because he could.

They hired me after a fairly informal interview, partly on the strength that I knew the Z-80 well enough to make offhand remarks about its poor index register implementation. (16-bit registers are fine, but an 8-bit offset? That's a tad parsimonious. For example, you couldn't use X as an index into two different variables simultaneously, each at different 16-bit locations. I would rather the index registers were 8-bit and the offset 16-bit.)

Once I started it turned out that they didn't really have anything for me to do. They gave me a listing of some software they wanted me to learn. It was barely commented, about one per page, so I set out to comment it and learn it at the same time. It turned out to be a pretty effective method that I have continued to use since then.

EPROM Programmer

I noticed that the EPROM programmer's software was very primitive and nearly unusable – it would burn one ROM at a time; to burn more you had to use DDT (CP/M's debug utility) to move the data around for each ROM. I used the debugger to grab the basic hardware drivers, converted them to assembly, and incorporated them into a simple but much friendlier application. The result of a few hours' work was an increase in productivity – and the gratitude of my co-workers.

My manager was impressed with this – not the work I had done so much as the fact that, having no assignments and being able to sit back and collect pay, instead I found something productive to do with my time. He was so impressed that he mentioned it on my first two reviews. (After that another manager took over the department.)

Format and Backup

Everything was on 8-inch floppies in those days. We were using a non-standard format; our formatting utility was very limited and annoying to use. Backing up consisted of manually copying files from one disc to another. I got tired of this; I extracted the drivers, expanded them, turned them into Pascal-callable functions, and wrote two utilities: Format and Backup.

One of the nice things about the Western Digital floppy controller at the time was the ability to find out what sector was going under the head. I used that ability and the knowledge of the interleave to reduce the average latency of a read or write from ½ of a track to 1½ sectors. So backups and format verifies were actually quite fast, faster than other utilities we encountered, as long as you chose the correct interleave.

If I were writing it now I'd have the backup utility actually read one track's interleave, store it, and use it instead of asking the user to provide the information.

As it is, my manager at the time wasn't convinced of their usefulness until he was having problems with his main development floppy. He asked me for help; I tucked it into my drive and ran my Backup utility on it, onto another floppy. It had no trouble reading it. At that point he was convinced.

The odd thing is that it wasn't Backup that fixed the disc! If the hardware was having problems reading, then my utility wouldn't have done any better than the operating system. But he was so happy to have his data that he wasn't listening. That's OK with me; he needed to start doing backups of his data anyway.

One day I discovered something: my modest, ugly utilities were being shipped with product! These were never intended to get out into the field, but they did anyway. By that time they were being used company-wide, I guess somebody just decided it made sense to include them with shipping systems. It did, but they should have been prettied up first at least.

File System

At one point they wanted to add a file system to one of their 8085-based devices, but just enough to save and load data – they didn't really want to implement an entire operating system. So I sat down and started designing.

I decided to keep it extremely simple: one directory entry per file; start sector and size. I don't remember how I implemented the free space algorithm, but it may have simply been a real-time directory scan (see what's used, the rest is available.

It included five utilities: Directory, Delete, Format, Space, and Compress.

  • Directory - Show a list of files on the disc.
  • Delete - Remove a file.
  • Format - Format the disc.
  • Space - Show the remaining space on the disc: total, and largest available chunk.
  • Compress - Move files down so that all empty space occupies a single chunk.

Actually, I don't remember exactly what I implemented. It was five utilities, but it could have been Load and Save instead of Directory and Format, or some other combination, because I also implemented a utility under CP/M to read and write those discs.

In any case, the file system worked well and was very lightweight.

Hard Drive and Scheduling

I remember a meeting where we told the head of Sales that we were planning on adding a hard drive – someday. Naturally he had sold two units within a month of this meeting.

About a year later we actually finally started planning on this. My manager (not the one who'd hired me) asked for an estimate for me to write the interface between CP/M and the hard drive. I sat down, thought about what it should take, considered bugs and unexpected issues, and came up with a number: six months.

No, he said. That's too long. So I sat down, cut out the fat, assumed everything would work perfectly the first time, no bugs and no issues, and submitted the new estimate: three months.

Much better, he said. Get to work on it. So I did. By now you probably already know where I'm going with this. How long do you suppose it took? Exactly correct: six months, almost to the day.

I hate doing estimates, but I try to be as honest as I can, and I always pad for unknowns.

By the way, the drivers worked very well.

Hacked Mouse Drivers

Drawing spectra means graphical displays. As events progressed we naturally moved from CP/M-based machines to DOS-based IBM clones. I spent some time with another developer writing applications that displayed data on standard IBM-type displays in graphical mode.

But we had a problem: the Logitec mice didn't work properly in graphical mode. After some debugging work we discovered that it was treating the high bit of the display mode – which was used as a bitmap vs. text flag – as part of the mode word, so a less-than compare consistently came up with the wrong answer.

Of course this meant adding code, and the obvious place to add code was the copyright string. But I found something else. The 8086-class processors have two sets of PUSH and POP operations, long (which was orthogonal with the rest of the operation set) and short (deliberately added for performance reasons, I presume). Not far from the code in question was a series of pushes and pops that for some reason was using the long operations instead of the short.

By replacing the stack operations with the short versions and adding a jump I was able to free up enough room to add the code we needed to properly test the current display mode, excluding the high bit, including a jump back into the original code. In the long run it didn't matter – truncating the copyright code and using that space would have been fine, but I considered this more elegant.

We wrote to Logitec and reported what we'd found, included a copy of the hacked driver with appropriate notes, and went on our merry way. We never heard back from Logitec but the next time we got a driver update we noticed that they had fixed the problem.

Plotter Drivers

One of the last things I did before I left Analect was to fix the plotter drivers. We were making infrared spectrophotometers, which would scan organic materials and give us a spectral analysis as a result. We were selling X-Y plotters with the devices, mostly HPGL, though we did support Watanabe as well. I have to say that the people who did the plotter drivers were smart enough to abstract the interface. However, there were some problems.

  • We tended to use cheap copy paper for our testing instead of the coated stock required for the felt-tipped plotter pens to draw properly at normal speed. In order to see the plots we were slowing the plotters down. This made sense for testing; however, we kept shipping the plotter drivers using the slow settings, as though that were the correct way to do it.
  • We were sending every coordinate pair to the plotter no matter how dense the plot. In some cases, because the plotter's resolution was so much less than the plot's, we might easily send the same pair of coordinates six or eight times in a row. Or more.
  • We were sending absolute coordinate pairs. Since HPGL uses delimited decimal numbers, that meant that we only needed to send as many digits as we had significance, so using relative coordinates would have been much faster.
  • We sent either a Pen Up or Pen Down command with every single coordinate pair.
  • In order to speed up text plotting (I assume) the character set we devised was skimpy – they didn't require many pen movements, but they tended to look ugly – especially when they were written large.

One day I simply got fed up with this and got permission to improve it.

Speed

The first thing I did was change the initialization string to return the plotter to its default settings, which automatically adjusted the pen speed according to the type of pens installed. I figured that the plotter was designed to be used a certain way; just because we weren't using it that way didn't mean the plotter was wrong.

This helped a little; any time the pen wrote lines (instead of curves) or moved with the pen up it moved faster. But very dense plots still took forever for the other reasons.

Plot Density

This is my favorite part. I decided that my biggest problem was that we were sending too many redundant coordinate pairs. I studied the software to see if there was a good way to prevent generating the extra information, but it was so tied into the data presentation – not only the data themselves, but how much of them the customer wanted to see – that I didn't see any clean way of doing it. So I decided to tackle it at a different point: just before the output.

Fortunately everything came through a single point. I intercepted the coordinates there and stored the last pair as I got them. When the next pair arrived I compared them; if they were the same, I threw them away and returned. Otherwise I sent them on.

The difference in speed was amazing, but I wasn't through yet.

Absolute vs. Relative

On the first pair of coordinates for a plot – I believe I used the command to eject the paper to determine that, though it may have been something else – I sent the coordinates on as absolutes. On all subsequent coordinate pairs, however, I switched to relative mode. Most plots were of spectra, where the coordinates of one data point are near the adjacent points, so relative coordinates were usually one or two digits, where absolutes could be four or five. (And the differences in X coordinates were almost always 1 in any case, and when they weren't, it was going to be a fast plot anyway.)

And that still wasn't enough. I was determined to squeeze every bit of speed out that I could.

Redundant Pen Commands

Once the pen is down there is no reason to keep sending Pen Down commands, and the same for Pen Up, until the pen has to change. We were sending pen commands with every coordinate pair! I kept track of what the pen was doing and only sent Pen commands when necessary.

In fact I did a little more than that. When I got movement commands while the pen was up I ignored them until I got a Pen Down command (except one that returned the pen to 0,0). The way they'd implemented the character writing routines was to position the pen to the top left of the character space, then position it to the first pen-down coordinate, put the pen down, draw as necessary; when it was done it would lift the pen and return it to the starting position. This sort of thing didn't hurt much when drawing spectra – it would only happen twice at most. But it added a lot of unnecessary pen movement between characters, and thus slowed character writing significantly.

By not sending movement commands until I got a Pen Down, and then moving directly to the last coordinate, I save a lot of excess movement and the extra time it took.

By not sending redundant Pen Up and Pen Down commands I saved three characters per coordinate pair, which at 9600 bps added up pretty quickly.

Less Ugly Characters

By this time I had squeezed out all the speed I could get. And what a difference! Plots that used to take 20 minutes to draw now took under 60 seconds. Now I decided to tackle those ugly characters. After all, the plotter was a lot faster now; I could afford some curves, or at least more angles.

Starting from the beginning I drew vector characters on graph paper, and as I completed each one converted it to a list of coordinates and replaced the old character in the code.

The only problem was, I was about 2/3 of the way through the alphabet when Laser Precision decided to divest itself of the Analect Instruments division and, to make it look more profitable, laid off its software staff.

 
analect_instruments.txt · Last modified: 2008/07/29 22:57 by jnork
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki