Another release of my Electromechanical Computer Simulation
Published Mon, Sep 29 2008 3:25 AM
I decided to play with some code today, and so I implemented the clock delay track-bar for my Electromechanical Computer Simulation program. This turned out to be a bit more involved than I had expected, since part of my “design requirements” is to keep the size of the application as small as possible and to ensure that it will run on as many (Windows based) systems as possible. If you've got a computer that's running Windows XP or Vista, you should be able to install the simulation and run it without any problem.
For those of you running Linux, I'm afraid you'll have to wait a while, since I'm only slowly porting it over to work there. I think I'll be using the KDE environment for the port, but I haven't really gotten very far with it yet. Part of the porting effort involves re-factoring the main application class to separate out the machine from the interface. Most of the machine is implemented in a separate class library, but the top level objects are still part of the main application and tied to the interface.
An Electromechanical Computer Simulation
My program is a simulation of an electromechanical computer. It's based upon a simulation of an electromechanical relay similar to the telegraph relay. The inspiration for this came from Charles Petzold's book Code: The Hidden Language of Computer Hardware and Software. Mr. Petzold's book gives an excellent explanation of how simple concepts can be built upon to produce computers like the one you're using now. Simple concepts like electricity, electromagnetism, Boolean logic, and feedback form the basis of early electronic computing. Here I'll present a very brief explanation (although it may seem long winded for a blog post) of these concepts and how they apply to the simulation.
Electricity
Most of you probably learned what I'm about to explain in grade school. If you didn't, it's easy enough to demonstrate for just a couple of bucks.
An electric current is the flow of electrons from one place to another. A lightning bolt is an example, as demonstrated by Benjamin Franklin. Lightning is a form of static electric discharge. Another form is the spark that you can generate by rubbing your shoes across a carpet and then touching a metal doorknob. That “shock” you feel and the spark you can see (if it's dark enough) are almost exactly like lightning, just a lot less powerful. When you rub your shoes across the carpet and touch the doorknob, electrons move from the carpet into your body (charging you up), and then from your finger into the doorknob (the discharge) and eventually back into the carpet.
Early scientists studying electricity worked out lots of ways to generate static electricity, and ways to store it as well. One of the ways that they developed to store static electricity was called the Leyden jar. In 1780 Luigi Galvani discovered that dissected frog legs could be made to twitch if you hung them from a metal nail and touched them with a probe made of a different metal (he actually used a steel scalpel and a brass hook when he made the discovery). Galvani thought that this was due to “animal electricity” and that the frog's muscles were generating the power. Alessandro Volta had a different idea, believing that it was the different metals that were the source of the electricity. He eventually came up with a way to generate electricity using different metals and no animal parts, inventing the electric battery (the “electric pile”, which he described in a letter to the Royal Society of London on March 20, 1800.
With the invention of the electric battery, a steady source of electricity became available. If you connect one end of a piece of bell wire (a relatively thin copper wire with a plastic insulator) to the positive terminal of a six volt lantern battery and the other end to the negative terminal, electricity will flow. So much electricity will flow that the wire will quickly become hot and may even melt! We take advantage of this heat to light our homes using Thomas Edison's most famous invention, the incandescent light bulb.
If we connect one end of a piece of bell wire to the positive terminal of a six volt lantern battery and the other end to one terminal of a light bulb, and then connect another piece of bell wire to the other terminal of the light bulb and its other end to the negative terminal of the battery, the light will turn on (assuming of course that we use a light bulb with the appropriate resistance). This time the wire won't melt (at least, it's not likely to). Now we have a basic electric circuit, with a power supply, a conductor, and a load. Add one more element, a way to safely disconnect the conductor from the power supply known as a switch, and you've got the light circuit we're all at least partly familiar with. Go to the wall and flip the light switch. The lights in the room either turn on or off — provided they haven't burnt out (the wire inside them hasn't melted), that they're plugged in (the conductors are connected to the wiring inside the wall), and of course that you've paid your electric bill (your house wiring is still connected to the power supply).
Electromagnetism
Whenever electrons move, there's an electric current. Whenever you have an electric current, you also have another interesting phenomenon — a magnetic field. You can demonstrate this by taking a nail and wrapping a piece of bell wire around it a few dozen times, then connecting the wire to a battery. If you have another small nail, you'll find that it's attracted to the nail with the wire wrapped around it — as long as the wire is connected to the battery. Disconnect the wire from the battery and the nails are no longer attracted to each other. As long as an electric current is flowing through the wire it acts like a magnet.
In fact, this works the other way around too. If you have a magnet, and you move a coil of wire through it, this time with a few hundred loops instead of a few dozen, you can see that an electric current will be generated in the wire. All you need is a small light bulb to complete your circuit. This is the principle upon which a bicycle generator, a car alternator, or the massive generators at hydroelectric dams work to generate electricity.
Both of these principles put together are what makes the loop sensors in the road trigger the traffic signals when your car approaches them. A large loop (with a few turns of wire) is embedded just under the road surface. A small current flows through the loop. As your car's bumper or frame (made of metal) moves through the magnetic field generated by the current in the loop, a weak electric current is made to flow through it. This weak electric field produces its own magnetic field, which moving over the wire loop in the ground induces a change in the current flowing through it. That change in current gets amplified and used to trigger a switch which eventually triggers the traffic signal to change.
Triggering that switch in the signal box is done using electromagnetism too. The switch is actually a small device called a relay. A relay is a small, spring-loaded switch that is operated using an electromagnet (like our wire wrapped nail). If you connect one side of the switch to the power supply (we'll label that side of the switch power) and the other side of the switch to your load, for example a light bulb (we'll label that side of the switch output), and if the switch is normally open (in other words, there's no connection between the power and the output) until it's pulled closed by the electromagnet (we'll label one side of the wire wrapping our electromagnet the input and assume the other is always connected to the back side of our power supply, the ground), then you have a simple relay. Assuming the power is on then if the input is also on, the output is on. If either the power or the input are off, the output is off.
Relays are pretty handy devices. You can use a small current at low voltage to control a much larger current at much higher voltage using relays. There are relays in your car that do this very thing, protecting you from electric shock when you operate the various circuits. For example, it takes a lot of power to run your car's headlamps. There's probably enough power running through that circuit when your lights are on to give you a really painful shock if you touched the bare wires, or if you were using a switch with faulty insulation to turn them on and off. To protect you, the circuit is designed so that the headlight switch uses a very small current to trigger a relay. That relay operates the actual headlight circuit, so you never make contact with the bigger current, even if the insulation on your headlight circuit wears thin.
There's another kind of relay that's pretty nice to have too. If the switch that's operated by the electromagnet is usually closed (allowing current to flow), but it's opened (stopping the current flow) by the electromagnet then we can call it an inverter. With an inverter, if the power is on and the input is off the output is on, but if the power is off or the input is on the output is off. You might find one of these in the ignition circuit for your car, typically attached to a set of contacts on your shifter. This particular inverter is called a neutral safety switch and it prevents you from starting your car with the transmission in any position other than park or neutral. (Not all neutral safety switches use an inverter. Some use a standard relay and the terminal contacts attached to the shifter work in the opposite way.)
The way the neutral safety switch works is pretty interesting (at least it is to me). When you turn the key in your car to the On position, you close a switch that energizes many of the car's circuits. One of these circuits sends power to a set of contacts connected to your car's shifter. If the shifter is in the Park or in the Neutral position, this circuit doesn't make a connection to the neutral safety switch's input terminal, so the electromagnet doesn't have any power flowing through it. Since the switch is actually an inverter, the switch is closed. If the shifter isn't in one of those positions, the circuit does make a connection to the neutral safety switch's input terminal and the electromagnet has power flowing through it, pulling the switch open.
When you turn the key in your car to the Start position, it sends power flowing to the power connection of the neutral safety switch. From the above discussion, you should be able to figure out that if the shifter is in either the Park or Neutral positions that the switch will be closed and power will flow through the switch to the output terminal. If the shifter is in any other position, the switch will be opened and power will not flow through it to the output terminal. The output terminal of the neutral safety switch is connected to the starter circuit. When power flows through the output terminal, it will flow through the starter circuit and operate the starter motor. If it doesn't flow through the output terminal, then it won't flow through the starter circuit and the starter motor won't run — the car won't start.
Boolean logic
You might be wondering by now what this has to do with computers. After all, I'm not (really) writing about the history of electrical discovery or how cars work, I'm writing about my program, the Electromechanical Computer Simulation. Trust me, we're almost there.
The principal purpose of a computer is to compute things. Early computers were simply people hired to compute tables of numbers, such as tables of logarithms. Such computation (performed by humans) can be labor intensive, tedious, time consuming, and error prone.
Computation (as opposed to problem solving) typically requires rigorous application of algorithms to achieve a correct result. If the algorithm has many steps and a mistake is made executing one of the steps, the result is invariably wrong. If the algorithm has many steps and a step is skipped or the wrong step is taken, the result is invariably wrong. And of course, sometimes the algorithms used are simply wrong.
These kind of problems led many men to try to come up with machines that could take the place of human computers. Various mechanical adding machines were invented. Charles Babbage started working on the problem in 1812. In 1822 he obtained a grant from the Royal Astronomy Society to begin working on his difference engine. While taking a much needed break from the work, he began working on the design for an analytical engine. The analytical engine was designed to be a general purpose mechanical computer (the first general purpose computer of any kind to be designed), programmable using punch cards for both input and instruction. The first design for this machine was produced in 1835, although neither the difference engine nor the analytical engine was ever completed.
In 1844 George Boole introduced a theory of symbolic logic in a paper on calculus. This is where we get Boolean algebra and Boolean logic from…
Boolean algebra is the algebra of two values. These are usually taken to be 0 and 1, as we shall do here, although F and T, false and true, etc. are also in common use. For the purpose of understanding Boolean algebra any Boolean domain of two values will do.
Regardless of nomenclature, the values are customarily thought of as essentially logical in character and are therefore referred to as truth values, in contrast to the natural numbers or the reals which are considered numerical values. On the other hand the algebra of the integers modulo 2, while ostensibly just as numeric as the integers themselves, was shown to constitute exactly Boolean algebra…
What's interesting about this is that since “any Boolean domain of two values will do”, we ought to be able to perform Boolean operations with various combinations of relays and/or inverters, since their inputs and outputs have a domain of two values, “on” (a current is flowing) and “off” (a current is not flowing). For example, the Boolean AND operation has the following truth table…
This can be read as follows... 0 AND 0 is 0, 0 AND 1 is 0, 1 AND 0 is 0, 1 AND 1 is 1. In other words, if either input is 0, then the output is 0, but if both inputs are 1 then the output is 1.
We can build an electrical circuit that obeys these rules by wiring two relays together such that the output terminal of one relay is connected to the power terminal of the second relay. If we do this and supply power to the first relay's power terminal, then the output terminal of the second relay will reflect the Boolean AND operation on the two relays inputs. We only need three examples to show this.
First, if the input terminal to the first relay has no current flowing into it, then the first relay's output will be off. Because the first relay's output is wired to the second relay's power terminal, the power to the second relay will be off. This will result in the second relay's output being off, regardless of the second relay's input. Second, if the input terminal to the first relay has current flowing into it, then the first relay's output will be on. Because the first relay's output is wired to the second relay's power terminal, the power to the second relay will be on. In this case, if the input terminal to the second relay has power flowing into it, then its output will be on, otherwise its output will be off. These various states correspond to the values shown in the truth table.
We call an electronic circuit consisting of two relays wired in this way an AND gate. Similarly, by wiring the outputs of two relays together we can create a circuit with states that match the truth table for the Boolean OR operation. By substituting inverters for the relays in an AND gate, we can create a circuit with states that match the truth table for the Boolean NOR operation (NOT OR), and so on.
Some Boolean operations require more complex circuits than can be implemented using just two relays. These can be built using combinations of simpler logic circuits, for example the XOR gate can be built by connecting the outputs of an OR gate and a NAND (NOT AND) gate to the inputs of an AND gate. Wire the corresponding input terminals of the OR gate and the NAND gate together so that the entire circuit still only has two inputs and use the output of the AND gate as the circuit's output and you have a circuit with input and output states that matches the truth table for the Boolean XOR (Exclusive OR) operation. Mr. Petzold's book shows how to wire this circuit up at the bottom of page 135 (in my paperback edition). By further combining logic circuits ever more complex circuitry can be created, from circuit's that can add two numbers together to other more complex circuits.
Essentially, if you can perform an operation in Boolean algebra, or derive a more complex one from Boolean algebra, you can build a circuit using nothing but relays, wire, and a power supply that can “perform” that same operation. We're almost there.
Feedback
I mentioned Charles Babbage a little while ago and noted that he is credited with the first design for a general purpose computer. Aside from having an architecture with a processor (the “Mill”) separate from system memory (the “Store”), it also had another interesting feature. It fed its output back into its input. Babbage called this “eating its own tail”. We call it feedback.
Examples of feedback abound in our everyday life. If you've ever been to a rock concert, I'm sure you've encountered feedback. When a guitarist takes an electric guitar and turns it to face the speaker that's producing sound amplified from the guitar's output, that sound causes the guitar's strings to vibrate, feeding it back into the amplifier and out the speakers and back into the guitar in an escalating cycle. The speaker quickly begins to howl with a sound that rises in pitch and volume, rapidly reaching an ear-splittiing level. Something similar happens when a singer turns their microphone toward a speaker or monitor.
Another example of feedback can be found at public schools and in bedrooms across the country — the alarm bell or buzzer. This raucous device is an electromagnetically operated clapper that strikes a bell or bar and bounces back several times a second. One easy way to make one of these is to integrate the clapper with a spring loaded switch. The switch is normally closed. The output of the switch is wired to the input of an electromagnet. Pass a current through the switch and the current will flow through the electromagnet. The electromagnet will open the switch, shutting off the flow of power and collapsing the magnetic field. The switch will swing back closed, restoring the power and the magnetic field, pulling open the switch and… well, you get the idea. And all the while this is going on, that clapper keeps hitting that bell.
Get rid of the clapper. Does this device sound familiar at all? Well, without the clapper, isn't it nothing more than an inverter with its output wired to its input? This handy device is a simple oscillator. Supply it with power and its output will oscillate, switching from on to off to on and so on until you turn off the power, and it will do it with regularity. This is about as simple a feedback circuit as you can create.
Another feedback circuit that's interesting can be made by wiring the outputs of two NOR gates into each other's inputs. Take two NOR gates. Label the first one “N1” and the second one “N2”. Label the inputs on each gate too. Label one of the inputs “A” and the other input “B”. Connect the output from gate N1 to the A input of gate N2. Connect the output from gate N2 to the B input of gate N1. Put the whole package into a box, with three wires running into it. Label the first wire “R” and connect it to the A input of gate N1. Label the second wire “S” and connect it to the B input of gate N2. Label the third wire “Q” and connect it to the output of gate N1. (We could also connect a fourth wire to the output of gate N2, but we don't really need it, at least not yet.)
This circuit has a really interesting behavior (assuming everything is powered up that is). If you supply power to the R input, the Q output will be off. If you then turn the power to the R input off, the Q output will remain off. If you supply power to the S input, the Q output will be on. If you then turn the power to the S input off, the Q output will remain on. If you then turn the power to the R input on again, the Q output will turn off. This circuit seems to “remember” which of the two inputs last had power supplied to it. It has two stable states when both inputs are off. Which one the circuit is in depends on which input was last on. This circuit is called an “RS Flip Flop” or a Flip Flop, and it's the basis for several more complex feedback circuits with somewhat more complex behaviors.
Charles Petzold describes several of these circuits, finally presenting one called an “Edge Triggered D-Type Flip Flop with Preset and Clear”. This is a really interesting circuit because of what you can do with it. The circuit has four inputs, “D”, “Clk”, “Pre”, and “Clr”. It also has two outputs, “Q” and “Q-Bar” (represented with a Q with a horizontal bar over the top, hence the name). Q-Bar always has the opposite value of Q. If the Pre input is turned on, the Q output will be turned on and remain on. If the Clr input is turned on the Q output will be turned off and remain off. The D input represents a bit of data, but the circuit won't remember the value of the D input, unless the Clk input is in the process of making a transition from off to on.
What's cool about this circuit is what happens when you connect the Q-Bar input from one of these to its D input and connect the Clk input to the output of an oscillator. Do this and the Q output will oscillate too, but at half of the frequency of the oscillator feeding its Clk input. If you feed the Q output from one of these circuits into the Clk input of another one, the second circuit will oscillate at one fourth of the frequency of the original oscillator. OK, maybe that doesn't sound really cool to you. Try stringing a few of them together and hooking up the Q outputs to some light bulbs. Pick a really slow oscillator for input and turn on the juice. Watch the blinking lights. Eventually you might see it — this circuit counts in binary.
Mr. Petzold goes on to describe a lot of other circuits you can put together using relays, toggle switches, light bulbs, and miles and miles of wire. He describes how to build a random access memory using flip flops, selectors and decoders. By extension he shows you how to build a nice round package of RAM, say sixty-four kilobytes. He shows you how to build adders, latches, and lots of other cool things. He shows you a general way to put them together to build an imaginary computer — still using nothing but relays, toggle switches, light bulbs and miles of wire.
The program
And that's what my program is. Only I can't afford the tens of millions of relays, the miles upon miles of wire, the mounting hardware and the like. I don't have a place big enough to store it all (unless I want to get rid of a few cars), and I certainly can't afford the power to operate the thing. But I can simulate it all, starting with simulated electromechanical relays. After all, all I have to simulate is a power supply, a switch, and a magnet. Heck, I don't even have to go that far. I just need a power input, a logic input, and a logic output and some rules to manipulate them with and I can simulate a relay or an inverter.
The initial version of this program was an intellectual exercise I decided to try when I quit working at Microsoft several years ago. I had Mr. Petzold's book and a copy of Visual Studio 2003. After about three months I had tried a few different approaches and come up with working code for several of the examples in the book. Getting an actual computer running based on all of this was a bit more than the approach I started with would let me do though.
About a year or so later I gave it another shot. I got a lot further with that version of the program, but ultimately I just couldn't get the timing worked out. Sixty four kilobytes of RAM wasn't exactly practical either, so I settled for four.
About two years ago I tried again and finally managed to get a working implementation running. It was written in C# and used the .NET framework. It still wasn't quite everything I wanted it to be, and so I set it aside again. Finally, in November last year I managed to get a complete working implementation of a computer that could do all of the things that the “chapter 17” computer in the book could do. It had the same instruction set and worked reasonably well, if slowly.
In January I decided I would re-write the whole thing, this time in C++, and without the .NET framework. I wanted something small and simple that could be installed on any Windows XP machine, so I also decided not to use the MFC framework either. The program is a straightforward Win32 application written to the basic Win32 API. The only dependencies it has other than the standard Windows libraries and the C++ runtime are for the common dialogs library (when you want to load a file containing a memory image) and the common controls library (for the trackbar). It's a fairly decent simulation, but it's not finished yet. I have several more features I want to add, including a stack pointer and some other instructions, perhaps even relative addressing, but it's still usable.
You can obtain a copy of the simulation here. Go on — give it a try.
It's a simulation
That's one of the important things to remember about this program. It's not really an electromechanical computer, it's a simulation of an electromechanical computer. You could actually build an electromechanical computer using the principals that went into building the simulation, but you'd find that you had quite a few problems left to solve before the physical machine would work correctly, and I'm not talking about the cost, space requirements, power requirements, or the maintenance requirements.
In a real electromechanical computer, one built from relays as my simulation is built from simulated relays, every relay requires a short amount of time to respond to its input. When an electromagnet turns on, the magnetic field may appear almost instantaneously, but that field must overcome the inertia of the metal in the spring loaded switch to open or close it. Overcoming that inertia takes time in proportion to the mass of the switch and inversely proportional to the strength of the magnetic field. In other words, the operation of the switch is not instantaneous. An AND gate, composed of two relays wired so that the output of one feeds the power supply of the other will quite naturally take twice as long to produce its output as a single relay will. More complex circuits will take even longer to produce a stable output. Thus one of the biggest problems that needs to be solved to build a real, working, physical implementation of the electromechanical computer is the timing of events.
The oscillator that drives the system clock is nothing more than an inverter that feeds its output into its input. The oscillator's output is also used as the basic clock signal that drives everything else. In order to make sure that all of the other hardware has time to function correctly, the oscillator has to be built using the slowest relay in the system. It actually has to be slower than the slowest circuit in the system. Otherwise, the oscillator might trigger the circuit to start processing its output as input before the output has been completely calculated. Similar problems can occur when a circuit used as input to another circuit takes a while to complete its operation. If a ripple counter is used as input to the address selection circuitry of a RAM array for example, the selected address can't be relied upon until the ripple counter has finished its operation. If the address selection circuitry is faster than the ripple counter then the RAM array's input or output may become corrupted if it's written or read from before the counter's output has stabilized.
Early computer hobbyists and some computer manufacturers should be familiar with this problem. Many computer hobbyists build their machines on a budget, and they'll look for the best deals on components. At the same time, mass production of computer chips usually results in a lot of quality chips, and a lot of bad chips. Better chips are worth more money, and bad chips are worthless or worth less. A chip manufacturer may produce a CPU chip designed to operate with an external clock. Some of the chips in a production run may not work at any clock speed and will be discarded. From the remaining accepted chips, some may be chosen and tested at a higher clock speed. The chips that pass this test will typically be sold at a higher price and rated at a higher clock speed than the ones that don't pass this test, or that weren't tested at this level. It follows then that some of the chips sold with a rating for a slower clock speed might be capable of operating at the higher clock speed, but not all of them.
Brave hobbyists might purchase the chips that weren't rated at the higher clock speed and use them with a faster clock. This is called overclocking. Frequently they get lucky and their cheaper chip will perform just as well as the more expensive one rated at the higher speed. Occasionally though, they'll run into a chip with a minor defect that won't work properly at the higher speed although it would have been just fine at the clock speed it was rated at. Early on in my career I got burned with just such a chip/clock combination in a machine that was built for me by a friend. It worked beautifully, even at the higher clock speed, until I switched operating systems and started using it in the 80386 protected mode. Only then did the flaw turn up, causing software that worked flawlessly on other machines to crash on mine.
My simulation avoids these problems by treating each component as a black box with instant response time. For example, changing the input to a device such as a ripple counter does not immediately result in an output. Instead, you change the inputs, step the counter, and only then can you read the output. While the ripple counter is processing it's inputs, the outputs are not available. When they are available, they're already stable. In a real circuit made from electromechanical relays this wouldn't be the case.
This points up one of the differences between simulations and reality. No matter how much effort you put into it, a simulation isn't reality, it's only a simulation. A simulated electromechanical computer may require tens of millions of simulated relays, but unless you have tens of millions of processors to process each of those simulated relays simultaneously, you're going to have to make compromises. My compromise was to treat complex assemblages of relays as though they respond just like single relays, and to process all inputs, step through a single cycle, and process the outputs. It works, but it ignores some of the aspects of the real system.
Similar compromises are made in every simulation of every process. We use computer programs to simulate weather systems. Some of them are quite good and we can get reasonably accurate weather forecasts for about a day and a half into the future. With less accuracy, we can go a few days into the future. Once the simulations get past a few days though you can't really rely on them any better than you could a guess based on experience.
We also use simulations to predict vehicle performance when we're designing new engines, building race motors, or using past performance and current conditions to predict the performance of a car in a bracket race. There are wonderful tools available to predict the horsepower and torque ratings of an engine based upon the characteristics of the parts used to build it. While these tools can give you a good estimate of what to expect, they still only give you an estimate. The only way to find out what an engine is really going to do is to perform a physical test. A “desktop dyno” is still no substitute for a real dynamometer.
I wish I knew who said it — I've read it so many times and I believe it to be true — I'd love to give credit where it's due…
In theory there's no difference between theory and practice, but in practice there is.
Oh. Do you recall that book by Charles Petzold I mentioned earlier? He's got another one out that's also pretty interesting reading (and I highly recommend it), but the math's a lot more involved in this one. This book is titled The Annotated Turing: A Guided Tour through Alan Turing's Historic Paper on Computability and the Turing Machine. In Alan Turing's paper, published in 1936, he described an imaginary computing machine, which he used to answer some fundamental questions about the computability of numbers and the solvability of problems using computation. Every computer in use in the world today is a descendant, in one way or another, of the Turing machine. That includes all of the computers running all of the computer simulations that are being run in every scientific research laboratory in the world.
I think this is important in a way, because of what Alan Turing proved in his paper. Not every number is computable — and not every problem is solvable by computation. Some numbers are computable, and some problems are solvable by computation, but not all of them. Maybe that's why “in practice there is”.
Simulation is no substitute for experimentation. Remember that the next time someone tells you that a simulation proves a point or offers one up as evidence of a conclusion.
Related Posts:
Trackback URI for this post: http://perrinelson.com/track.aspx?postid=1248
Permalink URI for this post: http://perrinelson.com/2008/9/29/1248.aspx
Subscribe to this entry's
comment feed. (Atom)
David responded with:
 | Perri, I'll come back to the post and reread it later--just skimmed quickly for now--but I did go ahead and download the setup files and install the program using WINE 1.1.5 under Ubuntu 8.04. Program installs, loads and appears to respond to input, thought I've not really done anything but click a few of the controls so far. |