When dealing with bits in Color BASIC, we have AND, OR and NOT. Unfortunately, we can really only use these on values 15-bits or less. For example, here is a table represent various 8-bit values in the range of 0-255:
Dec Hex Binary
----- ---- --------
0 00 00000000
1 01 00000001
2 02 00000010
4 04 00000100
8 08 00001000
16 10 00010000
32 20 00100000
64 40 01000000
128 80 10000000
255 FF 11111111
We have no problem using 8-bit values with standard Color BASIC. Here is my routine that will print out the bits of any 8-bit value:
0 REM 8BITS.BAS 10 DIM BT(7):FOR BT=0 TO 7:BT(BT)=2^BT:NEXT 20 INPUT "VALUE ";Z 30 GOSUB 500:GOTO 20 500 REM SHOW Z AS BINARY 510 FOR BT=7 TO 0 STEP-1 520 IF Z AND BT(BT) THEN PRINT "1"; ELSE PRINT "0"; 530 NEXT 540 PRINT Z:RETURN
Here is a program using that routine that will print out a similar table:
0 REM 8BITTABL.BAS 10 DIM BT(7):FOR BT=0 TO 7:BT(BT)=INT(2^BT):NEXT 20 PRINT "DEC HEX BINARY" 30 PRINT "----- ---- --------" 40 FOR I=0 TO 7:Z=INT(2^I) 50 GOSUB 100 60 NEXT 70 Z=255:GOSUB 100 80 END 100 REM PRINT TABLE ENTRY 110 PRINT USING"##### ";Z; 120 IF Z<&H10 THEN PRINT "0"; 130 PRINT HEX$(Z);" "; 140 GOSUB 500 150 RETURN 500 REM SHOW Z AS BINARY 510 FOR BT=7 TO 0 STEP-1 520 IF Z AND BT(BT) THEN PRINT "1"; ELSE PRINT "0"; 530 NEXT 540 PRINT:RETURN

When I started experimenting with bits like this, I tried to modify my routine to work with 16-bit values. It did not work:
0 REM 8BITTABL.BAS - DOES NOT WORK! 10 DIM BT(15):FOR BT=0 TO 15:BT(BT)=INT(2^BT):NEXT 20 PRINT "DEC HEX BINARY" 30 PRINT "----- ---- ----------------" 40 FOR I=0 TO 15:Z=INT(2^I) 50 GOSUB 100 60 NEXT 70 Z=255:GOSUB 100 80 END 100 REM PRINT TABLE ENTRY 110 PRINT USING"##### ";Z; 120 IF Z<&H10 THEN PRINT "0"; 121 IF Z<&H100 THEN PRINT "0"; 122 IF Z<&H1000 THEN PRINT "0"; 130 PRINT HEX$(Z);" "; 140 GOSUB 500 150 RETURN 500 REM SHOW Z AS BINARY 510 FOR BT=15 TO 0 STEP-1 520 IF Z AND BT(BT) THEN PRINT "1"; ELSE PRINT "0"; 530 NEXT 540 PRINT:RETURN

A bit of investigation revealed that AND could not operate on values greater than 32767 (&H3FFF in hex):

I did not understand why, but I expected it has something to do with integer values being treated as signed values, as if this was an INT16 (−32768 to +32767 range) rather than a UIN16 (0-65535 range).
rflberg to the rescue
I had recently posted a series of YouTube videos discussing bits in Color BASIC. My most recent one showed a program I wrote that demonstrated AND, OR and NOT operations:
The program I demonstrated looked like this:
0 REM ANDOR.BAS 10 DIM BT(7):FOR BT=0 TO 7:BT(BT)=INT(2^BT):NEXT 20 INPUT "VALUE ";V 30 PRINT "(A/O/N)"; 40 A$=INKEY$:IF A$="" THEN 40 50 IF A$="A" THEN M=0:PRINT "AND";:GOTO 90 60 IF A$="O" THEN M=1:PRINT "OR ";:GOTO 90 70 IF A$="N" THEN M=2:PRINT "NOT":GOTO 100 80 SOUND 1,1:GOTO 40 90 INPUT O 100 PRINT:PRINT " ";:Z=V:GOSUB 500 110 IF M=0 THEN PRINT "AND ";:Z=O:GOSUB 500:Z=V AND O:PRINT " ";:GOSUB 500 120 IF M=1 THEN PRINT "OR ";:Z=O:GOSUB 500:Z=V OR O:PRINT " ";:GOSUB 500 130 IF M=2 THEN PRINT "NOT ";:Z=NOT V:GOSUB 500 140 PRINT:GOTO 20 500 REM SHOW Z AS BINARY 510 FOR BT=7 TO 0 STEP-1 520 IF Z AND BT(BT) THEN PRINT "1"; ELSE PRINT "0"; 530 NEXT 540 PRINT:RETURN
In the video I explain how it works, somewhat, but you will notice it works only on 8-bit values. Because I did not know a way to make it work.
However, in the comments, use rflberg left a few comments:
IF you want to see the full bits change the program to this:
10 DIM BT(15):FOR BT=0 TO 15:BT(BT)=2^BT:NEXT
rflberg (via YouTube)
501 IF Z<0 THEN PRINT”1″; ELSE PRINT”0″;
510 FOR BT=14 TO 0 STEP -1
I was intrigued. The modifications did not work for me, but a few additional comments help me understand the intent:
-1 is actually 1111111111111111 and 255 is 0000000011111111. It computes numbers -32768 to 32767. Negative numbers the most significant bit is a 1 and positive numbers is a 0.
rflberg (via YouTube)
…
-32768 is 1000000000000000 and 32767 is 0111111111111111
I experimented with this for awhile last night, and now I think I understand it. AND, NOT and OR allow you to pass in 0 to 32677 just fine. But, you can also pass in -32768 to -1 as well! It seems to be using the high bit (bit 15) to indicate a negative value. The explanation was to simply use negative values to make AND, NOT and OR see that bit.
The code modification would work if I passed in 0-32767 for the normal 15-bit range then -32768 to 1 to represent the high-bit range. I should be able to modify my routine to do this automatically.
I could use standard bit values for bits 0 to 14 (my BT array values of 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, and 16384, just like in the earlier table), and then have a special case for bit 15 — a value of -32768 — which I would have in the array as BT(15)=-32768.
Then, in the print bit routine I could check to see if the value was greater than 32767, and turn it in to a negative number by subtracting 65536. (i.e., 32767 would be fine, but 32768 would turn in to -32768).
Since I print out the integer value after the bit display, I decided to make a temporary (altered) variable Z2, and retain the user’s intended Z value. This means I could pass in 32768 and it would print 32768, but would be really using -32768.
I ended up with a minor modification to my program, giving me this routine that will display the bits of any 16-bit value (0-65535):
0 REM 16BITS.BAS 1 REM WORKS THANKS TO rflberg 10 DIM BT(15):FOR BT=0 TO 14:BT(BT)=INT(2^BT):NEXT:BT(15)=-32768 20 INPUT "VALUE ";Z 30 GOSUB 500:GOTO 20 500 REM SHOW Z AS BINARY 505 IF Z>32767 THEN Z2=Z-65536 ELSE Z2=Z 510 FOR BT=15 TO 0 STEP-1 520 IF Z2 AND BT(BT) THEN PRINT "1"; ELSE PRINT "0"; 530 NEXT 540 PRINT Z;Z2:RETURN
Using this updated routine, I modified my table printing program to handle 16-bits:
0 REM 8BITTABL.BAS 1 REM WORKS THANKS TO rflberg 10 DIM BT(15):FOR BT=0 TO 14:BT(BT)=INT(2^BT):NEXT:BT(15)=-32768 20 PRINT "DEC HEX BINARY" 30 PRINT "----- ---- ----------------" 40 FOR I=0 TO 15:Z=INT(2^I) 50 GOSUB 100 60 NEXT 70 Z=65535:GOSUB 100 80 END 100 REM PRINT TABLE ENTRY 110 PRINT USING"##### ";Z; 120 IF Z<&H10 THEN PRINT "0"; 121 IF Z<&H100 THEN PRINT "0"; 122 IF Z<&H1000 THEN PRINT "0"; 130 PRINT HEX$(Z);" "; 140 GOSUB 500 150 RETURN 500 REM SHOW Z AS BINARY 505 IF Z>32767 THEN Z2=Z-65536 ELSE Z2=Z 510 FOR BT=15 TO 0 STEP-1 520 IF Z2 AND BT(BT) THEN PRINT "1"; ELSE PRINT "0"; 530 NEXT 540 PRINT:RETURN

Tada! Thanks for those great YouTube comments, I now have a workaround to doing bit detection on all 16 bits. Thank you very much, rflberg!












