-
-
Pushing BUTTONS
-
-
- BUTTONS
is a tiny computer that you can program entirely with a 2 button mouse by clicking on buttons.
- It features all of the operations you need to learn about computers and how they process numbers. All you need to
- do is click on the right buttons and make BUTTONS
do the math.
-
-
-
Stacking Plates
-
-
Imagine if I handed you a stack of dinner plates and told you to
- number each one. I give you a grease pen and a STACK
of 10
- plates and tell you to get to work. How would you number these plates?
- When you were done how would the plates be stacked? Let's call the
- unnumbered plates new plates
and your stack of numbered
- plates done plates
.
-
-
You would probably take the first plate off the top of the stack of
- new plates
, write the number 1
on it, and then set it to the
- side in the done plates
stack. You can't put it back on the
- new plates
stack of plates because then you wouldn't make
- your way through the plates. You take one off the top
of
- the new plates
, write the number 2
, and put it
- on top
of the stack of plates called done
- plates
. You then do this with #3, #4, #5, until you are done
- going through all 10 plates.
-
-
You then look over at your stack of numbered done plates
- and you're happy, but the plate on top
is numbered 10.
- You've stacked them in reverse, and you probably need to re-stack them in
- order. How would you do that? Well, you simply take one off the top of
- the done stack
and put it onto another stack (let's call
- that sorted
) until you're out of plates. Now sorted
- stack
is numbered 1-10, with 1 on top
.
-
-
Try this with 10 pieces of paper instead of dinner plates. Cut up 10 little cards that do
- not have numbers on them, and then write the numbers 1-10 on each piece of paper and stack
- it just like above. Then restack them again to get them in the sorted order. This is a
- stack and it's used in computers and in BUTTONS
.
-
-
PUSH & POP
-
-
The way BUTTONS
remembers what it's doing is with a
- STACK
. A STACK
is a very simple storage system
- that takes numbers one at a time and puts them on top of each other, just
- like with the dinner plates in the previous explanation. Numbers are
- pushed onto BUTTONS'
version of a STACK
and the
- last one in is the first one out.
-
-
- You should go get a note book and write these things down. Be sure to
- write, "A stack is a last in, first out number storage. The last number
- I push onto the stack is the first number to come out." I say this
- because I actually got this wrong in the first implementation of the
- stack, so if I can get it wrong, so can you.
-
-
You PUSH
numbers onto the STACK
, then call
- other operations (ADD
for example) to make
- BUTTONS
do math on them. When you PUSH
you
- have to give it the number it should push onto the top
of
- the STACK
. On the right you'll then see
- BUTTONS
show that number under the STACK
- output.
-
-
The POP
operation simple takes any number that's on the top
of
- the STACK
and removes it. Junks it. Throws it away. If you try to POP
- too much your BUTTONS
will crash. Don't do that.
-
-
Math
-
-
You can now PUSH
numbers onto the STACK
and use POP
to take
- them off. Big deal. That's not a computer...yet. The next piece of our puzzle game is to let you do math
- with these numbers on the STACK
. BUTTONS
has the following simple operations:
-
-
-
-
- OPERATION | MATH | DESCRIPTION |
-
-
-
-
- ADD | a + b | Adds two numbers |
-
-
- SUB | a - b | Subtracts two numbers |
-
-
- MUL | a * b | Multiplies two numbers |
-
-
- DIV | a / b | Divides two numbers |
-
-
- MOD | a % b | Modulus of two numbers |
-
-
-
-
-
The order of each operation is the same, with a being
- PUSH
on first, then b. That means when you're done
- your b number should be on the top
of the
- STACK
. Here's how I would add 1 + 2
:
-
-
-
-0: PUSH 1
-1: PUSH 2
-2: ADD
-
-
-
-
When you run these lines of code in BUTTONS
the number 3
will be at the top of the stack
- ready to use. You can also try POP
to remove it and see how that works.
-
-
-
- When you see the 0:
at the front of the line that's the line number. It's not code, just me being lazy and not wanting to implement line numbers in fancy CSS.
-
-
-
CLICKS
-
-
Before we get into loops I have to warn you that BUTTONS
- is not a very powerful computer. It can only perform 128
- operations before it runs out of energy called CLICKS
. If
- your program runs for 128 many clicks then BUTTONS
will stop
- running and give up because it is tired.
-
-
Looping with JUMP
-
-
To make a computer we need a way to repeatedly run code so we can do many calculations. BUTTONS
has
- the operation JUMP
that will jump to the line you give, then keep running. If I want to run a loop that counts from 1 to 128 I can do this in BUTTONS
:
-
-
-
-0: PUSH 1
-1: PUSH 1
-2: ADD
-3: JUMP 1
-
-
-
-
You really should study this simple little program because inside it's simplicity is an incredibly powerful idea. Here's some questions to ask while you study:
-
-
-
- - Why do I do
JUMP 1
instead of JUMP 2
to reach the second line?
- - Step through the code and write down what the top of the stack is at each step.
- - If you want to go up by a different count what do you do?
- - How does this work with
SUB, DIV, MUL, and MOD
operations?
-
-
-
Play with this code in BUTTONS
until you understand what's going on because if you don't get
- JUMP
then you definitely won't understand the next section.
-
-
- You can also JUMP
one line past the end of your code to end your program. That means if you have 4 lines of code, then you can do JUMP 5
and end your program. This becomes important later so write this down in your notebook too.
-
-
-
Logic with JZ/JNZ
-
-
You now know how to make BUTTONS
do math, use the STACK
, and do a loop to do lots of math. There's one last thing we need before we have a real working computer and that's the idea of a test
and jumping only if that test is true (or false).
-
-
-
Let's say you have the following code that counts down from 10 to 0:
-
-
-
-0: PUSH 10
-1: PUSH 1
-2: SUB
-3: JUMP 1
-
-
-
-
You run it, thinking it will stop at zero, and instead
- BUTTONS
does exactly what you told it to do and keeps going
- until it runs out of CLICKS
, leaving .... -32
on
- the top? What?!
-
-
The reason is you have no way to tell BUTTONS
when to stop. You can tell it to do the math and where to JUMP
but you have no way to tell buttons "when you reach 0 on the STACK
you should stop." You do this with the JZ
operation which means "JUMP if Zero
". It simply looks at the top of the STACK
and if that's 0 then it does a JUMP
to where you want. This is doing a test of the top of stack, and a jump. Now we can rewrite our program like this:
-
-
-
-0: PUSH 10
-1: PUSH 1
-2: SUB
-3: JZ 5
-4: JUMP 1
-
-
-
-
See how line 3 is now JZ 5
, but right after that on line
- 4 we have JUMP 1
? This seems very backwards, but we have to do this because we want
- line 3 to only JUMP 1
to the end (line 5 is the end) when the STACK
- is 0. It's working as a "guard" that prevents line 4 JUMP 1
from running when the STACK
- is 0. Another way to see this is it will "jump over" line 4 JUMP 1
when the STACK
is 0.
-
-
We can simplify this by using another operation called JNZ
which does the inverse of JZ
and "jumps if NOT zero". Using this operation we can now have:
-
-
-
-
-0: PUSH 10
-1: PUSH 1
-2: SUB
-3: JNZ 1
-
-
-
-
Instead of that weird "jump over the next line that's a jump if the
- stack is zero" in the previous program, we have "jump to line 1 if stack
- is not zero". Way easier to do, but keep in mind you many times need
- both. Both effectively do the same thing but it's sometimes easier to use
- one or the other (JZ
vs. JNZ
) depending on how
- you're doing the operation.
-
-
STOR/RSTOR Registers
-
-
You technically can do all of the computation you need with just that (minus input and output), but it's really annoying and hard to do much more than add some numbers in loops. To make it possible to implement larger more complex prgrams in BUTTONS
you have four REGISTERS
where you can keep temporary variables for later: AX, BX, CX, DX
. I named them this way just for old time's sake, and to keep things simple. You put things into these registers (and take them out) using the STOR
and RSTOR
(for "restore") operations:
-
-
-
-
- OPERATION | DESCRIPTION |
-
-
-
-
- STOR | Copies the STACK top to the named register. |
-
-
- RSTOR | PUSH the number in the named register onto the STACK . |
-
-
-
-
-
Let's say I want to count down like before, but I want to keep track of the previous number as you go. I don't know why. You just do. Ok, here's how:
-
-
-
-
-0: PUSH 10
-1: STOR AX
-2: PUSH 1
-3: SUB
-4: JNZ 1
-
-
-
-
Now as you step through this program you can watch the AX
register keep the previous stack top as it goes. Let's say you want to keep the initial value you started with for after the loop:
-
-
-
-
-0: PUSH 10
-1: STOR AX
-2: PUSH 1
-3: SUB
-4: JNZ 2
-5: RSTOR AX
-
-
-
-
Now I do JNZ 2
instead so that I avoid the 01: STOR AX
line, that does the loop like before but now the AX
register has my starting number. After line 4: JNZ 2
passes I then use RSTOR AX
to get that number back, and the program ends with two numbers on the stack: 10
and 0
.
-
-
-
Other Operations
-
-
You can also use these operations to do other things:
-
-
-
-
- OPERATION | DESCRIPTION |
-
-
-
-
- CLR | Clears BUTTONS . Good for debugging. |
-
-
- HALT | Stop the computer with a message. |
-
-
-
-
-
What About Input and Output?
-
-
Astute readers will notice I have no way to input a number from the world, and output a number (or character) to the screen. That's because I did this whole project in about 3 days while playing video games and I'm not sure how to make a fancy looking retro CRT screen. I'll get to that part eventually.
-
-