Page 1 of 1

Toggling binary bits

Posted: Tue Apr 23, 2019 3:43 pm
by LordVaderUK
I am developing a text adventure and I want to hold various attributes for items in a single byte in order to save memory.

I cannot work out how to toggle a single bit in a byte on and off, so for example if in binary it's &00010000 and I want to toggle that second bit on, resulting in &01010000, how do I do this? I can find assorted examples of how to do it in C but nothing in BBC BASIC... #-o

Re: Toggling binary bits

Posted: Tue Apr 23, 2019 3:49 pm
by dp11
Look up EOR

Re: Toggling binary bits

Posted: Tue Apr 23, 2019 3:51 pm
by cmorley
EOR - exclusive or

Code: Select all

   10A%=&8000
   20PRINT~A%
   30B%=GET
   40A%=A% EOR 2
   50GOTO20
>

Re: Toggling binary bits

Posted: Tue Apr 23, 2019 4:51 pm
by AndyF
Probably not that helpful:
eor_help.png
FWIW I did want to look into something like this for one of my random 'quick type in's' with the thought of using something I was used to on the ZX platform that being BIN xxxxxxxx for a value so I could in effect 'draw' the UDG but it did not seem to appreciate that on the 'B

Pic above is using the HelpRom something I find quite handy to keep installed.

Re: Toggling binary bits

Posted: Tue Apr 23, 2019 9:06 pm
by lurkio
AndyF wrote:
Tue Apr 23, 2019 4:51 pm
...something I was used to on the ZX platform that being BIN xxxxxxxx for a value so I could in effect 'draw' the UDG but it did not seem to appreciate that on the 'B
Try this:

Code: Select all

 10 MODE1
 20 VDU 23,224
 30 VDU FNbin("#      #")
 40 VDU FNbin(" #    # ")
 50 VDU FNbin("  #  #  ")
 60 VDU FNbin("   ##  #")
 70 VDU FNbin("  #  #  ")
 80 VDU FNbin(" # ## # ")
 90 VDU FNbin("#      #")
100 VDU FNbin("   ##   ")
110 PRINT'"   ";
120 PRINTCHR$224'
130 END
140 DEFFNbin(b$):LOCAL i%,b%
150  IF LEN(b$)<>8 PRINT"Wrong length!: ";b$:STOP
160  FOR i%=7 TO 0 STEP-1
170   IF MID$(b$,8-i%,1)="#" b%=b%+2^i%
180  NEXT
190 =b%
Run it in JSBeeb:
:idea:

Re: Toggling binary bits

Posted: Tue Apr 23, 2019 9:41 pm
by MartinB
The code below shows some one-line BASIC binary bit twiddles for bit number B% in integer number M%. Note importantly that B% is the target bit number and the LSB is numbered 0. For example, B% is 0-7 for an 8-bit number (where M% is 0-255) and B% is 0-15 for a 16-bit number (where M% is 0-65535)

Code: Select all

   10 REM * BASIC BIT TWIDDLING *
   20 :
   30 REM * TEST BIT N *
   40 IF (M% AND 2^B%) THEN PRINT"SET" ELSE PRINT"RESET"
   50 :
   60 REM * SET BIT N *
   70 M%=M% OR 2^B%
   80 :
   90 REM * CLEAR BIT N *
  100 M%=M% AND (255-2^B%)
  110 :
  120 REM * TOGGLE BIT N *
  130 M%=M% EOR 2^B%

Just noticed your example.....
I cannot work out how to toggle a single bit in a byte on and off, so for example if in binary it's &00010000 and I want to toggle that second bit on, resulting in &01010000, how do I do this?
Noting that the ampersand (&) prefix actually denotes hex in BBC BASIC, your example start byte is binary 00010000 which equates to decimal 16 or hex &10 and although you refer to toggling (here setting) the 'second' bit, that is actually Bit 6 of the byte. (Bits are numbered from the right to the left, i.e. LSB to MSB, and in an eight-bit number they are therefore Bits 0-7 from LSB to MSB or from right to left.)

So, using my example toggle twiddle above, the following would achieve your specific example....

M%=&10 : B%=6 :M%=M% EOR 2^B%

You will find that 'toggling' (or inverting) is not always appropriate and so the other twiddles show the full range of test, set, reset and toggle.


.

Re: Toggling binary bits

Posted: Wed Apr 24, 2019 11:06 pm
by LordVaderUK
Thanks everyone. Very grateful for the expert input. As you can see, I have a lot to learn (or possibly, re-learn - would you believe I used to program in Z80 assembler for my first full time job?!)