What are the 8 bits in 8-bit computing?
On the Facebook CoCo group, someone recently asked about how I handled bit-checking in a question I asked on the Retrocomputing StackExchange about the joystick. They didn’t phrase it as a question about bits because they didn’t know that their question was about bits.
It’s not surprising. I don’t know about other computers, but Radio Shack tended to hide the bitwise nature of their 8-bit computers. The only BASIC functions that worked with bits were the logical operators AND, OR, and NOT1, and they weren’t explained as bitwise. The first two are given a page in Getting Started with Extended Color BASIC, page 78, where they’re explained as if they’re the English words AND and OR.2
But these operators do not behave as the English words do, or as the explanation implies they do. Here’s an example. Go into your CoCo or an emulator such as Xroar, and type:
- PRINT 3 AND 5
- PRINT 3 OR 5
The first should give you 1
and the second should give you 7
. In most modern programming languages, both would give you true
, which, depending on the language, might be a boolean value or it might be the integer 1. It might even be one of the two values, the 3 or the 5, because of short-circuit evaluation.
How does Extended Color BASIC arrive by its return values? The answer is that AND and OR are bitwise operations. These are 8-bit computers. They describe their numbers in 8 bits3. Here are the bits for the numbers 3 and 5:
byte value | 8 bits |
---|---|
3 | 00000011 |
5 | 00000101 |
The logical operators do not compare bytes. They compare individual bits at matching bit locations. What AND does is, if the bit in the same location in each byte is 1, the bit in the resulting byte is 1. If either of the two bits are zero, the bit in the result for that location is zero. What OR does is return 1 if either of the bits are 1, and zero only if both bits are zero. So here’s what AND and OR do when comparing 3 and 5:
logic example | logic result | explanation |
---|---|---|
3 AND 5 | 00000001 | Only the 1st bit (counting from the right) is 1 in both cases, so it’s the only 1 in the result. |
3 OR 5 | 00000111 | The 1st, 2nd, and 3rd bits all have a 1 in one of the numbers, so all three of them are 1 in the result. |
So, why does 3 AND 5
return 1
in the example? Because the rightmost bit (bit number 1) is a stand-in for 1.
Why does 3 OR 5
return 7
in the example? Because bit 1 is a stand-in for 1, bit 2 is a stand-in for 2, and bit 3 is a stand-in for 4. Add them all together and you get 7.
Each bit, counting from the right, stands for a power of two. The rightmost bit is 2^0; the second rightmost bit is 2^1; the third is 2^2, and so on.4
Bit (from right) | Power of two | Value | Bit location |
---|---|---|---|
1 | 2^0 | 1 | 00000001 |
2 | 2^1 | 2 | 00000010 |
3 | 2^2 | 4 | 00000100 |
4 | 2^3 | 8 | 00001000 |
5 | 2^4 | 16 | 00010000 |
6 | 2^5 | 32 | 00100000 |
7 | 2^6 | 64 | 01000000 |
8 | 2^7 | 128 | 10000000 |
This is sometimes called “binary notation”, sometimes “base 2”.5 To get the value of a byte in an 8-bit computer, you add up the powers of two for all of the bits that are set to 1, and you end up with a number from zero to 255.
All numbers from 0 to 255 can be represented as the sum of powers of two. The value for 75, to pull a number out of the random dice roller from 42 Astounding Scripts, is 64+8+2+1.6 That’s 2^0 + 2^1 + 2^3 + 2^6; or a 1 in positions 1, 2, 4, and 7 of an 8-bit number: 01001011.
Byte Calculator
You can see the decimal value change as you check or uncheck each of the bits in the eight bits that make up an 8-bit byte.
(requires JavaScript)
If you have enough time on your hands, you can verify that eight bits, using powers of two, can generate all 256 numbers from zero through 255.
To see how AND and OR work, use this simple logical calculator:
(requires JavaScript)
Try putting in the values 3 and 5, and see how they turn into 1 or 7, depending on whether they’re combined via AND or OR.
How does this apply to the CoCo’s joysticks?
My question on StackExchange was about the Color Computer’s joysticks. The manual says that if PEEK(65280)
returns 255, no joystick button is pressed. If it returns 126 or 254, the right joystick button is pressed. And if it returns 125 or 253, the left joystick button is pressed.
I did some tests, and happened to notice that if I pressed both buttons, I got a 252. This led me to suspect that the values we should be looking at are not the entire number, but particular bits in that number. A lot of older computers had a direct, or nearly direct, linkage between bits and hardware. A single bit can only have two values: 0 and 1. A piece of hardware whose only values were on and off, such as a joystick button, would often be linked directly to a specific bit at a specific memory location.7
A little more testing, and here’s what I found for the values of PEEK(65280)
depending on which button I pressed:
byte value | 8 bits | button pressed |
---|---|---|
126 | 01111110 | right button |
254 | 11111110 | right button |
125 | 01111101 | left button |
253 | 11111101 | left button |
252 | 11111100 | both buttons |
255 | 11111111 | no button |
And the answer to my question is that, yes, there is a link between the rightmost bit and second rightmost bit and whether a button is pressed on a joystick.8 The right button is indicated by a zero in the 1st bit (2^0) and the left button by a zero in the 2nd bit (2^1).
Two to the zeroth power is 1; two to the 1st power is 2. This means that in BASIC, 1 AND <any number>
will return 1 only if the 1st bit in that number is also set to 1. And 2 AND <any number>
will return 2 only if the 2nd bit in that number is set to 1. It doesn’t matter what the other bits are set to. Because AND is a bitwise operator, and all but one of the bits in 1 and 2 are zero, the only bit that has a chance of being 1 (ON) in an AND with 1 or 2 is that single bit, respectively.
- 1 in binary is 00000001
- 2 in binary is 00000010
However, remember what actually marks that a button is pressed: it’s a zero, not a one. To put a 1 in those positions if a joystick button is pressed, I use the NOT operator. The NOT operator is also bitwise. It flips each bit in the number given. If a bit is 1, it becomes 0. And if a bit is 0, it becomes 1. This means that after using NOT on the number from PEEK(65280), a 0 in the 1st bit becomes a 1, and a 0 in the 2nd bit becomes a 1.9 At which point I can use AND on the value to detect whether a joystick button is pressed.
- 5 CLS
- 10 BU = PEEK(65280)
- 20 PRINT@0,"RIGHT BUTTON ";
- 30 IF (1 AND NOT BU)=1 THEN PRINT "ON" ELSE PRINT "OFF"
- 40 PRINT@32,"LEFT BUTTON ";
- 50 IF (2 AND NOT BU)=2 THEN PRINT "ON" ELSE PRINT "OFF"
- 60 GOTO 10
To repeat: the “1 AND” in line 30 is checking the rightmost bit of an 8-bit number. The “2 AND” in line 50 checks the second rightmost bit. Those are the bits that are set to zero for the right joystick button and the left joystick button, respectively. By using NOT on the PEEK value, those bits will be set to 1 if the button is pressed and zero if the button is not pressed.
Line 30, then, is taking whatever number, from zero through 255, comes out of PEEK(65280), flipping each bit, and comparing the result to 00000001. Line 50 also flips the number but compares the result to 00000010.10 In each case, a bit of 0 ANDed with either 1 or 0 remains zero. If the 1 remains in the appropriate bit position after anding, it means that particular button was pressed.
For example, if the right joystick button is pressed, the value of PEEK(65280)
might be 126. This corresponds to the binary value of 01111110.
- I apply
NOT
to this value. It is now 10000001. - I
AND
this value with 1, that is, with 00000001. - The result, going bit by bit is that every bit becomes 0 except the rightmost bit. So the result is 00000001. This is equivalent to the byte value of 1.
- I check that the result equals 1, and it does, so I know that the right joystick button is pressed.
If, on the other hand, it were the left joystick button that was pressed, PEEK(65280)
might return 125. This corresponds to the binary value of 01111101.
- I apply NOT to this value. It is now 10000010.
- I AND this value with 1, that is, with 00000001.
- The result, going bit by bit is that every bit becomes 0: at each position, there is a zero in at least one of the compared bits. So the result is 00000000. This is equivalent to the byte value of 0.
- I check that the result equals 1, and it does not, so I know that the right joystick button is not pressed.
By checking the bit value rather than the byte value, it is easier to know when both buttons are pressed. Instead of checking for 126, 254, 252, or 124, we’re specifically checking the bit that corresponds to the right joystick. Similarly for the left joystick. If there are conditions where other bits than the first and second change, this would change the value of the byte but it does not change the value of the joystick bits.
For reasons that I don’t fully comprehend, bitwise manipulations have always fascinated me. I wrote a program on the TRS-80 Model 1 that would take bytes and modify specified bits based on finding a 1 or a zero in other bit positions; I can’t remember if I wrote it in BASIC or in machine code. When I switched to OS-9 on the Color Computer, I was able to turn this into a filter, probably in BASIC09, that would alter piped text by altering specified bits if other specified bits matched. I rewrote it again when I moved to an account on a Unix minicomputer, probably in C.
It was never a useful program. I’d write it, fool around with it for a bit, and then forget about it until my next computer. Probably the only times I ever seriously used it was to test it while I was programming it. Sadly, all of these incarnations are lost now. I stopped converting the program when I started using a Macintosh as my main computer, sometime in the mid nineties.
In response to TRS-80 Color Computer Programming Tools: The TRS-80 Color Computer was a fascinating implementation of the 6809 computer chip, and was, from the Color Computer 1 through 3, possibly the longest-running of the old-school personal computers.
The 6809 had other bitwise operators in its instruction set, but as far as I know none were implemented in BASIC. For example, the bits in a byte could be shifted left or right, with the effect of multiplying the byte value by 2 or dividing it by two (and discarding any fractions), as long as the result was an integer greater than zero or less than 128. The 6809 also had an XOR, which was often used to display mouse cursors on the screen, for reasons which are too complicated to get into here.
↑The NOT operator isn’t even listed in the index, probably because it has no explanation in the book. Further, the example has a typo; possibly at some point the description described OR first, then AND, and they switched it up without changing the segue sentence.
↑Or in building blocks of eight bits. How the Color Computer builds numbers that need more than eight bits is a topic all on its own.
↑It is also common to count up from zero, rather than from one as I’m doing here. Then, the bits are numbered zero at the rightmost up to seven at the leftmost.
↑I’m not going to get into number bases here, but if you are familiar with the hexadecimal and octal values used by the Color Computer, it’s the same idea. Hexadecimal is base 16 and octal is base 8, just like binary is base 2.
↑It’s usually easiest to start from the highest power of two that is less than or equal to the decimal number you’re converting. Then the next highest power of two that is less than or equal to the remainder, and so on.
↑And hardware that produced variable values, such as joysticks, would often set an entire byte, resulting in values from 0 to 255; or would set part of a byte, resulting in values from 0 to one less than some lesser power of two. The Color Computers joysticks each produced a number from 0 to 63 (one less than 2^6) in each of the horizontal and vertical directions. The four joystick values (horizontal and vertical for the right and left joysticks) are in memory locations 346 through 349, according to 500 Pokes, Peeks ’n Execs for the TRS-80 Color Computer, page 25. But you have to EXEC 43486 first to fill those locations with a valid value.
↑Theoretically, there is also a 01111100, or 124, when both buttons are pressed, but I never saw that value.
↑A 1 would, of course, become a zero.
↑If this were real code, an arguably better place to put the NOT would be when PEEKing, on line 10: `10 BU PEEK = NOT PEEK(65280)`. Line 30 would then be `IF (1 AND BU)=1 THEN PRINT "ON" ELSE PRINT "OFF"` and line 50 would be the same, replacing “1” with “2”.
The way I’ve done it keeps all of the bitwise logic operations in one place.
↑
- 42 Astoundingly Useful Scripts and Automations for the Macintosh
- MacOS uses Perl, Python, AppleScript, and Automator and you can write scripts in all of these. Build a talking alarm. Roll dice. Preflight your social media comments. Play music and create ASCII art. Get your retro on and bring your Macintosh into the world of tomorrow with 42 Astoundingly Useful Scripts and Automations for the Macintosh!
- For TRS-80 Color Computer joystick buttons, is it correct to check the first or second bit of the value at PEEK(65280)? at Retrocomputing on StackExchange
- “It appears that the right button is indicated by a zero in position 1, and the left button by a zero in position 2. Is this correct? Is it (as) reliable to check those bits as to check for the numbers?”
- Getting Started with Extended Color BASIC at Internet Archive (ebook)
- This is the combined manuals for Color BASIC and Extended Color BASIC.
- Retrocomputing on StackExchange at StackExchange
- “Retrocomputing Stack Exchange is a question and answer site for vintage-computer hobbyists interested in restoring, preserving, and using the classic computer and gaming systems of yesteryear.”
- Short-circuit evaluation at Wikipedia
- “Short-circuit evaluation, minimal evaluation, or McCarthy evaluation is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression…”
- XRoar—Dragon & CoCo emulator
- “XRoar is a Dragon emulator for Linux, Unix, Mac OS X and Windows. Due to hardware similarities, XRoar also emulates the Tandy Colour Computer (CoCo) models 1 & 2. More features.”
More Color Computer
- Simple game menu for the Color Computer 2 with CoCoSDC
- This simple menu provides one screen for cartridges saved in the CoCoSDC’s flash ROM, and any number of screens for your favorite games for your friends to play.
- Rainbow Magazine preflight tool enhanced
- I’ve added several features to the Rainbow Magazine preflight tool, including a check for references to line numbers that don’t exist.
- CoCoFest! 2021
- Forty years later, I finally make it to CoCoFest!
- BASIC tokenization examined
- Why do old BASIC programs have strange characters in their .BAS files? Why do they look like they’re compiled code?
- The TRS-80 Color Computer 2
- The TRS-80/Tandy Color Computer 2 is a fascinating bit of computer history. It was the direct ancestor of the first inexpensive home Unix-like computer, the Color Computer 3.
- 19 more pages with the topic Color Computer, and other related pages