Stop Press: Flux hasn't had enough time to work on this project, so it's been put on hold. It will hopefully restart some time in 2013.
Logic will get you from A to B. Imagination will take you everywhere. -- Einstein
Part 1: Introduction
Or how Flux's imagination got the better of him..
Long ago, when I was young, I received a copy of The Way Things Work. It's an awesome book and I spent many happy hours studying it. The two things that fascinated me most were nuclear power and electronic adders. I wanted to make my own water-based adder (I didn't have any uranium). I didn't really know where to begin and it stayed firmly in the realm of my imagination.
Fast-forward twenty years and I've just joined the Space. Somewhere buried in my subconscious the idea is dusted off and *bam* it's back (2011-04-12). Water-based logic gates, memory, coloured water displays (think of the mixing)... this is what the MakerBot was made for! How many transistors did the Intel 4004 have? Only 2,300...
Today (2011-04-13) I mentioned this to Tom (Reading hacker extraordinaire) over tea. He loved it too and we started to think it through. Stay tuned for Part 2 where we get a teeny bit practical.
Part 2: Where to begin?
Or how Hoxton Lake will have have to wait
- Logic gates
The initial core of the machine, AND OR and XOR gates should allow the creation of an adder.
Broadly speaking there are two approaches (that I've thought of so far), fluid/statistical:
- Could treat ball bearings like a fluid (example project by David Bober)
Treating each 1/0 as a single entity:
- Use a ball for 1 and no ball for 0 - requires a central 'clock' (which may be needed anyway)
- Could use magnetised balls for 1 and unmagnetised balls for 0 (but wouldn't the magnetic balls stick together?)
- Could use different ball sizes for 1 and 0 (e.g. 4mm as 0 and 5mm as 1 - in which case a 0 ball weighs roughly half a 1 ball and different sizes grids/holes could be used to sort them). Would be useful if the 1s and 0s were different colours (if using each ball as a separate 1 or 0).
- Could use 2 balls for 1 and 1 ball for 0
Consider using compressed air or solenoids to hold ball bearings in place. Do we need some sort of clock to ensure all calculations happen in step? Perhaps turn a handle to run the computer?
Flux has ordered 100x4mm (0.2610g) and 100x5mm (0.5099g) high grade steel ball bearings for experimentation.
If we use different weights of balls for 1 and 0 then a simple balance test could compare numbers. If the high order bit of each number was farthest from the fulcrum then if the lever balances then the values are equal, otherwise is leans to the sizes which is larger. This does mean that the bit order in a nibble needs to be reversed for one of the numbers.
Do we use pure decimal or binary coded decimal or something else? BCD has the advantage it's easy to convert for display, but is a bit more complex to process arithmetically.
What about letters and other characters? The larger we make a byte the more complex everything becomes. One possible scheme is to use 4-bit nibbles for numbers with BCD, with two nibbles used for to represent a character or instruction. In BCD no number is of the form 11xx. So could separate letters from numbers by using 110x xxxx for letters and punctuation (room for 32 of them) and 111x xxxx for instructions (also leaves room for 32 of them).
Some possible examples:
- 0000 = 0
- 0010 = 2
- 1001 = 9
- 1001 0111 = 97
- 1100 0001 = a
- 1101 0010 = r
- 1110 0010 = read nibble from memory
- 1110 0011 = write nibble to memory
- 1110 0100 = add
This isn't especially compact, but would seem to make it easy to separate different operations (e.g. to pass instructions to the memory unit).
What about negative numbers? Do we use another nibble (one of the instruction ones) to indicate that? e.g. 1111 is negative (this halves the number of instructions possible to 16). Thus:
- 1111 0010 = -2
- 1111 1001 = -9
- 1111 1001 0111 = -97
Need to learn more about logic gates required to handle BCD.
Some approaches within a plastic grid (could use stepper motors and simple arm to move or read balls):
- a ball indicating 1 and a void 0
- a magnetised balls indicating 1 and non-magnetised 0
- a 5mm ball representing a 1 and a 4mm ball representing a 0
Do we read individual bit or a whole nibble? Nibbles make addressing easier. With a 16x16 grid of nibbles (so 32x32 ball slots) you'd be able to use 2 nibbles as an address (16x16 = 256 = 2^8). This would give 1 kilobit (256 nibbles) of memory. If we're using 4/5mm bearings and you allow 8mm by memory cell then this memory would be about 26cm to a side.
Physically this doesn't scale too horrendously. If we want to get ambitious then a 64x64 grid of nibbles (128x128 ball slots) would store 4096 nibbles, but would require 3 nibble addresses (12 bits) and be around 1m to a side (it would also require over 16 thousand ball bearings!). Could also be a stacked arrangement of draws: that way the third nibble controls which draw to open and how up/down the memory head needs to move. If we assume we need 2cm/draw then the memory would be a cube around 30cm to a side, which would be quite manageable (though note the 16,000 ball bearings would weigh around 8kg if they were all 1s).
This all assumes we use normal binary encoding for memory locations, not BCD. However that would mean adding numbers and addresses would be different.
We also need to consider whether we have some sort of stack or registers for the actual calculations (i.e. where do we read/write to and from?). Initial thought is that registers are easiest to manage physically, but a stack might make for nicer programming (though it would also overflow).