Now, as a recap, we can create memory using NAND gates intertwined, we have multiplexers (MUX) and demultiplexers (DMUX). Although it would be hard to use the switches as outputs, it's not unreasable to use NAND memory outputs and feed them back in as inputs. Now, if we encode an "instruction" to the format of OOOOXXYY, where each letter represents a single bit, we can make one byte instructions. XX will represent the "destination," and a value of 3 will represent the "OUTPUT" area, while any other number would correspond to the "register" with that designation. YY will represent hte "source," which works the same as "destination," except that a value of 3 represents the input switches. OOOO will represent one of 16 different "operations," where YY is applied to XX then stored in XX.

0x0: mov (move)
0x1: add
0x2: sub
0x3: and
0x4: or
0x5: xor
0x6: shl (shift to the left)
0x7: shr (shift to the right)
0x8 - 0xF: Reserved (meaning you shouldn't try to mess with them).

So, basically, if you wanted to put 5 in the r1 register, you'd create the value in "input" then set the value of "instruction" to 0x07 (op = 0, dest = 1, src = 3). This looks a bit like assembly programming, except with assembly we use an "assembler" to translate words to represent these values so we don't have to bother remembering them. So, take the following example.

mov r0, 5 (input = 5, instruction = 0x03)
add r0, 7 (input = 7, instruction = 0x13)



That is pretty much what the "lowest level programming langauge" (assembly) looks like. Fortunately, we're not far from that area. If you follow that formula, you'll find that r0 will end up with 12 (0x0c) on the display below.

Machine State: Awaiting initial input...
1286432168421
Input:
Instruction:
r0:
r1:
r2:
OUTPUT:
Overflow:
RESET

Now that your brain is probably fried (and/or you're frustrated from making mistakes while experimenting with the buttons [it's OK, even I did]), please understand that it gets much, much easier. The difficulty here is that you not only had to convert between hex, binary, and decimal (I know, I know, a little late to wrap it all up), but you had to use it in such a way that you would make your first code. If you were doing even the slightest bit of complex math, surely you've written down something in notepad to help you figure out what you wanted to accomplish before putting it into the artificial machine above. That, basically, would've been "source code." "Source code" usually gets translated by a program for us, but we're building the machine from the ground up, so we haven't gotten to the easy part, yet. The general idea, here, is that you take simple concepts, abstract them, put them together to make something that is complex, but it seems simple because you're doing abstractions. Surely, things seem rather rough right now (if they don't, then it's probably either a sign of some sort of gift, or you know a bit already). While the most complex components are hard to follow, you've already abstracted the most difficult components (RS-latch, logic gates, etc). As things move up in complexity, as long as you keep to your abstractions, they get easier.

NOTE: Doing something like 0x10 is only possible because we can use temporary registers to hold the value then cut them off before committing to an operation.

Get your own web kitty here!
©Copyright 2010, 2011, 2012, 2013, 2014, 2017, 2018. All rights reserved.